diff --git a/README b/README
index 9b18a3f..1789fbe 100644
--- a/README
+++ b/README
@@ -8,7 +8,6 @@
 
 Here's a brief guide to what's in here:
 
-compiler/      Dart static analyzer.
 editor/        Eclipse-based standalone Dart IDE.
 lib/           Libraries that ship with the Dart runtime (core, html, etc.).
 pkg/           Packages that are not shipped with the core runtime.
diff --git a/README.dart-sdk b/README.dart-sdk
index 8a5c750..c0c4b0d 100644
--- a/README.dart-sdk
+++ b/README.dart-sdk
@@ -8,7 +8,6 @@
   dart           Dart virtual machine
   dart2js        Dart-to-JavaScript compiler
   dartanalyzer   Dart static analyzer
-  dart_analyzer  The older, deprecated Dart static analyzer
   dartdoc        Dart documentation generator
   pub            Pub, the Dart package manager
 
diff --git a/compiler/.gitignore b/compiler/.gitignore
deleted file mode 100644
index 5a9c6a0..0000000
--- a/compiler/.gitignore
+++ /dev/null
@@ -1,41 +0,0 @@
-/compiler
-/third_party
-/compiler_corelib_sources.gypi
-/compiler_corelib_sources.xml
-/corelib_sources.gypi
-/corelib_sources.xml
-/domlib_sources.gypi
-/domlib_sources.xml
-/htmllib_sources.gypi
-/htmllib_sources.xml
-/isolatelib_sources.gypi
-/isolatelib_sources.xml
-/jsonlib_sources.gypi
-/jsonlib_sources.xml
-/sources.gypi
-/sources.txt
-/sources.xml
-/test_sources.gypi
-/test_sources.txt
-/test_sources.xml
-/out
-/xcodebuild
-/Debug
-/DebugARM
-/DebugIA32
-/DebugSIMARM
-/DebugX64
-/Release
-/ReleaseARM
-/ReleaseIA32
-/ReleaseSIMARM
-/ReleaseX64
-/Makefile
-/*.Makefile
-/*.sln
-/*.target.mk
-/*.vcproj
-/*.vcxproj
-/*.vcxproj.filters
-/*.vcxproj.user
-/*.xcodeproj
diff --git a/compiler/README b/compiler/README
deleted file mode 100644
index 4a2c250..0000000
--- a/compiler/README
+++ /dev/null
@@ -1,2 +0,0 @@
-This directory is a placeholder for the eventual Dart compiler.
-The Dart compiler consists of among others a Dart front-end, a Dart->JS backend, a Dart->Dart backend, tree-shaking tools, minification tools.
diff --git a/compiler/api.dart b/compiler/api.dart
deleted file mode 100644
index 660dd83..0000000
--- a/compiler/api.dart
+++ /dev/null
@@ -1,5 +0,0 @@
-library api;
-// dart:core is implicit
-import "dart:html";
-import "dart:json";
-import "dart:isolate";
diff --git a/compiler/build.xml b/compiler/build.xml
deleted file mode 100644
index 7e77b0e..0000000
--- a/compiler/build.xml
+++ /dev/null
@@ -1,185 +0,0 @@
-<!--
-  Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-  for details. All rights reserved. Use of this source code is governed by a
-  BSD-style license that can be found in the LICENSE file.
- -->
-<project default="dist">
-  <!--
-      EDIT DARTC.XML FIRST.  This file is no longer used to build
-      dartc proper.  It is only here to avoid breaking dartium.gyp
-      short term.  Change dartc.xml to get everything working, 
-      then update this file to match.
-  -->
-
-  <import file="sources.xml"/>
-  <import file="test_sources.xml"/>
-
-  <!--
-    The file build.properties does not exist. If provided, properties can be customized.
-  -->
-  <property file="build.properties" />
-
-  <!--
-    Configuration properties.
-  -->
-  <property name="build.dir" value="out"/>
-
-  <property name="build.classes.dir" value="${build.dir}/classes"/>
-
-  <property name="build.test.classes.dir" value="${build.dir}/test/classes"/>
-
-  <property name="dart_analyzer.jar" value="${build.dir}/dart_analyzer.jar"/>
-
-  <property name="dist.dir" value="${build.dir}/dist"/>
-
-  <property name="test.report.dir" value="${build.dir}/test"/>
-
-  <property name="third_party.dir" value="../third_party"/>
-
-  <property name="test_py" location="../tools/test.py"/>
-
-  <!--
-    Define buildtime and runtime classpaths.
-  -->
-  <path id="classpath.compile">
-    <pathelement location="${third_party.dir}/args4j/2.0.12/args4j-2.0.12.jar"/>
-    <pathelement location="${third_party.dir}/guava/r13/guava-13.0.1.jar"/>
-    <pathelement location="${third_party.dir}/json/r2_20080312/json.jar"/>
-  </path>
-
-  <path id="classpath.runtime">
-    <path refid="classpath.compile"/>
-  </path>
-
-  <path id="classpath.compile.tests">
-    <path refid="classpath.compile"/>
-    <pathelement location="${build.classes.dir}"/>
-    <pathelement location="${third_party.dir}/junit/v4_8_2/junit.jar"/>
-  </path>
-
-  <path id="classpath.run.tests">
-    <path refid="classpath.compile.tests"/>
-    <pathelement location="${build.test.classes.dir}"/>
-    <pathelement location="${third_party.dir}/hamcrest/v1_3/hamcrest-core-1.3.0RC2.jar"/>
-    <pathelement location="${third_party.dir}/hamcrest/v1_3/hamcrest-generator-1.3.0RC2.jar"/>
-    <pathelement location="${third_party.dir}/hamcrest/v1_3/hamcrest-integration-1.3.0RC2.jar"/>
-    <pathelement location="${third_party.dir}/hamcrest/v1_3/hamcrest-library-1.3.0RC2.jar"/>
-  </path>
-
-  <target name="compile" description="Compiles all of the java source and copies resources to the classes directory.">
-    <!--
-      Ensure the necessary subdirectories exist.
-    -->
-    <mkdir dir="${build.classes.dir}"/>
-
-    <javac destdir="${build.classes.dir}"
-           sourcepath=""
-           srcdir="java"
-           includes="${java_sources}"
-           fork="true"
-           debug="true"
-           source="1.6"
-           target="1.6"
-           encoding="UTF-8">
-      <classpath refid="classpath.compile"/>
-    </javac>
-    <!--
-      Copy all non-java resources.
-    -->
-    <copy todir="${build.classes.dir}">
-      <filelist refid="java_resources"/>
-    </copy>
-
-  </target>
-
-  <target name="compile-tests" depends="compile" description="Compiles all of the java tests and copies the resources to the test classes directory." >
-    <mkdir dir="${build.test.classes.dir}"/>
-    <javac destdir="${build.test.classes.dir}"
-           sourcepath=""
-           srcdir="javatests"
-           includes="${javatests_sources}"
-           excludes="com/google/dart/compiler/vm/**"
-           fork="true"
-           debug="true"
-           source="1.6"
-           target="1.6"
-           encoding="UTF-8">
-      <classpath refid="classpath.compile.tests"/>
-    </javac>
-    <!--
-      Copy the non-java resources.
-    -->
-    <copy todir="${build.test.classes.dir}">
-      <filelist refid="javatests_resources"/>
-    </copy>
-  </target>
-
-  <target name="dart_analyzer.jar" depends="compile" 
-      description="Creates a jar for dartc without bundling the dependencies.">
-    <jar destfile="${dart_analyzer.jar}" basedir="${build.classes.dir}" manifest="dart_analyzer.mf"/>
-  </target>
-
-  <target name="dist" depends="dart_analyzer.jar" description="Creates a directory that contains a standalone distribution.">
-    <!--
-      Ensure the necessary subdirectories exist.
-    -->
-    <mkdir dir="${dist.dir}/bin"/>
-    <mkdir dir="${dist.dir}/util"/>
-    <mkdir dir="${dist.dir}/util/analyzer"/>
-
-    <!--
-      Copy the dart jar to the lib folder.
-    -->
-    <copy file="${dart_analyzer.jar}" todir="${dist.dir}/util/analyzer"/>
-
-    <!--
-      Re-root the classpaths from third_party into the library folder of the distro.
-    -->
-    <pathconvert property="analyzer.classpath.runtime.unix" targetos="unix" refid="classpath.runtime">
-      <regexpmapper from="${third_party.dir}/(.*)" to="$DART_ANALYZER_LIBS/\1"/>
-    </pathconvert>
-
-    <copy file="scripts/dart_analyzer.sh" tofile="${dist.dir}/bin/dart_analyzer">
-      <filterset>
-        <filter token="CLASSPATH" value="$DART_ANALYZER_LIBS/dart_analyzer.jar:${analyzer.classpath.runtime.unix}"/>
-      </filterset>
-    </copy>
-    <chmod file="${dist.dir}/bin/dart_analyzer" perm="a+rx"/>
-
-    <copy file="scripts/dart_analyzer.bat" tofile="${dist.dir}/bin/dart_analyzer.bat">
-      <filterset>
-        <filter token="CLASSPATH" value="$DART_ANALYZER_LIBS/dart_analyzer.jar:${analyzer.classpath.runtime.win}"/>
-      </filterset>
-    </copy>
-
-   <!--
-      TODO: The following files are not strictly due to dist, move them out.
-    -->
-    <copy todir="${build.dir}">
-      <fileset dir="scripts">
-        <include name="analyzer_metrics.sh"/>
-      </fileset>
-      <filterset>
-        <filter token="CLASSPATH" value="$DARTC_LIBS/dart_analyzer.jar:${analyzer.classpath.runtime.unix}"/>
-      </filterset>
-    </copy>
-    <chmod file="${build.dir}/analyzer_metrics.sh" perm="a+rx"/>
-
-    <!--
-      Copy of all of the dependencies to the lib folder.
-    -->
-    <copy todir="${dist.dir}/util/analyzer">
-      <path refid="classpath.runtime"/>
-      <regexpmapper from="${third_party.dir}/(.*)" to="\1"/>
-    </copy>
-  </target>
-
-  <target name="clean" description="Deletes the build output directory.">
-    <delete dir="${build.dir}"/>
-    <delete dir="${dist.dir}"/>
-  </target>
-
-  <target name="tests.jar" depends="compile-tests">
-    <jar destfile="${build.dir}/tests.jar" basedir="${build.test.classes.dir}"/>
-  </target>
-</project>
diff --git a/compiler/dart-compiler.gyp b/compiler/dart-compiler.gyp
deleted file mode 100644
index 7e589e9..0000000
--- a/compiler/dart-compiler.gyp
+++ /dev/null
@@ -1,80 +0,0 @@
-# Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-# for details. All rights reserved. Use of this source code is governed by a
-# BSD-style license that can be found in the LICENSE file.
-
-{
-  'includes': [
-    'sources.gypi',
-    'test_sources.gypi',
-  ],
-  'targets': [
-    {
-      'target_name': 'dart_analyzer',
-      'type': 'none',
-      'conditions': [
-        [ 'OS!="win"', {
-          'variables': {
-            'script_suffix': '',
-          },
-        }],
-        [ 'OS=="win"', {
-          'variables': {
-            'script_suffix': '.bat',
-          },
-        }],
-      ],
-      'actions': [
-        {
-          'action_name': 'build_dart_analyzer',
-          'inputs': [
-            'sources.gypi',
-            'test_sources.gypi',
-            '<@(java_sources)',
-            '<@(java_resources)',
-            '<@(javatests_sources)',
-            '<@(javatests_resources)',
-            'dart_analyzer.xml',
-            'scripts/dart_analyzer.sh',
-            'scripts/dart_analyzer.bat',
-            'scripts/analyzer_metrics.sh',
-            '../third_party/args4j/2.0.12/args4j-2.0.12.jar',
-            '../third_party/guava/r13/guava-13.0.1.jar',
-            '../third_party/hamcrest/v1_3/hamcrest-core-1.3.0RC2.jar',
-            '../third_party/hamcrest/v1_3/hamcrest-generator-1.3.0RC2.jar',
-            '../third_party/hamcrest/v1_3/hamcrest-integration-1.3.0RC2.jar',
-            '../third_party/hamcrest/v1_3/hamcrest-library-1.3.0RC2.jar',
-          ],
-          'outputs': [
-            '<(INTERMEDIATE_DIR)/<(_target_name)/tests.jar',
-            '<(PRODUCT_DIR)/analyzer/bin/dart_analyzer',
-            '<(PRODUCT_DIR)/analyzer/bin/dart_analyzer.bat',
-            '<(PRODUCT_DIR)/analyzer/util/analyzer/dart_analyzer.jar',
-            '<(PRODUCT_DIR)/analyzer/util/analyzer/args4j/2.0.12/args4j-2.0.12.jar',
-            '<(PRODUCT_DIR)/analyzer/util/analyzer/guava/r13/guava-13.0.1.jar',
-          ],
-          'action' : [
-            '../third_party/apache_ant/1.8.4/bin/ant<(script_suffix)',
-            '-f', 'dart_analyzer.xml',
-            '-Dbuild.dir=<(INTERMEDIATE_DIR)/<(_target_name)',
-            '-Ddist.dir=<(PRODUCT_DIR)/analyzer',
-            'clean',
-            'dist',
-            'tests.jar',
-          ],
-          'message': 'Building dart_analyzer.',
-        },
-        {
-          'action_name': 'copy_tests',
-          'inputs': [ '<(INTERMEDIATE_DIR)/<(_target_name)/tests.jar' ],
-          'outputs': [ '<(PRODUCT_DIR)/analyzer/dart_analyzer_tests.jar' ],
-          'action': [ 'cp', '<@(_inputs)', '<@(_outputs)' ]
-        },
-      ],
-    },
-    {
-      # GYP won't generate a catch-all target if there's only one target.
-      'target_name': 'dummy',
-      'type': 'none',
-    },
-  ],
-}
diff --git a/compiler/dart_analyzer.mf b/compiler/dart_analyzer.mf
deleted file mode 100644
index f85084d..0000000
--- a/compiler/dart_analyzer.mf
+++ /dev/null
@@ -1,3 +0,0 @@
-Manifest-Version: 1.0
-Main-Class: com.google.dart.compiler.DartCompiler
-Class-Path: deploy_deploy.jar
diff --git a/compiler/dart_analyzer.xml b/compiler/dart_analyzer.xml
deleted file mode 100644
index ff63f2f..0000000
--- a/compiler/dart_analyzer.xml
+++ /dev/null
@@ -1,190 +0,0 @@
-<!--
-  Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-  for details. All rights reserved. Use of this source code is governed by a
-  BSD-style license that can be found in the LICENSE file.
- -->
-<project default="dist">
-  <import file="sources.xml"/>
-  <import file="test_sources.xml"/>
-
-  <!--
-    The file build.properties does not exist. If provided, properties can be customized.
-  -->
-  <property file="build.properties" />
-
-  <!--
-    Configuration properties.
-  -->
-  <property name="build.dir" value="out"/>
-
-  <property name="build.classes.dir" value="${build.dir}/classes"/>
-
-  <property name="build.test.classes.dir" value="${build.dir}/test/classes"/>
-
-  <property name="dart_analyzer.jar" value="${build.dir}/dart_analyzer.jar"/>
-
-  <property name="dist.dir" value="${build.dir}/dist"/>
-
-  <property name="test.report.dir" value="${build.dir}/test"/>
-
-  <property name="third_party.dir" value="../third_party"/>
-
-  <property name="test_py" location="../tools/test.py"/>
-
-  <!--
-    Define buildtime and runtime classpaths.
-  -->
-  <path id="classpath.compile">
-    <pathelement location="${third_party.dir}/args4j/2.0.12/args4j-2.0.12.jar"/>
-    <pathelement location="${third_party.dir}/guava/r13/guava-13.0.1.jar"/>
-    <pathelement location="${third_party.dir}/json/r2_20080312/json.jar"/>
-  </path>
-
-  <path id="classpath.runtime">
-    <path refid="classpath.compile"/>
-  </path>
-
-  <path id="classpath.compile.tests">
-    <path refid="classpath.compile"/>
-    <pathelement location="${build.classes.dir}"/>
-    <pathelement location="${third_party.dir}/junit/v4_8_2/junit.jar"/>
-  </path>
-
-  <path id="classpath.run.tests">
-    <path refid="classpath.compile.tests"/>
-    <pathelement location="${build.test.classes.dir}"/>
-    <pathelement location="${third_party.dir}/hamcrest/v1_3/hamcrest-core-1.3.0RC2.jar"/>
-    <pathelement location="${third_party.dir}/hamcrest/v1_3/hamcrest-generator-1.3.0RC2.jar"/>
-    <pathelement location="${third_party.dir}/hamcrest/v1_3/hamcrest-integration-1.3.0RC2.jar"/>
-    <pathelement location="${third_party.dir}/hamcrest/v1_3/hamcrest-library-1.3.0RC2.jar"/>
-    <pathelement location="${third_party.dir}/fest/fest-util-1.1.6.jar"/>
-    <pathelement location="${third_party.dir}/fest/fest-assert-1.4.jar"/>
-  </path>
-
-  <target name="compile" description="Compiles all of the java source and copies resources to the classes directory.">
-    <!--
-      Ensure the necessary subdirectories exist.
-    -->
-    <mkdir dir="${build.classes.dir}"/>
-
-    <javac destdir="${build.classes.dir}"
-           sourcepath=""
-           srcdir="java"
-           includes="${java_sources}"
-           fork="true"
-           debug="true"
-           source="1.6"
-           target="1.6"
-           includeAntRuntime="false">
-      <classpath refid="classpath.compile"/>
-    </javac>
-    <!--
-      Copy all non-java resources.
-    -->
-    <copy todir="${build.classes.dir}">
-      <filelist refid="java_resources"/>
-    </copy>
-  </target>
-
-  <!--
-    We rely on GYP to call these targets when dependencies change, hence this
-    ant file cannot be used standalone.
-  -->
-  <target name="compile-tests" depends="compile" description="Compiles all of the java tests and copies the resources to the test classes directory." >
-    <mkdir dir="${build.test.classes.dir}"/>
-    <javac destdir="${build.test.classes.dir}"
-           sourcepath=""
-           srcdir="javatests"
-           includes="${javatests_sources}"
-           excludes="com/google/dart/compiler/vm/**"
-           fork="true"
-           debug="true"
-           source="1.6"
-           target="1.6"
-           includeAntRuntime="false">
-      <classpath refid="classpath.compile.tests"/>
-    </javac>
-    <!--
-      Copy the non-java resources.
-    -->
-    <copy todir="${build.test.classes.dir}">
-      <filelist refid="javatests_resources"/>
-    </copy>
-  </target>
-
-  <target name="dart_analyzer.jar" depends="compile" description="Creates a jar without bundling the dependencies.">
-    <jar destfile="${dart_analyzer.jar}" basedir="${build.classes.dir}" 
-        manifest="dart_analyzer.mf"/>
-  </target>
-
-  <target name="dist" depends="dart_analyzer.jar" 
-      description="Create a directory with a standalone distribution.">
-    <!--
-      Ensure the necessary subdirectories exist.
-    -->
-    <mkdir dir="${dist.dir}/bin"/>
-    <mkdir dir="${dist.dir}/util"/>
-    <mkdir dir="${dist.dir}/util/analyzer"/>
-
-    <!--
-      Copy the dart jar to the lib folder.
-    -->
-    <copy file="${dart_analyzer.jar}" todir="${dist.dir}/util/analyzer"/>
-
-    <!--
-      Re-root the classpaths from third_party into the util folder of the distro.
-    -->
-    <pathconvert property="analyzer.classpath.runtime.unix" targetos="unix" refid="classpath.runtime">
-      <regexpmapper from="${third_party.dir}/(.*)" to="$DART_ANALYZER_LIBS/\1"/>
-    </pathconvert>
-
-    <pathconvert property="analyzer.classpath.runtime.win" targetos="windows" refid="classpath.runtime">
-      <regexpmapper from="(.*)third_party\\(.*)" to="%DART_ANALYZER_LIBS%\\\2"/>
-    </pathconvert>
-
-    <copy file="scripts/dart_analyzer.sh" tofile="${dist.dir}/bin/dart_analyzer">
-      <filterset>
-        <filter token="CLASSPATH" value="$DART_ANALYZER_LIBS/dart_analyzer.jar:${analyzer.classpath.runtime.unix}"/>
-      </filterset>
-    </copy>
-    <chmod file="${dist.dir}/bin/dart_analyzer" perm="a+rx"/>
-
-    <copy file="scripts/dart_analyzer.bat" tofile="${dist.dir}/bin/dart_analyzer.bat">
-      <filterset>
-        <filter
-          token="CLASSPATH"
-          value="%DART_ANALYZER_LIBS%\dart_analyzer.jar;${analyzer.classpath.runtime.win}"/>
-      </filterset>
-    </copy>
-
-   <!--
-      TODO: The following files are not strictly due to dist, move them out.
-    -->
-    <copy todir="${build.dir}">
-      <fileset dir="scripts">
-        <include name="analyzer_metrics.sh"/>
-      </fileset>
-      <filterset>
-        <filter token="CLASSPATH" value="$DART_ANALYZER_LIBS/dart_analyzer.jar:${analyzer.classpath.runtime.unix}"/>
-      </filterset>
-    </copy>
-    <chmod file="${build.dir}/analyzer_metrics.sh" perm="a+rx"/>
-
-    <!--
-      Copy of all dependencies to the util folder.
-    -->
-    <copy todir="${dist.dir}/util/analyzer">
-      <path refid="classpath.runtime"/>
-      <regexpmapper from="(.*)third_party[/\\](.*)" to="\2"/>
-    </copy>
-  </target>
-
-  <target name="clean" description="Deletes the build output directory.">
-    <delete dir="${build.dir}"/>
-    <delete dir="${dist.dir}"/>
-  </target>
-
-  <target name="tests.jar" depends="compile-tests">
-    <jar destfile="${build.dir}/tests.jar" basedir="${build.test.classes.dir}"/>
-  </target>
-</project>
diff --git a/compiler/dartium.gyp b/compiler/dartium.gyp
deleted file mode 100644
index 83a32e9..0000000
--- a/compiler/dartium.gyp
+++ /dev/null
@@ -1,39 +0,0 @@
-# Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-# for details. All rights reserved. Use of this source code is governed by a
-# BSD-style license that can be found in the LICENSE file.
-
-# TODO(vsm): Remove this file and use dart.gyp once that can be pulled
-# into the dartium build.
-{
-  'includes': [
-    # TODO(mmendez): Add the appropriate gypi includes here.
-  ],
-  'targets': [
-    {
-      'target_name': 'dartc',
-      'type': 'none',
-      'actions': [
-        {
-          'action_name': 'Build and test',
-          'inputs': [
-          ],
-          'outputs': [
-            'dummy_target',
-          ],
-          'action' : [
-            '../third_party/apache_ant/1.8.4/bin/ant',
-            '-Dbuild.dir=<(PRODUCT_DIR)/ant-out',
-            'clean',
-            'dist',
-          ],
-          'message': 'Building dartc.',
-        },
-      ],
-    },
-    {
-      # GYP won't generate a catch-all target if there's only one target.
-      'target_name': 'dummy',
-      'type': 'none',
-    },
-  ],
-}
diff --git a/compiler/eclipse.workspace/README.txt b/compiler/eclipse.workspace/README.txt
deleted file mode 100644
index 3f0eaa0..0000000
--- a/compiler/eclipse.workspace/README.txt
+++ /dev/null
@@ -1,49 +0,0 @@
-This is an Eclipse workspace for Helios Service Release 2.
-
-HOW TO
-
-1. When you open Eclipse the first time, it will ask you to create a
-   workspace or select an existing one. You can use this directory as
-   workspace, or you can choose a different one.
-
-2. If you're already using Eclipse, you can either switch to a new
-   workspace (File > Switch Workspace) or use your current workspace.
-
-3. Add the following "Path Variable" to your workspace:
-   (Open Preferences... > General > Workspace > Linked Resources)
-   DART_TRUNK: point to the root of your checkout
-  
-
-4. Add a "Classpath Variable" to your workspace called DART_TRUNK
-   that points to the same directory as your DART_TRUNK path variable.
-   (Open Preferences... > Java > Build Path > Classpath Variables).
-
-5. Regardless if you're using this directory as a workspace, you have
-   to import the projects (File > Import... > General > Existing
-   Projects into Workspace).
-
-6. Click "Next >"
-
-7. Select root directory. Browse to: compiler/eclipse.workspace.
-
-8. It should find and select two projects (dartc and tests).
-
-9. Click Finish. (At this point Eclipse may get stuck, if so, exit
-   Eclipse by right-clicking on the dock icon, and restart).
-
-10. Open Preferences... > Java > Compiler > Errors/Warnings > Potential
-    programming problems. Change "Serializable class without
-    serialVersionUID" to "Ignore".
-
-11. Import the launch configuration (File > Import... > Run/Debug >
-    Launch Configurations).
-
-12. Click "Next >"
-
-13. In SVN, browse to: compiler/eclipse.workspace/tests.
-
-14. Select "tests".
-
-15. Click Finish.
-
-16. Try running the tests: Run > Run History > dartc test suites.
diff --git a/compiler/eclipse.workspace/dartc/.classpath b/compiler/eclipse.workspace/dartc/.classpath
deleted file mode 100644
index 12f7079..0000000
--- a/compiler/eclipse.workspace/dartc/.classpath
+++ /dev/null
@@ -1,14 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<classpath>
-	<classpathentry kind="src" path="src"/>
-	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
-	<classpathentry kind="var" path="DART_TRUNK/third_party/args4j/2.0.12/args4j-2.0.12.jar" sourcepath="/DART_TRUNK/third_party/args4j/2.0.12/args4j-2.0.12-src.jar"/>
-	<classpathentry kind="var" path="DART_TRUNK/third_party/guava/r13/guava-13.0.1.jar" sourcepath="/DART_TRUNK/third_party/guava/r13/guava-13.0.1-sources.zip"/>
-	<classpathentry kind="var" path="DART_TRUNK/third_party/hamcrest/v1_3/hamcrest-core-1.3.0RC2.jar"/>
-	<classpathentry kind="var" path="DART_TRUNK/third_party/hamcrest/v1_3/hamcrest-generator-1.3.0RC2.jar"/>
-	<classpathentry kind="var" path="DART_TRUNK/third_party/hamcrest/v1_3/hamcrest-integration-1.3.0RC2.jar"/>
-	<classpathentry kind="var" path="DART_TRUNK/third_party/hamcrest/v1_3/hamcrest-library-1.3.0RC2.jar"/>
-	<classpathentry kind="var" path="DART_TRUNK/third_party/json/r2_20080312/json.jar"/>
-	<classpathentry kind="var" path="DART_TRUNK/third_party/junit/v4_8_2/junit.jar" sourcepath="/DART_TRUNK/third_party/junit/v4_8_2/junit-src.jar"/>
-	<classpathentry kind="output" path="output"/>
-</classpath>
diff --git a/compiler/eclipse.workspace/dartc/.gitignore b/compiler/eclipse.workspace/dartc/.gitignore
deleted file mode 100644
index 1f57b97..0000000
--- a/compiler/eclipse.workspace/dartc/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-/output
diff --git a/compiler/eclipse.workspace/dartc/.project b/compiler/eclipse.workspace/dartc/.project
deleted file mode 100644
index 58e595c..0000000
--- a/compiler/eclipse.workspace/dartc/.project
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<projectDescription>
-	<name>dartc</name>
-	<comment></comment>
-	<projects>
-	</projects>
-	<buildSpec>
-		<buildCommand>
-			<name>org.eclipse.jdt.core.javabuilder</name>
-			<arguments>
-			</arguments>
-		</buildCommand>
-	</buildSpec>
-	<natures>
-		<nature>org.eclipse.jdt.core.javanature</nature>
-	</natures>
-	<linkedResources>
-		<link>
-			<name>src</name>
-			<type>2</type>
-			<locationURI>DART_TRUNK/compiler/java</locationURI>
-		</link>
-	</linkedResources>
-</projectDescription>
diff --git a/compiler/eclipse.workspace/tests/.classpath b/compiler/eclipse.workspace/tests/.classpath
deleted file mode 100644
index 704cbcd..0000000
--- a/compiler/eclipse.workspace/tests/.classpath
+++ /dev/null
@@ -1,12 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<classpath>
-	<classpathentry kind="src" path="cases"/>
-	<classpathentry kind="src" path="suites"/>
-	<classpathentry kind="src" path="imported"/>
-	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
-	<classpathentry combineaccessrules="false" kind="src" path="/dartc"/>
-	<classpathentry kind="var" path="DART_TRUNK/third_party/args4j/2.0.12/args4j-2.0.12.jar" sourcepath="/DART_TRUNK/third_party/args4j/2.0.12/args4j-2.0.12-src.jar"/>
-	<classpathentry kind="var" path="DART_TRUNK/third_party/junit/v4_8_2/junit.jar"/>
-	<classpathentry kind="var" path="DART_TRUNK/third_party/guava/r13/guava-13.0.1.jar"/>
-	<classpathentry kind="output" path="output"/>
-</classpath>
diff --git a/compiler/eclipse.workspace/tests/.gitignore b/compiler/eclipse.workspace/tests/.gitignore
deleted file mode 100644
index 4ab5c99..0000000
--- a/compiler/eclipse.workspace/tests/.gitignore
+++ /dev/null
@@ -1,2 +0,0 @@
-/output
-/.settings
diff --git a/compiler/eclipse.workspace/tests/.project b/compiler/eclipse.workspace/tests/.project
deleted file mode 100644
index 980f025..0000000
--- a/compiler/eclipse.workspace/tests/.project
+++ /dev/null
@@ -1,118 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<projectDescription>
-	<name>tests</name>
-	<comment></comment>
-	<projects>
-	</projects>
-	<buildSpec>
-		<buildCommand>
-			<name>org.eclipse.jdt.core.javabuilder</name>
-			<arguments>
-			</arguments>
-		</buildCommand>
-	</buildSpec>
-	<natures>
-		<nature>org.eclipse.jdt.core.javanature</nature>
-	</natures>
-	<linkedResources>
-		<link>
-			<name>cases</name>
-			<type>2</type>
-			<locationURI>DART_TRUNK/compiler/javatests</locationURI>
-		</link>
-		<link>
-			<name>suites</name>
-			<type>2</type>
-			<locationURI>DART_TRUNK/compiler/javatests</locationURI>
-		</link>
-		<link>
-			<name>test.py</name>
-			<type>1</type>
-			<locationURI>DART_TRUNK/tools/test.py</locationURI>
-		</link>
-		<link>
-			<name>imported/third_party/java_src/dart/corelib/tests</name>
-			<type>2</type>
-			<locationURI>DART_TRUNK/corelib/tests</locationURI>
-		</link>
-		<link>
-			<name>imported/third_party/java_src/dart/execution/runtime/tests</name>
-			<type>2</type>
-			<locationURI>DART_TRUNK/runtime/tests</locationURI>
-		</link>
-	</linkedResources>
-	<filteredResources>
-		<filter>
-			<id>1311331907127</id>
-			<name>cases</name>
-			<type>22</type>
-			<matcher>
-				<id>org.eclipse.ui.ide.multiFilter</id>
-				<arguments>1.0-name-matches-false-false-*Tests.java</arguments>
-			</matcher>
-		</filter>
-		<filter>
-			<id>1311331781529</id>
-			<name>imported</name>
-			<type>21</type>
-			<matcher>
-				<id>org.eclipse.ui.ide.multiFilter</id>
-				<arguments>1.0-name-matches-false-false-*.dart</arguments>
-			</matcher>
-		</filter>
-		<filter>
-			<id>1311331571786</id>
-			<name>jscomp</name>
-			<type>21</type>
-			<matcher>
-				<id>org.eclipse.ui.ide.multiFilter</id>
-				<arguments>1.0-name-matches-false-false-*OptTests.java</arguments>
-			</matcher>
-		</filter>
-		<filter>
-			<id>1311331079908</id>
-			<name>suites</name>
-			<type>21</type>
-			<matcher>
-				<id>org.eclipse.ui.ide.multiFilter</id>
-				<arguments>1.0-name-matches-true-false-*Tests.java</arguments>
-			</matcher>
-		</filter>
-		<filter>
-			<id>1311331715338</id>
-			<name>cases/com/google/dart/compiler</name>
-			<type>10</type>
-			<matcher>
-				<id>org.eclipse.ui.ide.multiFilter</id>
-				<arguments>1.0-name-matches-false-false-vm</arguments>
-			</matcher>
-		</filter>
-		<filter>
-			<id>1311331633045</id>
-			<name>jscomp/com/google/dart/compiler</name>
-			<type>10</type>
-			<matcher>
-				<id>org.eclipse.ui.ide.multiFilter</id>
-				<arguments>1.0-name-matches-false-false-vm</arguments>
-			</matcher>
-		</filter>
-		<filter>
-			<id>1311331190572</id>
-			<name>suites/com/google/dart/compiler</name>
-			<type>10</type>
-			<matcher>
-				<id>org.eclipse.ui.ide.multiFilter</id>
-				<arguments>1.0-name-matches-false-false-vm</arguments>
-			</matcher>
-		</filter>
-		<filter>
-			<id>1311331455715</id>
-			<name>suites/com/google/dart/compiler/end2end</name>
-			<type>6</type>
-			<matcher>
-				<id>org.eclipse.ui.ide.multiFilter</id>
-				<arguments>1.0-name-matches-false-false-*OptTests.java</arguments>
-			</matcher>
-		</filter>
-	</filteredResources>
-</projectDescription>
diff --git a/compiler/eclipse.workspace/tests/SharedTests.launch b/compiler/eclipse.workspace/tests/SharedTests.launch
deleted file mode 100644
index 7e43202..0000000
--- a/compiler/eclipse.workspace/tests/SharedTests.launch
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<launchConfiguration type="org.eclipse.jdt.junit.launchconfig">
-<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS">
-<listEntry value="/tests/suites/com/google/dart/corelib/SharedTests.java"/>
-</listAttribute>
-<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES">
-<listEntry value="1"/>
-</listAttribute>
-<listAttribute key="org.eclipse.debug.ui.favoriteGroups">
-<listEntry value="org.eclipse.debug.ui.launchGroup.debug"/>
-<listEntry value="org.eclipse.debug.ui.launchGroup.run"/>
-</listAttribute>
-<stringAttribute key="org.eclipse.jdt.junit.CONTAINER" value=""/>
-<booleanAttribute key="org.eclipse.jdt.junit.KEEPRUNNING_ATTR" value="false"/>
-<stringAttribute key="org.eclipse.jdt.junit.TESTNAME" value=""/>
-<stringAttribute key="org.eclipse.jdt.junit.TEST_KIND" value="org.eclipse.jdt.junit.loader.junit3"/>
-<stringAttribute key="org.eclipse.jdt.launching.MAIN_TYPE" value="com.google.dart.corelib.SharedTests"/>
-<stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="tests"/>
-<stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-ea&#10;-Dcom.google.dart.corelib.SharedTests.test_py=${resource_loc:/tests/test.py}&#10;"/>
-</launchConfiguration>
diff --git a/compiler/eclipse.workspace/tests/TestSharedTests.launch b/compiler/eclipse.workspace/tests/TestSharedTests.launch
deleted file mode 100644
index 6854d4e..0000000
--- a/compiler/eclipse.workspace/tests/TestSharedTests.launch
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<launchConfiguration type="org.eclipse.jdt.junit.launchconfig">
-<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS">
-<listEntry value="/tests/suites/com/google/dart/corelib/TestSharedTests.java"/>
-</listAttribute>
-<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES">
-<listEntry value="1"/>
-</listAttribute>
-<listAttribute key="org.eclipse.debug.ui.favoriteGroups">
-<listEntry value="org.eclipse.debug.ui.launchGroup.debug"/>
-<listEntry value="org.eclipse.debug.ui.launchGroup.run"/>
-</listAttribute>
-<stringAttribute key="org.eclipse.jdt.junit.CONTAINER" value=""/>
-<booleanAttribute key="org.eclipse.jdt.junit.KEEPRUNNING_ATTR" value="false"/>
-<stringAttribute key="org.eclipse.jdt.junit.TESTNAME" value=""/>
-<stringAttribute key="org.eclipse.jdt.junit.TEST_KIND" value="org.eclipse.jdt.junit.loader.junit3"/>
-<stringAttribute key="org.eclipse.jdt.launching.MAIN_TYPE" value="com.google.dart.corelib.TestSharedTests"/>
-<stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="tests"/>
-<stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-ea&#10;-Dcom.google.dart.corelib.SharedTests.test_py=${resource_loc:/tests/test.py}&#10;"/>
-</launchConfiguration>
diff --git a/compiler/eclipse.workspace/tests/dartc_tests_suites.launch b/compiler/eclipse.workspace/tests/dartc_tests_suites.launch
deleted file mode 100644
index 4570ece..0000000
--- a/compiler/eclipse.workspace/tests/dartc_tests_suites.launch
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<launchConfiguration type="org.eclipse.jdt.junit.launchconfig">
-<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS">
-<listEntry value="/tests/suites"/>
-</listAttribute>
-<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES">
-<listEntry value="2"/>
-</listAttribute>
-<mapAttribute key="org.eclipse.debug.core.environmentVariables">
-</mapAttribute>
-<listAttribute key="org.eclipse.debug.ui.favoriteGroups">
-<listEntry value="org.eclipse.debug.ui.launchGroup.debug"/>
-<listEntry value="org.eclipse.debug.ui.launchGroup.run"/>
-</listAttribute>
-<stringAttribute key="org.eclipse.jdt.junit.CONTAINER" value="=tests/suites"/>
-<booleanAttribute key="org.eclipse.jdt.junit.KEEPRUNNING_ATTR" value="false"/>
-<stringAttribute key="org.eclipse.jdt.junit.TESTNAME" value=""/>
-<stringAttribute key="org.eclipse.jdt.junit.TEST_KIND" value="org.eclipse.jdt.junit.loader.junit3"/>
-<stringAttribute key="org.eclipse.jdt.launching.MAIN_TYPE" value=""/>
-<stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="tests"/>
-<stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-ea&#10;-Dcom.google.dart.corelib.SharedTests.test_py=${resource_loc:/tests/test.py}&#10;"/>
-</launchConfiguration>
diff --git a/compiler/generate_systemlibrary_list.py b/compiler/generate_systemlibrary_list.py
deleted file mode 100644
index 1754436..0000000
--- a/compiler/generate_systemlibrary_list.py
+++ /dev/null
@@ -1,122 +0,0 @@
-#!/usr/bin/env python
-# Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-# for details. All rights reserved. Use of this source code is governed by a
-# BSD-style license that can be found in the LICENSE file.
-
-from __future__ import with_statement
-import StringIO
-import os
-import sys
-import re
-from collections import deque
-
-class GenerateError(Exception):
-
-  def __init__(self, value):
-    self.value = value
-
-  def __str__(self):
-    return repr(self.value)
-
-
-class Generator:
-
-  def __init__(self, base_directory, name, output, path, *includes):
-    self.base_directory = base_directory
-    self.name = name
-    self.output = output
-    self.path = path
-    self.includes = set()
-    for x in includes:
-      self.includes.add(x)
-    self.sources = []
-    self.resources = []
-
-  def _list_files(self):
-    drain = deque()
-    drain.extend(self.includes)
-    while len(drain) > 0:
-      target = drain.popleft()
-      # Avoid circular dependencies
-      if target in self.resources:
-        continue
-      if (target.startswith("dart:")):
-        continue
-      self.resources.append(target)
-      if (target.endswith(".dart")):
-        with open(os.path.join(self.base_directory,self.path,target),"r") as fobj:
-          text = fobj.read()
-        file_sources = re.findall(r"#source\(['\"](?P<name>.*)['\"]\);",text)
-        file_native = re.findall(r"#native\(['\"](?P<name>.*)['\"]\);",text)
-        file_imports = re.findall(r"#import\(['\"](?P<name>.*)['\"]\);",text)
-        self.resources.extend(file_sources)
-        self.resources.extend(file_native)
-        drain.extend(file_imports)
-    self.sources.sort()
-    self.resources.sort()
-
-  def _print_gypi_files(self, out, name, files):
-    out.write("    '%s': [\n" % name)
-    for filename in files:
-      out.write("      '%s/%s',\n" % (self.path, filename))
-    out.write("    ],\n")
-
-  def _print_ant_files(self, out, name, files):
-    out.write("  <filelist id='%s' dir='%s'>\n" % (name, self.path))
-    for filename in files:
-      out.write("    <file name='%s'/>\n" % filename)
-    out.write("  </filelist>\n")
-    out.write("  <pathconvert pathsep=',' property='%s' refid='%s'>\n"
-              % (name, name))
-    out.write("    <map from='${basedir}/%s/' to=''/>\n" % self.path)
-    out.write("  </pathconvert>\n")
-
-  def _make_output(self, file_name):
-    if os.path.exists(file_name):
-      return StringIO.StringIO()
-    else:
-      return file(file_name, 'w')
-
-  def _close(self, file_name, output):
-    if not isinstance(output, StringIO.StringIO):
-      output.close()
-      return
-    new_text = output.getvalue()
-    output.close()
-    with open(file_name, 'r') as f:
-      old_text = f.read()
-    if old_text == new_text:
-      return
-    sys.stderr.write('Updating %s\n' % file_name)
-    with open(file_name, 'w') as f:
-      f.write(new_text)
-
-  def generate(self):
-    self._list_files()
-    file_name = self.output + '.gypi';
-    gypi = self._make_output(file_name)
-    gypi.write("{\n  'variables': {\n")
-    self._print_gypi_files(gypi, self.name + '_sources', self.sources)
-    self._print_gypi_files(gypi, self.name + '_resources', self.resources)
-    gypi.write("  },\n}\n")
-    self._close(file_name, gypi)
-    file_name = self.output + '.xml'
-    ant = self._make_output(file_name)
-    ant.write("<project>\n")
-    self._print_ant_files(ant, self.name + '_sources', self.sources)
-    self._print_ant_files(ant, self.name + '_resources', self.resources)
-    ant.write("</project>\n")
-    self._close(file_name, ant)
-
-
-def Main(script_name = None, name = None, output = None, path = None,
-         *rest):
-  if not path:
-    raise GenerateError("usage: %s NAME OUTPUT PATH EXCLUDE_DIR_NAME ..."
-                        % script_name)
-  base_directory = os.path.dirname(output)
-  Generator(base_directory, name, output, path, *rest).generate()
-
-
-if __name__ == '__main__':
-  sys.exit(Main(*sys.argv))
diff --git a/compiler/java/com/google/dart/compiler/CommandLineOptions.java b/compiler/java/com/google/dart/compiler/CommandLineOptions.java
deleted file mode 100644
index 0e3ed28..0000000
--- a/compiler/java/com/google/dart/compiler/CommandLineOptions.java
+++ /dev/null
@@ -1,347 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler;
-
-import com.google.common.collect.Lists;
-import com.google.dart.compiler.CompilerConfiguration.ErrorFormat;
-import com.google.dart.compiler.util.apache.StringUtils;
-
-import org.kohsuke.args4j.Argument;
-import org.kohsuke.args4j.CmdLineException;
-import org.kohsuke.args4j.CmdLineParser;
-import org.kohsuke.args4j.Option;
-
-import java.io.File;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-
-/**
- * Options that can be specified on the command line.
- */
-public class CommandLineOptions {
-
-  /**
-   * Command line options accepted by the {@link DartCompiler} entry point.
-   */
-  public static class CompilerOptions {
-
-    @Option(name = "--batch", aliases = { "-batch" },
-        usage = "Batch mode (for unit testing)")
-    private boolean batch = false;
-
-    @Option(name = "--error_format",
-        usage = "Format errors as normal or machine")
-    private String errorFormat = "";
-    
-    @Option(name = "--machine", //
-    usage = "Print errors in a format suitable for parsing")
-    private boolean machineFormat = false;
-    
-    @Option(name = "--extended-exit-code",
-        usage = "0 - clean; 1 - has warnings; 2 - has errors")
-    private boolean extendedExitCode = false;
-
-    @Option(name = "--enable_type_checks",
-        usage = "Generate runtime type checks")
-    private boolean developerModeChecks = false;
-
-    @Option(name = "--ignore-unrecognized-flags",
-        usage = "Ignore unrecognized command line flags")
-    private boolean ignoreUnrecognizedFlags = false;
-
-    @Option(name = "--jvm-metrics-detail",
-        usage = "Display summary (default) or\n verbose metrics")
-    private String jvmMetricDetail = "summary";
-
-    @Option(name = "--jvm-metrics-format",
-        usage = "Output metrics in tabular (default)\n or pretty format")
-    private String jvmMetricFormat = "tabular";
-
-    @Option(name = "--jvm-metrics-type",
-        usage = "Comma-separated list to display:\n "
-        + "  all:  (default) all stat types\n "
-        + "  gc:   show garbage collection stats\n "
-        + "  mem:  show memory stats\n "
-        + "  jit:  show jit stats")
-    private String jvmMetricType = "all";
-
-    // leave the command line flag for legacy purposes.
-    @SuppressWarnings("unused")
-    @Option(name = "--noincremental",
-        usage = "Disable incremental compilation (default)")
-    private boolean noincremental = true; // not used, just a placeholder for arg parsing
-
-    @Option(name = "--incremental",
-    usage = "Enable incremental compilation")
-    private boolean incremental = false;
-
-    @Option(name = "--work", aliases = { "-out" },
-        usage = "Directory to receive compiler output\n for future incremental builds")
-    private File workDirectory = new File("out");
-
-    @Option(name = "--help", aliases = { "-?", "-help" },
-        usage = "Prints this help message")
-    private boolean showHelp = false;
-
-    @Option(name = "--jvm-metrics",
-        usage = "Print jvm metrics at end of compile")
-    private boolean showJvmMetrics = false;
-
-    @Option(name = "--metrics",
-        usage = "Print compilation metrics")
-    private boolean showMetrics = false;
-
-    @Option(name = "--fatal-type-errors", aliases = { "-fatal-type-errors" },
-        usage = "Treat type errors as fatal")
-    private boolean typeErrorsAreFatal = false;
-
-    @Option(name = "--fatal-warnings", aliases = { "-Werror" },
-        usage = "Treat non-type warnings as fatal")
-    private boolean warningsAreFatal = false;
-
-    @Option(name = "--platform",
-        usage = "Platform libraries to analyze (e.g. dartium, vm, dart2js, any)")
-    private String platformName = PackageLibraryManager.DEFAULT_PLATFORM;
-
-    @Option(name = "--dart-sdk",
-        usage = "Path to dart sdk.  (system property com.google.dart.sdk)")
-    private File dartSdkPath = PackageLibraryManager.DEFAULT_SDK_PATH;
-    
-    @Option(name = "--package-root",
-        usage = "Root directory used for the package: scheme")
-    private File packageRoot = PackageLibraryManager.DEFAULT_PACKAGE_ROOT;
-    
-    @Option(name = "--show-sdk-warnings", usage = "show warnings from SDK source")
-    private boolean showSdkWarnings = false;
-    
-    @Option(name = "--source-from-ast",
-        usage = "For debugging, reconstitute source code from the parsed AST.")
-    private boolean showSourceFromAst = false;
-
-    @Option(name = "--resolve-on-parse-error",
-        usage = "For debugging, continue on with resolution even if there are parse errors.")
-    private boolean resolveDespiteParseErrors;
-
-    @Option(name = "--type-checks-for-inferred-types",
-        usage = "[not in spec] Enables 'interface has no method/field' for receivers with inferred types.")
-    private boolean typeChecksForInferredTypes = false;
-
-    @Option(name = "--version",
-        usage = "Show analyzer version")
-    private boolean showVersion = false;
-
-    @Argument
-    private final List<String> sourceFiles = new ArrayList<String>();
-
-    public String getJvmMetricOptions() {
-      if (!showJvmMetrics) {
-        return null;
-      }
-      return jvmMetricDetail + ":" + jvmMetricFormat + ":" + jvmMetricType;
-    }
-
-    public String getPlatformName() {
-      return platformName;
-    }
-
-    /**
-     * @return the packageRoot
-     */
-    public File getPackageRoot() {
-      return packageRoot;
-    }
-
-    public File getDartSdkPath() {
-      return dartSdkPath;
-    }
-    
-    public boolean extendedExitCode() {
-      return extendedExitCode;
-    }
-
-    /**
-     * Returns whether warnings from SDK files should be suppressed.
-     */
-    public boolean suppressSdkWarnings() {
-      return !showSdkWarnings;
-    }
-    
-    /**
-     * Returns whether inferred types should be used for type checks.
-     */
-    public boolean typeChecksForInferredTypes() {
-      return this.typeChecksForInferredTypes;
-    }
-    
-    /**
-     * Returns whether "no such member" should be reported for classes which implement
-     * "noSuchMethod" method.
-     */
-    public boolean reportNoMemberWhenHasInterceptor() {
-      return true;
-    }
-    
-    /**
-     * Returns the list of files passed to the compiler.
-     */
-    public List<String> getSourceFiles() {
-      return sourceFiles;
-    }
-
-    /**
-     * Returns the path to receive compiler intermediate output.
-     */
-    public File getWorkDirectory() {
-      return workDirectory;
-    }
-
-    public boolean ignoreUnrecognizedFlags() {
-      return ignoreUnrecognizedFlags;
-    }
-
-    /**
-     * Returns whether the compiler should attempt to incrementally recompile.
-     */
-    public boolean buildIncrementally() {
-      return incremental;
-    }
-
-    public boolean shouldBatch() {
-      return batch;
-    }
-
-    public boolean resolveDespiteParseErrors() {
-      return resolveDespiteParseErrors;
-    }
-    
-    /**
-     * Returns <code>true</code> if the compiler should print it's help message.
-     */
-    public boolean showHelp() {
-      return showHelp;
-    }
-
-    public boolean showJvmMetrics() {
-      return showJvmMetrics;
-    }
-
-    public boolean showMetrics() {
-      return showMetrics;
-    }
-
-    public boolean showVersion() {
-      return showVersion;
-    }
-
-    /**
-     * if <code>true</code>, run the AST back through the DartSourceVisitor to create source
-     * from the parsed AST and print to stdout.
-     */
-    public boolean showSourceFromAst() {
-      return showSourceFromAst;
-    }
-    
-    /**
-     * Returns whether type errors are fatal.
-     */
-    public boolean typeErrorsAreFatal() {
-      return typeErrorsAreFatal;
-    }
-
-    /**
-     * Returns whether warnings (excluding type warnings) are fatal.
-     */
-    public boolean warningsAreFatal() {
-      return warningsAreFatal;
-    }
-
-    public boolean developerModeChecks() {
-      return developerModeChecks;
-    }
-
-    /**
-     * @return the format to use for printing errors
-     */
-    public ErrorFormat printErrorFormat() {
-      if (machineFormat) {
-        return ErrorFormat.MACHINE;
-      }
-      
-      String lowerError = errorFormat.toLowerCase();
-      
-      if ("machine".equals(lowerError)) {
-        return ErrorFormat.MACHINE;
-      }
-      
-      return ErrorFormat.NORMAL;
-    }
-  }
-
-  /**
-   * Parses command line options, handling the feature to ignore unrecognized
-   * flags.
-   *
-   * If one of the options is 'ignore-unrecognized-flags', then any exceptions
-   * for 'not a valid option' are suppressed.
-   *
-   * @param args Arguments passed from main()
-   * @param parsedOptions [out parameter] parsed options
-   * @throws CmdLineException Thrown if there is a problem parsing the options.
-   */
-  public static CmdLineParser parse(String[] args, CompilerOptions parsedOptions)
-      throws CmdLineException {
-    // convert new "--name=value" into old "--name value" style
-    {
-      List<String> argList = Lists.newArrayList();
-      for (String arg : args) {
-        String[] parts = StringUtils.split(arg, '=');
-        Collections.addAll(argList, parts);
-      }
-      args = argList.toArray(new String[argList.size()]);
-    }
-
-    boolean ignoreUnrecognized = false;
-    for (String arg : args) {
-      if (arg.equals("--ignore-unrecognized-flags")) {
-        ignoreUnrecognized = true;
-        break;
-      }
-    }
-
-    if (!ignoreUnrecognized) {
-      CmdLineParser cmdLineParser = new CmdLineParser(parsedOptions);
-      cmdLineParser.parseArgument(args);
-      return cmdLineParser;
-    }
-    CmdLineParser cmdLineParser = new CmdLineParser(parsedOptions);
-    for (int i = 0, len = args.length; i < len; i++) {
-      try {
-        cmdLineParser.parseArgument(args);
-      } catch (CmdLineException e) {
-        String msg = e.getMessage();
-
-        if (e.getMessage().endsWith(" is not a valid option")) {
-          String option = msg.substring(1);
-          int closeQuote = option.indexOf('\"');
-          option = option.substring(0, closeQuote);
-          List<String> newArgs = Lists.newArrayList();
-          for (String arg : args) {
-            if (arg.equals(option)) {
-              System.out.println("(Ignoring unrecognized flag: " + arg + ")");
-              continue;
-            }
-            newArgs.add(arg);
-          }
-          args = newArgs.toArray(new String[newArgs.size()]);
-          cmdLineParser = new CmdLineParser(parsedOptions);
-          continue;
-        }
-      }
-      break;
-    }
-    return cmdLineParser;
-  }
-}
diff --git a/compiler/java/com/google/dart/compiler/CompilerConfiguration.java b/compiler/java/com/google/dart/compiler/CompilerConfiguration.java
deleted file mode 100644
index 7216edb..0000000
--- a/compiler/java/com/google/dart/compiler/CompilerConfiguration.java
+++ /dev/null
@@ -1,86 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler;
-
-import com.google.dart.compiler.CommandLineOptions.CompilerOptions;
-import com.google.dart.compiler.metrics.CompilerMetrics;
-
-import java.io.File;
-import java.util.List;
-
-/**
- * A configuration for the Dart compiler specifying which phases will be executed.
- */
-public interface CompilerConfiguration {
-
-  enum ErrorFormat {
-    NORMAL,  // Library/File, line, message
-    MACHINE, // All information including severity, subsystem, etc
-  }
-
-  List<DartCompilationPhase> getPhases();
-
-  /**
-   * Indicates whether developer-mode runtime checks are needed. 
-   * @return true if developer-mode checks should be inserted, false if not
-   */
-  boolean developerModeChecks();
-
-  /**
-   * Returns the {@link CompilerMetrics} instance or <code>null</code> if metrics should not be
-   * recorded.
-   *
-   * @return the metrics instance, <code>null</code> if metrics should not be recorded
-   */
-  CompilerMetrics getCompilerMetrics();
-
-  /**
-   * Returns a comma-separated string list of options for displaying jvm metrics.
-   * Returns <code>null</code> if jvm metrics are not enabled.
-   */
-  String getJvmMetricOptions();
-
-  boolean typeErrorsAreFatal();
-
-  boolean warningsAreFatal();
-
-  /**
-   * Returns <code>true</code> if the compiler should try to resolve
-   * even after having seen parse-errors.
-   */
-  boolean resolveDespiteParseErrors();
-
-  /**
-   * Temporary flag to turn on incremental compilation. This will be removed once we're certain
-   * incremental compilation is correct.
-   */
-  boolean incremental();
-
-  /**
-   * The work directory where incremental build output is stored between invocations.
-   */
-  File getOutputDirectory();
-
-  /**
-   * Returns the error formatting the compiler should print with
-   */
-  ErrorFormat printErrorFormat();
-
-  /**
-   * Return the system library corresponding to the specified "dart:<libname>" spec.
-   */
-  LibrarySource getSystemLibraryFor(String importSpec);
-
-  /**
-   * Return the system library manager 
-   */
-  PackageLibraryManager getPackageLibraryManager();
-  
-  /**
-   * Return {@link CompilerOptions} instance.
-   * @return command line options passed to the compiler.
-   */
-  CompilerOptions getCompilerOptions();
-}
diff --git a/compiler/java/com/google/dart/compiler/DartArtifactProvider.java b/compiler/java/com/google/dart/compiler/DartArtifactProvider.java
deleted file mode 100644
index a3b165d..0000000
--- a/compiler/java/com/google/dart/compiler/DartArtifactProvider.java
+++ /dev/null
@@ -1,67 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler;
-
-import java.io.IOException;
-import java.io.Reader;
-import java.io.Writer;
-import java.net.URI;
-
-/**
- * Abstract class that {@link DartCompiler} consumers can use to specify where
- * generated files are located.
- */
-public abstract class DartArtifactProvider {
-
-  /**
-   * Gets a reader for an artifact associated with the specified source, which
-   * must have been written to {@link #getArtifactWriter(Source, String, String)}. The
-   * caller is responsible for closing the reader. Only one artifact may be
-   * associated with the given extension.
-   *
-   * @param source the source file (not <code>null</code>)
-   * @param part a component of the source file to get a reader for (may be empty).
-   * @param extension the file extension for this artifact (not
-   *          <code>null</code>, not empty)
-   * @return the reader, or <code>null</code> if there is no such artifact
-   */
-  public abstract Reader getArtifactReader(Source source, String part, String extension)
-      throws IOException;
-
-  /**
-   * Gets the {@link URI} for an artifact associated with this source.
-   *
-   * @param source the source file (not <code>null</code>)
-   * @param part a component of the source file to get a reader for (may be empty).
-   * @param extension the file extension for this artifact (not
-   *          <code>null</code>, not empty)
-   */
-  public abstract URI getArtifactUri(Source source, String part, String extension);
-
-  /**
-   * Gets a writer for an artifact associated with this source. The caller is
-   * responsible for closing the writer. Only one artifact may be associated
-   * with the given extension.
-   *
-   * @param source the source file (not <code>null</code>)
-   * @param part a component of the source file to get a reader for (may be empty).
-   * @param extension the file extension for this artifact (not
-   *          <code>null</code>, not empty)
-   */
-  public abstract Writer getArtifactWriter(Source source, String part, String extension)
-      throws IOException;
-
-  /**
-   * Determines whether an artifact for the specified source is out of date
-   * with respect to some other source.
-   *
-   * @param source the source file to check (not <code>null</code>)
-   * @param base the artifact's base source (not <code>null</code>)
-   * @param extension the file extension for this artifact (not
-   *          <code>null</code>, not empty)
-   * @return <code>true</code> if out of date
-   */
-   public abstract boolean isOutOfDate(Source source, Source base, String extension);
-}
diff --git a/compiler/java/com/google/dart/compiler/DartCompilationError.java b/compiler/java/com/google/dart/compiler/DartCompilationError.java
deleted file mode 100644
index ddf7e33..0000000
--- a/compiler/java/com/google/dart/compiler/DartCompilationError.java
+++ /dev/null
@@ -1,191 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler;
-
-import com.google.dart.compiler.common.HasSourceInfo;
-import com.google.dart.compiler.common.SourceInfo;
-import com.google.dart.compiler.parser.DartScanner.Location;
-
-/**
- * Information about a compilation error.
- * 
- * @see DartCompilerListener
- */
-public class DartCompilationError {
-
-  /**
-   * The character offset from the beginning of the source (zero based) where the error occurred.
-   */
-  private int offset = 0;
-
-  /**
-   * The number of characters from the startPosition to the end of the source which encompasses the
-   * compilation error.
-   */
-  private int length = 0;
-
-  /**
-   * The line number in the source (one based) where the error occurred or -1 if it is undefined.
-   */
-  private int lineNumber = -1;
-
-  /**
-   * The column number in the source (one based) where the error occurred or -1 if it is undefined.
-   */
-  private int columnNumber = -1;
-
-  /**
-   * The error code associated with the error.
-   */
-  private ErrorCode errorCode;
-
-  /**
-   * The compilation error message.
-   */
-  private String message;
-
-  /**
-   * The source in which the error occurred or <code>null</code> if unknown.
-   */
-  private Source source;
-
-  /**
-   * Compilation error for the specified {@link Source}, without location.
-   * 
-   * @param source the {@link Source} for which the exception occurred
-   * @param errorCode the {@link ErrorCode} to be associated with this error
-   * @param arguments the arguments used to build the error message
-   */
-  public DartCompilationError(Source source, ErrorCode errorCode, Object... arguments) {
-    this.source = source;
-    this.errorCode = errorCode;
-    this.message = String.format(errorCode.getMessage(), arguments);
-  }
-
-  /**
-   * Compilation error at the {@link SourceInfo} from specified {@link HasSourceInfo}.
-   * 
-   * @param hasSourceInfo the provider of {@link SourceInfo} where the error occurred
-   * @param errorCode the {@link ErrorCode} to be associated with this error
-   * @param arguments the arguments used to build the error message
-   */
-  public DartCompilationError(HasSourceInfo hasSourceInfo, ErrorCode errorCode, Object... arguments) {
-    this(hasSourceInfo.getSourceInfo(), errorCode, arguments);
-  }
-
-  /**
-   * Compilation error at the specified {@link SourceInfo}.
-   * 
-   * @param sourceInfo the {@link SourceInfo} where the error occurred
-   * @param errorCode the {@link ErrorCode} to be associated with this error
-   * @param arguments the arguments used to build the error message
-   */
-  public DartCompilationError(SourceInfo sourceInfo, ErrorCode errorCode, Object... arguments) {
-    this.source = sourceInfo.getSource();
-    this.lineNumber = sourceInfo.getLine();
-    this.columnNumber = sourceInfo.getColumn();
-    this.offset = sourceInfo.getOffset();
-    this.length = sourceInfo.getLength();
-    this.errorCode = errorCode;
-    this.message = String.format(errorCode.getMessage(), arguments);
-  }
-
-  /**
-   * Instantiate a new instance representing a compilation error at the specified location.
-   * 
-   * @param source the source reference
-   * @param location the source range where the error occurred
-   * @param errorCode the error code to be associated with this error
-   * @param arguments the arguments used to build the error message
-   */
-  public DartCompilationError(Source source,
-      Location location,
-      ErrorCode errorCode,
-      Object... arguments) {
-    this.source = source;
-    this.errorCode = errorCode;
-    this.message = String.format(errorCode.getMessage(), arguments);
-    if (location != null) {
-      offset = location.getBegin();
-      SourceInfo sourceInfo = new SourceInfo(source, offset, 0);
-      lineNumber = sourceInfo.getLine();
-      columnNumber = sourceInfo.getColumn();
-      length = location.getEnd() - offset;
-    }
-  }
-
-  /**
-   * The column number in the source (one based) where the error occurred.
-   */
-  public int getColumnNumber() {
-    return columnNumber;
-  }
-
-  /**
-   * Return the error code associated with the error.
-   */
-  public ErrorCode getErrorCode() {
-    return errorCode;
-  }
-
-  /**
-   * The line number in the source (one based) where the error occurred.
-   */
-  public int getLineNumber() {
-    return lineNumber;
-  }
-
-  /**
-   * The compilation error message.
-   */
-  public String getMessage() {
-    return message;
-  }
-
-  /**
-   * Return the source in which the error occurred or <code>null</code> if unknown.
-   */
-  public Source getSource() {
-    return source;
-  }
-
-  /**
-   * The character offset from the beginning of the source (zero based) where the error occurred.
-   */
-  public int getStartPosition() {
-    return offset;
-  }
-
-  /**
-   * The length of the error location.
-   */
-  public int getLength() {
-    return length;
-  }
-
-  @Override
-  public int hashCode() {
-    int hashCode = offset;
-    hashCode ^= (message != null) ? message.hashCode() : 0;
-    hashCode ^= (source != null) ? source.getName().hashCode() : 0;
-    return hashCode;
-  }
-
-  /**
-   * Set the source in which the error occurred or <code>null</code> if unknown.
-   */
-  public void setSource(Source source) {
-    this.source = source;
-  }
-
-  @Override
-  public String toString() {
-    StringBuilder sb = new StringBuilder();
-    sb.append((source != null) ? source.getName() : "<unknown source>");
-    sb.append("(" + lineNumber + ":" + columnNumber + "): ");
-    sb.append(message);
-    return sb.toString();
-  }
-}
diff --git a/compiler/java/com/google/dart/compiler/DartCompilationPhase.java b/compiler/java/com/google/dart/compiler/DartCompilationPhase.java
deleted file mode 100644
index 24a0341..0000000
--- a/compiler/java/com/google/dart/compiler/DartCompilationPhase.java
+++ /dev/null
@@ -1,23 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler;
-
-import com.google.dart.compiler.ast.DartUnit;
-import com.google.dart.compiler.resolver.CoreTypeProvider;
-
-/**
- * A compiler phase that processes a unit and possibly transforms it or reports
- * compilation errors.
- */
-public interface DartCompilationPhase {
-
-  /**
-   * Execute this phase on a unit.
-   *
-   * @param unit the program to process
-   * @param context context where to report error messages
-   */
-  DartUnit exec(DartUnit unit, DartCompilerContext context, CoreTypeProvider typeProvider);
-}
diff --git a/compiler/java/com/google/dart/compiler/DartCompiler.java b/compiler/java/com/google/dart/compiler/DartCompiler.java
deleted file mode 100644
index b939d6a..0000000
--- a/compiler/java/com/google/dart/compiler/DartCompiler.java
+++ /dev/null
@@ -1,1463 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler;
-
-import com.google.common.base.Objects;
-import com.google.common.collect.Maps;
-import com.google.common.collect.Sets;
-import com.google.common.collect.Sets.SetView;
-import com.google.common.io.CharStreams;
-import com.google.common.io.Closeables;
-import com.google.dart.compiler.CommandLineOptions.CompilerOptions;
-import com.google.dart.compiler.LibraryDeps.Dependency;
-import com.google.dart.compiler.UnitTestBatchRunner.Invocation;
-import com.google.dart.compiler.ast.DartDirective;
-import com.google.dart.compiler.ast.DartLibraryDirective;
-import com.google.dart.compiler.ast.DartNode;
-import com.google.dart.compiler.ast.DartPartOfDirective;
-import com.google.dart.compiler.ast.DartToSourceVisitor;
-import com.google.dart.compiler.ast.DartUnit;
-import com.google.dart.compiler.ast.LibraryExport;
-import com.google.dart.compiler.ast.LibraryNode;
-import com.google.dart.compiler.ast.LibraryUnit;
-import com.google.dart.compiler.ast.Modifiers;
-import com.google.dart.compiler.common.SourceInfo;
-import com.google.dart.compiler.metrics.CompilerMetrics;
-import com.google.dart.compiler.metrics.DartEventType;
-import com.google.dart.compiler.metrics.JvmMetrics;
-import com.google.dart.compiler.metrics.Tracer;
-import com.google.dart.compiler.metrics.Tracer.TraceEvent;
-import com.google.dart.compiler.parser.DartParser;
-import com.google.dart.compiler.resolver.CompileTimeConstantAnalyzer;
-import com.google.dart.compiler.resolver.CoreTypeProvider;
-import com.google.dart.compiler.resolver.CoreTypeProviderImplementation;
-import com.google.dart.compiler.resolver.Element;
-import com.google.dart.compiler.resolver.ElementKind;
-import com.google.dart.compiler.resolver.Elements;
-import com.google.dart.compiler.resolver.LibraryElement;
-import com.google.dart.compiler.resolver.MemberBuilder;
-import com.google.dart.compiler.resolver.MethodElement;
-import com.google.dart.compiler.resolver.Resolver;
-import com.google.dart.compiler.resolver.ResolverErrorCode;
-import com.google.dart.compiler.resolver.SupertypeResolver;
-import com.google.dart.compiler.resolver.TopLevelElementBuilder;
-import com.google.dart.compiler.type.TypeAnalyzer;
-import com.google.dart.compiler.util.DefaultTextOutput;
-import com.google.dart.compiler.util.apache.StringUtils;
-
-import org.kohsuke.args4j.CmdLineException;
-import org.kohsuke.args4j.CmdLineParser;
-
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.FileReader;
-import java.io.IOException;
-import java.io.PrintStream;
-import java.io.Reader;
-import java.io.Writer;
-import java.net.URI;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
-
-/**
- * Entry point for the Dart compiler.
- */
-public class DartCompiler {
-
-  static final int RESULT_OK = 0;
-  static final int RESULT_WARNINGS = 1;
-  static final int RESULT_ERRORS = 2;
-  static final int RESULT_OTHER = 127;
-
-  static class Result {
-    final int code;
-    final String message;
-    public Result(int code, String message) {
-      this.code = code;
-      this.message = message;
-    }
-    Result merge(Result other) {
-      if (other.code > code) {
-        return other;
-      }
-      return this;
-    }
-  }
-
-  public static final String EXTENSION_DEPS = "deps";
-  public static final String EXTENSION_LOG = "log";
-  public static final String EXTENSION_TIMESTAMP = "timestamp";
-
-  public static final String CORELIB_URL_SPEC = "dart:core";
-  public static final String MAIN_ENTRY_POINT_NAME = "main";
-
-  private static class Compiler {
-    private final LibrarySource app;
-    private final List<LibrarySource> embeddedLibraries = new ArrayList<LibrarySource>();
-    private final DartCompilerMainContext context;
-    private final CompilerConfiguration config;
-    private final Map<URI, LibraryUnit> libraries = new LinkedHashMap<URI, LibraryUnit>();
-    private CoreTypeProvider typeProvider;
-    private final boolean incremental;
-    private final List<DartCompilationPhase> phases;
-    private final LibrarySource coreLibrarySource;
-
-    private Compiler(LibrarySource app, List<LibrarySource> embedded, CompilerConfiguration config,
-        DartCompilerMainContext context) {
-      this.app = app;
-      this.config = config;
-      this.phases = config.getPhases();
-      this.context = context;
-      for (LibrarySource library : embedded) {
-        if (PackageLibraryManager.isDartSpec(library.getName())) {
-          LibrarySource foundLibrary = context.getSystemLibraryFor(library.getName());
-          assert(foundLibrary != null);
-          embeddedLibraries.add(foundLibrary);
-        } else {
-          embeddedLibraries.add(library);
-        }
-      }
-      coreLibrarySource = context.getSystemLibraryFor(CORELIB_URL_SPEC);
-      assert(coreLibrarySource != null);
-      embeddedLibraries.add(coreLibrarySource);
-
-      incremental = config.incremental();
-    }
-
-    void addResolvedLibraries(Map<URI, LibraryUnit> resolvedLibraries) {
-      libraries.putAll(resolvedLibraries);
-    }
-
-    Map<URI, LibraryUnit> getLibraries() {
-      return libraries;
-    }
-
-    private void compile() {
-      TraceEvent logEvent = Tracer.canTrace() ? Tracer.start(DartEventType.COMPILE) : null;
-      try {
-        updateAndResolve();
-        if (!config.resolveDespiteParseErrors() && context.getErrorCount() > 0) {
-          return;
-        }
-        compileLibraries();
-      } catch (IOException e) {
-        context.onError(new DartCompilationError(app, DartCompilerErrorCode.IO, e.getMessage()));
-      } finally {
-        Tracer.end(logEvent);
-      }
-    }
-
-    /**
-     * Update the current application and any referenced libraries and resolve
-     * them.
-     *
-     * @return a {@link LibraryUnit}, maybe <code>null</code>
-     * @throws IOException on IO errors - the caller must log this if it cares
-     */
-    private LibraryUnit updateAndResolve() throws IOException {
-      TraceEvent logEvent = Tracer.canTrace() ? Tracer.start(DartEventType.UPDATE_RESOLVE) : null;
-
-      CompilerMetrics compilerMetrics = context.getCompilerMetrics();
-      if (compilerMetrics != null) {
-        compilerMetrics.startUpdateAndResolveTime();
-      }
-
-      try {
-        LibraryUnit library = updateLibraries(app);
-        importEmbeddedLibraries();
-        parseOutOfDateFiles();
-        if (incremental) {
-          addOutOfDateDeps();
-        }
-        if (!config.resolveDespiteParseErrors() && (context.getErrorCount() > 0)) {
-          return library;
-        }
-        buildLibraryScopes();
-        LibraryUnit corelibUnit = updateLibraries(coreLibrarySource);
-        typeProvider = new CoreTypeProviderImplementation(corelibUnit.getElement().getScope(),
-                                                          context);
-        resolveLibraries();
-        validateLibraryDirectives();
-        return library;
-      } finally {
-        if(compilerMetrics != null) {
-          compilerMetrics.endUpdateAndResolveTime();
-        }
-
-        Tracer.end(logEvent);
-      }
-    }
-
-    /**
-     * This method reads all libraries. They will be populated from some combination of fully-parsed
-     * and diet-parser compilation units.
-     */
-    private void parseOutOfDateFiles() throws IOException {
-      TraceEvent logEvent =
-          Tracer.canTrace() ? Tracer.start(DartEventType.PARSE_OUTOFDATE) : null;
-      CompilerMetrics compilerMetrics = context.getCompilerMetrics();
-      long parseStart = compilerMetrics != null ? CompilerMetrics.getCPUTime() : 0;
-
-      try {
-        final Set<String> topLevelSymbolsDiff = Sets.newHashSet();
-        for (LibraryUnit lib : getLibrariesToProcess()) {
-          LibrarySource libSrc = lib.getSource();
-          LibraryNode selfSourcePath = lib.getSelfSourcePath();
-
-          // Load the existing DEPS, or create an empty one.
-          LibraryDeps deps = lib.getDeps(context);
-          Set<String> newUnitPaths = Sets.newHashSet();
-
-          // Parse each compilation unit.
-          for (LibraryNode sourcePathNode : lib.getSourcePaths()) {
-            String relPath = sourcePathNode.getText();
-            newUnitPaths.add(relPath);
-
-            // Prepare DartSource for "#source" unit.
-            final DartSource dartSrc = libSrc.getSourceFor(relPath);
-            if (dartSrc == null || !dartSrc.exists()) {
-              continue;
-            }
-
-            if (!incremental
-                || PackageLibraryManager.isDartUri(libSrc.getUri())
-                || isSourceOutOfDate(dartSrc)) {
-              DartUnit unit = parse(dartSrc, lib.getPrefixes(),  false);
-              // If we just parsed unit of library, report problems.
-              if (sourcePathNode == selfSourcePath) {
-                // report "#import" problems
-                for (LibraryNode importPathNode : lib.getImportPaths()) {
-                  LibrarySource dep = getImportSource(libSrc, importPathNode);
-                  if (dep == null) {
-                    reportMissingSource(context, libSrc, importPathNode);
-                  }
-                }
-                // report "#source" problems
-                for (LibraryNode checkSourcePathNode : lib.getSourcePaths()) {
-                  String checkRelPath = checkSourcePathNode.getText();
-                  final DartSource checkSource = libSrc.getSourceFor(checkRelPath);
-                  if (checkSource == null || !checkSource.exists()) {
-                    reportMissingSource(context, libSrc, checkSourcePathNode);
-                  }
-                }
-              }
-
-              // Process unit, if exists.
-              if (unit != null) {
-                if (sourcePathNode == selfSourcePath) {
-                  lib.setSelfDartUnit(unit);
-                }
-                // Replace unit within the library.
-                lib.putUnit(unit);
-                context.setFilesHaveChanged();
-                // Include into top-level symbols diff from current units, already existed or new.
-                {
-                  LibraryDeps.Source source = deps.getSource(relPath);
-                  Set<String> newTopSymbols = unit.getTopDeclarationNames();
-                  if (source != null) {
-                    Set<String> oldTopSymbols = source.getTopSymbols();
-                    SetView<String> diff0 = Sets.symmetricDifference(oldTopSymbols, newTopSymbols);
-                    topLevelSymbolsDiff.addAll(diff0);
-                  } else {
-                    topLevelSymbolsDiff.addAll(newTopSymbols);
-                  }
-                }
-              }
-            } else {
-              DartUnit dietUnit = parse(dartSrc, lib.getPrefixes(), true);
-              if (dietUnit != null) {
-                if (sourcePathNode == selfSourcePath) {
-                  lib.setSelfDartUnit(dietUnit);
-                }
-                lib.putUnit(dietUnit);
-              }
-            }
-          }
-
-          // Include into top-level symbols diff from units which disappeared since last compiling.
-          {
-            Set<String> oldUnitPaths = deps.getUnitPaths();
-            Set<String> disappearedUnitPaths = Sets.difference(oldUnitPaths, newUnitPaths);
-            for (String relPath : disappearedUnitPaths) {
-              LibraryDeps.Source source = deps.getSource(relPath);
-              if (source != null) {
-                Set<String> oldTopSymbols = source.getTopSymbols();
-                topLevelSymbolsDiff.addAll(oldTopSymbols);
-              }
-            }
-          }
-        }
-
-        // Parse units, which potentially depend on the difference in top-level symbols.
-        if (!topLevelSymbolsDiff.isEmpty()) {
-          context.setFilesHaveChanged();
-          for (LibraryUnit lib : getLibrariesToProcess()) {
-            LibrarySource libSrc = lib.getSource();
-            LibraryNode selfSourcePath = lib.getSelfSourcePath();
-            LibraryDeps deps = lib.getDeps(context);
-            for (LibraryNode libNode : lib.getSourcePaths()) {
-              String relPath = libNode.getText();
-              // Prepare source dependency.
-              LibraryDeps.Source source = deps.getSource(relPath);
-              if (source == null) {
-                continue;
-              }
-              // Check re-compilation conditions.
-              if (source.shouldRecompileOnAnyTopLevelChange()
-                  || !Sets.intersection(source.getAllSymbols(), topLevelSymbolsDiff).isEmpty()
-                  || !Sets.intersection(source.getHoles(), topLevelSymbolsDiff).isEmpty()) {
-                DartSource dartSrc = libSrc.getSourceFor(relPath);
-                if (dartSrc == null || !dartSrc.exists()) {
-                  continue;
-                }
-                DartUnit unit = parse(dartSrc, lib.getPrefixes(), false);
-                if (unit != null) {
-                  if (libNode == selfSourcePath) {
-                    lib.setSelfDartUnit(unit);
-                  } else {
-                    lib.putUnit(unit);
-                  }
-                }
-              }
-            }
-          }
-        }
-      } finally {
-        if (compilerMetrics != null) {
-          compilerMetrics.addParseWallTimeNano(CompilerMetrics.getCPUTime() - parseStart);
-        }
-        Tracer.end(logEvent);
-      }
-    }
-
-    Collection<LibraryUnit> getLibrariesToProcess() {
-      return libraries.values();
-    }
-
-    /**
-     * This method reads the embedded library sources, making sure they are added
-     * to the list of libraries to compile. It then adds the libraries as imports
-     * of all libraries. The import is without prefix.
-     */
-    private void importEmbeddedLibraries() throws IOException {
-      TraceEvent importEvent =
-          Tracer.canTrace() ? Tracer.start(DartEventType.IMPORT_EMBEDDED_LIBRARIES) : null;
-      try {
-        for (LibrarySource embedded : embeddedLibraries) {
-          updateLibraries(embedded);
-        }
-
-        for (LibraryUnit lib : getLibrariesToProcess()) {
-          for (LibrarySource embedded : embeddedLibraries) {
-            LibraryUnit imp = libraries.get(embedded.getUri());
-            // Check that the current library is not the embedded library, and
-            // that the current library does not already import the embedded
-            // library.
-            if (lib != imp && !lib.hasImport(imp)) {
-              lib.addImport(imp, null);
-            }
-          }
-        }
-      } finally {
-        Tracer.end(importEvent);
-      }
-    }
-
-    /**
-     * This method reads a library source and sets it up with its imports. When it
-     * completes, it is guaranteed that {@link Compiler#libraries} will be completely populated.
-     */
-    private LibraryUnit updateLibraries(LibrarySource libSrc) throws IOException {
-      TraceEvent updateEvent =
-          Tracer.canTrace() ? Tracer.start(DartEventType.UPDATE_LIBRARIES, "name",
-              libSrc.getName()) : null;
-      try {
-        // Avoid cycles.
-        LibraryUnit lib = libraries.get(libSrc.getUri());
-        if (lib != null) {
-          return lib;
-        }
-
-        lib = context.getLibraryUnit(libSrc);
-        // If we could not find the library, continue. The context will report
-        // the error at the end.
-        if (lib == null) {
-          return null;
-        }
-
-        libraries.put(libSrc.getUri(), lib);
-
-        // Update dependencies.
-        for (LibraryNode libNode : lib.getImportPaths()) {
-          LibrarySource dep = getImportSource(libSrc, libNode);
-          if (dep != null) {
-            LibraryUnit importedLib = updateLibraries(dep);
-            lib.addImport(importedLib, libNode);
-            if (libNode.isExported()) {
-              lib.addExport(importedLib, libNode);
-            }
-          }
-        }
-        for (LibraryNode libNode : lib.getExportPaths()) {
-          LibrarySource dep = getImportSource(libSrc, libNode);
-          if (dep != null) {
-            lib.addExport(updateLibraries(dep), libNode);
-          }
-        }
-        return lib;
-      } finally {
-        Tracer.end(updateEvent);
-      }
-    }
-
-    /**
-     * @return the {@link LibrarySource} referenced in the "#import" from "libSrc". May be
-     *         <code>null</code> if invalid URI or not existing library.
-     */
-    private LibrarySource getImportSource(LibrarySource libSrc, LibraryNode libNode)
-        throws IOException {
-      String libSpec = libNode.getText();
-      LibrarySource dep;
-      try {
-        if (PackageLibraryManager.isDartSpec(libSpec)) {
-          dep = context.getSystemLibraryFor(libSpec);
-        } else {
-          dep = libSrc.getImportFor(libSpec);
-        }
-      } catch (Throwable e) {
-        return null;
-      }
-      if (dep == null || !dep.exists()) {
-        return null;
-      }
-      return dep;
-    }
-
-    /**
-     * Determines whether the given source is out-of-date with respect to its artifacts.
-     */
-    private boolean isSourceOutOfDate(DartSource dartSrc) {
-      TraceEvent logEvent =
-          Tracer.canTrace() ? Tracer.start(DartEventType.IS_SOURCE_OUTOFDATE, "src",
-              dartSrc.getName()) : null;
-
-      try {
-        // If incremental compilation is disabled, just return true to force all
-        // units to be recompiled.
-        if (!incremental) {
-          return true;
-        }
-
-        TraceEvent timestampEvent =
-            Tracer.canTrace() ? Tracer.start(
-                DartEventType.TIMESTAMP_OUTOFDATE,
-                "src",
-                dartSrc.getName()) : null;
-        try {
-          return context.isOutOfDate(dartSrc, dartSrc, EXTENSION_TIMESTAMP);
-        } finally {
-          Tracer.end(timestampEvent);
-        }
-      } finally {
-        Tracer.end(logEvent);
-      }
-    }
-
-    /**
-     * Build scopes for the given libraries.
-     */
-    private void buildLibraryScopes() {
-      TraceEvent logEvent =
-          Tracer.canTrace() ? Tracer.start(DartEventType.BUILD_LIB_SCOPES) : null;
-      try {
-        Collection<LibraryUnit> libs = getLibrariesToProcess();
-
-        // Build the class elements declared in the sources of a library.
-        // Loop can be parallelized.
-        for (LibraryUnit lib : libs) {
-          new TopLevelElementBuilder().exec(lib, context);
-        }
-
-        // The library scope can then be constructed, containing types declared
-        // in the library, and types declared in the imports. Loop can be parallelized.
-        for (LibraryUnit lib : libs) {
-          new TopLevelElementBuilder().fillInLibraryScope(lib, context);
-        }
-      } finally {
-        Tracer.end(logEvent);
-      }
-    }
-
-    /**
-     * Parses compilation units that are out-of-date with respect to their dependencies.
-     */
-    private void addOutOfDateDeps() throws IOException {
-      TraceEvent logEvent = Tracer.canTrace() ? Tracer.start(DartEventType.ADD_OUTOFDATE) : null;
-      try {
-        boolean filesHaveChanged = false;
-        for (LibraryUnit lib : getLibrariesToProcess()) {
-
-          // Load the existing DEPS, or create an empty one.
-          LibraryDeps deps = lib.getDeps(context);
-
-          // Prepare all top-level symbols.
-          Set<String> oldTopLevelSymbols = Sets.newHashSet();
-          for (LibraryDeps.Source source : deps.getSources()) {
-            oldTopLevelSymbols.addAll(source.getTopSymbols());
-          }
-
-          // Parse units that are out-of-date with respect to their dependencies.
-          for (DartUnit unit : lib.getUnits()) {
-            if (unit.isDiet()) {
-              String relPath = ((DartSource) unit.getSourceInfo().getSource()).getRelativePath();
-              LibraryDeps.Source source = deps.getSource(relPath);
-              if (isUnitOutOfDate(lib, source)) {
-                filesHaveChanged = true;
-                DartSource dartSrc = lib.getSource().getSourceFor(relPath);
-                if (dartSrc != null && dartSrc.exists()) {
-                  unit = parse(dartSrc, lib.getPrefixes(), false);
-                  if (unit != null) {
-                    lib.putUnit(unit);
-                  }
-                }
-              }
-            }
-          }
-        }
-
-        if (filesHaveChanged) {
-          context.setFilesHaveChanged();
-        }
-      } finally {
-        Tracer.end(logEvent);
-      }
-    }
-
-    /**
-     * Determines whether the given dependencies are out-of-date.
-     */
-    private boolean isUnitOutOfDate(LibraryUnit lib, LibraryDeps.Source source) {
-      // If we don't have dependency information, then we can not be sure that nothing changed.
-      if (source == null) {
-        return true;
-      }
-      // Check all dependencies.
-      for (Dependency dep : source.getDeps()) {
-        LibraryUnit depLib = libraries.get(dep.getLibUri());
-        if (depLib == null) {
-          return true;
-        }
-        // Prepare unit.
-        DartUnit depUnit = depLib.getUnit(dep.getUnitName());
-        if (depUnit == null) {
-          return true;
-        }
-        // May be unit modified.
-        if (depUnit.getSourceInfo().getSource().getLastModified() != dep.getLastModified()) {
-          return true;
-        }
-      }
-      // No changed dependencies.
-      return false;
-    }
-
-    /**
-     * Resolve all libraries. Assume that all library scopes are already built.
-     */
-    private void resolveLibraries() {
-      TraceEvent logEvent =
-          Tracer.canTrace() ? Tracer.start(DartEventType.RESOLVE_LIBRARIES) : null;
-      try {
-        // TODO(jgw): Optimization: Skip work for libraries that have nothing to
-        // compile.
-
-        // Resolve super class chain, and build the member elements. Both passes
-        // need the library scope to be setup. Each for loop can be
-        // parallelized.
-        for (LibraryUnit lib : getLibrariesToProcess()) {
-          for (DartUnit unit : lib.getUnits()) {
-            // These two method calls can be parallelized.
-            new SupertypeResolver().exec(unit, context, getTypeProvider());
-            new MemberBuilder().exec(unit, context, getTypeProvider());
-          }
-        }
-
-      } finally {
-        Tracer.end(logEvent);
-      }
-    }
-
-    private void validateLibraryDirectives() {
-      for (LibraryUnit lib : getLibrariesToProcess()) {
-        // don't need to validate system libraries
-        if (PackageLibraryManager.isDartUri(lib.getSource().getUri())) {
-          continue;
-        }
-        
-        // check for #source uniqueness
-        {
-          Set<URI> includedSourceUris = Sets.newHashSet();
-          for (LibraryNode sourceNode : lib.getSourcePaths()) {
-            String path = sourceNode.getText();
-            DartSource source = lib.getSource().getSourceFor(path);
-            if (source != null) {
-              URI uri = source.getUri();
-              if (includedSourceUris.contains(uri)) {
-                context.onError(new DartCompilationError(sourceNode.getSourceInfo(),
-                    DartCompilerErrorCode.UNIT_WAS_ALREADY_INCLUDED, uri));
-              }
-              includedSourceUris.add(uri);
-            }
-          }
-        }
-
-        // Validate imports.
-        boolean hasIO = false;
-        boolean hasHTML = false;
-        for (LibraryNode importNode : lib.getImportPaths()) {
-          String libSpec = importNode.getText();
-          hasIO |= "dart:io".equals(libSpec);
-          hasHTML |= "dart:html".equals(libSpec);
-          // "dart:mirrors" are not done yet
-          if ("dart:mirrors".equals(libSpec)) {
-            context.onError(new DartCompilationError(importNode,
-                DartCompilerErrorCode.MIRRORS_NOT_FULLY_IMPLEMENTED));
-          }
-          // validate console/web mix
-          if (hasIO && hasHTML) {
-            context.onError(new DartCompilationError(importNode.getSourceInfo(),
-                DartCompilerErrorCode.CONSOLE_WEB_MIX));
-          }
-        }
-
-        // check that each exported library has a library directive
-        for (LibraryExport libraryExport : lib.getExports()) {
-          LibraryUnit exportedLibrary = libraryExport.getLibrary();
-          String exportedLibraryName = getLibraryName(exportedLibrary);
-          // no => error
-          if (exportedLibraryName == null) {
-            SourceInfo info = findExportDirective(lib, exportedLibrary);
-            if (info != null) {
-              Source expSource = exportedLibrary.getSelfDartUnit().getSourceInfo().getSource();
-              context.onError(new DartCompilationError(info,
-                  DartCompilerErrorCode.MISSING_LIBRARY_DIRECTIVE_EXPORT,
-                  ((DartSource) expSource).getRelativePath()));
-            }
-          }
-        }
-          
-        // check that each imported library has a library directive
-        Map<String, LibraryUnit> nameToImportedLibrary = Maps.newHashMap();
-        for (LibraryUnit importedLib  : lib.getImportedLibraries()) {
-
-          if (PackageLibraryManager.isDartUri(importedLib.getSource().getUri())) {
-            // system libraries are always valid
-            continue;
-          }
-
-          // get the dart unit corresponding to this library
-          DartUnit unit = importedLib.getSelfDartUnit();
-          if (unit == null || unit.isDiet()) {
-            // don't need to check a unit that hasn't changed
-            continue;
-          }
-
-          // find imported library name
-          String importedLibraryName = getLibraryName(importedLib);
-          
-          // no name => error
-          if (importedLibraryName == null) {
-            SourceInfo info = findImportDirective(lib, importedLib);
-            if (info != null) {
-              context.onError(new DartCompilationError(info,
-                  DartCompilerErrorCode.MISSING_LIBRARY_DIRECTIVE_IMPORT,
-                  ((DartSource) unit.getSourceInfo().getSource()).getRelativePath()));
-            }
-          }
-          
-          // has already library with such name => error
-          if (importedLibraryName != null) {
-            LibraryUnit prevLibraryWithSameName = nameToImportedLibrary.get(importedLibraryName);
-            if (prevLibraryWithSameName != null) {
-              SourceInfo info = findImportDirective(lib, importedLib);
-              if (info != null) {
-                Source prevSource = prevLibraryWithSameName.getSelfDartUnit().getSourceInfo().getSource();
-                context.onError(new DartCompilationError(info,
-                    DartCompilerErrorCode.DUPLICATE_IMPORTED_LIBRARY_NAME,
-                    importedLibraryName,
-                    ((DartSource) prevSource).getRelativePath()));
-              }
-            } else {
-              nameToImportedLibrary.put(importedLibraryName, importedLib);
-            }
-          }
-        }
-
-        // check that all sourced units have no directives
-        for (DartUnit unit : lib.getUnits()) {
-          // don't need to check a unit that hasn't changed
-          if (unit.isDiet()) {
-            continue;
-          }
-          // ignore library unit
-          DartSource unitSource = (DartSource) unit.getSourceInfo().getSource();
-          if (isLibrarySelfUnit(lib, unitSource)) {
-            continue;
-          }
-          // analyze directives
-          List<DartDirective> directives = unit.getDirectives();
-          if (directives.isEmpty()) {
-            context.onError(new DartCompilationError(unitSource,
-                DartCompilerErrorCode.MISSING_PART_OF_DIRECTIVE, lib.getName()));
-          } else if (directives.size() == 1 && directives.get(0) instanceof DartPartOfDirective) {
-            DartPartOfDirective directive = (DartPartOfDirective) directives.get(0);
-            String dirName = directive.getLibraryName();
-            if (!Objects.equal(dirName, lib.getName())) {
-              context.onError(new DartCompilationError(directive,
-                  DartCompilerErrorCode.WRONG_PART_OF_NAME, lib.getName(), dirName));
-            }
-          } else {
-            context.onError(new DartCompilationError(directives.get(0),
-                DartCompilerErrorCode.ILLEGAL_DIRECTIVES_IN_SOURCED_UNIT,
-                Elements.getRelativeSourcePath(unitSource, lib.getSource())));
-          }
-        }
-      }
-    }
-    
-    /**
-     * @return the name of the given {@link LibraryUnit} specified in {@link DartLibraryDirective}.
-     */
-    private static String getLibraryName(LibraryUnit libraryUnit) {
-      DartUnit unit = libraryUnit.getSelfDartUnit();
-      for (DartDirective directive : unit.getDirectives()) {
-        if (directive instanceof DartLibraryDirective) {
-          return ((DartLibraryDirective) directive).getLibraryName();
-        }
-      }
-      return null;
-    }
-
-    /**
-     * @return the {@link SourceInfo} of the import directive in "lib" for "importedLib".
-     */
-    private static SourceInfo findImportDirective(LibraryUnit lib, LibraryUnit importedLib) {
-      for (LibraryNode importPath : lib.getImportPaths()) {
-        if (importPath.getText().equals(importedLib.getSelfSourcePath().getText())) {
-          return importPath.getSourceInfo();
-        }
-      }
-      return null;
-    }
-    
-    /**
-     * @return the {@link SourceInfo} of the export directive in "lib" for "importedLib".
-     */
-    private static SourceInfo findExportDirective(LibraryUnit lib, LibraryUnit importedLib) {
-      for (LibraryNode exportPath : lib.getExportPaths()) {
-        if (exportPath.getText().equals(importedLib.getSelfSourcePath().getText())) {
-          return exportPath.getSourceInfo();
-        }
-      }
-      return null;
-    }
-
-    private static boolean isLibrarySelfUnit(LibraryUnit lib, DartSource unitSource) {
-      String unitRelativePath = unitSource.getRelativePath();
-      for (LibraryNode sourceNode : lib.getSourcePaths()) {
-        if (unitRelativePath.equals(sourceNode.getText())) {
-          if (sourceNode == lib.getSelfSourcePath()) {
-            return true;
-          }
-          return false;
-        }
-      }
-      return false;
-    }
-
-    private void setEntryPoint() {
-      LibraryUnit lib = context.getAppLibraryUnit();
-      lib.setEntryNode(new LibraryNode(MAIN_ENTRY_POINT_NAME));
-      // this ensures that if we find it, it's a top-level static element
-      Element element = lib.getElement().lookupLocalElement(MAIN_ENTRY_POINT_NAME);
-      switch (ElementKind.of(element)) {
-        case NONE:
-          // this is ok, it might just be a library
-          break;
-
-        case METHOD:
-          MethodElement methodElement = (MethodElement) element;
-          Modifiers modifiers = methodElement.getModifiers();
-          if (modifiers.isGetter()) {
-            context.onError(new DartCompilationError(element,
-                DartCompilerErrorCode.ENTRY_POINT_METHOD_MAY_NOT_BE_GETTER, MAIN_ENTRY_POINT_NAME));
-          } else if (modifiers.isSetter()) {
-            context.onError(new DartCompilationError(element,
-                DartCompilerErrorCode.ENTRY_POINT_METHOD_MAY_NOT_BE_SETTER, MAIN_ENTRY_POINT_NAME));
-          } else if (methodElement.getParameters().size() > 0) {
-            context.onError(new DartCompilationError(element,
-                DartCompilerErrorCode.ENTRY_POINT_METHOD_CANNOT_HAVE_PARAMETERS,
-                MAIN_ENTRY_POINT_NAME));
-          } else {
-            lib.getElement().setEntryPoint(methodElement);
-          }
-          break;
-
-        default:
-          context.onError(new DartCompilationError(element,
-              ResolverErrorCode.NOT_A_STATIC_METHOD, MAIN_ENTRY_POINT_NAME));
-          break;
-      }
-    }
-
-    private void compileLibraries() throws IOException {
-      TraceEvent logEvent =
-          Tracer.canTrace() ? Tracer.start(DartEventType.COMPILE_LIBRARIES) : null;
-
-      CompilerMetrics compilerMetrics = context.getCompilerMetrics();
-      if (compilerMetrics != null) {
-        compilerMetrics.startCompileLibrariesTime();
-      }
-
-      try {
-        // Set entry point
-        setEntryPoint();
-
-        // The two following for loops can be parallelized.
-        for (LibraryUnit lib : getLibrariesToProcess()) {
-          boolean persist = false;
-
-          // Compile all the units in this library.
-          for (DartCompilationPhase phase : phases) {
-
-            // Run all compiler phases including AST simplification and symbol
-            // resolution. This must run in serial.
-            for (DartUnit unit : lib.getUnits()) {
-              
-              // Don't compile diet units.
-              if (unit.isDiet()) {
-                continue;
-              }
-
-              unit = phase.exec(unit, context, getTypeProvider());
-              if (!config.resolveDespiteParseErrors() && context.getErrorCount() > 0) {
-                return;
-              }
-            }
-
-          }
-
-          for (DartUnit unit : lib.getUnits()) {
-            if (unit.isDiet()) {
-              continue;
-            }
-            updateAnalysisTimestamp(unit);
-            // To help support the IDE, notify the listener that this unit is compiled.
-            context.unitCompiled(unit);
-            // Update deps.
-            lib.getDeps(context).update(context, unit);
-            // We analyzed something, so we need to persist the deps.
-            persist = true;
-          }
-
-          // Persist the DEPS file.
-          if (persist) {
-            lib.writeDeps(context);
-          }
-        }
-      } finally {
-        if (compilerMetrics != null) {
-          compilerMetrics.endCompileLibrariesTime();
-        }
-        Tracer.end(logEvent);
-      }
-    }
-
-    private void updateAnalysisTimestamp(DartUnit unit) throws IOException {
-      // Update timestamp.
-      Writer writer =
-          context.getArtifactWriter(unit.getSourceInfo().getSource(), "", EXTENSION_TIMESTAMP);
-      String timestampData = String.format("%d\n", System.currentTimeMillis());
-      writer.write(timestampData);
-      writer.close();
-    }
-
-    DartUnit parse(DartSource dartSrc, Set<String> libraryPrefixes, boolean diet) throws IOException {
-      TraceEvent parseEvent =
-          Tracer.canTrace() ? Tracer.start(DartEventType.PARSE, "src", dartSrc.getName()) : null;
-      CompilerMetrics compilerMetrics = context.getCompilerMetrics();
-      long parseStart = compilerMetrics != null ? CompilerMetrics.getThreadTime() : 0;
-      Reader r = dartSrc.getSourceReader();
-      String srcCode;
-      boolean failed = true;
-      try {
-        try {
-          srcCode = CharStreams.toString(r);
-          failed = false;
-        } finally {
-          Closeables.close(r, failed);
-        }
-
-        DartParser parser = new DartParser(dartSrc, srcCode, diet, libraryPrefixes, context,
-            context.getCompilerMetrics());
-        DartUnit unit = parser.parseUnit();
-        if (compilerMetrics != null) {
-          compilerMetrics.addParseTimeNano(CompilerMetrics.getThreadTime() - parseStart);
-        }
-
-        if (!config.resolveDespiteParseErrors() && context.getErrorCount() > 0) {
-          // We don't return this unit, so no more processing expected for it.
-          context.unitCompiled(unit);
-          return null;
-        }
-        return unit;
-      } finally {
-        Tracer.end(parseEvent);
-      }
-    }
-
-    private void reportMissingSource(DartCompilerContext context,
-                                     LibrarySource libSrc,
-                                     LibraryNode libNode) {
-      if (libNode != null && StringUtils.startsWith(libNode.getText(), "dart-ext:")) {
-        return;
-      }
-      DartCompilationError event = new DartCompilationError(libNode,
-                                                            DartCompilerErrorCode.MISSING_SOURCE,
-                                                            libNode.getText());
-      event.setSource(libSrc);
-      context.onError(event);
-    }
-    CoreTypeProvider getTypeProvider() {
-      typeProvider.getClass(); // Quick null check.
-      return typeProvider;
-    }
-  }
-
-  /**
-   * Provides cached parse and resolution results during selective compilation
-   */
-  public abstract static class SelectiveCache {
-
-    /**
-     * Answer the cached resolved libraries
-     * 
-     * @return a mapping (not <code>null</code>) of library source URI to cached {@link LibraryUnit}
-     */
-    public abstract Map<URI, LibraryUnit> getResolvedLibraries();
-
-    /**
-     * Answer the cached unresolved {@link DartUnit} for the specified source
-     * 
-     * @param dartSrc the source (not <code>null</code>)
-     * @return the cached unit or <code>null</code> if it is not cached
-     */
-    public abstract DartUnit getUnresolvedDartUnit(DartSource dartSrc);
-  }
-
-  /**
-   * Selectively compile a library. Use supplied libraries and ASTs when available.
-   * This allows programming tools to provide customized ASTs for code that is currently being
-   * edited, and may not compile correctly.
-   */
-  static class SelectiveCompiler extends Compiler {
-    private final SelectiveCache selectiveCache;
-    private Collection<LibraryUnit> librariesToProcess;
-
-    private SelectiveCompiler(LibrarySource app, SelectiveCache selectiveCache,
-        CompilerConfiguration config, DartCompilerMainContext context) {
-      super(app, Collections.<LibrarySource>emptyList(), config, context);
-      this.selectiveCache = selectiveCache;
-      addResolvedLibraries(selectiveCache.getResolvedLibraries());
-    }
-
-    @Override
-    Collection<LibraryUnit> getLibrariesToProcess() {
-      if (librariesToProcess == null) {
-        librariesToProcess = new ArrayList<LibraryUnit>();
-        librariesToProcess.addAll(super.getLibrariesToProcess());
-        librariesToProcess.removeAll(selectiveCache.getResolvedLibraries().values());
-      }
-      return librariesToProcess;
-    }
-
-    @Override
-    DartUnit parse(DartSource dartSrc, Set<String> prefixes, boolean diet) throws IOException {
-      DartUnit parsedUnit = selectiveCache.getUnresolvedDartUnit(dartSrc);
-      if (parsedUnit != null) {
-        return parsedUnit;
-      }
-      return super.parse(dartSrc, prefixes, diet);
-    }
-  }
-
-  private static CompilerOptions processCommandLineOptions(String[] args) {
-    CmdLineParser cmdLineParser = null;
-    CompilerOptions compilerOptions = null;
-    try {
-      compilerOptions = new CompilerOptions();
-      cmdLineParser = CommandLineOptions.parse(args, compilerOptions);
-      if (args.length == 0 || compilerOptions.showHelp()) {
-        showUsage(cmdLineParser, System.err);
-        System.exit(1);
-      }
-    } catch (CmdLineException e) {
-      System.err.println(e.getLocalizedMessage());
-      showUsage(cmdLineParser, System.err);
-      System.exit(1);
-    }
-
-    assert compilerOptions != null;
-    return compilerOptions;
-  }
-
-  public static void main(final String[] topArgs) {
-    Tracer.init();
-
-    CompilerOptions topCompilerOptions = processCommandLineOptions(topArgs);
-    Result result = null;
-    try {
-      // configure UTF-8 output
-      System.setOut(new PrintStream(System.out, true, "UTF-8"));
-      System.setErr(new PrintStream(System.err, true, "UTF-8"));
-
-      if (topCompilerOptions.showVersion()) {
-        showVersion(topCompilerOptions);
-        System.exit(RESULT_OK);
-      }
-      if (topCompilerOptions.shouldBatch()) {
-        if (topArgs.length > 1) {
-          System.err.println("(Extra arguments specified with -batch ignored.)");
-        }
-        result = UnitTestBatchRunner.runAsBatch(topArgs, new Invocation() {
-          @Override
-          public Result invoke(String[] lineArgs) throws Throwable {
-            List<String> allArgs = new ArrayList<String>();
-            for (String arg: topArgs) {
-              if (!arg.equals("-batch")) {
-                allArgs.add(arg);
-              }
-            }
-            for (String arg: lineArgs) {
-              allArgs.add(arg);
-            }
-
-            CompilerOptions compilerOptions = processCommandLineOptions(
-                allArgs.toArray(new String[allArgs.size()]));
-            if (compilerOptions.shouldBatch()) {
-              System.err.println("-batch ignored: Already in batch mode.");
-            }
-            return compilerMain(compilerOptions);
-          }
-        });
-      } else {
-        System.out.println("WARNING: This command is now deprecated, please use dartanalyzer instead.");
-        System.out.println("For more info, see www.dartlang.org/tools/analyzer.");
-        System.out.println();
-        
-        result = compilerMain(topCompilerOptions);
-      }
-    } catch (Throwable t) {
-      t.printStackTrace();
-      crash();
-    }
-    // exit
-    {
-      int exitCode = result.code;
-      if (!topCompilerOptions.extendedExitCode()) {
-        if (exitCode == RESULT_ERRORS) {
-          exitCode = 1;
-        } else {
-          exitCode = 0;
-        }
-      }
-      System.exit(exitCode);
-    }
-  }
-
-  /**
-   * Invoke the compiler to build single application.
-   * 
-   * @param compilerOptions parsed command line arguments
-   * @return the result as integer when <code>0</code> means clean; <code>1</code> there were
-   *         warnings; <code>2</code> there were errors; <code>127</code> other problems or
-   *         exceptions.
-   */
-  public static Result compilerMain(CompilerOptions compilerOptions) throws IOException {
-    List<String> sourceFiles = compilerOptions.getSourceFiles();
-    if (sourceFiles.size() == 0) {
-      System.err.println("dart_analyzer: no source files were specified.");
-      showUsage(null, System.err);
-      return new Result(RESULT_OTHER, null);
-    }
-
-    File sourceFile = new File(sourceFiles.get(0));
-    if (!sourceFile.exists()) {
-      System.err.println("dart_analyzer: file not found: " + sourceFile);
-      showUsage(null, System.err);
-      return new Result(RESULT_OTHER, null);
-    }
-
-    CompilerConfiguration config = new DefaultCompilerConfiguration(compilerOptions);
-    config.getPackageLibraryManager().setPackageRoots(Arrays.asList(new File[]{compilerOptions.getPackageRoot()}));
-    return compilerMain(sourceFile, config);
-  }
-
-  /**
-   * Invoke the compiler to build single application.
-   *
-   * @param sourceFile file passed on the command line to build
-   * @param config compiler configuration built from parsed command line options
-   */
-  public static Result compilerMain(File sourceFile, CompilerConfiguration config)
-      throws IOException {
-    Result result = compileApp(sourceFile, config);
-    String errorMessage = result.message;
-    if (errorMessage != null) {
-      System.err.println(errorMessage);
-      return result;
-    }
-
-    TraceEvent logEvent = Tracer.canTrace() ? Tracer.start(DartEventType.WRITE_METRICS) : null;
-    try {
-      maybeShowMetrics(config);
-    } finally {
-      Tracer.end(logEvent);
-    }
-    return result;
-  }
-
-  public static void crash() {
-    // Our test scripts look for 253 to signal a "crash".
-    System.exit(253);
-  }
-
-  private static void showUsage(CmdLineParser cmdLineParser, PrintStream out) {
-    out.println("Usage: dart_analyzer [<options>] <dart-script> [script-arguments]");
-    out.println("Available options:");
-    if (cmdLineParser == null) {
-      cmdLineParser = new CmdLineParser(new CompilerOptions());
-    }
-    cmdLineParser.printUsage(out);
-  }
-
-  private static void maybeShowMetrics(CompilerConfiguration config) {
-    CompilerMetrics compilerMetrics = config.getCompilerMetrics();
-    if (compilerMetrics != null) {
-      compilerMetrics.write(System.out);
-    }
-
-    JvmMetrics.maybeWriteJvmMetrics(System.out, config.getJvmMetricOptions());
-  }
-
-  /**
-   * Treats the <code>sourceFile</code> as the top level library and generates compiled output by
-   * linking the dart source in this file with all libraries referenced with <code>#import</code>
-   * statements.
-   * 
-   * @return the result as integer when <code>0</code> means clean; <code>1</code> there were
-   *         warnings; <code>2</code> there were errors; <code>127</code> other problems or
-   *         exceptions.
-   */
-  public static Result compileApp(File sourceFile, CompilerConfiguration config) throws IOException {
-    TraceEvent logEvent =
-        Tracer.canTrace() ? Tracer.start(DartEventType.COMPILE_APP, "src", sourceFile.toString())
-            : null;
-    try {
-      File outputDirectory = config.getOutputDirectory();
-      DefaultDartArtifactProvider provider = new DefaultDartArtifactProvider(outputDirectory);
-      // Compile the Dart application and its dependencies.
-      PackageLibraryManager libraryManager = config.getPackageLibraryManager();
-      final LibrarySource lib = new UrlLibrarySource(sourceFile.toURI(),libraryManager);
-      DefaultDartCompilerListener listener;
-      if (config.getCompilerOptions().showSourceFromAst()) {
-        listener = new DefaultDartCompilerListener(config.printErrorFormat()) {
-          @Override
-          public void unitCompiled(DartUnit unit) {
-            if (unit.getLibrary() != null) {
-              if (unit.getLibrary().getSource() == lib) {
-                DefaultTextOutput output = new DefaultTextOutput(false);
-                unit.accept(new DartToSourceVisitor(output));
-                System.out.println(output.toString());
-              }
-            }
-          }
-        };
-      } else {
-        listener = new DefaultDartCompilerListener(config.printErrorFormat());
-      }
-      return compileLib(lib, config, provider, listener);
-    } finally {
-      Tracer.end(logEvent);
-    }
-  }
-
-  /**
-   * Compiles the given library, translating all its source files, and those
-   * of its imported libraries, transitively.
-   *
-   * @param lib The library to be compiled (not <code>null</code>)
-   * @param config The compiler configuration specifying the compilation phases
-   * @param provider A mechanism for specifying where code should be generated
-   * @param listener An object notified when compilation errors occur
-   */
-  public static Result compileLib(LibrarySource lib, CompilerConfiguration config,
-      DartArtifactProvider provider, DartCompilerListener listener) throws IOException {
-    return compileLib(lib, Collections.<LibrarySource>emptyList(), config, provider, listener);
-  }
-
-  /**
-   * Same method as above, but also takes a list of libraries that should be
-   * implicitly imported by all libraries. These libraries are provided by the embedder.
-   */
-  public static Result compileLib(LibrarySource lib,
-                                  List<LibrarySource> embeddedLibraries,
-                                  CompilerConfiguration config,
-                                  DartArtifactProvider provider,
-                                  DartCompilerListener listener) throws IOException {
-    DartCompilerMainContext context = new DartCompilerMainContext(lib, provider, listener,
-                                                                  config);
-    new Compiler(lib, embeddedLibraries, config, context).compile();
-    int errorCount = context.getErrorCount();
-    if (config.typeErrorsAreFatal()) {
-      errorCount += context.getTypeErrorCount();
-    }
-    if (config.warningsAreFatal()) {
-      errorCount += context.getWarningCount();
-    }
-    if (errorCount > 0) {
-      return new Result(RESULT_ERRORS, "Compilation failed with " + errorCount
-          + (errorCount == 1 ? " problem." : " problems."));
-    }
-    if (!context.getFilesHaveChanged()) {
-      return null;
-    }
-    // Write checking log.
-    {
-      Writer writer = provider.getArtifactWriter(lib, "", EXTENSION_LOG);
-      boolean threw = true;
-      try {
-        writer.write(String.format("Checked %s and found:%n", lib.getName()));
-        writer.write(String.format("  no load/resolution errors%n"));
-        writer.write(String.format("  %s type errors%n", context.getTypeErrorCount()));
-        threw = false;
-      } finally {
-        Closeables.close(writer, threw);
-      }
-    }
-    {
-      int resultCode = RESULT_OK;
-      if (context.getWarningCount() != 0) {
-        resultCode = RESULT_WARNINGS;
-      }
-      return new Result(resultCode, null);
-    }
-  }
-
-  /**
-   * Analyzes the given library and all its transitive dependencies.
-   *
-   * @param lib The library to be analyzed
-   * @param parsedUnits A collection of unresolved ASTs that should be used
-   * instead of parsing the associated source from storage. Intended for
-   * IDE use when modified buffers must be analyzed. AST nodes in the map may be
-   * ignored if not referenced by {@code lib}. (May be null.)
-   * @param config The compiler configuration (phases will not be used), but resolution and
-   * type-analysis will be invoked
-   * @param provider A mechanism for specifying where code should be generated
-   * @param listener An object notified when compilation errors occur
-   * @throws NullPointerException if any of the arguments except {@code parsedUnits}
-   * are {@code null}
-   * @throws IOException on IO errors, which are not logged
-   */
-  public static LibraryUnit analyzeLibrary(LibrarySource lib, final Map<URI, DartUnit> parsedUnits,
-      CompilerConfiguration config, DartArtifactProvider provider, DartCompilerListener listener)
-      throws IOException {
-    final PackageLibraryManager manager = config.getPackageLibraryManager();
-    final HashMap<URI, LibraryUnit> resolvedLibs = new HashMap<URI, LibraryUnit>();
-    SelectiveCache selectiveCache = new SelectiveCache() {
-      @Override
-      public Map<URI, LibraryUnit> getResolvedLibraries() {
-        return resolvedLibs;
-      }
-      @Override
-      public DartUnit getUnresolvedDartUnit(DartSource dartSrc) {
-        if (parsedUnits == null) {
-          return null;
-        }
-        URI srcUri = dartSrc.getUri();
-        DartUnit parsedUnit = parsedUnits.remove(srcUri);
-        if (parsedUnit != null) {
-          return parsedUnit;
-        }
-        URI fileUri = manager.resolveDartUri(srcUri);
-        return parsedUnits.remove(fileUri);
-      }
-    };
-    Map<URI, LibraryUnit> libraryUnit = analyzeLibraries(lib, selectiveCache, config,
-        provider, listener, false);
-    return libraryUnit != null ? libraryUnit.get(lib.getUri()) : null;
-  }
-
-  /**
-   * Analyzes the given library and all its transitive dependencies.
-   *
-   * @param lib The library to be analyzed
-   * @param selectiveCache Provides cached parse and resolution results 
-   *    during selective compilation (not <code>null</code>)
-   * @param config The compiler configuration (phases and backends
-   *    will not be used), but resolution and type-analysis will be invoked
-   * @param provider A mechanism for specifying where code should be generated
-   * @param listener An object notified when compilation errors occur
-   * @param resolveAllNewLibs <code>true</code> if all new libraries should be resolved
-   *    or false if only the library specified by the "lib" parameter should be resolved
-   * @throws NullPointerException if any of the arguments except {@code parsedUnits}
-   *    are {@code null}
-   * @throws IOException on IO errors, which are not logged
-   */
-  public static Map<URI, LibraryUnit> analyzeLibraries(LibrarySource lib,
-      SelectiveCache selectiveCache, CompilerConfiguration config,
-      DartArtifactProvider provider, DartCompilerListener listener, 
-      boolean resolveAllNewLibs) throws IOException {
-    lib.getClass(); // Quick null check.
-    provider.getClass(); // Quick null check.
-    listener.getClass(); // Quick null check.
-    Map<URI, LibraryUnit> resolvedLibs = selectiveCache.getResolvedLibraries();
-    DartCompilerMainContext context = new DartCompilerMainContext(lib, provider, listener, config);
-    Compiler compiler = new SelectiveCompiler(lib, selectiveCache, config, context);
-
-    LibraryUnit topLibUnit = compiler.updateAndResolve();
-    if (topLibUnit == null) {
-      return null;
-    }
-
-    Map<URI, LibraryUnit> librariesToResolve;
-    librariesToResolve = new HashMap<URI, LibraryUnit>();
-    if (resolveAllNewLibs) {
-      librariesToResolve.putAll(compiler.getLibraries());
-    }
-    librariesToResolve.put(topLibUnit.getSource().getUri(), topLibUnit);
-    
-    DartCompilationPhase[] phases = {
-        new Resolver.Phase(),
-        new CompileTimeConstantAnalyzer.Phase(),
-        new TypeAnalyzer()};
-    Map<URI, LibraryUnit> newLibraries = Maps.newHashMap();
-    for (Entry<URI, LibraryUnit> entry : librariesToResolve.entrySet()) {
-      URI libUri = entry.getKey();
-      LibraryUnit libUnit = entry.getValue();
-      if (!resolvedLibs.containsKey(libUri) && libUnit != null) {
-        newLibraries.put(libUri, libUnit);
-        for (DartCompilationPhase phase : phases) {
-          // Run phase on all units, because "const" phase expects to have fully resolved library.
-          for (DartUnit unit : libUnit.getUnits()) {
-            if (unit.isDiet()) {
-              continue;
-            }
-            unit = phase.exec(unit, context, compiler.getTypeProvider());
-          }
-        }
-        // To help support the IDE, notify the listener that these unit were compiled.
-        for (DartUnit unit : libUnit.getUnits()) {
-          context.unitCompiled(unit);
-        }
-      }
-    }
-
-    return newLibraries;
-  }
-
-  /**
-   * Re-analyzes source code after a modification. The modification is described by a SourceDelta.
-   *
-   * @param delta what has changed
-   * @param enclosingLibrary the library in which the change occurred
-   * @param interestStart beginning of interest area (as character offset from the beginning of the
-   *          source file after the change.
-   * @param interestLength length of interest area
-   * @return a node which covers the entire interest area.
-   */
-  public static DartNode analyzeDelta(SourceDelta delta,
-                                      LibraryElement enclosingLibrary,
-                                      LibraryElement coreLibrary,
-                                      DartNode interestNode,
-                                      int interestStart,
-                                      int interestLength,
-                                      CompilerConfiguration config,
-                                      DartCompilerListener listener) throws IOException {
-    DeltaAnalyzer analyzer = new DeltaAnalyzer(delta, enclosingLibrary, coreLibrary,
-                                               interestNode, interestStart, interestLength,
-                                               config, listener);
-    return analyzer.analyze();
-  }
-
-  public static LibraryUnit findLibrary(LibraryUnit libraryUnit, String uri,
-      Set<LibraryElement> seen) {
-    if (seen.contains(libraryUnit.getElement())) {
-      return null;
-    }
-    seen.add(libraryUnit.getElement());
-    if (uri.equals(libraryUnit.getName())) {
-      return libraryUnit;
-    }
-    for (LibraryNode src : libraryUnit.getSourcePaths()) {
-      if (src.getText().equals(uri)) {
-        return libraryUnit;
-      }
-    }
-    for (LibraryUnit importedLibrary : libraryUnit.getImportedLibraries()) {
-      LibraryUnit unit = findLibrary(importedLibrary, uri, seen);
-      if (unit != null) {
-        return unit;
-      }
-    }
-    return null;
-  }
-
-  public static LibraryUnit getCoreLib(LibraryUnit libraryUnit) {
-    LibraryUnit coreLib = findLibrary(libraryUnit, "dart.core", new HashSet<LibraryElement>());
-    if (coreLib == null) {
-      coreLib = findLibrary(libraryUnit, "dart:core", new HashSet<LibraryElement>());
-    }
-    return coreLib;
-  }
-
-  private static void showVersion(CompilerOptions options) {
-    String version = getSdkVersion(options);
-    if (version == null) {
-      version = "<unkown>";
-    }
-    System.out.println("dart_analyzer version " + version);
-  }
-
-  /**
-   * @return the numeric revision of SDK, may be <code>null</code> if cannot find.
-   */
-  private static String getSdkVersion(CompilerOptions options) {
-    try {
-      File sdkPath = options.getDartSdkPath();
-      File revisionFile = new File(sdkPath, "version");
-      if (revisionFile.exists() && revisionFile.isFile()) {
-        BufferedReader br = new BufferedReader(new FileReader(revisionFile));
-        try {
-          return br.readLine();
-        } finally {
-          br.close();
-        }
-      }
-    } catch (Throwable e) {
-    }
-    return null;
-  }
-}
diff --git a/compiler/java/com/google/dart/compiler/DartCompilerContext.java b/compiler/java/com/google/dart/compiler/DartCompilerContext.java
deleted file mode 100644
index 61e3302..0000000
--- a/compiler/java/com/google/dart/compiler/DartCompilerContext.java
+++ /dev/null
@@ -1,122 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler;
-
-import com.google.dart.compiler.ast.LibraryUnit;
-import com.google.dart.compiler.metrics.CompilerMetrics;
-
-import java.io.IOException;
-import java.io.Reader;
-import java.io.Writer;
-import java.net.URI;
-
-/**
- * An interface used internally by the {@link DartCompiler} for determining where an artifact should
- * be generated and providing feedback during the compilation process. This is an internal compiler
- * construct and as such should not be instantiated or implemented by those outside the compiler
- * itself.
- */
-public interface DartCompilerContext {
-
-  /**
-   * Parse the application being compiled and return the result. The "application unit" is a
-   * library that specifies an entry-point.
-   * 
-   * This method will be removed in favor of {@link #getAppLibraryUnit()}.
-   *
-   * @return the parsed result (not <code>null</code>)
-   */
-  LibraryUnit getApplicationUnit();
-
-  /**
-   * Parse the application being compiled and return the result. The "app" library unit is a
-   * library that specifies an entry-point.
-   *
-   * @return the parsed result (not <code>null</code>)
-   */
-  LibraryUnit getAppLibraryUnit();
-
-  /**
-   * Parse the specified library and return the result.
-   *
-   * @param lib the library to parse (not <code>null</code>)
-   * @return the parsed result (not <code>null</code>)
-   */
-  LibraryUnit getLibraryUnit(LibrarySource lib);
-
-  /**
-   * Called by the compiler when a error (fatal or non-fatal) has occurred in a Dart file.
-   *
-   * @param event the event information (not <code>null</code>)
-   */
-  void onError(DartCompilationError event);
-
-  /**
-   * Gets a reader for an artifact associated with the specified source, which
-   * must have been written to {@link #getArtifactWriter(Source, String, String)}. The
-   * caller is responsible for closing the reader. Only one artifact may be
-   * associated with the given extension.
-   *
-   * @param source the source file (not <code>null</code>)
-   * @param part a component of the source file to get a reader for (may be empty).
-   * @param extension the file extension for this artifact (not
-   *          <code>null</code>, not empty)
-   * @return the reader, or <code>null</code> if no such artifact exists
-   */
-  Reader getArtifactReader(Source source, String part, String extension) throws IOException;
-
-  /**
-   * Gets the {@link URI} for an artifact associated with this source.
-   * 
-   * @param source the source file (not <code>null</code>)
-   * @param part a component of the source file to get a reader for (may be empty).
-   * @param extension the file extension for this artifact (not
-   *          <code>null</code>, not empty)
-   */
-  URI getArtifactUri(DartSource source, String part, String extension);
-
-  /**
-   * Gets a writer for an artifact associated with this source. The caller is
-   * responsible for closing the writer. Only one artifact may be associated
-   * with the given extension.
-   *
-   * @param source the source file (not <code>null</code>)
-   * @param part a component of the source file to get a reader for (may be empty).
-   * @param extension the file extension for this artifact (not
-   *          <code>null</code>, not empty)
-   */
-  Writer getArtifactWriter(Source source, String part, String extension) throws IOException;
-
-  /**
-   * Determines whether an artifact for the specified source is out of date
-   * with respect to some other source.
-   *
-   * @param source the source file to check (not <code>null</code>)
-   * @param base the artifact's base source (not <code>null</code>)
-   * @param extension the file extension for this artifact (not
-   *          <code>null</code>, not empty)
-   * @return <code>true</code> if out of date
-   */
-  boolean isOutOfDate(Source source, Source base, String extension);
-
-  /**
-   * Returns the {@link CompilerMetrics} instance or <code>null</code> if we should not record
-   * metrics.
-   *
-   * @return the metrics instance, <code>null</code> if metrics should not be recorded
-   */
-  CompilerMetrics getCompilerMetrics();
-
-  /**
-   * Returns the {@link CompilerConfiguration} instance.
-   * @return the compiler configuration instance.
-   */
-  CompilerConfiguration getCompilerConfiguration();
-
-  /**
-   * Return the system library corresponding to the specified "dart:<libname>" spec.
-   */
-  LibrarySource getSystemLibraryFor(String importSpec);
-}
diff --git a/compiler/java/com/google/dart/compiler/DartCompilerErrorCode.java b/compiler/java/com/google/dart/compiler/DartCompilerErrorCode.java
deleted file mode 100644
index 5476e2e..0000000
--- a/compiler/java/com/google/dart/compiler/DartCompilerErrorCode.java
+++ /dev/null
@@ -1,69 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler;
-
-/**
- * Valid error codes for the errors produced by the Dart compiler.
- */
-public enum DartCompilerErrorCode implements ErrorCode {
-  CONSOLE_WEB_MIX(ErrorSeverity.INFO,
-      "Libraries 'dart:io' (console apps only) and 'dart:html' (web apps only) cannot be used together"),
-  DUPLICATE_IMPORTED_LIBRARY_NAME("a library with name '%s' was already imported: %s"),
-  ENTRY_POINT_METHOD_CANNOT_HAVE_PARAMETERS(ErrorSeverity.WARNING, 
-      "Main entry point method cannot have parameters"),
-  ENTRY_POINT_METHOD_MAY_NOT_BE_GETTER(ErrorSeverity.WARNING,
-      "Entry point \"%s\" may not be a getter"),
-  ENTRY_POINT_METHOD_MAY_NOT_BE_SETTER(ErrorSeverity.WARNING,
-      "Entry point \"%s\" may not be a setter"),
-  ILLEGAL_DIRECTIVES_IN_SOURCED_UNIT("This part was included by %s via a "
-      + "part directive, so cannot itself contain directives other than a 'part of' directive"),
-  IO("Input/Output error: %s"),
-  MIRRORS_NOT_FULLY_IMPLEMENTED(ErrorSeverity.WARNING, "dart:mirrors is not fully implemented yet"),
-  MISSING_LIBRARY_DIRECTIVE_IMPORT("a library which is imported is missing a library directive: %s"),
-  MISSING_LIBRARY_DIRECTIVE_EXPORT("a library which is exported is missing a library directive: %s"),
-  MISSING_SOURCE("Cannot find referenced source: %s"),
-  MISSING_PART_OF_DIRECTIVE("Unit is part of library '%s', but has no 'part of' directive"),
-  UNIT_WAS_ALREADY_INCLUDED("Unit '%s' was already included"),
-  WRONG_PART_OF_NAME(
-      ErrorSeverity.WARNING,
-      "This part was included by '%s' via a 'part' directive, but uses name '%s' in 'part of' directive");
-  private final ErrorSeverity severity;
-  private final String message;
-
-  /**
-   * Initialize a newly created error code to have the given message and ERROR severity.
-   */
-  private DartCompilerErrorCode(String message) {
-    this(ErrorSeverity.ERROR, message);
-  }
-
-  /**
-   * Initialize a newly created error code to have the given severity and message.
-   */
-  private DartCompilerErrorCode(ErrorSeverity severity, String message) {
-    this.severity = severity;
-    this.message = message;
-  }
-
-  @Override
-  public String getMessage() {
-    return message;
-  }
-
-  @Override
-  public ErrorSeverity getErrorSeverity() {
-    return severity;
-  }
-
-  @Override
-  public SubSystem getSubSystem() {
-    return SubSystem.COMPILER;
-  }
-
-  @Override
-  public boolean needsRecompilation() {
-    return true;
-  }
-}
diff --git a/compiler/java/com/google/dart/compiler/DartCompilerListener.java b/compiler/java/com/google/dart/compiler/DartCompilerListener.java
deleted file mode 100644
index 9216c5b..0000000
--- a/compiler/java/com/google/dart/compiler/DartCompilerListener.java
+++ /dev/null
@@ -1,53 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-package com.google.dart.compiler;
-
-import com.google.dart.compiler.ast.DartUnit;
-
-/**
- * Interface that {@link DartCompiler} consumers can use to monitor compilation progress and report
- * various problems that occur during compilation.
- */
-public interface DartCompilerListener {
-  /**
-   * Called by the compiler when a compilation error has occurred in a Dart file.
-   * 
-   * @param event the event information (not <code>null</code>)
-   */
-  void onError(DartCompilationError event);
-
-  /**
-   * Called by the compiler before parsing given {@link DartSource}.
-   */
-  void unitAboutToCompile(DartSource source, boolean diet);
-
-  /**
-   * Called by the compiler after the resolution and type analyzer phase for each unit.
-   * 
-   * @param unit the {@link DartUnit} having just been compiled (not <code>null</code>)
-   */
-  void unitCompiled(DartUnit unit);
-
-  /**
-   * Implementation of {@link DartCompilerListener} which does nothing.
-   */
-  public static class Empty implements DartCompilerListener {
-    @Override
-    public void onError(DartCompilationError event) {
-    }
-
-    @Override
-    public void unitAboutToCompile(DartSource source, boolean diet) {
-    }
-
-    @Override
-    public void unitCompiled(DartUnit unit) {
-    }
-  }
-  
-  /**
-   * Instance of {@link DartCompilerListener} which does nothing.
-   */
-  public static final DartCompilerListener EMPTY = new Empty();
-}
diff --git a/compiler/java/com/google/dart/compiler/DartCompilerMainContext.java b/compiler/java/com/google/dart/compiler/DartCompilerMainContext.java
deleted file mode 100644
index ea3ea09..0000000
--- a/compiler/java/com/google/dart/compiler/DartCompilerMainContext.java
+++ /dev/null
@@ -1,232 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler;
-
-import com.google.common.collect.Lists;
-import com.google.common.collect.Maps;
-import com.google.common.collect.Sets;
-import com.google.dart.compiler.ast.DartUnit;
-import com.google.dart.compiler.ast.LibraryUnit;
-import com.google.dart.compiler.metrics.CompilerMetrics;
-import com.google.dart.compiler.parser.DartParser;
-import com.google.dart.compiler.resolver.Elements;
-import com.google.dart.compiler.resolver.ResolverErrorCode;
-import com.google.dart.compiler.resolver.TypeErrorCode;
-
-import java.io.IOException;
-import java.io.Reader;
-import java.io.Writer;
-import java.net.URI;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.atomic.AtomicBoolean;
-import java.util.concurrent.atomic.AtomicInteger;
-
-/**
- * An overall context for the Dart compiler providing an adapter and forwarding
- * mechanism for to both {@link DartArtifactProvider} and
- * {@link DartCompilerListener}. This is an internal compiler construct and as
- * such should not be instantiated or subclassed by those outside the compiler
- * itself.
- */
-final class DartCompilerMainContext implements DartCompilerListener, DartCompilerContext {
-
-  private final LibrarySource lib;
-  private final DartArtifactProvider provider;
-  private final DartCompilerListener listener;
-  private final Map<Source, List<DartCompilationError>> errors = Maps.newHashMap();
-  private final AtomicInteger errorCount = new AtomicInteger(0);
-  private final AtomicInteger warningCount = new AtomicInteger(0);
-  private final AtomicInteger typeErrorCount = new AtomicInteger(0);
-  private final AtomicBoolean filesHaveChanged = new AtomicBoolean();
-  // declared volatile for thread-safety
-  private volatile LibraryUnit appLibraryUnit = null;
-
-  private final CompilerConfiguration compilerConfiguration;
-
-  DartCompilerMainContext(LibrarySource lib, DartArtifactProvider provider,
-      DartCompilerListener listener,
-      CompilerConfiguration compilerConfiguration) {
-    this.lib = lib;
-    this.provider = provider;
-    this.listener = listener;
-    this.compilerConfiguration = compilerConfiguration;
-  }
-
-  @Override
-  public void onError(DartCompilationError event) {
-    // problems in dart:core are not interesting
-    // http://code.google.com/p/dart/issues/detail?id=7128
-    if (Elements.isCoreLibrarySource(event.getSource())) {
-      ErrorCode ec = event.getErrorCode();
-      if (ec == ResolverErrorCode.EXPECTED_CONSTANT_EXPRESSION_NUMBER
-          || ec == TypeErrorCode.ASSERT_BOOL
-          || ec == TypeErrorCode.TYPE_NOT_ASSIGNMENT_COMPATIBLE
-          || ec == TypeErrorCode.FOR_IN_WITH_INVALID_ITERATOR_RETURN_TYPE
-          || ec == TypeErrorCode.OPERATOR_EQUALS_BOOL_RETURN_TYPE
-          || ec == TypeErrorCode.CANNOT_OVERRIDE_TYPED_MEMBER
-          || ec == TypeErrorCode.CANNOT_OVERRIDE_METHOD_NOT_SUBTYPE
-          || ec == TypeErrorCode.OPERATOR_WRONG_OPERAND_TYPE) {
-        return;
-      }
-    }
-
-    // Remember error.
-    {
-      Source source = event.getSource();
-      if (source != null) {
-        List<DartCompilationError> sourceErrors = errors.get(source);
-        if (sourceErrors == null) {
-          sourceErrors = Lists.newArrayList();
-          errors.put(source, sourceErrors);
-        }
-        sourceErrors.add(event);
-      }
-    }
-    // Increment counters.
-    if (event.getErrorCode().getSubSystem() == SubSystem.STATIC_TYPE) {
-      incrementTypeErrorCount();
-    }
-    if (event.getErrorCode().getErrorSeverity() == ErrorSeverity.ERROR) {
-      incrementErrorCount();
-    } else if (event.getErrorCode().getErrorSeverity() == ErrorSeverity.WARNING) {
-      incrementWarningCount();
-    }
-    // Notify listener.
-    listener.onError(event);
-  }
-
-  @Override
-  public LibraryUnit getApplicationUnit() {
-    return getAppLibraryUnit();
-  }
-
-  @Override
-  public LibraryUnit getAppLibraryUnit() {
-    // use double-checked looking pattern with use of volatile
-    if (appLibraryUnit == null) {
-      synchronized (this) {
-        if (appLibraryUnit == null) {
-          try {
-            appLibraryUnit = new DartParser(lib, DartParser.read(lib), false,
-                Sets.<String> newHashSet(), DartCompilerListener.EMPTY, null).preProcessLibraryDirectives(lib);
-          } catch (IOException e) {
-            onError(new DartCompilationError(lib, DartCompilerErrorCode.IO, e.getMessage()));
-            return null;
-          }
-        }
-      }
-    }
-    return appLibraryUnit;
-  }
-
-  @Override
-  public Reader getArtifactReader(Source source, String part, String extension)
-      throws IOException {
-    return provider.getArtifactReader(source, part, extension);
-  }
-
-  @Override
-  public URI getArtifactUri(DartSource source, String part, String extension) {
-    return provider.getArtifactUri(source, part, extension);
-  }
-
-  @Override
-  public Writer getArtifactWriter(Source source, String part, String extension)
-      throws IOException {
-    return provider.getArtifactWriter(source, part, extension);
-  }
-
-  /**
-   * @return the {@link DartCompilationError}s found in the given {@link Source}.
-   */
-  public List<DartCompilationError> getSourceErrors(Source source) {
-    List<DartCompilationError> sourceErrors = errors.get(source);
-    if (sourceErrors != null) {
-      return sourceErrors;
-    }
-    return Collections.emptyList();
-  }
-
-  public int getErrorCount() {
-    return errorCount.get();
-  }
-
-  public int getWarningCount() {
-    return warningCount.get();
-  }
-
-  public int getTypeErrorCount() {
-    return typeErrorCount.get();
-  }
-
-  @Override
-  public LibraryUnit getLibraryUnit(LibrarySource libSrc) {
-    if (libSrc == lib) {
-      return getApplicationUnit();
-    }
-    try {
-      return new DartParser(libSrc, DartParser.read(libSrc), false,
-          Sets.<String> newHashSet(), listener, null).preProcessLibraryDirectives(libSrc);
-    } catch (IOException e) {
-      onError(new DartCompilationError(libSrc, DartCompilerErrorCode.IO, e.getMessage()));
-      return null;
-    }
-  }
-
-  @Override
-  public boolean isOutOfDate(Source source, Source base, String extension) {
-    return provider.isOutOfDate(source, base, extension);
-  }
-
-  protected void incrementErrorCount() {
-    errorCount.incrementAndGet();
-  }
-
-  protected void incrementWarningCount() {
-    warningCount.incrementAndGet();
-  }
-
-  protected void incrementTypeErrorCount() {
-    typeErrorCount.incrementAndGet();
-  }
-
-  @Override
-  public CompilerMetrics getCompilerMetrics() {
-    return compilerConfiguration.getCompilerMetrics();
-  }
-
-  public void setFilesHaveChanged() {
-    filesHaveChanged.set(true);
-  }
-
-  public boolean getFilesHaveChanged() {
-    return filesHaveChanged.get();
-  }
-
-  @Override
-  public CompilerConfiguration getCompilerConfiguration() {
-    return compilerConfiguration;
-  }
-
-  /**
-   * Return the system library corresponding to the specified "dart:<libname>" spec.
-   */
-  @Override
-  public LibrarySource getSystemLibraryFor(String importSpec) {
-    return compilerConfiguration.getSystemLibraryFor(importSpec);
-  }
-
-  @Override
-  public void unitAboutToCompile(DartSource source, boolean diet) {
-    listener.unitAboutToCompile(source, diet);
-  }
-
-  @Override
-  public void unitCompiled(DartUnit unit) {
-    listener.unitCompiled(unit);
-  }
-}
diff --git a/compiler/java/com/google/dart/compiler/DartSource.java b/compiler/java/com/google/dart/compiler/DartSource.java
deleted file mode 100644
index 2962e17..0000000
--- a/compiler/java/com/google/dart/compiler/DartSource.java
+++ /dev/null
@@ -1,21 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler;
-
-/**
- * Abstract interface to Dart source.
- */
-public interface DartSource extends Source {
-
-  /**
-   * Gets the library with which this Dart source is associated.
-   */
-  LibrarySource getLibrary();
-
-  /**
-   * Gets the path of this source, relative to its library.
-   */
-  String getRelativePath();
-}
diff --git a/compiler/java/com/google/dart/compiler/DefaultCompilerConfiguration.java b/compiler/java/com/google/dart/compiler/DefaultCompilerConfiguration.java
deleted file mode 100644
index f66190a..0000000
--- a/compiler/java/com/google/dart/compiler/DefaultCompilerConfiguration.java
+++ /dev/null
@@ -1,142 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler;
-
-import com.google.dart.compiler.CommandLineOptions.CompilerOptions;
-import com.google.dart.compiler.metrics.CompilerMetrics;
-import com.google.dart.compiler.resolver.CompileTimeConstantAnalyzer;
-import com.google.dart.compiler.resolver.Resolver;
-import com.google.dart.compiler.type.TypeAnalyzer;
-
-import java.io.File;
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * A configuration for the Dart compiler specifying which phases will be executed.
- */
-public class DefaultCompilerConfiguration implements CompilerConfiguration {
-
-  private final CompilerOptions compilerOptions;
-
-  private final CompilerMetrics compilerMetrics;
-
-  private final PackageLibraryManager packageLibraryManager;
-
-
-  /**
-   * A default configuration.
-   */
-  public DefaultCompilerConfiguration() {
-    this(new CompilerOptions());
-  }
-
-  /**
-   * A new instance with the specified {@link CompilerOptions}.
-   */
-  public DefaultCompilerConfiguration(CompilerOptions compilerOptions) {
-    this(compilerOptions, new PackageLibraryManager(compilerOptions.getDartSdkPath(),
-                                                   compilerOptions.getPlatformName()));
-  }
-
-  /**
-   * A new instance with the specified options and system library manager.
-   */
-  public DefaultCompilerConfiguration(CompilerOptions compilerOptions,
-      PackageLibraryManager libraryManager) {
-    this.compilerOptions = compilerOptions;
-    this.compilerMetrics = compilerOptions.showMetrics() ? new CompilerMetrics() : null;
-    this.packageLibraryManager = libraryManager;
-  }
-
-  @Override
-  public List<DartCompilationPhase> getPhases() {
-    List<DartCompilationPhase> phases = new ArrayList<DartCompilationPhase>();
-    phases.add(new Resolver.Phase());
-    phases.add(new CompileTimeConstantAnalyzer.Phase());
-    phases.add(new TypeAnalyzer());
-    return phases;
-  }
-
-  @Override
-  public boolean developerModeChecks() {
-    return compilerOptions.developerModeChecks();
-  }
-
-  @Override
-  public CompilerMetrics getCompilerMetrics() {
-    return compilerMetrics;
-  }
-
-  @Override
-  public String getJvmMetricOptions() {
-    return compilerOptions.getJvmMetricOptions();
-  }
-
-  @Override
-  public boolean typeErrorsAreFatal() {
-    return compilerOptions.typeErrorsAreFatal();
-  }
-
-  @Override
-  public boolean warningsAreFatal() {
-    return compilerOptions.warningsAreFatal();
-  }
-
-  @Override
-  public boolean resolveDespiteParseErrors() {
-    return compilerOptions.resolveDespiteParseErrors();
-  }
-
-  @Override
-  public boolean incremental() {
-    return compilerOptions.buildIncrementally();
-  }
-
-  @Override
-  public File getOutputDirectory() {
-    return compilerOptions.getWorkDirectory();
-  }
-
-  @Override
-  public LibrarySource getSystemLibraryFor(String importSpec) {
-    URI systemUri;
-    try {
-      systemUri = new URI(importSpec);
-    } catch (URISyntaxException e) {
-      throw new RuntimeException(e);
-    }
-
-    // Verify the dart system library exists
-    if( null == this.packageLibraryManager.expandRelativeDartUri(systemUri) ) {
-      return null;
-    }
-
-    // Ensure we are using the short form if it exists
-    URI shortUri = packageLibraryManager.getShortUri(systemUri);
-    if (shortUri != null) {
-      systemUri = shortUri;
-    }
-
-    return new UrlLibrarySource(systemUri, this.packageLibraryManager);
-  }
-  
-  @Override
-  public CompilerOptions getCompilerOptions() {
-    return compilerOptions;
-  }
-
-  @Override
-  public ErrorFormat printErrorFormat() {
-    return compilerOptions.printErrorFormat();
-  }
-  
-  @Override
-  public PackageLibraryManager getPackageLibraryManager() {
-    return packageLibraryManager;
-  }
-}
diff --git a/compiler/java/com/google/dart/compiler/DefaultDartArtifactProvider.java b/compiler/java/com/google/dart/compiler/DefaultDartArtifactProvider.java
deleted file mode 100644
index 5874051..0000000
--- a/compiler/java/com/google/dart/compiler/DefaultDartArtifactProvider.java
+++ /dev/null
@@ -1,235 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler;
-
-import java.io.BufferedReader;
-import java.io.BufferedWriter;
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.FileReader;
-import java.io.FileWriter;
-import java.io.IOException;
-import java.io.Reader;
-import java.io.Writer;
-import java.net.URI;
-import java.net.URISyntaxException;
-
-/**
- * A default implementation of {@link DartArtifactProvider} specifying
- * generated files be placed in the same directory as source files.
- */
-public class DefaultDartArtifactProvider extends DartArtifactProvider {
-
-  private final File outputDirectory;
-
-  public DefaultDartArtifactProvider() {
-    this(new File("out"));
-  }
-
-  public DefaultDartArtifactProvider(File outputDirectory) {
-    this.outputDirectory = outputDirectory;
-  }
-
-  @Override
-  public Reader getArtifactReader(Source source, String part, String extension)
-      throws IOException {
-    if (PackageLibraryManager.isDartUri(source.getUri())) {
-      DartSource bundledSource = getBundledArtifact(source, source, part, extension);
-      if (bundledSource != null) {
-        Reader reader = null;
-        try {
-          reader = bundledSource.getSourceReader();
-        } catch (FileNotFoundException e) {
-          /* thrown if file doesn't exist, which is fine */
-        }
-        if (reader != null) {
-          return new BufferedReader(reader);
-        }
-      }
-    }
-    File file = getArtifactFile(source, part, extension);
-    if (!file.exists()) {
-      return null;
-    }
-    return new BufferedReader(new FileReader(file));
-  }
-
-  @Override
-  public URI getArtifactUri(Source source, String part, String extension) {
-    try {
-      return new URI("file", getArtifactFile(source, part, extension).getPath(), null);
-    } catch (URISyntaxException e) {
-      throw new IllegalArgumentException(e);
-    }
-  }
-
-  @Override
-  public Writer getArtifactWriter(Source source, String part, String extension) throws IOException {
-    return new BufferedWriter(new FileWriter(makeDirectories(getArtifactFile(source, part,
-        extension))));
-  }
-
-  @Override
-  public boolean isOutOfDate(Source source, Source base, String extension) {
-    if (PackageLibraryManager.isDartUri(base.getUri())) {
-      Source bundledSource = getBundledArtifact(source, base, "", extension);
-      if (bundledSource != null && bundledSource.exists()) {
-        // Note: Artifacts bundled with sources are always up to date
-        return false;
-      }
-    }
-    File artifactFile = getArtifactFile(base, "", extension);
-    return !artifactFile.exists() || artifactFile.lastModified() < source.getLastModified();
-  }
-
-  // TODO(jbrosenberg): remove 'source' argument from this method, it's not used
-  protected DartSource getBundledArtifact(Source source, Source base, String part, String extension) {
-    LibrarySource library;
-    URI relativeUri;
-    if (base instanceof LibrarySource) {
-      library = (LibrarySource) base;
-      relativeUri = library.getUri().resolve(".").normalize().relativize(base.getUri());
-    } else if (base instanceof DartSource){
-      library = ((DartSource) base).getLibrary();
-      String name = base.getName();
-      URI nameUri = URI.create(name).normalize();
-      relativeUri = library.getUri().resolve(".").normalize().relativize(nameUri);
-    } else {
-      throw new AssertionError(base.getClass().getName());
-    }
-
-    DartSource bundledSource;
-    if (!relativeUri.isAbsolute()) {
-      bundledSource = library.getSourceFor(fullname(relativeUri.getPath(), part, extension));
-    } else {
-      bundledSource = null;
-    }
-    return bundledSource;
-  }
-
-  /**
-   * Answer the artifact file associated with the specified source. Only one
-   * artifact may be associated with the given extension.
-   *
-   * @param source the source file (not <code>null</code>)
-   * @param part a component of the source file to get a reader for (may be empty).
-   * @param extension the file extension for this artifact (not
-   *          <code>null</code>, not empty)
-   * @return the artifact file (not <code>null</code>)
-   */
-  protected File getArtifactFile(Source source, String part, String extension) {
-    String name = source.getName();
-    name = URI.create(name).normalize().toString();
-    name = normalizeArtifactName(name);
-    File file = new File(outputDirectory, fullname(name, part, extension));
-    return file;
-  }
-  
-  /*
-   * Removes extraneous punctuation and file path syntax.
-   */
-  private String normalizeArtifactName(String name) {
-    /**
-     * For efficiency, String operations are replaced with a single pass over
-     * the character array data.
-     * 
-     * Note: This is a refactor of a previous version which used repeated calls
-     * to String.replace(), which turns out to be unnecessarily expensive. This
-     * particular method has been identified as being called a large number of
-     * times, thus the need for the micro-optimization here.
-     * 
-     * This is the original logic being implemented here:
-     * 
-     * <code>
-     * name = name.replace("//", File.separator);
-     * name = name.replace(":", "");
-     * name = name.replace("!", "");
-     * name = name.replace("..", "_");
-     * </code>
-     * 
-     * Please update the above if the logic being implemented ever changes.
-     * 
-     * TODO(jbrosenberg): Figure out a better way such that this normalization
-     * is no longer needed in the first place. Source objects could be built
-     * from pre-normalized prefixes, etc. Or if it can be called less often,
-     * then use pre-compiled Patterns and Matchers instead.
-     */
-    boolean lastCharWasSlash = false;
-    boolean lastCharWasPeriod = false;
-    boolean madeChanges = false;
-    int nameLen = name.length();
-    char[] newName = new char[nameLen];
-    int idx = 0;
-    for (char ch : name.toCharArray()) {
-      if (lastCharWasPeriod && ch != '.') {
-        // didn't get a second period, so append the one we did get
-        newName[idx++] = '.';
-        lastCharWasPeriod = false;
-      } else if (lastCharWasSlash && ch != '/') {
-        // didn't get a second slash, so append the one we did get
-        newName[idx++] = '/';
-        lastCharWasSlash = false;
-      }
-
-      switch (ch) {
-        case ':':
-        case '!':
-            // replace ':'s and '!'s with empty string
-            madeChanges = true;
-            break;
-        case '/':
-            if (lastCharWasSlash) {
-              // got a second slash, replace with File.separatorChar
-              madeChanges = true;
-              newName[idx++] = File.separatorChar;
-              lastCharWasSlash = false;
-            } else {
-              lastCharWasSlash = true;
-            }
-            break;
-        case '.':
-            if (lastCharWasPeriod) {
-              // got a second period, replace with a '_'
-              madeChanges = true;
-              newName[idx++] = ('_');
-              lastCharWasPeriod = false;
-            } else {
-              lastCharWasPeriod = true;
-            }
-            break;
-        default:
-            newName[idx++] = ch;
-            lastCharWasSlash = false;
-            lastCharWasPeriod = false;
-      }
-    }
-    if (lastCharWasPeriod) {
-      // didn't get a final second period, so append the one we did get
-      newName[idx++] = '.';
-    } else if (lastCharWasSlash) {
-      // didn't get a final second slash, so append the one we did get
-      newName[idx++] = '/';
-    }
-
-    if (madeChanges) {
-      name = new String(newName, 0, idx);
-    }
-
-    return name;
-  }
-  
-  private File makeDirectories(File file) {
-    file.getParentFile().mkdirs();
-    return file;
-  }
-
-  private String fullname(String name, String part, String extension) {
-    if (part.isEmpty()) {
-      return name + "." + extension;
-    } else {
-      return name + "$" + part + "." + extension;
-    }
-  }
-}
diff --git a/compiler/java/com/google/dart/compiler/DefaultDartCompilerListener.java b/compiler/java/com/google/dart/compiler/DefaultDartCompilerListener.java
deleted file mode 100644
index 7b7be62..0000000
--- a/compiler/java/com/google/dart/compiler/DefaultDartCompilerListener.java
+++ /dev/null
@@ -1,121 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler;
-
-import com.google.dart.compiler.CompilerConfiguration.ErrorFormat;
-import com.google.dart.compiler.ast.DartUnit;
-
-import java.io.PrintStream;
-
-/**
- * A default implementation of {@link DartCompilerListener} which counts
- * compilation errors.
- */
-public class DefaultDartCompilerListener implements DartCompilerListener {
-
-  /**
-   * The number of (fatal) problems that occurred during compilation.
-   */
-  private int errorCount = 0;
-
-  /**
-   * The number of (non-fatal) problems that occurred during compilation.
-   */
-  private int warningCount = 0;
-
-  /**
-   * The number of (non-fatal) problems that occurred during compilation.
-   */
-  private int typeErrorCount = 0;
-
-  /**
-   * Formatter used to report error messages. Marked protected so that
-   * subclasses can override it (e.g. for a test server using HTML formatting).
-   */
-  protected final ErrorFormatter formatter;
-
-  public DefaultDartCompilerListener(ErrorFormat errorFormat) {
-    this(System.err, errorFormat);
-  }
-
-  /**
-   * @param outputStream the {@link PrintStream} to use for {@link ErrorFormatter}.
-   */
-  public DefaultDartCompilerListener(PrintStream outputStream, ErrorFormat errorFormat) {
-    formatter = new  PrettyErrorFormatter(outputStream, useColor(), errorFormat);
-  }
-
-  private boolean useColor() {
-    return String.valueOf(System.getenv("TERM")).startsWith("xterm") && System.console() != null;
-  }
-
-  /**
-   * Answer the number of fatal errors that occurred during compilation.
-   *
-   * @return the number of problems
-   */
-  public int getErrorCount() {
-    return errorCount;
-  }
-
-  /**
-   * Answer the number of non-fatal warnings that occurred during compilation.
-   *
-   * @return the number of problems
-   */
-  public int getWarningCount() {
-    return warningCount;
-  }
-
-  /**
-   * Answer the number of non-fatal type problems that occurred during compilation.
-   *
-   * @return the number of problems
-   */
-  public int getTypeErrorCount() {
-    return typeErrorCount;
-  }
-
-  /**
-   * Increment the {@link #errorCount} by 1
-   */
-  protected void incrementErrorCount() {
-    errorCount++;
-  }
-
-  /**
-   * Increment the {@link #warningCount} by 1
-   */
-  protected void incrementWarningCount() {
-    warningCount++;
-  }
-
-  /**
-   * Increment the {@link #typeErrorCount} by 1
-   */
-  protected void incrementTypeErrorCount() {
-    typeErrorCount++;
-  }
-
-  @Override
-  public void onError(DartCompilationError event) {
-    formatter.format(event);
-    if (event.getErrorCode().getSubSystem() == SubSystem.STATIC_TYPE) {
-      incrementTypeErrorCount();
-    } else if (event.getErrorCode().getErrorSeverity() == ErrorSeverity.ERROR) {
-      incrementErrorCount();
-    } else if (event.getErrorCode().getErrorSeverity() == ErrorSeverity.WARNING) {
-      incrementWarningCount();
-    }
-  }
-
-  @Override
-  public void unitAboutToCompile(DartSource source, boolean diet) {
-  }
-
-  @Override
-  public void unitCompiled(DartUnit unit) {
-  }
-}
diff --git a/compiler/java/com/google/dart/compiler/DefaultErrorFormatter.java b/compiler/java/com/google/dart/compiler/DefaultErrorFormatter.java
deleted file mode 100644
index a908369..0000000
--- a/compiler/java/com/google/dart/compiler/DefaultErrorFormatter.java
+++ /dev/null
@@ -1,93 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler;
-
-import com.google.common.base.Objects;
-import com.google.dart.compiler.CompilerConfiguration.ErrorFormat;
-
-import java.io.PrintStream;
-
-/**
- * An error formatter that simply prints the file name with the line and column
- * location.
- */
-public class DefaultErrorFormatter implements ErrorFormatter {
-  protected final PrintStream outputStream;
-  protected final ErrorFormat errorFormat;
-  
-  public DefaultErrorFormatter(PrintStream outputStream, ErrorFormat errorFormat) {
-    this.outputStream = outputStream;
-    this.errorFormat = errorFormat;
-  }
-
-  @Override
-  public void format(DartCompilationError event) {
-    StringBuilder buf = new StringBuilder();
-    appendError(buf, event);
-    outputStream.print(buf);
-    outputStream.print("\n");
-  }
-
-  protected void appendError(StringBuilder buf, DartCompilationError error) {
-    Source source = error.getSource();
-    String sourceName = getSourceName(source);
-    int line = error.getLineNumber();
-    int col = error.getColumnNumber();
-    int length = error.getLength();
-    if (errorFormat == ErrorFormat.MACHINE) {
-      buf.append(String.format(
-          "%s|%s|%s|%s|%d|%d|%d|%s",
-          escapePipe(error.getErrorCode().getErrorSeverity().toString()),
-          escapePipe(error.getErrorCode().getSubSystem().toString()),
-          escapePipe(error.getErrorCode().toString()),
-          escapePipe(sourceName),
-          line,
-          col,
-          length,
-          escapePipe(error.getMessage())));
-    } else {
-      String includeFrom = getImportString(source);
-      buf.append(String.format(
-          "%s:%d:%d: %s%s",
-          sourceName,
-          line,
-          col,
-          error.getMessage(),
-          includeFrom));
-    }
-  }
-
-  protected static String getImportString(Source sourceFile) {
-    String includeFrom = "";
-    if (sourceFile instanceof DartSource) {
-      LibrarySource lib = ((DartSource) sourceFile).getLibrary();
-      if (lib != null && !Objects.equal(sourceFile.getUri(), lib.getUri())) {
-        includeFrom = " (sourced from " + lib.getUri() + ")";
-      }
-    }
-    return includeFrom;
-  }
-  
-  protected static String getSourceName(Source source) {
-    if (source instanceof UrlDartSource) {
-      return source.getUri().toString();
-    }
-    if (source != null) {
-      return source.getName();
-    }
-    return "<unknown-source-file>";
-  }
-
-  protected static String escapePipe(String input) {
-    StringBuilder result = new StringBuilder();
-    for (char c : input.toCharArray()) {
-      if (c == '\\' || c == '|') {
-        result.append('\\');
-      }
-      result.append(c);
-    }
-    return result.toString();
-  }
-}
diff --git a/compiler/java/com/google/dart/compiler/DefaultLibrarySource.java b/compiler/java/com/google/dart/compiler/DefaultLibrarySource.java
deleted file mode 100644
index 82a4c1c..0000000
--- a/compiler/java/com/google/dart/compiler/DefaultLibrarySource.java
+++ /dev/null
@@ -1,202 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler;
-
-import com.google.dart.compiler.util.DartSourceString;
-import com.google.dart.compiler.util.Lists;
-import com.google.dart.compiler.util.Paths;
-
-import java.io.File;
-import java.io.PrintWriter;
-import java.io.Reader;
-import java.io.StringReader;
-import java.io.StringWriter;
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-/**
- * Create a default app library specification when compiling a single dart file.
- *
- * @author johnlenz@google.com (John Lenz)
- */
-public class DefaultLibrarySource extends UrlSource implements LibrarySource {
-  private static final String WRAPPED_NAME_PREFIX = "_DefaultLibrarySource.wrapper.";
-  private final File sourceFile;
-  private final Map<String, DartSource> sources;
-  private final Map<String, LibrarySource> imports;
-  private String source;
-  private String wrappedName;
-
-  // TODO: Deprecated
-  public DefaultLibrarySource(List<String> sources, String entryPoint) {
-    this(sources.get(0), Paths.toFiles(sources),  entryPoint);
-  }
-
-  // TODO: Deprecated
-  public DefaultLibrarySource(List<String> sources, List<String> imports, String entryPoint) {
-    this(sources.get(0), Paths.toFiles(sources), Paths.toFiles(imports), entryPoint);
-  }
-
-  // TODO: Deprecated
-  public DefaultLibrarySource(File sourceFile, String entryPoint) {
-    this(sourceFile.getName(), Lists.<File> create(sourceFile),
-         Lists.<File> create(), entryPoint);
-  }
-
-  public DefaultLibrarySource(String appName, List<File> sourceFiles, String entryPoint) {
-    this(appName, sourceFiles, Lists.<File> create(), entryPoint);
-  }
-
-  /**
-   * Answer a new instance representing a {@link LibrarySource} with the
-   * specified name and that contains the specified imports and source files.
-   *
-   * @param appName the application name (not <code>null</code>, not empty)
-   * @param sourceFiles the source files to be included in the application (not
-   *          <code>null</code>, and must contain at least one file)
-   * @param importFiles libraries to be imported into the application (e.g. from
-   *          #import directives)
-   * @param entryPoint The name of the static method to call to invoke the
-   *          library. A synthetic main() method will be generated which wraps a call to
-   *          this method. Pass <code>null</code> to use the default main() method
-   *          lookup.
-   */
-  public DefaultLibrarySource(String appName, List<File> sourceFiles, List<File> importFiles,
-      String entryPoint) {
-    this(sourceFiles.get(0));
-
-    for (File file : sourceFiles) {
-      String relPath = Paths.relativePathFor(sourceFile, file);
-      this.sources.put(relPath, new UrlDartSource(file, this));
-    }
-    for (File file : importFiles) {
-      String relPath = Paths.relativePathFor(sourceFile, file);
-      this.imports.put(relPath, new UrlLibrarySource(file));
-    }
-    wrappedName = WRAPPED_NAME_PREFIX + appName;
-    source = generateSource(wrappedName, sourceFile, importFiles, sourceFiles, entryPoint);
-    this.sources.put(wrappedName, new DartSourceString(wrappedName, source));
-  }
-
-  private DefaultLibrarySource(File sourceFile) {
-    super(sourceFile);
-
-    this.sourceFile = sourceFile;
-    this.sources = new HashMap<String, DartSource>();
-    this.imports = new HashMap<String, LibrarySource>();
-  }
-
-  /**
-   * Generate source declaring a library. An app library will specify a
-   * non-<code>null</code> entryPoint.
-   *
-   * @param name the name of the application or library
-   * @param imports a collection of relative paths indicating the libraries
-   *          imported by this application or library
-   * @param sources a collection of relative paths indicating the dart sources
-   *          included in this application or library
-   * @param entryPoint The name of the static method to call to invoke the
-   *          library. A synthetic main() method will be generated which wraps a call to
-   *          this method. Pass <code>null</code> to use the default main() method
-   *          lookup.
-   * @return the source (not <code>null</code>)
-   */
-  public static String generateSource(String name, List<String> imports,
-      List<String> sources, String entryPoint) {
-    return generateSource(name, new File(name), Paths.toFiles(imports),
-        Paths.toFiles(sources), entryPoint);
-  }
-
-  /**
-   * Generate source declaring a library. If an entryPoint is provided a main()
-   * method will be synthesized which wraps a call to the provided entryPoint
-   * method.
-   *
-   * @param name the name of the application or library
-   * @param baseFile the application or library file that will contain this
-   *        source or any file in that same directory (not <code>null</code>,
-   *        but does not need to exist)
-   * @param importFiles a collection of library files imported by this
-   *        application or library
-   * @param sourceFiles a collection of dart source files included in this
-   *        application or library
-  * @param entryPoint The name of the static method to call to invoke the
-   *          library. A synthetic main() method will be generated which wraps a call to
-   *          this method. Pass <code>null</code> to use the default main() method
-   *          lookup.
-   * @return the source (not <code>null</code>)
-   */
-  public static String generateSource(String name, File baseFile, List<File> importFiles,
-      List<File> sourceFiles, String entryPoint) {
-    StringWriter sw = new StringWriter(200);
-    PrintWriter pw = new PrintWriter(sw);
-    pw.println("library " + name + ";");
-    if (importFiles != null) {
-      for (File file : importFiles) {
-        String relPath = file.getPath();
-        if (!relPath.startsWith("dart:")) {
-          relPath = Paths.relativePathFor(baseFile, file);
-        }
-        if (relPath != null) {
-          pw.println("import '" + relPath + "';");
-        }
-      }
-    }
-    if (sourceFiles != null) {
-      for (File file : sourceFiles) {
-        String relPath = Paths.relativePathFor(baseFile, file);
-        if (relPath != null) {
-          pw.println("part '" + relPath + "';");
-        }
-      }
-    }
-    if (entryPoint != null) {
-      // synthesize a main method, which wraps the entryPoint method call
-      pw.println();
-      pw.println(DartCompiler.MAIN_ENTRY_POINT_NAME + "() {");
-      pw.println("  " + entryPoint + "();");
-      pw.println("}");
-    }
-    return sw.toString();
-  }
-
-  @Override
-  public Reader getSourceReader() {
-    return new StringReader(source);
-  }
-
-  @Override
-  public String getUniqueIdentifier() {
-    return "string://" + wrappedName;
-  }
-
-  @Override
-  public URI getUri() {
-    try {
-      // A bogus uri (but which ends with our wrappedName)
-      return new URI("string://" + wrappedName);
-    } catch (URISyntaxException e) {
-      throw new AssertionError(e);
-    }
-  }
-
-  @Override
-  public String getName() {
-    return wrappedName;
-  }
-
-  @Override
-  public LibrarySource getImportFor(String relPath) {
-    return imports.get(relPath);
-  }
-
-  @Override
-  public DartSource getSourceFor(String relPath) {
-    return sources.get(relPath);
-  }
-}
diff --git a/compiler/java/com/google/dart/compiler/DelegatingCompilerConfiguration.java b/compiler/java/com/google/dart/compiler/DelegatingCompilerConfiguration.java
deleted file mode 100644
index cf377f2..0000000
--- a/compiler/java/com/google/dart/compiler/DelegatingCompilerConfiguration.java
+++ /dev/null
@@ -1,90 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler;
-
-import com.google.dart.compiler.CommandLineOptions.CompilerOptions;
-import com.google.dart.compiler.metrics.CompilerMetrics;
-
-import java.io.File;
-import java.util.List;
-
-/**
- * Provides a way to override a specific method of an existing instance of a CompilerConfiguration.
- *
- * @author zundel@google.com (Eric Ayers)
- */
-public class DelegatingCompilerConfiguration implements CompilerConfiguration {
-
-  private CompilerConfiguration delegate;
-
-  public DelegatingCompilerConfiguration(CompilerConfiguration delegate) {
-    this.delegate = delegate;
-  }
-
-  @Override
-  public boolean developerModeChecks() {
-    return delegate.developerModeChecks();
-  }
-
-  @Override
-  public List<DartCompilationPhase> getPhases() {
-    return delegate.getPhases();
-  }
-
-  @Override
-  public CompilerMetrics getCompilerMetrics() {
-    return delegate.getCompilerMetrics();
-  }
-
-  @Override
-  public String getJvmMetricOptions() {
-    return delegate.getJvmMetricOptions();
-  }
-
-  @Override
-  public boolean typeErrorsAreFatal() {
-    return delegate.typeErrorsAreFatal();
-  }
-
-  @Override
-  public boolean warningsAreFatal() {
-    return delegate.warningsAreFatal();
-  }
-
-  @Override
-  public boolean resolveDespiteParseErrors() {
-    return delegate.resolveDespiteParseErrors();
-  }
-
-  @Override
-  public boolean incremental() {
-    return delegate.incremental();
-  }
-
-  @Override
-  public File getOutputDirectory() {
-    return delegate.getOutputDirectory();
-  }
-
-  @Override
-  public LibrarySource getSystemLibraryFor(String importSpec) {
-    return delegate.getSystemLibraryFor(importSpec);
-  }
-
-  @Override
-  public CompilerOptions getCompilerOptions() {
-    return delegate.getCompilerOptions();
-  }
-
-  @Override
-  public ErrorFormat printErrorFormat() {
-    return delegate.printErrorFormat();
-  }
-
-  @Override
-  public PackageLibraryManager getPackageLibraryManager() {
-    return delegate.getPackageLibraryManager();
-  }
-}
diff --git a/compiler/java/com/google/dart/compiler/DeltaAnalyzer.java b/compiler/java/com/google/dart/compiler/DeltaAnalyzer.java
deleted file mode 100644
index 2829cd9..0000000
--- a/compiler/java/com/google/dart/compiler/DeltaAnalyzer.java
+++ /dev/null
@@ -1,225 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler;
-
-import com.google.common.collect.Sets;
-import com.google.common.io.CharStreams;
-import com.google.common.io.Closeables;
-import com.google.dart.compiler.ast.DartNode;
-import com.google.dart.compiler.ast.DartUnit;
-import com.google.dart.compiler.ast.LibraryNode;
-import com.google.dart.compiler.ast.LibraryUnit;
-import com.google.dart.compiler.metrics.CompilerMetrics;
-import com.google.dart.compiler.parser.DartParser;
-import com.google.dart.compiler.resolver.CoreTypeProvider;
-import com.google.dart.compiler.resolver.CoreTypeProviderImplementation;
-import com.google.dart.compiler.resolver.Element;
-import com.google.dart.compiler.resolver.ElementKind;
-import com.google.dart.compiler.resolver.LibraryElement;
-import com.google.dart.compiler.resolver.MemberBuilder;
-import com.google.dart.compiler.resolver.Resolver;
-import com.google.dart.compiler.resolver.Scope;
-import com.google.dart.compiler.resolver.SupertypeResolver;
-import com.google.dart.compiler.resolver.TopLevelElementBuilder;
-import com.google.dart.compiler.type.TypeAnalyzer;
-
-import java.io.IOException;
-import java.io.Reader;
-import java.io.Writer;
-import java.net.URI;
-
-class DeltaAnalyzer {
-  private final SourceDelta delta;
-  private final LibraryElement enclosingLibrary;
-  private final CompilerConfiguration config;
-  private final DartCompilerListener listener;
-  private final CoreTypeProvider typeProvider;
-  private final DartCompilerContext context;
-
-  public DeltaAnalyzer(SourceDelta delta,
-                       LibraryElement enclosingLibrary,
-                       LibraryElement coreLibrary,
-                       DartNode interestNode,
-                       int interestStart,
-                       int interestLength,
-                       CompilerConfiguration config,
-                       DartCompilerListener listener) {
-    this.delta = delta;
-    this.enclosingLibrary = enclosingLibrary;
-    this.config = config;
-    this.listener = listener;
-    typeProvider = new CoreTypeProviderImplementation(coreLibrary.getScope(), listener);
-    this.context = new Context();
-  }
-
-  public DartNode analyze() throws IOException {
-    Source originalSource = delta.getSourceBefore();
-    DartUnit unit = delta.getUnitAfter();
-    if (unit == null) {
-      DartSource source = delta.getSourceAfter();
-      unit = getParser(source).parseUnit();
-    }
-    Scope scope = deltaLibraryScope(originalSource, unit);
-    // We have to create supertypes and member elements for the entire unit. For example, if you're
-    // doing code-completion, you are only interested in the current expression, but you may be
-    // code-completing on a type that is defined outside the current class.
-    new SupertypeResolver().exec(unit, context, typeProvider);
-    new MemberBuilder().exec(unit, context, typeProvider);
-
-    // The following two phases can be narrowed down to the interest area. We currently ignore the
-    // interest area, but long term, we will need to narrow down to the interest area to handle
-    // very large files.
-    new Resolver(context, scope, typeProvider).exec(unit);
-    new TypeAnalyzer().exec(unit, context, typeProvider);
-    return unit;
-  }
-
-  private Scope deltaLibraryScope(Source originalSource, DartUnit unit) {
-    // Create a library unit which holds the new unit.
-    LibraryUnit libraryUnit = new LibraryUnit(makeLibrarySource("delta"));
-    // Copy all the imports
-    for (LibraryNode path : enclosingLibrary.getLibraryUnit().getImportPaths()) {
-      libraryUnit.addImportPath(path);
-    }
-    for (LibraryUnit importUnit : enclosingLibrary.getLibraryUnit().getImportedLibraries()) {
-      libraryUnit.addImport(importUnit, importUnit.getEntryNode());
-    }
-    libraryUnit.putUnit(unit);
-
-    // Create top-level elements for the new unit.
-    new TopLevelElementBuilder().exec(libraryUnit, context);
-    new TopLevelElementBuilder().fillInLibraryScope(libraryUnit, listener);
-
-    // Copy all the elements from the old library, except the ones declared in the original source.
-    Scope scope = libraryUnit.getElement().getScope();
-    for (Element member : enclosingLibrary.getMembers()) {
-      if (member.getSourceInfo().getSource() != originalSource) {
-        String name = member.getName();
-        if (ElementKind.of(member) == ElementKind.LIBRARY) {
-          name = "__library_" + ((LibraryElement) member).getLibraryUnit().getName();
-        }
-        scope.declareElement(name, member);
-      }
-    }
-    return scope;
-  }
-
-  private LibrarySource makeLibrarySource(final String name) {
-    final URI uri = URI.create(name);
-    return new LibrarySource() {
-      @Override
-      public String getUniqueIdentifier() {
-        return uri.toString();
-      }
-
-      @Override
-      public URI getUri() {
-        return uri;
-      }
-
-      @Override
-      public Reader getSourceReader() {
-        throw new AssertionError();
-      }
-
-      @Override
-      public String getName() {
-        return name;
-      }
-
-      @Override
-      public long getLastModified() {
-        throw new AssertionError();
-      }
-
-      @Override
-      public boolean exists() {
-        throw new AssertionError();
-      }
-
-      @Override
-      public DartSource getSourceFor(String relPath) {
-        return null;
-      }
-
-      @Override
-      public LibrarySource getImportFor(String relPath) {
-        return null;
-      }
-    };
-  }
-
-  private DartParser getParser(Source source) throws IOException {
-    Reader r = source.getSourceReader();
-    String sourceString = CharStreams.toString(r);
-    Closeables.close(r, false);
-    return new DartParser(source, sourceString, false, Sets.<String>newHashSet(), listener, null);
-  }
-
-  private class Context implements DartCompilerListener, DartCompilerContext {
-    @Override
-    public LibraryUnit getApplicationUnit() {
-      throw new AssertionError();
-    }
-
-    @Override
-    public LibraryUnit getAppLibraryUnit() {
-      throw new AssertionError();
-    }
-
-    @Override
-    public LibraryUnit getLibraryUnit(LibrarySource lib) {
-      throw new AssertionError();
-    }
-
-    @Override
-    public Reader getArtifactReader(Source source, String part, String extension) {
-      throw new AssertionError();
-    }
-
-    @Override
-    public URI getArtifactUri(DartSource source, String part, String extension) {
-      throw new AssertionError();
-    }
-
-    @Override
-    public Writer getArtifactWriter(Source source, String part, String extension) {
-      throw new AssertionError();
-    }
-
-    @Override
-    public boolean isOutOfDate(Source source, Source base, String extension) {
-      throw new AssertionError();
-    }
-
-    @Override
-    public CompilerMetrics getCompilerMetrics() {
-      return null;
-    }
-
-    @Override
-    public CompilerConfiguration getCompilerConfiguration() {
-      return config;
-    }
-
-    @Override
-    public LibrarySource getSystemLibraryFor(String importSpec) {
-      throw new AssertionError();
-    }
-
-    @Override
-    public void onError(DartCompilationError event) {
-      listener.onError(event);
-    }
-
-    @Override
-    public void unitAboutToCompile(DartSource source, boolean diet) {
-    }
-
-    @Override
-    public void unitCompiled(DartUnit unit) {
-    }
-  }
-}
diff --git a/compiler/java/com/google/dart/compiler/ErrorCode.java b/compiler/java/com/google/dart/compiler/ErrorCode.java
deleted file mode 100644
index 395bcaa..0000000
--- a/compiler/java/com/google/dart/compiler/ErrorCode.java
+++ /dev/null
@@ -1,58 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-package com.google.dart.compiler;
-
-import com.google.dart.compiler.util.apache.StringUtils;
-
-/**
- * The behavior common to objects representing error codes associated with
- * {@link DartCompilationError Dart compilation errors}.
- */
-public interface ErrorCode {
-  /**
-   * Return the message template used to create the message to be displayed for this error.
-   */
-  String getMessage();
-
-  /**
-   * @return the {@link ErrorSeverity} of this error.
-   */
-  ErrorSeverity getErrorSeverity();
-
-  /**
-   * @return the {@link SubSystem} which issued this error.
-   */
-  SubSystem getSubSystem();
-
-  /**
-   * @return <code>true</code> if this {@link ErrorCode} should cause recompilation of the source
-   *         during next incremental compilation.
-   */
-  boolean needsRecompilation();
-  
-  public class Helper {
-    /**
-     * @return the "qualified name" of the given {@link ErrorCode} enumeration, good for passing it
-     *         to {@link #forQualifiedName(String)}.
-     */
-    public static String toQualifiedName(ErrorCode errorCode) {
-      return errorCode.getClass().getCanonicalName() + "." + ((Enum<?>) errorCode).name();
-    }
-
-    /**
-     * @return the {@link ErrorCode} enumeration constant for string from
-     *         {@link #toQualifiedName(ErrorCode)}.
-     */
-    public static ErrorCode forQualifiedName(String qualifiedName) {
-      try {
-        String className = StringUtils.substringBeforeLast(qualifiedName, ".");
-        String fieldName = StringUtils.substringAfterLast(qualifiedName, ".");
-        Class<?> errorCodeClass = Class.forName(className);
-        return (ErrorCode) errorCodeClass.getField(fieldName).get(null);
-      } catch (Throwable e) {
-        return null;
-      }
-    }
-  }
-}
diff --git a/compiler/java/com/google/dart/compiler/ErrorFormatter.java b/compiler/java/com/google/dart/compiler/ErrorFormatter.java
deleted file mode 100644
index b04ed13..0000000
--- a/compiler/java/com/google/dart/compiler/ErrorFormatter.java
+++ /dev/null
@@ -1,16 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler;
-
-/**
- * A class that that helps presenting error messages in the command line.
- *
- * @see DefaultErrorFormatter
- * @see PrettyErrorFormatter
- */
-public interface ErrorFormatter {
-
-  public void format(DartCompilationError event);
-}
diff --git a/compiler/java/com/google/dart/compiler/ErrorSeverity.java b/compiler/java/com/google/dart/compiler/ErrorSeverity.java
deleted file mode 100644
index 49d7688..0000000
--- a/compiler/java/com/google/dart/compiler/ErrorSeverity.java
+++ /dev/null
@@ -1,33 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler;
-
-/**
- * The severity of {@link ErrorCode}.
- */
-public enum ErrorSeverity {
-  /**
-   * Fatal error.
-   */
-  ERROR("E"),
-  /**
-   * Warning, may become error with -Werror command line flag.
-   */
-  WARNING("W"),
-  /**
-   * Info, not considered an official warning
-   */
-  INFO("I");
-
-  final String name;
-
-  ErrorSeverity(String name) {
-    this.name = name;
-  }
-
-  public String getName() {
-    return name;
-  }
-}
\ No newline at end of file
diff --git a/compiler/java/com/google/dart/compiler/FileBasedSystemLibraryProvider.java b/compiler/java/com/google/dart/compiler/FileBasedSystemLibraryProvider.java
deleted file mode 100644
index d659f76..0000000
--- a/compiler/java/com/google/dart/compiler/FileBasedSystemLibraryProvider.java
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Copyright (c) 2012, the Dart project authors.
- * 
- * Licensed under the Eclipse Public License v1.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.eclipse.org/legal/epl-v10.html
- * 
- * 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.dart.compiler;
-
-import java.io.File;
-import java.io.IOException;
-import java.net.URI;
-
-/**
- * A file-based {@link SystemLibraryProvider} that reads dart-sdk/lib/_internal/libraries.dart for
- * system library information.
- */
-public class FileBasedSystemLibraryProvider extends SystemLibraryProvider {
-
-  private File sdkLibPath;
-
-  /**
-   * Create a {@link FileBasedSystemLibraryProvider} with the given path to the dart SDK.
-   */
-  public FileBasedSystemLibraryProvider(File sdkPath) {
-    super(new File(sdkPath, "lib").getAbsoluteFile().toURI());
-    //TODO(pquitslund): remove this duplicated file creation
-    sdkLibPath = new File(sdkPath, "lib").getAbsoluteFile();
-  }
-
-  @Override
-  protected SystemLibrariesReader createReader() throws IOException {
-    return new SystemLibrariesReader(sdkLibPath);
-  }
-
-  @Override
-  public SystemLibrary createSystemLibrary(String name, String host, String pathToLib,
-      String category, boolean documented, boolean implementation) {
-    
-    
-    File dir = new File(sdkLibPath, host);
-    
-    File libFile = new File(dir, pathToLib);
-    if (!libFile.isFile()) {
-      throw new InternalCompilerException("Error mapping dart:" + host + ", path "
-          + libFile.getAbsolutePath() + " is not a file.");
-    }
-    
-    return new SystemLibrary(
-        name, host, pathToLib, dir, category, documented, implementation);
-  }
-  
-  @Override
-  public boolean exists(URI uri) {
-    return new File(uri).exists();
-  }
-  
-  @Override
-  public URI resolveHost(String host, URI uri) {
-    return new File(sdkLibPath, host).toURI().resolve("." + uri.getPath());
-  }
-  
-}
\ No newline at end of file
diff --git a/compiler/java/com/google/dart/compiler/InternalCompilerException.java b/compiler/java/com/google/dart/compiler/InternalCompilerException.java
deleted file mode 100644
index 2c073c5..0000000
--- a/compiler/java/com/google/dart/compiler/InternalCompilerException.java
+++ /dev/null
@@ -1,20 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler;
-
-/**
- * Exception thrown when the compiler encounters an unexpected internal error.
- */
-public class InternalCompilerException extends RuntimeException {
-  private static final long serialVersionUID = 1L;
-
-  public InternalCompilerException(String message) {
-    super(message);
-  }
-  
-  public InternalCompilerException(String message, Throwable t) {
-    super(message, t);
-  }
-}
diff --git a/compiler/java/com/google/dart/compiler/LibraryDeps.java b/compiler/java/com/google/dart/compiler/LibraryDeps.java
deleted file mode 100644
index bcdf2e4..0000000
--- a/compiler/java/com/google/dart/compiler/LibraryDeps.java
+++ /dev/null
@@ -1,313 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-package com.google.dart.compiler;
-
-import com.google.common.base.Objects;
-import com.google.common.base.Splitter;
-import com.google.common.base.Strings;
-import com.google.common.collect.Iterables;
-import com.google.common.collect.Maps;
-import com.google.common.collect.Sets;
-import com.google.dart.compiler.ast.DartUnit;
-
-import java.io.BufferedReader;
-import java.io.IOException;
-import java.io.Reader;
-import java.io.Writer;
-import java.net.URI;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
-
-/**
- * Represents a library's dependencies artifact.
- */
-public class LibraryDeps {
-  private static final String VERSION = "v00001";
-
-  /**
-   * Each dependency record contains the library in which it was found, name of the unit in this
-   * library and last-modified timestamp. Any change in the timestamp of the target dependency will
-   * force a recompile of the associated compilation unit.
-   */
-  public static class Dependency {
-    private final URI libUri;
-    private final String unitName;
-    private final long lastModified;
-
-    public Dependency(URI libUri, String unitName, long lastModified) {
-      this.libUri = libUri;
-      this.unitName = unitName;
-      this.lastModified = lastModified;
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-      if (obj instanceof Dependency) {
-        Dependency dep = (Dependency) obj;
-        return Objects.equal(libUri, dep.libUri) && Objects.equal(unitName, dep.unitName);
-      }
-      return false;
-    }
-
-    @Override
-    public int hashCode() {
-      return Objects.hashCode(libUri, unitName);
-    }
-
-    public URI getLibUri() {
-      return libUri;
-    }
-
-    public String getUnitName() {
-      return unitName;
-    }
-
-    public long getLastModified() {
-      return lastModified;
-    }
-  }
-
-  public static class Source {
-    private final Set<Dependency> deps = Sets.newHashSet();
-    private final Set<String> topSymbols = Sets.newHashSet();
-    private final Set<String> allSymbols = Sets.newHashSet();
-    private final Set<String> holes = Sets.newHashSet();
-    private boolean shouldRecompileOnAnyTopLevelChange = false;
-
-    /**
-     * @return the {@link Set} of {@link Dependency}s.
-     */
-    public Set<Dependency> getDeps() {
-      return deps;
-    }
-
-    /**
-     * @return the names of top-level elements, such as methods and classes.
-     */
-    public Set<String> getTopSymbols() {
-      return topSymbols;
-    }
-
-    /**
-     * @return the names of all elements in unit, such as names of local variables, fields, etc.
-     */
-    public Set<String> getAllSymbols() {
-      return allSymbols;
-    }
-
-    /**
-     * @return the names of functions, which are invoked without qualifier. So, declaration or
-     *         removing function with such name on top-level should cause recompiling.
-     */
-    public Set<String> getHoles() {
-      return holes;
-    }
-
-    /**
-     * @return <code>true</code> if this unit should be recompiled on any change in the set of
-     *         top-level symbols. Typically unit has compilation errors, which potentially may be
-     *         fixed, so we should recompile this unit.
-     */
-    public boolean shouldRecompileOnAnyTopLevelChange() {
-      return shouldRecompileOnAnyTopLevelChange;
-    }
-
-    /**
-     * Adds new {@link Dependency}.
-     */
-    public void addDep(Dependency dep) {
-      deps.add(dep);
-    }
-
-    /**
-     * Adds symbol to the {@link Set} of top symbols.
-     */
-    public void addTopSymbol(String symbol) {
-      if (!Strings.isNullOrEmpty(symbol)) {
-        topSymbols.add(symbol);
-      }
-    }
-
-    /**
-     * Adds symbol to the {@link Set} of all symbols.
-     */
-    public void addAllSymbol(String symbol) {
-      allSymbols.add(symbol);
-    }
-
-    /**
-     * Adds new hole for {@link #getHoles()}.
-     */
-    public void addHole(String hole) {
-      holes.add(hole);
-    }
-  }
-
-  public static LibraryDeps fromReader(Reader reader) {
-    try {
-      return fromReaderEx(reader);
-    } catch (Throwable e) {
-      return null;
-    }
-  }
-
-  private static LibraryDeps fromReaderEx(Reader reader) throws Exception {
-    LibraryDeps deps = new LibraryDeps();
-    BufferedReader buf = new BufferedReader(reader);
-    // Check version.
-    {
-      String line = buf.readLine();
-      if (!Objects.equal(line, VERSION)) {
-        return deps;
-      }
-    }
-    // Read units dependencies.
-    String relPath;
-    while (null != (relPath = buf.readLine())) {
-      Source source = new Source();
-      // Read flags.
-      source.shouldRecompileOnAnyTopLevelChange = Boolean.parseBoolean(buf.readLine());
-      // Read top symbols.
-      {
-        String line = buf.readLine();
-        Iterable<String> topSymbols = Splitter.on(' ').omitEmptyStrings().split(line);
-        Iterables.addAll(source.topSymbols, topSymbols);
-      }
-      // Read all symbols.
-      {
-        String line = buf.readLine();
-        Iterable<String> allSymbols = Splitter.on(' ').omitEmptyStrings().split(line);
-        Iterables.addAll(source.allSymbols, allSymbols);
-      }
-      // Read holes.
-      {
-        String line = buf.readLine();
-        Iterable<String> holes = Splitter.on(' ').omitEmptyStrings().split(line);
-        Iterables.addAll(source.holes, holes);
-      }
-      // Read dependencies.
-      while (true) {
-        String line = buf.readLine();
-        // Blank line: next unit.
-        if (line.length() == 0) {
-          break;
-        }
-        // Parse line.
-        String[] parts = line.split(" ");
-        source.deps.add(new Dependency(new URI(parts[0]), parts[1], Long.parseLong(parts[2])));
-      }
-      // Remember dependencies for current unit.
-      deps.sources.put(relPath, source);
-    }
-    return deps;
-  }
-
-  private final Map<String, Source> sources = Maps.newHashMap();
-
-  public LibraryDeps() {
-  }
-
-  /**
-   * @return the relative paths of all units with remembered dependencies.
-   */
-  public Set<String> getUnitPaths() {
-    return sources.keySet();
-  }
-
-  /**
-   * @return all {@link Source} descriptions for all units in this library.
-   */
-  public Iterable<Source> getSources() {
-    return sources.values();
-  }
-
-  /**
-   * @return the {@link Source} description of the unit with given path.
-   */
-  public Source getSource(String relPath) {
-    return sources.get(relPath);
-  }
-
-  /**
-   * Remembers {@link Dependency}s of the unit with given path.
-   */
-  public void putSource(String relPath, Source source) {
-    sources.put(relPath, source);
-  }
-
-  /**
-   * Update the library dependencies to reflect this unit's classes.
-   */
-  public void update(DartCompilerMainContext context, DartUnit unit) {
-    Source source = new Source();
-    DartSource unitSource = (DartSource) unit.getSourceInfo().getSource();
-    String relPath = unitSource.getRelativePath();
-    putSource(relPath, source);
-    // Remember dependencies.
-    LibraryDepsVisitor.exec(unit, source);
-    // Fill Source with symbols.
-    for (String name : unit.getDeclarationNames()) {
-      source.addAllSymbol(name);
-    }
-    for (String name : unit.getTopDeclarationNames()) {
-      source.addTopSymbol(name);
-    }
-    // Analyze errors and see if any of them should force recompilation.
-    List<DartCompilationError> sourceErrors = context.getSourceErrors(unitSource);
-    for (DartCompilationError error : sourceErrors) {
-      if (error.getErrorCode().needsRecompilation()) {
-        source.shouldRecompileOnAnyTopLevelChange = true;
-        break;
-      }
-    }
-  }
-
-  public void write(Writer writer) throws IOException {
-    // Write version.
-    writer.write(VERSION);
-    writer.write('\n');
-    // Write entries.
-    for (Entry<String, Source> entry : sources.entrySet()) {
-      String relPath = entry.getKey();
-      Source source = entry.getValue();
-      // Unit name.
-      writer.write(relPath);
-      writer.write('\n');
-      // Flags.
-      writer.write(Boolean.toString(source.shouldRecompileOnAnyTopLevelChange));
-      writer.write('\n');
-      // Write top symbols.
-      for (String symbol : source.topSymbols) {
-        writer.write(symbol);
-        writer.write(' ');
-      }
-      writer.write('\n');
-      // Write all symbols.
-      for (String symbol : source.allSymbols) {
-        writer.write(symbol);
-        writer.write(' ');
-      }
-      writer.write('\n');
-      // Write holes.
-      for (String hole : source.holes) {
-        writer.write(hole);
-        writer.write(' ');
-      }
-      writer.write('\n');
-      // Write dependencies.
-      for (Dependency dep : source.deps) {
-        writer.write(dep.libUri.toString());
-        writer.write(' ');
-        writer.write(dep.unitName);
-        writer.write(' ');
-        writer.write(Long.toString(dep.lastModified));
-        writer.write('\n');
-      }
-      // Empty line after each unit.
-      writer.write('\n');
-    }
-  }
-}
diff --git a/compiler/java/com/google/dart/compiler/LibraryDepsVisitor.java b/compiler/java/com/google/dart/compiler/LibraryDepsVisitor.java
deleted file mode 100644
index d0acd51..0000000
--- a/compiler/java/com/google/dart/compiler/LibraryDepsVisitor.java
+++ /dev/null
@@ -1,168 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-package com.google.dart.compiler;
-
-import com.google.dart.compiler.ast.ASTVisitor;
-import com.google.dart.compiler.ast.DartClass;
-import com.google.dart.compiler.ast.DartIdentifier;
-import com.google.dart.compiler.ast.DartMethodInvocation;
-import com.google.dart.compiler.ast.DartParameterizedTypeNode;
-import com.google.dart.compiler.ast.DartPropertyAccess;
-import com.google.dart.compiler.ast.DartTypeNode;
-import com.google.dart.compiler.ast.DartUnit;
-import com.google.dart.compiler.resolver.Element;
-import com.google.dart.compiler.resolver.ElementKind;
-import com.google.dart.compiler.type.InterfaceType;
-import com.google.dart.compiler.type.Type;
-import com.google.dart.compiler.type.TypeKind;
-
-import java.net.URI;
-
-/**
- * A visitor that fills in {@link LibraryDeps} for a compilation unit.
- */
-public class LibraryDepsVisitor extends ASTVisitor<Void> {
-  /**
-   * Fill in {@link LibraryDeps} from a {@link DartUnit}.
-   */
-  static void exec(DartUnit unit, LibraryDeps.Source source) {
-    LibraryDepsVisitor v = new LibraryDepsVisitor(source);
-    unit.accept(v);
-  }
-
-  private final LibraryDeps.Source source;
-  private Element currentClass;
-
-  private LibraryDepsVisitor(LibraryDeps.Source source) {
-    this.source = source;
-  }
-
-  @Override
-  public Void visitIdentifier(DartIdentifier node) {
-    Element target = node.getElement();
-    ElementKind kind = ElementKind.of(target);
-    // Add dependency on the field or method.
-    switch (kind) {
-      case FIELD:
-      case METHOD: {
-        Element enclosing = target.getEnclosingElement();
-        addHoleIfUnqualifiedSuper(node, enclosing);
-        if (enclosing.getKind().equals(ElementKind.LIBRARY)) {
-          addElementDependency(target);
-        }
-        break;
-      }
-    }
-    // Add dependency on the computed type of identifiers.
-    switch (kind) {
-      case NONE:
-        source.addHole(node.getName());
-        break;
-      case DYNAMIC:
-        break;
-      default: {
-        Type type = target.getType();
-        if (type != null) {
-          Element element = type.getElement();
-          if (ElementKind.of(element).equals(ElementKind.CLASS)) {
-            addElementDependency(element);
-          }
-        }
-        break;
-      }
-    }
-    return null;
-  }
-
-  @Override
-  public Void visitPropertyAccess(DartPropertyAccess node) {
-    if (node.getQualifier() instanceof DartIdentifier) {
-      DartIdentifier qualifier = (DartIdentifier) node.getQualifier();
-      Element target = qualifier.getElement();
-      if (target != null && target.getKind() == ElementKind.LIBRARY) {
-        // Handle library prefixes normally.
-        // The prefix part of the qualifier doesn't contain any resolvable library source info.
-        return super.visitPropertyAccess(node);
-      }
-    }
-    // Skip rhs of property accesses, so that all identifiers we visit will be unqualified.
-    if (node.isCascade()) {
-      return null;
-    }
-    return node.getQualifier().accept(this);
-  }
-
-  @Override
-  public Void visitClass(DartClass node) {
-    currentClass = node.getElement();
-    node.visitChildren(this);
-    currentClass = null;
-    return null;
-  }
-
-  @Override
-  public Void visitParameterizedTypeNode(DartParameterizedTypeNode node) {
-    if (TypeKind.of(node.getType()).equals(TypeKind.INTERFACE)) {
-      addElementDependency(((InterfaceType) node.getType()).getElement());
-    }
-    node.visitChildren(this);
-    return null;
-  }
-
-  @Override
-  public Void visitTypeNode(DartTypeNode node) {
-    if (TypeKind.of(node.getType()).equals(TypeKind.INTERFACE)) {
-      addElementDependency(((InterfaceType) node.getType()).getElement());
-    }
-    node.visitChildren(this);
-    return null;
-  }
-
-  /**
-   * Add a 'hole' for the given identifier, if its declaring class is a superclass of the current
-   * class. A 'hole' dependency specifies a name that, if filled by something in the library scope,
-   * would require this unit to be recompiled.
-   * 
-   * This situation occurs because names in the library scope bind more strongly than unqualified
-   * superclass members.
-   */
-  private void addHoleIfUnqualifiedSuper(DartIdentifier node, Element holder) {
-    if (isQualified(node)) {
-      return;
-    }
-    if (ElementKind.of(holder) == ElementKind.CLASS && holder != currentClass) {
-      source.addHole(node.getName());
-    }
-  }
-
-  /**
-   * Adds a direct dependency on the unit providing given {@link Element}.
-   */
-  private void addElementDependency(Element element) {
-    DartSource elementSource = (DartSource) element.getSourceInfo().getSource();
-    if (elementSource != null) {
-      LibrarySource library = elementSource.getLibrary();
-      if (library != null) {
-        URI libUri = library.getUri();
-        LibraryDeps.Dependency dep = new LibraryDeps.Dependency(libUri, elementSource.getName(),
-            elementSource.getLastModified());
-        source.addDep(dep);
-      }
-    }
-  }
-
-  /**
-   * @return <code>true</code> if given {@link DartIdentifier} is "name" part of qualified property
-   *         access or method invocation.
-   */
-  private static boolean isQualified(DartIdentifier node) {
-    if (node.getParent() instanceof DartPropertyAccess) {
-      return ((DartPropertyAccess) node.getParent()).getName() == node;
-    }
-    if (node.getParent() instanceof DartMethodInvocation) {
-      return ((DartMethodInvocation) node.getParent()).getFunctionName() == node;
-    }
-    return false;
-  }
-}
diff --git a/compiler/java/com/google/dart/compiler/LibrarySource.java b/compiler/java/com/google/dart/compiler/LibrarySource.java
deleted file mode 100644
index 1d2ab24..0000000
--- a/compiler/java/com/google/dart/compiler/LibrarySource.java
+++ /dev/null
@@ -1,36 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler;
-
-import java.io.IOException;
-
-/**
- * Abstract interface to library source.
- * 
- * TODO(jgw): Consider requiring implementors to intern LibrarySource instances so that users can
- * depend upon reference equality to avoid cycles (or require them to use .equals()). As it is,
- * there are two pieces of code in {@link DartCompiler} that do this manually, and it's a little
- * tricky.
- */
-public interface LibrarySource extends Source {
-
-  /**
-   * Answer the {@link LibrarySource} for the path specified in the receiver's
-   * imports declaration
-   *
-   * @param relPath path to the {@link LibrarySource} relative to the receiver
-   * @return the dart source or <code>null</code> if could not be found
-   */
-  LibrarySource getImportFor(String relPath) throws IOException;
-
-  /**
-   * Answer the {@link DartSource} for the path specified in the receiver's
-   * sources declaration
-   *
-   * @param relPath the path to the {@link DartSource} relative to the receiver
-   * @return the dart source or <code>null</code> if could not be found
-   */
-  DartSource getSourceFor(String relPath);
-}
diff --git a/compiler/java/com/google/dart/compiler/PackageLibraryManager.java b/compiler/java/com/google/dart/compiler/PackageLibraryManager.java
deleted file mode 100644
index ddd5d8f..0000000
--- a/compiler/java/com/google/dart/compiler/PackageLibraryManager.java
+++ /dev/null
@@ -1,346 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler;
-
-import java.io.File;
-import java.io.IOException;
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.List;
-
-
-/**
- * Manages the collection of {@link SystemLibrary}s.
- */
-public class PackageLibraryManager {
-
-  public static class NotADartShortUriException extends RuntimeException {
-    private static final long serialVersionUID = 1L;
-
-    public NotADartShortUriException(String uriString) {
-      super("Expected dart:<short name>, got: " + uriString);
-    }
-
-    public NotADartShortUriException(URI uri) {
-      super("Expected dart:<short name>, got: " + uri.toString());
-    }
-  }
-
-  /**
-   * The "any" platform is meant to have definitions for all known dart system libraries.
-   * Other implementations may only contain a subset.
-   */
-  public static final String DEFAULT_PLATFORM = "any";
-  public static final File DEFAULT_SDK_PATH = new File(System.getProperty(
-      "com.google.dart.sdk", "../"));
-  
-  public static final File DEFAULT_PACKAGE_ROOT = new File("packages");
-  public static final List<File> DEFAULT_PACKAGE_ROOTS = Arrays.asList(new File[] {DEFAULT_PACKAGE_ROOT});
-
-  public static final String PACKAGE_SCHEME = "package";
-  public static final String PACKAGE_SCHEME_SPEC = "package:";
-
-  public static final String DART_SCHEME = "dart";
-  public static final String DART_SCHEME_SPEC = "dart:";
-  
-
-  /**
-   * Answer <code>true</code> if the string is a dart spec
-   */
-  public static boolean isDartSpec(String spec) {
-    return spec != null && spec.startsWith(DART_SCHEME_SPEC);
-  }
-
-  /**
-   * Answer <code>true</code> if the specified URI has a "dart" scheme
-   */
-  public static boolean isDartUri(URI uri) {
-    return uri != null && DART_SCHEME.equals(uri.getScheme());
-  }
-
-  /**
-   * Answer <code>true</code> if the string is a package spec
-   */
-  public static boolean isPackageSpec(String spec) {
-    return spec != null && spec.startsWith(PACKAGE_SCHEME_SPEC);
-  }
-
-  /**
-   * Answer <code>true</code> if the specified URI has a "package" scheme
-   */
-  public static boolean isPackageUri(URI uri) {
-    return uri != null && PACKAGE_SCHEME.equals(uri.getScheme());
-  }
-
-  private static SystemLibraryManager SDK_LIBRARY_MANAGER;
-  
-  private List<File> packageRoots = new ArrayList<File>();
-  private List<URI> packageRootsUri = new ArrayList<URI>(); 
-
-  public PackageLibraryManager() {
-    this(DEFAULT_SDK_PATH, DEFAULT_PLATFORM);
-  }
-
-  public PackageLibraryManager(File sdkPath, String platformName) {
-    this(new FileBasedSystemLibraryProvider(sdkPath));
-  }
-
-  public PackageLibraryManager(SystemLibraryProvider libraryProvider) {
-    initLibraryManager(libraryProvider);
-    setPackageRoots(DEFAULT_PACKAGE_ROOTS);
-  }
-  
-  protected void initLibraryManager(SystemLibraryProvider libraryProvider) {
-    if (SDK_LIBRARY_MANAGER == null) {
-      SDK_LIBRARY_MANAGER = new SystemLibraryManager(libraryProvider);
-    }
-  }
-
-
-  /**
-   * Expand a relative or short URI (e.g. "dart:html") which is implementation independent to its
-   * full URI (e.g. "dart://html/com/google/dart/htmllib/html.dart").
-   *
-   * @param uri the relative URI
-   * @return the expanded URI
-   *  or the original URI if it could not be expanded
-   *  or null if the uri is of the form "dart:<libname>" but does not correspond to a system library
-   */
-  public URI expandRelativeDartUri(URI uri) throws AssertionError {
-    if (isDartUri(uri)) {
-      return SDK_LIBRARY_MANAGER.expandRelativeDartUri(uri);
-    } 
-    if (isPackageUri(uri)){
-      String host = uri.getHost();
-      if (host == null) {
-        String spec = uri.getSchemeSpecificPart();
-        if (!spec.startsWith("//")){
-          try {
-            if (spec.startsWith("/")){
-              // TODO(keertip): fix to handle spaces
-              uri = new URI(PACKAGE_SCHEME + ":/" + spec);
-            } else {
-              uri = new URI(PACKAGE_SCHEME + "://" + spec);
-            } 
-          } catch (URISyntaxException e) {
-            throw new AssertionError(e);
-          }
-        }       
-      }
-    }
-    return uri;
-  }
-
- 
-  
-  /**
-   * Given an absolute file URI (e.g. "file:/some/install/directory/dart-sdk/lib/core/bool.dart"),
-   *  answer the corresponding dart: URI (e.g. "dart://core/bool.dart") for that file URI,
-   *  or <code>null</code> if the file URI does not map to a dart: URI 
-   * @param fileUri the file URI
-   * @return the dart URI or <code>null</code>
-   */
-  public URI getRelativeUri(URI fileUri) {
-    // TODO (danrubel): does not convert dart: libraries outside the dart-sdk/lib directory
-    if (fileUri == null || !fileUri.getScheme().equals("file")) {
-      return null;
-    }
-   
-    URI relativeUri = SDK_LIBRARY_MANAGER.getRelativeUri(fileUri);
-    if (relativeUri != null){
-      return relativeUri;
-    }
-    
-    for (URI rootUri : packageRootsUri){
-      relativeUri = rootUri.relativize(fileUri);
-        if (relativeUri.getScheme() == null) {
-          try {
-            return new URI(null, null, "package://" + relativeUri.getPath(), null, null);
-          } catch (URISyntaxException e) {
-        //$FALL-THROUGH$
-        }
-      }
-    }
-    return null;
-  }
-
-  /**
-   * Given a package URI (package:foo/foo.dart), convert it into a file system URI.
-   */
-  public URI resolvePackageUri(String packageUriRef) {
-    if (packageUriRef.startsWith(PACKAGE_SCHEME_SPEC)) {
-      String relPath = packageUriRef.substring(PACKAGE_SCHEME_SPEC.length());
-      if (relPath.startsWith("/")){
-        relPath = relPath.replaceAll("^\\/+", "");
-      }
-      for (URI rootUri : packageRootsUri){
-        URI fileUri = rootUri.resolve(relPath);
-        File file = new File(fileUri);
-        if (file.exists()){
-          try {
-            return file.getCanonicalFile().toURI();
-          } catch (IOException e) {
-            file.toURI();
-          }
-        }
-      }
-      // don't return null for package scheme
-      return packageRootsUri.get(0).resolve(relPath);
-    }
-   return null; 
-  }
-
-  /**
-   * Answer the original "dart:<libname>" URI for the specified resolved URI or <code>null</code> if
-   * it does not map to a short URI.
-   */
-  public URI getShortUri(URI uri) {
-    URI shortUri = SDK_LIBRARY_MANAGER.getShortUri(uri);
-    if (shortUri != null){
-      return shortUri;
-    }
-    shortUri = getRelativeUri(uri);
-    if (shortUri != null){
-      try {
-        if (shortUri.getHost() != null){
-          return new URI(null, null, shortUri.getScheme() + ":" +  shortUri.getHost() + shortUri.getPath(),null, null);
-        }
-        else {
-          return new URI(null, null, shortUri.getScheme() + ":" +  shortUri.getSchemeSpecificPart(), null, null);
-        }
-      } catch (URISyntaxException e) {
-      }
-    }
-    return null;
-  }
-
-  /**
-   * Expand a relative or short URI (e.g. "dart:html") which is implementation independent to its
-   * full URI (e.g. "dart://html/com/google/dart/htmllib/html.dart") and then translate that URI to
-   * a "file:"  URI (e.g.
-   * "file:/some/install/directory/com/google/dart/htmllib/html.dart").
-   *
-   * @param uri the original URI
-   * @return the expanded and translated URI, which may be <code>null</code> and may not exist
-   * @exception RuntimeException if the URI is a "dart" scheme, but does not map to a defined system
-   *     library
-   */
-  public URI resolveDartUri(URI uri) {
-    return translateDartUri(expandRelativeDartUri(uri));
-  }
-  
-  
-  public List<File> getPackageRoots(){
-    return packageRoots;
-  }
-  
-  
-  public void setPackageRoots(List<File> roots){
-    if (roots == null || roots.isEmpty()){
-      roots = DEFAULT_PACKAGE_ROOTS;
-    }
-    packageRoots.clear();
-    for (File file : roots){   
-      packageRoots.add(file.getAbsoluteFile());
-    }   
-    packageRootsUri.clear();
-    for (File file : roots){
-      packageRootsUri.add(file.toURI());
-    }
-  }
-  
-  /**
-   * Translate the URI from dart://[host]/[pathToLib] (e.g. dart://html/html.dart)
-   * to a "file:" URI (e.g. "file:/some/install/directory/html.dart")
-   *
-   * @param uri the original URI
-   * @return the translated URI, which may be <code>null</code> and may not exist
-   * @exception RuntimeException if the URI is a "dart" scheme,
-   *     but does not map to a defined system library
-   */
-  public URI translateDartUri(URI uri) {
-    if (isDartUri(uri)) {
-     return SDK_LIBRARY_MANAGER.translateDartUri(uri);
-    } 
-    if (isPackageUri(uri)){   
-      URI fileUri;
-      for (URI rootUri : packageRootsUri){
-        fileUri = getResolvedPackageUri(uri, rootUri);
-        File file  = new File(fileUri);
-        if (file.exists()){
-          try {
-            return file.getCanonicalFile().toURI();
-          } catch (IOException e) {
-            return file.toURI();
-          }
-        }
-      }
-      // resolve against first package root
-      fileUri = getResolvedPackageUri(uri, packageRootsUri.get(0));
-      return fileUri;
-    }
-    return uri;
-  }
-
-  
-  /**
-   * Given a uri, resolve against the list of package roots, used to find generated files
-   * @return uri - resolved uri if file exists, else return given uri 
-   */
-  public URI findExistingFileInPackages(URI fileUri){
-    
-    URI resolvedUri = getRelativeUri(fileUri);
-    if (isPackageUri(resolvedUri)){
-      resolvedUri = resolvePackageUri(resolvedUri.toString());
-      return resolvedUri;
-    }
-    return fileUri;
-  }
-
-  /**
-   * Resolves the given uri against the package root uri
-   */
-  private URI getResolvedPackageUri(URI uri, URI packageRootUri) {
-    URI fileUri;
-    // TODO(keertip): Investigate further
-    // if uri.getHost() returns null, then it is resolved right
-    // so use uri.getAuthority to resolve
-    // package://third_party/dart_lang/lib/unittest/unittest.dart
-    if (uri.getHost() != null){
-      fileUri =  packageRootUri.resolve(uri.getHost() + uri.getPath());
-    } else {
-      fileUri = packageRootUri.resolve(uri.getAuthority() + uri.getPath());
-    }
-    return fileUri;
-  }
-
-  /**
-   * Answer a collection of all bundled library URL specs (e.g. "dart:html").
-   *
-   * @return a collection of specs (not <code>null</code>, contains no <code>null</code>s)
-   */
-  public Collection<String> getAllLibrarySpecs() {
-    return SDK_LIBRARY_MANAGER.getAllLibrarySpecs();
-  }
-  
-  protected SystemLibrary[] getDefaultLibraries() {
-    return SDK_LIBRARY_MANAGER.getDefaultLibraries(); 
-  }
-  
-  public Collection<SystemLibrary> getSystemLibraries(){
-    return SDK_LIBRARY_MANAGER.getAllSystemLibraries();
-  }
-
-  /**
-   * Check if this URI denotes a patch file.
-   */
-  public static boolean isPatchFile(File file) {
-    return SDK_LIBRARY_MANAGER.isPatchFile(file.toURI());
-  } 
-  
-}
diff --git a/compiler/java/com/google/dart/compiler/PrettyErrorFormatter.java b/compiler/java/com/google/dart/compiler/PrettyErrorFormatter.java
deleted file mode 100644
index 0baa651..0000000
--- a/compiler/java/com/google/dart/compiler/PrettyErrorFormatter.java
+++ /dev/null
@@ -1,156 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler;
-
-import com.google.common.io.Closeables;
-import com.google.dart.compiler.CompilerConfiguration.ErrorFormat;
-
-import java.io.BufferedReader;
-import java.io.IOException;
-import java.io.PrintStream;
-import java.io.Reader;
-
-/**
- * An error formatter that scans the source file and prints the error line and
- * some context around it. This formatter has two modes: with or without color.
- * When using colors, it prints the error message in red, and it highlights the
- * portion of the line containing the error in red. Without colors, it prints an
- * extra line underlying the portion of the line containing the error.
- */
-public class PrettyErrorFormatter extends DefaultErrorFormatter {
-  public static final String ERROR_BOLD_COLOR = "\033[31;1m";
-  public static final String ERROR_COLOR = "\033[31m";
-
-  // Mix ANSI with xterm colors, giving ANSI priority.  The terminal should ignore xterm codes
-  // if it doesn't support them.
-  public static final String WARNING_BOLD_COLOR = "\033[33;1m\033[38;5;202m";
-  public static final String WARNING_COLOR = "\033[33m\033[38;5;208m";
-
-  public static final String NO_COLOR = "\033[0m";
-
-  private final boolean useColor;
-
-  public PrettyErrorFormatter(PrintStream outputStream,
-      boolean useColor,
-      ErrorFormat errorFormat) {
-    super(outputStream, errorFormat);
-    this.useColor = useColor;
-  }
-
-  @Override
-  public void format(DartCompilationError event) {
-    Source sourceFile = event.getSource();
-
-    // if this is an unknown source type, default to the basic error formatter
-    if (!(sourceFile instanceof DartSource) && !(sourceFile instanceof LibrarySource)) {
-      super.format(event);
-      return;
-    }
-
-    BufferedReader reader = null;
-    try {
-      Reader sourceReader = sourceFile.getSourceReader();
-      if (sourceReader != null) {
-        reader = new BufferedReader(sourceReader);
-      }
-
-      // get the error line and the line above it (note: line starts at 1)
-      int line = event.getLineNumber();
-      String lineBefore = null;
-      String lineText = null;
-
-      if (reader != null) {
-        lineBefore = getLineAt(reader, line - 1);
-        lineText = getLineAt(reader, 1);
-      }
-
-      // if there is no line to highlight, default to the basic error formatter
-      if (lineText == null) {
-        super.format(event);
-        return;
-      }
-
-      // get column/length and ensure they are within the line limits.
-      int col = event.getColumnNumber() - 1;
-      int length = event.getLength();
-      col = between(col, 0, lineText.length());
-      length = between(length, 0, lineText.length() - col);
-      length = length == 0 ? lineText.length() - col : length;
-
-      // print the error message
-      StringBuilder buf = new StringBuilder();
-      if (useColor) {
-        buf.append(event.getErrorCode().getErrorSeverity() == ErrorSeverity.WARNING
-            ? WARNING_BOLD_COLOR : ERROR_BOLD_COLOR);
-      }
-      appendError(buf, event);
-      if (useColor) {
-        buf.append(NO_COLOR);
-      }
-      buf.append("\n");
-      // show the previous line for context
-      if (lineBefore != null) {
-        buf.append(String.format("%6d: %s\n", line - 1, lineBefore));
-      }
-
-      if (useColor) {
-        // highlight error in red
-        buf.append(String.format("%6d: %s%s%s%s%s\n",
-              line,
-              lineText.substring(0, col),
-              event.getErrorCode().getErrorSeverity() == ErrorSeverity.WARNING
-              ? WARNING_COLOR : ERROR_COLOR,
-              lineText.substring(col, col + length),
-              NO_COLOR,
-              lineText.substring(col + length)));
-      } else {
-        // print the error line without formatting
-        buf.append(String.format("%6d: %s\n", line, lineText));
-
-        // underline error portion
-        buf.append("        ");
-        for (int i = 0; i < col; ++i) {
-          buf.append(' ');
-        }
-        buf.append('~');
-        if (length > 1) {
-          for (int i = 0; i < length - 2; ++i) {
-            buf.append('~');
-          }
-          buf.append('~');
-        }
-        buf.append('\n');
-      }
-
-      outputStream.print(buf.toString());
-    } catch (IOException ex) {
-      super.format(event);
-    } finally {
-      if (reader != null) {
-        Closeables.closeQuietly(reader);
-      }
-    }
-  }
-
-  private String getLineAt(BufferedReader reader, int line) throws IOException {
-    if (line <= 0) {
-      return null;
-    }
-    String currentLine = null;
-    // TODO(sigmund): do something more efficient - we currently do a linear
-    // scan of the file every time an error is reported. This will not scale
-    // when many errors are reported on the same file.
-    while ((currentLine = reader.readLine()) != null && line-- > 1){}
-    return currentLine;
-  }
-
-  /**
-   * Returns the closest value in {@code [start,end]} to the given value. If
-   * the given range is entirely empty, then {@code start} is returned.
-   */
-  private static int between(int val, int start, int end) {
-    return Math.max(start, Math.min(val, end));
-  }
-}
diff --git a/compiler/java/com/google/dart/compiler/Source.java b/compiler/java/com/google/dart/compiler/Source.java
deleted file mode 100644
index eb43b65..0000000
--- a/compiler/java/com/google/dart/compiler/Source.java
+++ /dev/null
@@ -1,52 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler;
-
-import java.io.IOException;
-import java.io.Reader;
-import java.net.URI;
-import java.util.Date;
-
-/**
- * Abstract interface to a source file.
- */
-public interface Source {
-
-  /**
-   * Determines whether the given source exists.
-   */
-  boolean exists();
-
-  /**
-   * Returns the last-modified timestamp for this source, using the same units as
-   * {@link Date#getTime()}.
-   */
-  long getLastModified();
-
-  /**
-   * Gets the name of this source.
-   */
-  String getName();
-
-  /**
-   * Gets a reader for the dart file's source code. The caller is responsible for closing the
-   * returned reader.
-   */
-  Reader getSourceReader() throws IOException;
-
-  /**
-   * Return an identifier that will uniquely identify this source.
-   *
-   * @return the unique identifier for this source.
-   */
-  String getUniqueIdentifier();
-
-  /**
-   * Gets the identifier for this source. This is used to uniquely identify the
-   * source, but should not be used to obtain the source content. Use
-   * {@link #getSourceReader()} to obtain the source content.
-   */
-  URI getUri();
-}
diff --git a/compiler/java/com/google/dart/compiler/SourceDelta.java b/compiler/java/com/google/dart/compiler/SourceDelta.java
deleted file mode 100644
index e048c4f..0000000
--- a/compiler/java/com/google/dart/compiler/SourceDelta.java
+++ /dev/null
@@ -1,57 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler;
-
-import com.google.dart.compiler.ast.DartUnit;
-
-/**
- * Representation of changes to source.
- */
-public abstract class SourceDelta {
-  public abstract Source getSourceBefore();
-
-  public abstract DartSource getSourceAfter();
-
-  public abstract DartUnit getUnitAfter();
-
-  public final SourceDelta after(DartSource sourceAfter) {
-    return new BeforeAfter(getSourceBefore(), sourceAfter, null);
-  }
-
-  public final SourceDelta after(DartUnit nodeAfter) {
-    return new BeforeAfter(getSourceBefore(), null, nodeAfter);
-  }
-
-  public static SourceDelta before(final DartSource sourceBefore) {
-    return new BeforeAfter(sourceBefore, sourceBefore, null);
-  }
-
-  private static class BeforeAfter extends SourceDelta {
-    private final Source sourceBefore;
-    private final DartSource sourceAfter;
-    private final DartUnit nodeAfter;
-
-    BeforeAfter(Source sourceBefore, DartSource sourceAfter, DartUnit nodeAfter) {
-      this.sourceBefore = sourceBefore;
-      this.sourceAfter = sourceAfter;
-      this.nodeAfter = nodeAfter;
-    }
-
-    @Override
-    public Source getSourceBefore() {
-      return sourceBefore;
-    }
-
-    @Override
-    public DartSource getSourceAfter() {
-      return sourceAfter;
-    }
-
-    @Override
-    public DartUnit getUnitAfter() {
-      return nodeAfter;
-    }
-  }
-}
diff --git a/compiler/java/com/google/dart/compiler/SubSystem.java b/compiler/java/com/google/dart/compiler/SubSystem.java
deleted file mode 100644
index c85755d..0000000
--- a/compiler/java/com/google/dart/compiler/SubSystem.java
+++ /dev/null
@@ -1,12 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler;
-
-/**
- * Subsystem of compiler.
- */
-public enum SubSystem {
-  COMPILER, PARSER, STATIC_TYPE, RESOLVER
-}
\ No newline at end of file
diff --git a/compiler/java/com/google/dart/compiler/SystemLibrariesReader.java b/compiler/java/com/google/dart/compiler/SystemLibrariesReader.java
deleted file mode 100644
index 56d3bbf..0000000
--- a/compiler/java/com/google/dart/compiler/SystemLibrariesReader.java
+++ /dev/null
@@ -1,264 +0,0 @@
-/*
- * Copyright (c) 2012, the Dart project authors.
- * 
- * Licensed under the Eclipse Public License v1.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.eclipse.org/legal/epl-v10.html
- * 
- * 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.dart.compiler;
-
-import com.google.common.annotations.VisibleForTesting;
-import com.google.common.io.CharStreams;
-import com.google.common.io.Closeables;
-import com.google.dart.compiler.CompilerConfiguration.ErrorFormat;
-import com.google.dart.compiler.ast.ASTVisitor;
-import com.google.dart.compiler.ast.DartBooleanLiteral;
-import com.google.dart.compiler.ast.DartExpression;
-import com.google.dart.compiler.ast.DartFieldDefinition;
-import com.google.dart.compiler.ast.DartIdentifier;
-import com.google.dart.compiler.ast.DartMapLiteralEntry;
-import com.google.dart.compiler.ast.DartNamedExpression;
-import com.google.dart.compiler.ast.DartNewExpression;
-import com.google.dart.compiler.ast.DartNode;
-import com.google.dart.compiler.ast.DartStringLiteral;
-import com.google.dart.compiler.ast.DartUnit;
-import com.google.dart.compiler.metrics.CompilerMetrics;
-import com.google.dart.compiler.parser.DartParser;
-import com.google.dart.compiler.util.DartSourceString;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.io.Reader;
-import java.net.URI;
-import java.nio.charset.Charset;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-
-/**
- * A reader that parses and reads the libraries dart-sdk/lib/_internal/libraries.dart file for
- * system library information library information is in the format final Map<String, LibraryInfo>
- * LIBRARIES = const <LibraryInfo> { // Used by VM applications "builtin": const LibraryInfo(
- * "builtin/builtin_runtime.dart", category: "Server", platforms: VM_PLATFORM), "compiler": const
- * LibraryInfo( "compiler/compiler.dart", category: "Tools", platforms: 0), };
- */
-public class SystemLibrariesReader {
-
-  @VisibleForTesting
-  public class DartLibrary {
-
-    private String shortName = null;
-    private String path = null;
-    private String category = "Shared";
-    private boolean documented = true;
-    private boolean implementation = false;
-    private int platforms = 0;
-
-    DartLibrary(String name) {
-      this.shortName = name;
-    }
-
-    public String getShortName() {
-      return shortName;
-    }
-
-    public String getPath() {
-      return path;
-    }
-
-    public void setPath(String path) {
-      this.path = path;
-    }
-
-    public String getCategory() {
-      return category;
-    }
-
-    public void setCategory(String category) {
-      this.category = category;
-    }
-
-    public boolean isDocumented() {
-      return documented;
-    }
-
-    public void setDocumented(boolean documented) {
-      this.documented = documented;
-    }
-
-    public boolean isImplementation() {
-      return implementation;
-    }
-
-    public void setImplementation(boolean implementation) {
-      this.implementation = implementation;
-    }
-
-    public boolean isDart2JsLibrary() {
-      return (platforms & DART2JS_PLATFORM) != 0;
-    }
-
-    public boolean isVmLibrary() {
-      return (platforms & VM_PLATFORM) != 0;
-    }
-
-    public void setPlatforms(int platforms) {
-      this.platforms = platforms;
-    }
-  }
-
-  class LibrariesFileAstVistor extends ASTVisitor<Void> {
-
-    @Override
-    public Void visitMapLiteralEntry(DartMapLiteralEntry node) {
-
-      String keyString = null;
-      DartExpression key = node.getKey();
-      if (key instanceof DartStringLiteral) {
-        keyString = "dart:" + ((DartStringLiteral) key).getValue();
-      }
-      DartExpression value = node.getValue();
-      if (value instanceof DartNewExpression) {
-        DartLibrary library = new DartLibrary(keyString);
-        List<DartExpression> args = ((DartNewExpression) value).getArguments();
-        for (DartExpression arg : args) {
-          if (arg instanceof DartStringLiteral) {
-            library.setPath(((DartStringLiteral) arg).getValue());
-          }
-          if (arg instanceof DartNamedExpression) {
-            String name = ((DartNamedExpression) arg).getName().getName();
-            DartExpression expression = ((DartNamedExpression) arg).getExpression();
-            if (name.equals(CATEGORY)) {
-              library.setCategory(((DartStringLiteral) expression).getValue());
-            } else if (name.equals(IMPLEMENTATION)) {
-              library.setImplementation(((DartBooleanLiteral) expression).getValue());
-            } else if (name.equals(DOCUMENTED)) {
-              library.setDocumented(((DartBooleanLiteral) expression).getValue());
-            } else if (name.equals(PATCH_PATH)) {
-              String path = ((DartStringLiteral) expression).getValue();
-              URI uri = sdkLibPath.resolve(URI.create(path));
-              patchPaths.add(uri);
-            } else if (name.equals(PLATFORMS)) {
-              if (expression instanceof DartIdentifier) {
-                String identifier = ((DartIdentifier) expression).getName();
-                if (identifier.equals("VM_PLATFORM")) {
-                  library.setPlatforms(VM_PLATFORM);
-                } else {
-                  library.setPlatforms(DART2JS_PLATFORM);
-                }
-              }
-            }
-          }
-        }
-        librariesMap.put(keyString, library);
-      }
-      return null;
-    }
-
-  }
-
-  public static final String LIBRARIES_FILE = "libraries.dart";
-  public static final String INTERNAL_DIR = "_internal";
-
-  private static final String IMPLEMENTATION = "implementation";
-  private static final String DOCUMENTED = "documented";
-  private static final String CATEGORY = "category";
-  private static final String PATCH_PATH = "dart2jsPatchPath";
-  private static final String PLATFORMS = "platforms";
-
-  private static final int DART2JS_PLATFORM = 1;
-  private static final int VM_PLATFORM = 2;
-
-  private final URI sdkLibPath;
-  private final Map<String, DartLibrary> librariesMap = new HashMap<String, DartLibrary>();
-  private final List<URI> patchPaths = new ArrayList<URI>();
-
-  public SystemLibrariesReader(URI sdkLibPath, Reader sdkFileReader) {
-    this.sdkLibPath = sdkLibPath;
-    loadLibraryInfo(sdkFileReader);
-  }
-
-  public SystemLibrariesReader(File sdkLibPath) throws IOException {
-    this(sdkLibPath.getAbsoluteFile().toURI(), new InputStreamReader(new FileInputStream(
-        getLibrariesFile(sdkLibPath)), Charset.forName("UTF8")));
-  }
-
-  public Map<String, DartLibrary> getLibrariesMap() {
-    return librariesMap;
-  }
-
-  public List<URI> getPatchPaths() {
-    return patchPaths;
-  }
-
-  private void loadLibraryInfo(Reader sdkFileReader) {
-
-    DartUnit unit = getDartUnit(sdkFileReader);
-
-    List<DartNode> nodes = unit.getTopLevelNodes();
-    for (DartNode node : nodes) {
-      if (node instanceof DartFieldDefinition) {
-        node.accept(new LibrariesFileAstVistor());
-      }
-    }
-  }
-
-  /**
-   * Parse the given dart file and return the AST
-   * 
-   * @param fileReader the dart file reader
-   * @return the parsed AST
-   */
-  private DartUnit getDartUnit(Reader fileReader) {
-
-    String srcCode = getSource(fileReader);
-    DartSourceString dartSource = new DartSourceString(LIBRARIES_FILE, srcCode);
-    DefaultDartCompilerListener listener = new DefaultDartCompilerListener(ErrorFormat.NORMAL);
-    DartParser parser = new DartParser(
-        dartSource,
-        srcCode,
-        false,
-        new HashSet<String>(),
-        listener,
-        new CompilerMetrics());
-    return parser.parseUnit();
-  }
-
-  private String getSource(Reader reader) {
-    String srcCode = null;
-    boolean failed = true;
-    try {
-      srcCode = CharStreams.toString(reader);
-      failed = false;
-    } catch (IOException e) {
-      e.printStackTrace();
-    } finally {
-      try {
-        Closeables.close(reader, failed);
-      } catch (IOException e) {
-        e.printStackTrace();
-      }
-    }
-    return srcCode;
-  }
-
-  private static File getLibrariesFile(File sdkLibDir) {
-    File file = new File(new File(sdkLibDir, INTERNAL_DIR), LIBRARIES_FILE);
-    if (!file.exists()) {
-      throw new InternalCompilerException("Failed to find " + file.toString()
-          + ".  Is dart-sdk path correct?");
-    }
-    return file;
-  }
-
-}
diff --git a/compiler/java/com/google/dart/compiler/SystemLibrary.java b/compiler/java/com/google/dart/compiler/SystemLibrary.java
deleted file mode 100644
index a1a4726..0000000
--- a/compiler/java/com/google/dart/compiler/SystemLibrary.java
+++ /dev/null
@@ -1,98 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler;
-
-import java.io.File;
-import java.net.URI;
-import java.net.URISyntaxException;
-
-/**
- * A library accessible via the "dart:<libname>.lib" protocol.
- */
-public class SystemLibrary {
-
-  private final String shortName;
-  private final String host;
-  private final String pathToLib;
-  private final File dirOrZip;
-  private String category;
-  private boolean documented;
-  private boolean implementation;
-
-  /**
-   * Define a new system library such that dart:[shortLibName] will automatically be expanded to
-   * dart://[host]/[pathToLib]. For example this call
-   *
-   * <pre>
-   *    new SystemLibrary("html.lib", "html", "dart_html.lib");
-   * </pre>
-   *
-   * will define a new system library such that "dart:html.lib" to automatically be expanded to
-   * "dart://html/dart_html.lib". The dirOrZip argument is either the root directory or a zip file
-   * containing all files for this library.
-   */
-  public SystemLibrary(String shortName, String host, String pathToLib, File dirOrZip, String category, 
-      boolean documented, boolean implementation) {
-    this.shortName = shortName;
-    this.host = host;
-    this.pathToLib = pathToLib;
-    this.dirOrZip = dirOrZip;
-    this.category = category;
-    this.documented = documented;
-    this.implementation = implementation;
-  }
-
-  public String getCategory() {
-    return category;
-  }
- 
-  public boolean isDocumented() {
-    return documented;
-  }
- 
-  public boolean isImplementation() {
-    return implementation;
-  }
-
-  public boolean isShared(){
-    return category.equals("Shared");
-  }
-  
-  public String getHost() {
-    return host;
-  }
-
-  public String getPathToLib() {
-    return pathToLib;
-  }
-
-  public String getShortName() {
-    return shortName;
-  }
-
-  public File getLibraryDir() {
-    return dirOrZip;
-  }
-
-  public URI translateUri(URI dartUri) {
-    if (!dirOrZip.exists()) {
-      throw new RuntimeException("System library for " + dartUri + " does not exist: " + dirOrZip.getPath());
-    }
-    try {
-      URI dirOrZipURI = dirOrZip.toURI();
-      if (dirOrZip.isFile()) {
-        return new URI("jar", "file:" + dirOrZipURI.getPath() + "!" + dartUri.getPath(), null);
-      } else {
-        return dirOrZipURI.resolve("." + dartUri.getPath());
-      }
-    } catch (URISyntaxException e) {
-      throw new AssertionError();
-    }
-  }
-  
-  public File getFile() {
-    return this.dirOrZip;
-  }
-}
diff --git a/compiler/java/com/google/dart/compiler/SystemLibraryManager.java b/compiler/java/com/google/dart/compiler/SystemLibraryManager.java
deleted file mode 100644
index a86558e..0000000
--- a/compiler/java/com/google/dart/compiler/SystemLibraryManager.java
+++ /dev/null
@@ -1,241 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler;
-
-import com.google.dart.compiler.SystemLibrariesReader.DartLibrary;
-
-import java.io.File;
-import java.net.URI;
-import java.net.URISyntaxException;
-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.Map.Entry;
-
-/**
- * A Library manager that manages system libraries 
- */
-public class SystemLibraryManager  {
-  
-  private HashMap<String, String> expansionMap;
-  private Map<String, SystemLibrary> hostMap;
-  private final URI sdkLibPathUri;
-  
-  private Map<URI, URI> longToShortUriMap;
-
-  private List<SystemLibrary> libraries;
-  private final SystemLibraryProvider libraryProvider;
-
-  public SystemLibraryManager(File sdkPath) {
-    this(new FileBasedSystemLibraryProvider(sdkPath));  
-  }
-
-  public SystemLibraryManager(SystemLibraryProvider libraryProvider) {
-    this.libraryProvider = libraryProvider;
-    this.sdkLibPathUri = libraryProvider.getSdkLibPathUri();
-    setLibraries(getDefaultLibraries());
-  }
-  
-  public URI expandRelativeDartUri(URI uri) throws AssertionError {
-      String host = uri.getHost();
-      if (host == null && uri.getAuthority() == null) {
-        String spec = uri.getSchemeSpecificPart();
-        String replacement = expansionMap.get(spec);
-        if (replacement != null) {
-          try {
-            uri = new URI(PackageLibraryManager.DART_SCHEME + ":" + replacement);
-          } catch (URISyntaxException e) {
-            throw new AssertionError();
-          }
-        } else {
-          return null;
-        }
-      }
-      return uri;
-  }
-  
-  public URI getRelativeUri(URI fileUri) {
-    
-    if (fileUri == null || !fileUri.getScheme().equals("file")){
-      return null;
-    }
-  
-    URI relativeUri = sdkLibPathUri.relativize(fileUri);
-    if (relativeUri.getScheme() == null) {
-      try {
-        return new URI(null, null, "dart://" + relativeUri.getPath(), null, null);
-      } catch (URISyntaxException e) {
-        //$FALL-THROUGH$
-      }
-    } 
-    return null;
-  }
-  
-  public URI getShortUri(URI uri) {
-    URI shortUri = longToShortUriMap.get(uri);
-    if (shortUri != null){
-      return shortUri;
-    }
-    shortUri = getRelativeUri(uri);
-    if (shortUri != null){
-      try {
-        return new URI(null, null, shortUri.getScheme() + ":" +  shortUri.getHost() + shortUri.getPath(),null, null);
-      } catch (URISyntaxException e) {
-      }
-    }
-    return null;
-  }
-  
-  public URI translateDartUri(URI uri) {
-   
-      String host = uri.getHost();
-      
-      SystemLibrary library = hostMap.get(host);
-      if (library != null) {
-        return library.translateUri(uri);
-      }
-      if (host != null) {        
-        return libraryProvider.resolveHost(host, uri);
-      }
-      String authorithy = uri.getAuthority();
-      if (authorithy != null){
-        return libraryProvider.resolveHost(authorithy, uri);
-      }
-      throw new RuntimeException("No system library defined for " + uri);
-   
-  }
-  
-  
-  public Collection<String> getAllLibrarySpecs() {
-    Collection<String> result = new ArrayList<String>(libraries.size());
-    for (SystemLibrary lib : libraries) {
-      result.add("dart:" + lib.getShortName());
-    }
-    return result;
-  }
-  
-  public Collection<SystemLibrary> getAllSystemLibraries(){
-    return libraries;
-  }
-  
-  /**
-   * Load the libraries listed out in the libraries.dart files as read by the {@link SystemLibrariesReader}
-   */
-  protected SystemLibrary[] getDefaultLibraries() {
-    libraries = new ArrayList<SystemLibrary>();
-    longToShortUriMap = new HashMap<URI, URI>();
-
-    // Cycle through the import.config, extracting explicit mappings and searching directories
-    URI base = this.sdkLibPathUri;
-    
-    Map<String, DartLibrary> declaredLibraries = libraryProvider.getLibraryMap();
-    
-    HashSet<String> explicitShortNames = new HashSet<String>();
-    
-    for (Entry<String, DartLibrary> entry : declaredLibraries.entrySet()) {
-      if (entry.getValue().getCategory().equals("Internal")
-          // TODO(8365): the following line allows dart:_collection-dev to
-          // be imported even though it's a hidden library.
-          && !entry.getKey().equals("dart:_collection-dev")) {
-        continue;
-      }
-      String shortName = entry.getKey().trim();
-      DartLibrary library = entry.getValue();
-      String path = library.getPath();
-      URI libFileUri;
-      try {
-        libFileUri = base.resolve(new URI(null, null, path, null, null)).normalize();
-      } catch (URISyntaxException e) {
-        continue;
-      }
-      
-      if (!libraryProvider.exists(libFileUri)) {
-        throw new InternalCompilerException("Can't find system library dart:" + shortName
-          + " at " + libFileUri);
-      }
-      
-      int index = shortName.indexOf(':');
-      if (index == -1) {
-        continue;
-      }
-      explicitShortNames.add(shortName);
-      String scheme = shortName.substring(0, index + 1);
-      String name = shortName.substring(index + 1);
-      
-      String relPath = sdkLibPathUri.relativize(libFileUri).getPath();
-      index = relPath.indexOf('/');
-      if (index == -1) {
-        continue;
-      }
-      String host = relPath.substring(0, index);
-      String pathToLib = relPath.substring(index + 1);
-      
-      addLib(scheme, 
-          host, 
-          name, 
-          pathToLib, 
-          library.getCategory(),
-          library.isDocumented(), 
-          library.isImplementation());
-      
-    }
-    return libraries.toArray(new SystemLibrary[libraries.size()]);
-  }
-  
-  protected boolean addLib(String scheme, String host, String name, String pathToLib, 
-                          String category, boolean documented, boolean implementation)
-      throws AssertionError {
-    
-    SystemLibrary lib = libraryProvider.createSystemLibrary(name, host, pathToLib, category, documented, implementation);
-    libraries.add(lib);
-    
-    String libSpec = scheme + name;
-    URI libUri;
-    URI expandedUri;
-    try {
-      libUri = new URI(libSpec);
-      expandedUri = new URI("dart:" + "//" + host + "/" + pathToLib);
-    } catch (URISyntaxException e) {
-      throw new AssertionError(e);
-    }
-    URI resolvedUri = lib.translateUri(expandedUri);
-    longToShortUriMap.put(resolvedUri, libUri);
-    longToShortUriMap.put(expandedUri, libUri);
-    return true;
-  }
-
-  /**
-   * Register system libraries for the "dart:" protocol such that dart:[shortLibName] (e.g.
-   * "dart:html") will automatically be expanded to dart://[host]/[pathToLib] (e.g.
-   * dart://html/html.dart)
-   */
-  private void setLibraries(SystemLibrary[] newLibraries) {
-    libraries = new ArrayList<SystemLibrary>();
-    hostMap = new HashMap<String, SystemLibrary>();
-    expansionMap = new HashMap<String, String>();
-    for (SystemLibrary library : newLibraries) {
-      String host = library.getHost();
-      SystemLibrary existingLib = hostMap.get(host);
-      if (existingLib != null) {
-        libraries.remove(existingLib);
-      }
-      libraries.add(library);
-      hostMap.put(host, library);
-      expansionMap.put(library.getShortName(),
-          "//" + host + "/" + library.getPathToLib());
-    }
-  }
-
-  /**
-   * Check if this URI denotes a patch file.
-   */
-  public boolean isPatchFile(URI uri) {
-    return libraryProvider.isPatchFile(uri);
-  }
-
-}
diff --git a/compiler/java/com/google/dart/compiler/SystemLibraryProvider.java b/compiler/java/com/google/dart/compiler/SystemLibraryProvider.java
deleted file mode 100644
index af6ab2d..0000000
--- a/compiler/java/com/google/dart/compiler/SystemLibraryProvider.java
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * Copyright (c) 2012, the Dart project authors.
- * 
- * Licensed under the Eclipse Public License v1.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.eclipse.org/legal/epl-v10.html
- * 
- * 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.dart.compiler;
-
-import com.google.dart.compiler.SystemLibrariesReader.DartLibrary;
-
-import java.io.IOException;
-import java.net.URI;
-import java.util.Map;
-
-/**
- * A provider for System libraries.
- */
-public abstract class SystemLibraryProvider {
-
-  private final URI sdkLibPathUri;
-  private SystemLibrariesReader reader;
-
-  /**
-   * Create a {@link SystemLibraryProvider} with the given path to the dart SDK.
-   */
-  public SystemLibraryProvider(URI sdkLibPathUri) {
-    this.sdkLibPathUri = sdkLibPathUri;
-  }
-
-  /**
-   * Define a new system library.
-   * 
-   * @param name the short name of the library
-   * @param host the host
-   * @param pathToLib the path to the library
-   * @param category the library category
-   * @param documented <code>true</code> if documented, <code>false</code> otherwise
-   * @param implementation <code>true</code> if an implementation library, <code>false</code>
-   *          otherwise
-   * @return the resulting {@link SystemLibrary}
-   */
-  public abstract SystemLibrary createSystemLibrary(String name, String host, String pathToLib,
-      String category, boolean documented, boolean implementation);
-
-  /**
-   * Tests whether the resource denoted by this abstract URI exists.
-   * 
-   * @param uri the URI to test
-   * @return <code>true</code> if and only if the resource denoted by this URI exists;
-   *         <code>false</code> otherwise
-   */
-  public abstract boolean exists(URI uri);
-
-  /**
-   * Get a URI describing the root of the SDK.
-   */
-  public URI getSdkLibPathUri() {
-    return sdkLibPathUri;
-  }
-
-  /**
-   * Get a mapping of symbolic names (e.g., "dart:html") to {@link DartLibrary}s.
-   */
-  public Map<String, DartLibrary> getLibraryMap() {
-    return getReader().getLibrariesMap();
-  }
-
-  /**
-   * Check if this URI denotes a patch file.
-   */
-  public boolean isPatchFile(URI uri) {
-    return getReader().getPatchPaths().contains(uri);
-  }
-
-  /**
-   * Constructs a new URI by parsing the given host string and then resolving it against this URI.
-   * 
-   * @param host the host string
-   * @param uri the uri to resolve against
-   * @return the resulting URI
-   */
-  public abstract URI resolveHost(String host, URI uri);
-
-  /**
-   * Create the system libraries reader.
-   * 
-   * @return a reader for parsing system libraries
-   */
-  protected abstract SystemLibrariesReader createReader() throws IOException;
-
-  private SystemLibrariesReader getReader() {
-    if (reader == null) {
-      try {
-        reader = createReader();
-      } catch (IOException e) {
-        throw new InternalCompilerException("Unable to create system library reader", e);
-      }
-    }
-    return reader;
-  }
-
-}
diff --git a/compiler/java/com/google/dart/compiler/UnitTestBatchRunner.java b/compiler/java/com/google/dart/compiler/UnitTestBatchRunner.java
deleted file mode 100644
index bbabf4a..0000000
--- a/compiler/java/com/google/dart/compiler/UnitTestBatchRunner.java
+++ /dev/null
@@ -1,72 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler;
-
-
-import com.google.dart.compiler.DartCompiler.Result;
-
-import java.io.BufferedReader;
-import java.io.InputStreamReader;
-
-/**
- * Provides a framework to read command line options from stdin and feed them to
- * the {@link DartCompiler}.
- *
- */
-public class UnitTestBatchRunner {
-
-  public interface Invocation {
-    public Result invoke (String[] args) throws Throwable;
-  }
-
-  /**
-   * Run the tool in 'batch' mode, receiving command lines through stdin and returning
-   * pass/fail status through stdout.  This feature is intended for use in unit testing.
-   *
-   * @param batchArgs command line arguments forwarded from main().
-   */
-  public static Result runAsBatch(String[] batchArgs, Invocation toolInvocation) throws Throwable {
-    System.out.println(">>> BATCH START");
-
-    // Read command lines in from stdin and create a new compiler for each one.
-    BufferedReader cmdlineReader = new BufferedReader(new InputStreamReader(
-        System.in));
-    long startTime = System.currentTimeMillis();
-    int testsFailed = 0;
-    int totalTests = 0;
-    Result batchResult = new Result(DartCompiler.RESULT_OK, null);
-    try {
-      String line;
-      for (; (line = cmdlineReader.readLine()) != null; totalTests++) {
-        long testStart = System.currentTimeMillis();
-        // TODO(zundel): These are shell script cmdlines: be smarter about quoted strings.
-        String[] args = line.trim().split("\\s+");
-        Result result = toolInvocation.invoke(args);
-        boolean resultPass = result.code < DartCompiler.RESULT_ERRORS;
-        if (resultPass) {
-          testsFailed++;
-        }
-        batchResult = batchResult.merge(result);
-        // Write stderr end token and flush.
-        System.err.println(">>> EOF STDERR");
-        System.err.flush();
-        System.out.println(">>> TEST " + (resultPass ? "PASS" : "FAIL") + " "
-            + (System.currentTimeMillis() - testStart) + "ms");
-        System.out.flush();
-      }
-    } catch (Throwable e) {
-      System.err.println(">>> EOF STDERR");
-      System.err.flush();
-      System.out.println(">>> TEST CRASH");
-      System.out.flush();
-      throw e;
-    }
-    long elapsed = System.currentTimeMillis() - startTime;
-    System.out.println(">>> BATCH END (" + (totalTests - testsFailed) + "/"
-        + totalTests + ") " + elapsed + "ms");
-    System.out.flush();
-    return batchResult;
-  }
-}
diff --git a/compiler/java/com/google/dart/compiler/UrlDartSource.java b/compiler/java/com/google/dart/compiler/UrlDartSource.java
deleted file mode 100644
index 2e13899..0000000
--- a/compiler/java/com/google/dart/compiler/UrlDartSource.java
+++ /dev/null
@@ -1,54 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler;
-
-import java.io.File;
-import java.net.URI;
-import java.net.URISyntaxException;
-
-/**
- * A {@link DartSource} backed by a URL.
- */
-public class UrlDartSource extends UrlSource implements DartSource {
-
-  private final LibrarySource lib;
-  private final String relPath;
-
-  protected UrlDartSource(URI uri, String relPath, LibrarySource lib, PackageLibraryManager slm) {
-    super(uri,slm);
-    this.relPath = relPath;
-    this.lib = lib;
-  }
-
-  protected UrlDartSource(URI uri, String relPath, LibrarySource lib) {
-    this(uri, relPath, lib, null);
-  }
-
-  public UrlDartSource(File file, LibrarySource lib) {
-    super(file);
-    this.relPath = file.getPath();
-    this.lib = lib;
-  }
-
-  @Override
-  public LibrarySource getLibrary() {
-    return lib;
-  }
-
-  @Override
-  public String getName() {
-    try {
-      String uriSafeName = new URI(null, null, relPath, null).toString();
-      return lib.getName() + "/" + uriSafeName;
-    } catch (URISyntaxException e) {
-      throw new AssertionError(e);
-    }
-  }
-
-  @Override
-  public String getRelativePath() {
-    return relPath;
-  }
-}
diff --git a/compiler/java/com/google/dart/compiler/UrlLibrarySource.java b/compiler/java/com/google/dart/compiler/UrlLibrarySource.java
deleted file mode 100644
index 27fce70..0000000
--- a/compiler/java/com/google/dart/compiler/UrlLibrarySource.java
+++ /dev/null
@@ -1,124 +0,0 @@
-// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-package com.google.dart.compiler;
-
-import java.io.File;
-import java.net.URI;
-
-/**
- * A {@link LibrarySource} backed by a URL.
- */
-public class UrlLibrarySource extends UrlSource implements LibrarySource {
-  
-  public UrlLibrarySource(URI uri, PackageLibraryManager slm) {
-    super(uri, slm);
-  }
-
-  public UrlLibrarySource(URI uri) {
-    this(uri, null);
-  }
-
-  public UrlLibrarySource(File file) {
-    super(file);
-  }
-
-  @Override
-  public String getName() {
-    return getUri().toString();
-  }
-
-  @Override
-  public LibrarySource getImportFor(String relPath) {
-    if (relPath == null || relPath.isEmpty()) {
-      return null;
-    }
-    try {
-      // Force the creation of an escaped relative URI to deal with spaces, etc.
-      URI uri = getUri().resolve(new URI(null, null, relPath, null, null)).normalize();
-      String path = uri.getPath();
-      // Resolve relative reference out of one system library into another
-      if (PackageLibraryManager.isDartUri(uri)) {
-        if (path != null && path.startsWith("/..")) {
-          URI fileUri = packageLibraryManager.resolveDartUri(uri);
-          URI shortUri = packageLibraryManager.getShortUri(fileUri);
-          if (shortUri != null) {
-            uri = shortUri;
-          }
-        }
-      } else if (PackageLibraryManager.isPackageUri(uri)) {
-        URI fileUri = packageLibraryManager.resolveDartUri(uri);
-        if (fileUri != null) {
-          uri = fileUri;
-        }
-      } else if (!resourceExists(uri)) {
-        // resolve against package root directories to find file
-        uri = packageLibraryManager.findExistingFileInPackages(uri);
-      }
-
-      return createLibrarySource(uri, packageLibraryManager);
-    } catch (Throwable e) {
-      return null;
-    }
-  }
-
-  @Override
-  public DartSource getSourceFor(final String relPath) {
-    if (relPath == null || relPath.isEmpty()) {
-      return null;
-    }
-    try {
-      // Force the creation of an escaped relative URI to deal with spaces, etc.
-      URI uri = getUri().resolve(new URI(null, null, relPath, null, null)).normalize();
-      if (PackageLibraryManager.isPackageUri(uri)) {
-        URI fileUri = packageLibraryManager.resolveDartUri(uri);
-        if (fileUri != null) {
-          uri = fileUri;
-        }
-      }
-      return createDartSource(uri, relPath, this, packageLibraryManager);
-    } catch (Throwable e) {
-      return null;
-    }
-  }
-
-  /**
-   * Create a URL library source. 
-   * 
-   * (Clients can override.)
-   * 
-   * @param uri the URI of the library
-   * @param relPath relative path to the dart source
-   * @param libSource the library source
-   * @param packageManager the package library manager
-   * @return the resulting dart source
-   */
-  protected UrlDartSource createDartSource(URI uri, String relPath, UrlLibrarySource libSource, PackageLibraryManager packageManager) {
-    return new UrlDartSource(uri, relPath, libSource, packageManager);
-  }
-
-  /**
-   * Create a URL library source. 
-   * 
-   * (Clients can override.)
-   * 
-   * @param uri the URI of the library
-   * @return the resulting library source
-   */
-  protected UrlLibrarySource createLibrarySource(URI uri, PackageLibraryManager packageManager) {
-    return new UrlLibrarySource(uri, packageManager);
-  }
-  
-  /**
-   * Check if a resource exists at this URI.
-   * 
-   * (Clients can override.)
-   * 
-   * @param uri the URI to test
-   * @return <code>true</code> if a resource exists at this URI, <code>false</code> otherwise
-   */
-  protected boolean resourceExists(URI uri) {
-    String path = uri.getPath();
-    return path == null || new File(path).exists();
-  }
-}
diff --git a/compiler/java/com/google/dart/compiler/UrlSource.java b/compiler/java/com/google/dart/compiler/UrlSource.java
deleted file mode 100644
index 890df68..0000000
--- a/compiler/java/com/google/dart/compiler/UrlSource.java
+++ /dev/null
@@ -1,205 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.io.Reader;
-import java.net.JarURLConnection;
-import java.net.URI;
-import java.net.URL;
-import java.nio.charset.Charset;
-import java.util.jar.JarEntry;
-
-/**
- * A {@link Source} backed by a URL (or optionally by a file).
- */
-public abstract class UrlSource implements Source {
-
-  private final static String FILE_PROTOCOL = "file";
-  private final static String JAR_PROTOCOL = "jar";
-  private final static URI CURRENT_DIR = new File(".").toURI().normalize();
-  private final static Charset UTF8 = Charset.forName("UTF8");
-  private final static URI BASE_URI = CURRENT_DIR;
-
-  private final URI uri;
-  private final URI absoluteUri;
-  private final URI translatedUri;
-  private final boolean shouldCareAboutLastModified;
-  private volatile boolean exists = false;
-  private volatile long lastModified = -1;
-  private volatile boolean propertiesInitialized = false;
-
-  // generally, one or the other of these will be non-null after properties are initialized
-  private volatile File sourceFile = null;
-  private volatile JarURLConnection jarConn = null;
-
-  protected final PackageLibraryManager packageLibraryManager;
-
-  protected UrlSource(URI uri) {
-    this(uri,null);
-  }
-
-  protected UrlSource(URI uri, PackageLibraryManager slm) {
-    URI expanded = slm != null ? slm.expandRelativeDartUri(uri) : uri;
-    if (expanded == null) {
-      // import("dart:typo") case
-      expanded = uri;
-    }
-    this.uri = BASE_URI.relativize(expanded.normalize());
-    this.absoluteUri = BASE_URI.resolve(expanded);
-    this.packageLibraryManager = slm;
-    if (PackageLibraryManager.isDartUri(this.uri) || PackageLibraryManager.isPackageUri(this.uri)) {
-      assert slm != null;
-      this.shouldCareAboutLastModified = false;
-      this.translatedUri = slm.resolveDartUri(this.absoluteUri);
-    } else {
-      this.shouldCareAboutLastModified = true;
-      this.translatedUri = this.absoluteUri;
-    }
-  }
-
-  protected UrlSource(File file) {
-    URI uri = file.toURI().normalize();
-    if (!file.exists()) {
-      // TODO(jgw): This is a bit ugly, but some of the test infrastructure depends upon
-      // non-existant relative files being looked up as classpath resources. This was
-      // previously embedded in DartSourceFile.getSourceReader().
-      URL url = getClass().getClassLoader().getResource(file.getPath());
-      if (url != null) {
-        uri = URI.create(url.toString());
-      }
-    }
-
-    this.uri = BASE_URI.relativize(uri);
-    this.translatedUri = this.absoluteUri = BASE_URI.resolve(uri);
-    this.packageLibraryManager = null;
-    this.shouldCareAboutLastModified = true;
-  }
-
-  @Override
-  public boolean exists() {
-    initProperties();
-    return exists;
-  }
-
-  @Override
-  public long getLastModified() {
-    initProperties();
-    return lastModified;
-  }
-
-  @Override
-  public Reader getSourceReader() throws IOException {
-    initProperties();
-    if (sourceFile != null) {
-      return new InputStreamReader(new FileInputStream(sourceFile), UTF8);
-    } else if (jarConn != null) {
-      return new InputStreamReader(jarConn.getInputStream(), UTF8);
-    }
-    // fall back case
-    if (translatedUri != null) {
-      InputStream stream = translatedUri.toURL().openStream();
-      if (stream != null) {
-        return new InputStreamReader(stream, UTF8);
-      }
-    }
-    throw new FileNotFoundException(getName());
-  }
-
-  @Override
-  public String getUniqueIdentifier() {
-    return absoluteUri.toString();
-  }
-
-  /**
-   * Get the translated URI for this source.
-   * 
-   * @return the translated URI
-   */
-  public URI getTranslatedUri() {
-    return translatedUri;
-  }
-  
-  @Override
-  public URI getUri() {
-    return absoluteUri;
-  }
-
-  private void initProperties() {
-    synchronized (this) {
-      if (!propertiesInitialized) {
-        try {
-          initPropertiesEx();
-        } catch (Throwable e) {
-        } finally {
-          propertiesInitialized = true;
-        }
-      }
-    }
-  }
-
-  /**
-   * Implementation of {@link #initProperties()} which can throw exceptions.
-   */
-  private void initPropertiesEx() throws Exception {
-    URI resolvedUri = BASE_URI.resolve(translatedUri);
-    String scheme = resolvedUri.getScheme();
-    if (scheme == null || FILE_PROTOCOL.equals(scheme)) {
-      File file = new File(resolvedUri);
-      lastModified = file.lastModified();
-      exists = file.exists();
-      sourceFile = file;
-    } else {
-      URL url = translatedUri.toURL();
-      if (JAR_PROTOCOL.equals(url.getProtocol())) {
-        getJarEntryProperties(url);
-      } else {
-        /*
-         * TODO(jbrosenberg): Flesh out the support for other
-         * protocols, like http, etc. Note, calling
-         * URLConnection.getLastModified() can be dangerous, some
-         * URLConnection sub-classes don't have a way to close a
-         * connection opened by this call. Return 0 for now.
-         */
-        lastModified = 0;
-        // Default this to true for now.
-        exists = true;
-      }
-    }
-  }
-
-  private void getJarEntryProperties(URL url) {
-    try {
-      jarConn = (JarURLConnection) url.openConnection();
-      // useCaches is usually set to true by default, but make sure here
-      jarConn.setUseCaches(true);
-      // See if our entry exists
-      JarEntry jarEntry = jarConn.getJarEntry();
-      if (jarEntry != null) {
-        exists = true;
-        if (!shouldCareAboutLastModified) {
-          lastModified = 0;
-          return;
-        }
-        // TODO(jbrosenberg): Note the time field for a jarEntry can be
-        // unreliable, and is not always required in a jar file. Consider using
-        // the timestamp on the jar file itself.
-        lastModified = jarEntry.getTime();
-      }
-      if (!exists) {
-        lastModified = -1;
-        return;
-      }
-    } catch (IOException e) {
-      exists = false;
-      lastModified = -1;
-    }
-  }
-}
\ No newline at end of file
diff --git a/compiler/java/com/google/dart/compiler/ast/ASTNodes.java b/compiler/java/com/google/dart/compiler/ast/ASTNodes.java
deleted file mode 100644
index 2e3b87f..0000000
--- a/compiler/java/com/google/dart/compiler/ast/ASTNodes.java
+++ /dev/null
@@ -1,1448 +0,0 @@
-/*
- * Copyright (c) 2012, the Dart project authors.
- * 
- * Licensed under the Eclipse Public License v1.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.eclipse.org/legal/epl-v10.html
- * 
- * 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.dart.compiler.ast;
-
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.Lists;
-import com.google.dart.compiler.common.SourceInfo;
-import com.google.dart.compiler.parser.Token;
-import com.google.dart.compiler.resolver.Element;
-import com.google.dart.compiler.resolver.ElementKind;
-import com.google.dart.compiler.resolver.FieldElement;
-import com.google.dart.compiler.resolver.MethodElement;
-import com.google.dart.compiler.resolver.VariableElement;
-import com.google.dart.compiler.type.InterfaceType;
-import com.google.dart.compiler.type.Type;
-import com.google.dart.compiler.type.TypeKind;
-
-import java.util.Collections;
-import java.util.List;
-import java.util.concurrent.atomic.AtomicBoolean;
-
-/**
- * Defines utility methods that operate on nodes in a Dart AST structure (instances of
- * {@link DartNode} and its subclasses).
- */
-public class ASTNodes {
-
-  /**
-   * @return <code>true</code> if given {@link DartNode} is part of static method, static field or
-   *         top-level function.
-   */
-  public static boolean isStaticContext(DartNode node) {
-    while (node != null) {
-      DartNode parent = node.getParent();
-      if (node instanceof DartMethodDefinition) {
-        DartMethodDefinition method = (DartMethodDefinition) node;
-        if (method.getModifiers().isStatic()) {
-          return true;
-        }
-        return parent instanceof DartUnit;
-      }
-      if (node instanceof DartField) {
-        DartField field = (DartField) node;
-        if (field.getModifiers().isStatic()) {
-          return true;
-        }
-        return parent != null && parent.getParent() instanceof DartUnit;
-      }
-      node = parent;
-    }
-    return false;
-  }
-
-  /**
-   * @return <code>true</code> if given {@link DartNode} is part of factory method.
-   */
-  public static boolean isFactoryContext(DartNode node) {
-    while (node != null) {
-      if (node instanceof DartMethodDefinition) {
-        DartMethodDefinition method = (DartMethodDefinition) node;
-        return method.getModifiers().isFactory();
-      }
-      node = node.getParent();
-    }
-    return false;
-  }
-
-  /**
-   * @return <code>true</code> if given {@link DartNode} is part of static method or factory.
-   */
-  public static boolean isStaticOrFactoryContext(DartNode node) {
-    return isFactoryContext(node) || isStaticContext(node);
-  }
-  
-  /**
-   * Returns complete field access node for given field name.
-   * 
-   * <pre>
-   * node = 1;        => node
-   * obj.node = 1;    => obj.node
-   * </pre>
-   * 
-   * Note, that we don't check if given {@link DartNode} is actually field name.
-   */
-  public static DartNode getPropertyAccessNode(DartNode node) {
-    DartNode parent = node.getParent();
-    if (parent instanceof DartPropertyAccess && ((DartPropertyAccess) parent).getName() == node) {
-      return parent;
-    }
-    return node;
-  }
-
-  public static List<DartNode> findDeepestCommonPath(List<DartNode> nodes) {
-    List<List<DartNode>> parents = Lists.newArrayList();
-    for (DartNode node : nodes) {
-      parents.add(getParents(node));
-    }
-    return getLongestListPrefix(parents);
-  }
-
-  /**
-   * @return the {@link DartNode} of given {@link Class} which is given {@link DartNode} itself, or
-   *         one of its parents.
-   */
-  @SuppressWarnings("unchecked")
-  public static <E extends DartNode> E getAncestor(DartNode node, Class<E> enclosingClass) {
-    while (node != null && !enclosingClass.isInstance(node)) {
-      node = node.getParent();
-    };
-    return (E) node;
-  }
-
-  /**
-   * Get the element associated with the given AST node.
-   * 
-   * @param node the target node
-   * @param includeDeclarations <code>true</code> if elements should be returned for declaration
-   *          sites as well as for reference sites
-   * @return the associated element (or <code>null</code> if none can be found)
-   */
-  public static Element getElement(DartNode node, boolean includeDeclarations) {
-    Element targetElement = node.getElement();
-    DartNode parent = node.getParent();
-    // name of named parameter in invocation
-    if (node instanceof DartIdentifier && node.getParent() instanceof DartNamedExpression) {
-      DartNamedExpression namedExpression = (DartNamedExpression) node.getParent();
-      if (namedExpression.getName() == node) {
-        Object parameterId = ((DartIdentifier) node).getInvocationParameterId();
-        if (parameterId instanceof VariableElement) {
-          targetElement = (VariableElement) parameterId;
-        }
-      }
-    }
-    // target of "new X()" or "new X.a()" is not just a type, it is a constructor
-    if (parent instanceof DartTypeNode || parent instanceof DartPropertyAccess) {
-      DartNode grandparent = parent.getParent();
-      if (grandparent instanceof DartNewExpression) {
-        targetElement = ((DartNewExpression) grandparent).getElement();
-      }
-    } else if (parent instanceof DartRedirectConstructorInvocation
-        || parent instanceof DartSuperConstructorInvocation) {
-      targetElement = parent.getElement();
-    }
-    return targetElement;
-  }
-
-  /**
-   * Return the class definition enclosing the given node, or <code>null</code> if the node is not a
-   * child of a class definition.
-   * 
-   * @param node the node enclosed in the class definition to be returned
-   * @return the class definition enclosing the given node
-   */
-  public static DartClass getEnclosingDartClass(DartNode node) {
-    return getEnclosingNodeOfType(DartClass.class, node);
-  }
-
-  /**
-   * Return the first node of the given class that encloses the given node, or <code>null</code> if
-   * the node is not a child of a node of the given class. The node itself will <b>not</b> be
-   * returned, even if it is an instance of the given class.
-   * 
-   * @param enclosingNodeClass the class of node to be returned
-   * @param node the child of the node to be returned
-   * @return the specified parent of the given node
-   */
-  @SuppressWarnings("unchecked")
-  public static <E extends DartNode> E getEnclosingNodeOfType(Class<E> enclosingNodeClass,
-      DartNode node) {
-    DartNode parent = node.getParent();
-    while (parent != null && !enclosingNodeClass.isInstance(parent)) {
-      parent = parent.getParent();
-    }
-    return (E) parent;
-  }
-
-  public static int getExclusiveEnd(DartNode node) {
-    SourceInfo sourceInfo = node.getSourceInfo();
-    return sourceInfo.getOffset() + sourceInfo.getLength();
-  }
-
-  /**
-   * @return the {@link FieldElement} with {@link ElementKind#VARIABLE} if the given
-   *         {@link DartIdentifier} is the field reference, or <code>null</code> in the other case.
-   */
-  public static FieldElement getFieldElement(DartIdentifier node) {
-    Element element = node.getElement();
-    if (ElementKind.of(element) == ElementKind.FIELD) {
-      return (FieldElement) element;
-    }
-    return null;
-  }
-
-  public static int getInclusiveEnd(DartNode node) {
-    SourceInfo sourceInfo = node.getSourceInfo();
-    return sourceInfo.getOffset() + sourceInfo.getLength() - 1;
-  }
-
-  /**
-   * @return the {@link DartExpression} qualified if given node is name part of
-   *         {@link DartPropertyAccess}. May be <code>null</code>.
-   */
-  public static DartNode getNodeQualifier(DartIdentifier node) {
-    if (node.getParent() instanceof DartPropertyAccess) {
-      DartPropertyAccess propertyAccess = (DartPropertyAccess) node.getParent();
-      if (propertyAccess.getName() == node) {
-        return propertyAccess.getQualifier();
-      }
-    }
-    return null;
-  }
-
-  /**
-   * @return the {@link VariableElement} if the given {@link DartIdentifier} is the parameter
-   *         reference, or <code>null</code> in the other case.
-   */
-  public static VariableElement getParameterElement(DartIdentifier node) {
-    Element element = node.getElement();
-    if (ElementKind.of(element) == ElementKind.PARAMETER) {
-      return (VariableElement) element;
-    }
-    return null;
-  }
-
-  /**
-   * @return the index of given {@link VariableElement} in parameters, or <code>-1</code> if not
-   *         parameter.
-   */
-  public static int getParameterIndex(VariableElement variableElement) {
-    Element enclosingElement = variableElement.getEnclosingElement();
-    if (enclosingElement instanceof MethodElement) {
-      MethodElement methodElement = (MethodElement) enclosingElement;
-      return methodElement.getParameters().indexOf(variableElement);
-    }
-    return -1;
-  }
-
-  /**
-   * Returns the closest ancestor of <code>node</code> that is an instance of
-   * <code>parentClass</code>, or <code>null</code> if none.
-   * <p>
-   * <b>Warning:</b> This method does not stop at any boundaries like parentheses, statements, body
-   * declarations, etc. The resulting node may be in a totally different scope than the given node.
-   * Consider using one of the {@link ASTResolving}<code>.find(..)</code> methods instead.
-   * </p>
-   * 
-   * @param node the node
-   * @param parentClass the class of the sought ancestor node
-   * @return the closest ancestor of <code>node</code> that is an instance of
-   *         <code>parentClass</code>, or <code>null</code> if none
-   */
-  @SuppressWarnings("unchecked")
-  public static <E extends DartNode> E getParent(DartNode node, Class<E> parentClass) {
-    do {
-      node = node.getParent();
-    } while (node != null && !parentClass.isInstance(node));
-    return (E) node;
-  }
-
-//  private static class ChildrenCollector extends ASTVisitor<Void> {
-//    public List<DartNode> result;
-//
-//    @Override
-//    public Void visitNode(DartNode node) {
-//      // first visitNode: on the node's parent: do nothing, return true
-//      if (result == null) {
-//        result = Lists.newArrayList();
-//        return super.visitNode(node);
-//      } else {
-//        result.add(node);
-//      }
-//    }
-//  }
-//
-//  public static final int NODE_ONLY = 0;
-//  public static final int INCLUDE_FIRST_PARENT = 1;
-//
-//  public static final int INCLUDE_ALL_PARENTS = 2;
-//  public static final int WARNING = 1 << 0;
-//  public static final int ERROR = 1 << 1;
-//
-//  public static final int PROBLEMS = WARNING | ERROR;
-//  private static final Message[] EMPTY_MESSAGES = new Message[0];
-//
-//  private static final IProblem[] EMPTY_PROBLEMS = new IProblem[0];
-//
-//  private static final int CLEAR_VISIBILITY =
-//      ~(Modifier.PUBLIC | Modifier.PROTECTED | Modifier.PRIVATE);
-//
-//  public static String asFormattedString(DartNode node,
-//      int indent,
-//      String lineDelim,
-//      Map<String, String> options) {
-//    String unformatted = asString(node);
-//    TextEdit edit = CodeFormatterUtil.format2(node, unformatted, indent, lineDelim, options);
-//    if (edit != null) {
-//      Document document = new Document(unformatted);
-//      try {
-//        edit.apply(document, TextEdit.NONE);
-//      } catch (BadLocationException e) {
-//        JavaPlugin.log(e);
-//      }
-//      return document.get();
-//    }
-//    return unformatted; // unknown node
-//  }
-//
-//  public static String asString(DartNode node) {
-//    ASTFlattener flattener = new ASTFlattener();
-//    node.accept(flattener);
-//    return flattener.getResult();
-//  }
-//
-//  public static int changeVisibility(int modifiers, int visibility) {
-//    return modifiers & CLEAR_VISIBILITY | visibility;
-//  }
-//
-//  public static InfixExpression.Operator convertToInfixOperator(Assignment.Operator operator) {
-//    if (operator.equals(Assignment.Operator.PLUS_ASSIGN)) {
-//      return InfixExpression.Operator.PLUS;
-//    }
-//
-//    if (operator.equals(Assignment.Operator.MINUS_ASSIGN)) {
-//      return InfixExpression.Operator.MINUS;
-//    }
-//
-//    if (operator.equals(Assignment.Operator.TIMES_ASSIGN)) {
-//      return InfixExpression.Operator.TIMES;
-//    }
-//
-//    if (operator.equals(Assignment.Operator.DIVIDE_ASSIGN)) {
-//      return InfixExpression.Operator.DIVIDE;
-//    }
-//
-//    if (operator.equals(Assignment.Operator.BIT_AND_ASSIGN)) {
-//      return InfixExpression.Operator.AND;
-//    }
-//
-//    if (operator.equals(Assignment.Operator.BIT_OR_ASSIGN)) {
-//      return InfixExpression.Operator.OR;
-//    }
-//
-//    if (operator.equals(Assignment.Operator.BIT_XOR_ASSIGN)) {
-//      return InfixExpression.Operator.XOR;
-//    }
-//
-//    if (operator.equals(Assignment.Operator.REMAINDER_ASSIGN)) {
-//      return InfixExpression.Operator.REMAINDER;
-//    }
-//
-//    if (operator.equals(Assignment.Operator.LEFT_SHIFT_ASSIGN)) {
-//      return InfixExpression.Operator.LEFT_SHIFT;
-//    }
-//
-//    if (operator.equals(Assignment.Operator.RIGHT_SHIFT_SIGNED_ASSIGN)) {
-//      return InfixExpression.Operator.RIGHT_SHIFT_SIGNED;
-//    }
-//
-//    if (operator.equals(Assignment.Operator.RIGHT_SHIFT_UNSIGNED_ASSIGN)) {
-//      return InfixExpression.Operator.RIGHT_SHIFT_UNSIGNED;
-//    }
-//
-//    Assert.isTrue(false, "Cannot convert assignment operator"); //$NON-NLS-1$
-//    return null;
-//  }
-//
-//  public static DartNode findDeclaration(IBinding binding, DartNode root) {
-//    root = root.getRoot();
-//    if (root instanceof CompilationUnit) {
-//      return ((CompilationUnit) root).findDeclaringNode(binding);
-//    }
-//    return null;
-//  }
-//
-//  public static Modifier findModifierNode(int flag, List<IExtendedModifier> modifiers) {
-//    for (int i = 0; i < modifiers.size(); i++) {
-//      Object curr = modifiers.get(i);
-//      if (curr instanceof Modifier && ((Modifier) curr).getKeyword().toFlagValue() == flag) {
-//        return (Modifier) curr;
-//      }
-//    }
-//    return null;
-//  }
-//
-//  public static DartNode findParent(DartNode node, StructuralPropertyDescriptor[][] pathes) {
-//    for (int p = 0; p < pathes.length; p++) {
-//      StructuralPropertyDescriptor[] path = pathes[p];
-//      DartNode current = node;
-//      int d = path.length - 1;
-//      for (; d >= 0 && current != null; d--) {
-//        StructuralPropertyDescriptor descriptor = path[d];
-//        if (!descriptor.equals(current.getLocationInParent())) {
-//          break;
-//        }
-//        current = current.getParent();
-//      }
-//      if (d < 0) {
-//        return current;
-//      }
-//    }
-//    return null;
-//  }
-//
-//  public static VariableDeclaration findVariableDeclaration(IVariableBinding binding, DartNode root) {
-//    if (binding.isField()) {
-//      return null;
-//    }
-//    DartNode result = findDeclaration(binding, root);
-//    if (result instanceof VariableDeclaration) {
-//      return (VariableDeclaration) result;
-//    }
-//
-//    return null;
-//  }
-//
-//  public static List<BodyDeclaration> getBodyDeclarations(DartNode node) {
-//    if (node instanceof AbstractTypeDeclaration) {
-//      return ((AbstractTypeDeclaration) node).bodyDeclarations();
-//    } else if (node instanceof AnonymousClassDeclaration) {
-//      return ((AnonymousClassDeclaration) node).bodyDeclarations();
-//    }
-//    // should not happen.
-//    Assert.isTrue(false);
-//    return null;
-//  }
-//
-//  /**
-//   * Returns the structural property descriptor for the "bodyDeclarations" property of this node
-//   * (element type: {@link BodyDeclaration}).
-//   * 
-//   * @param node the node, either an {@link AbstractTypeDeclaration} or an
-//   *          {@link AnonymousClassDeclaration}
-//   * @return the property descriptor
-//   */
-//  public static ChildListPropertyDescriptor getBodyDeclarationsProperty(DartNode node) {
-//    if (node instanceof AbstractTypeDeclaration) {
-//      return ((AbstractTypeDeclaration) node).getBodyDeclarationsProperty();
-//    } else if (node instanceof AnonymousClassDeclaration) {
-//      return AnonymousClassDeclaration.BODY_DECLARATIONS_PROPERTY;
-//    }
-//    // should not happen.
-//    Assert.isTrue(false);
-//    return null;
-//  }
-//
-//  /**
-//   * Returns a list of the direct children of a node. The siblings are ordered by start offset.
-//   * 
-//   * @param node the node to get the children for
-//   * @return the children
-//   */
-//  public static List<DartNode> getChildren(DartNode node) {
-//    ChildrenCollector visitor = new ChildrenCollector();
-//    node.accept(visitor);
-//    return visitor.result;
-//  }
-//
-//  /**
-//   * Returns the list that contains the given DartNode. If the node isn't part of any list,
-//   * <code>null</code> is returned.
-//   * 
-//   * @param node the node in question
-//   * @return the list that contains the node or <code>null</code>
-//   */
-//  public static List<? extends DartNode> getContainingList(DartNode node) {
-//    StructuralPropertyDescriptor locationInParent = node.getLocationInParent();
-//    if (locationInParent != null && locationInParent.isChildListProperty()) {
-//      return (List<? extends DartNode>) node.getParent().getStructuralProperty(locationInParent);
-//    }
-//    return null;
-//  }
-//
-//  public static int getDimensions(VariableDeclaration declaration) {
-//    int dim = declaration.getExtraDimensions();
-//    Type type = getType(declaration);
-//    if (type instanceof ArrayType) {
-//      dim += ((ArrayType) type).getDimensions();
-//    }
-//    return dim;
-//  }
-//
-//  /**
-//   * Returns the element type. This is a convenience method that returns its argument if it is a
-//   * simple type and the element type if the parameter is an array type.
-//   * 
-//   * @param type The type to get the element type from.
-//   * @return The element type of the type or the type itself.
-//   */
-//  public static Type getElementType(Type type) {
-//    if (!type.isArrayType()) {
-//      return type;
-//    }
-//    return ((ArrayType) type).getElementType();
-//  }
-//
-//  public static ITypeBinding getEnclosingType(DartNode node) {
-//    while (node != null) {
-//      if (node instanceof AbstractTypeDeclaration) {
-//        return ((AbstractTypeDeclaration) node).resolveBinding();
-//      } else if (node instanceof AnonymousClassDeclaration) {
-//        return ((AnonymousClassDeclaration) node).resolveBinding();
-//      }
-//      node = node.getParent();
-//    }
-//    return null;
-//  }
-//
-//  public static int getExclusiveEnd(DartNode node) {
-//    return node.getStartPosition() + node.getLength();
-//  }
-//
-//  /**
-//   * Returns the type to which an inlined variable initializer should be cast, or <code>null</code>
-//   * if no cast is necessary.
-//   * 
-//   * @param initializer the initializer expression of the variable to inline
-//   * @param reference the reference to the variable (which is to be inlined)
-//   * @return a type binding to which the initializer should be cast, or <code>null</code> iff no
-//   *         cast is necessary
-//   */
-//  public static ITypeBinding getExplicitCast(Expression initializer, Expression reference) {
-//    ITypeBinding initializerType = initializer.resolveTypeBinding();
-//    ITypeBinding referenceType = reference.resolveTypeBinding();
-//    if (initializerType == null || referenceType == null) {
-//      return null;
-//    }
-//
-//    if (initializerType.isPrimitive()
-//        && referenceType.isPrimitive()
-//        && !referenceType.isEqualTo(initializerType)) {
-//      return referenceType;
-//
-//    } else if (initializerType.isPrimitive() && !referenceType.isPrimitive()) { // initializer is autoboxed
-//      ITypeBinding unboxedReferenceType =
-//          Bindings.getUnboxedTypeBinding(referenceType, reference.getAST());
-//      if (!unboxedReferenceType.isEqualTo(initializerType)) {
-//        return unboxedReferenceType;
-//      } else if (needsExplicitBoxing(reference)) {
-//        return referenceType;
-//      }
-//
-//    } else if (!initializerType.isPrimitive() && referenceType.isPrimitive()) { // initializer is autounboxed
-//      ITypeBinding unboxedInitializerType =
-//          Bindings.getUnboxedTypeBinding(initializerType, reference.getAST());
-//      if (!unboxedInitializerType.isEqualTo(referenceType)) {
-//        return referenceType;
-//      }
-//
-//    } else if (initializerType.isRawType() && referenceType.isParameterizedType()) {
-//      return referenceType; // don't lose the unchecked conversion
-//
-//    } else if (!TypeRules.canAssign(initializerType, referenceType)) {
-//      if (!Bindings.containsTypeVariables(referenceType)) {
-//        return referenceType;
-//      }
-//    }
-//
-//    return null;
-//  }
-//
-//  public static IVariableBinding getFieldBinding(Name node) {
-//    IVariableBinding result = getVariableBinding(node);
-//    if (result == null || !result.isField()) {
-//      return null;
-//    }
-//
-//    return result;
-//  }
-//
-//  public static int getInclusiveEnd(DartNode node) {
-//    return node.getStartPosition() + node.getLength() - 1;
-//  }
-//
-//  /**
-//   * Computes the insertion index to be used to add the given member to the the list
-//   * <code>container</code>.
-//   * 
-//   * @param member the member to add
-//   * @param container a list containing objects of type <code>BodyDeclaration</code>
-//   * @return the insertion index to be used
-//   */
-//  public static int getInsertionIndex(BodyDeclaration member,
-//      List<? extends BodyDeclaration> container) {
-//    int containerSize = container.size();
-//
-//    MembersOrderPreferenceCache orderStore =
-//        JavaPlugin.getDefault().getMemberOrderPreferenceCache();
-//
-//    int orderIndex = getOrderPreference(member, orderStore);
-//
-//    int insertPos = containerSize;
-//    int insertPosOrderIndex = -1;
-//
-//    for (int i = containerSize - 1; i >= 0; i--) {
-//      int currOrderIndex = getOrderPreference(container.get(i), orderStore);
-//      if (orderIndex == currOrderIndex) {
-//        if (insertPosOrderIndex != orderIndex) { // no perfect match yet
-//          insertPos = i + 1; // after a same kind
-//          insertPosOrderIndex = orderIndex; // perfect match
-//        }
-//      } else if (insertPosOrderIndex != orderIndex) { // not yet a perfect match
-//        if (currOrderIndex < orderIndex) { // we are bigger
-//          if (insertPosOrderIndex == -1) {
-//            insertPos = i + 1; // after
-//            insertPosOrderIndex = currOrderIndex;
-//          }
-//        } else {
-//          insertPos = i; // before
-//          insertPosOrderIndex = currOrderIndex;
-//        }
-//      }
-//    }
-//    return insertPos;
-//  }
-//
-//  public static SimpleName getLeftMostSimpleName(Name name) {
-//    if (name instanceof SimpleName) {
-//      return (SimpleName) name;
-//    } else {
-//      final SimpleName[] result = new SimpleName[1];
-//      ASTVisitor visitor = new ASTVisitor() {
-//        @Override
-//        public boolean visit(QualifiedName qualifiedName) {
-//          Name left = qualifiedName.getQualifier();
-//          if (left instanceof SimpleName) {
-//            result[0] = (SimpleName) left;
-//          } else {
-//            left.accept(this);
-//          }
-//          return false;
-//        }
-//      };
-//      name.accept(visitor);
-//      return result[0];
-//    }
-//  }
-//
-//  public static SimpleType getLeftMostSimpleType(QualifiedType type) {
-//    final SimpleType[] result = new SimpleType[1];
-//    ASTVisitor visitor = new ASTVisitor() {
-//      @Override
-//      public boolean visit(QualifiedType qualifiedType) {
-//        Type left = qualifiedType.getQualifier();
-//        if (left instanceof SimpleType) {
-//          result[0] = (SimpleType) left;
-//        } else {
-//          left.accept(this);
-//        }
-//        return false;
-//      }
-//    };
-//    type.accept(visitor);
-//    return result[0];
-//  }
-//
-//  public static IVariableBinding getLocalVariableBinding(Name node) {
-//    IVariableBinding result = getVariableBinding(node);
-//    if (result == null || result.isField()) {
-//      return null;
-//    }
-//
-//    return result;
-//  }
-//
-//  public static Message[] getMessages(DartNode node, int flags) {
-//    DartNode root = node.getRoot();
-//    if (!(root instanceof CompilationUnit)) {
-//      return EMPTY_MESSAGES;
-//    }
-//    Message[] messages = ((CompilationUnit) root).getMessages();
-//    if (root == node) {
-//      return messages;
-//    }
-//    final int iterations = computeIterations(flags);
-//    List<Message> result = new ArrayList<Message>(5);
-//    for (int i = 0; i < messages.length; i++) {
-//      Message message = messages[i];
-//      DartNode temp = node;
-//      int count = iterations;
-//      do {
-//        int nodeOffset = temp.getStartPosition();
-//        int messageOffset = message.getStartPosition();
-//        if (nodeOffset <= messageOffset && messageOffset < nodeOffset + temp.getLength()) {
-//          result.add(message);
-//          count = 0;
-//        } else {
-//          count--;
-//        }
-//      } while ((temp = temp.getParent()) != null && count > 0);
-//    }
-//    return result.toArray(new Message[result.size()]);
-//  }
-//
-//  public static IMethodBinding getMethodBinding(Name node) {
-//    IBinding binding = node.resolveBinding();
-//    if (binding instanceof IMethodBinding) {
-//      return (IMethodBinding) binding;
-//    }
-//    return null;
-//  }
-//
-//  public static List<IExtendedModifier> getModifiers(VariableDeclaration declaration) {
-//    Assert.isNotNull(declaration);
-//    if (declaration instanceof SingleVariableDeclaration) {
-//      return ((SingleVariableDeclaration) declaration).modifiers();
-//    } else if (declaration instanceof VariableDeclarationFragment) {
-//      DartNode parent = declaration.getParent();
-//      if (parent instanceof VariableDeclarationExpression) {
-//        return ((VariableDeclarationExpression) parent).modifiers();
-//      } else if (parent instanceof VariableDeclarationStatement) {
-//        return ((VariableDeclarationStatement) parent).modifiers();
-//      }
-//    }
-//    return new ArrayList<IExtendedModifier>(0);
-//  }
-//
-//  /**
-//   * Returns the source of the given node from the location where it was parsed.
-//   * 
-//   * @param node the node to get the source from
-//   * @param extendedRange if set, the extended ranges of the nodes should ne used
-//   * @param removeIndent if set, the indentation is removed.
-//   * @return return the source for the given node or null if accessing the source failed.
-//   */
-//  public static String getNodeSource(DartNode node, boolean extendedRange, boolean removeIndent) {
-//    DartNode root = node.getRoot();
-//    if (root instanceof CompilationUnit) {
-//      CompilationUnit astRoot = (CompilationUnit) root;
-//      ITypeRoot typeRoot = astRoot.getTypeRoot();
-//      try {
-//        if (typeRoot != null && typeRoot.getBuffer() != null) {
-//          IBuffer buffer = typeRoot.getBuffer();
-//          int offset =
-//              extendedRange ? astRoot.getExtendedStartPosition(node) : node.getStartPosition();
-//          int length = extendedRange ? astRoot.getExtendedLength(node) : node.getLength();
-//          String str = buffer.getText(offset, length);
-//          if (removeIndent) {
-//            IJavaProject project = typeRoot.getJavaProject();
-//            int indent = StubUtility.getIndentUsed(buffer, node.getStartPosition(), project);
-//            str =
-//                Strings.changeIndent(
-//                    str,
-//                    indent,
-//                    project,
-//                    new String(),
-//                    typeRoot.findRecommendedLineSeparator());
-//          }
-//          return str;
-//        }
-//      } catch (JavaModelException e) {
-//        // ignore
-//      }
-//    }
-//    return null;
-//  }
-//
-//  public static DartNode getNormalizedNode(DartNode node) {
-//    DartNode current = node;
-//    // normalize name
-//    if (QualifiedName.NAME_PROPERTY.equals(current.getLocationInParent())) {
-//      current = current.getParent();
-//    }
-//    // normalize type
-//    if (QualifiedType.NAME_PROPERTY.equals(current.getLocationInParent())
-//        || SimpleType.NAME_PROPERTY.equals(current.getLocationInParent())) {
-//      current = current.getParent();
-//    }
-//    // normalize parameterized types
-//    if (ParameterizedType.TYPE_PROPERTY.equals(current.getLocationInParent())) {
-//      current = current.getParent();
-//    }
-//    return current;
-//  }
-
-  /**
-   * @return parent {@link DartNode}s from {@link DartUnit} (at index "0") to the given one.
-   */
-  public static List<DartNode> getParents(DartNode node) {
-    List<DartNode> parents = Lists.newArrayList();
-    DartNode current = node;
-    do {
-      parents.add(current.getParent());
-      current = current.getParent();
-    } while (current.getParent() != null);
-    Collections.reverse(parents);
-    return parents;
-  }
-
-  /**
-   * @return given {@link DartStatement} if not {@link DartBlock}, first child {@link DartStatement}
-   *         if {@link DartBlock}, or <code>null</code> if more than one child.
-   */
-  public static DartStatement getSingleStatement(DartStatement statement) {
-    if (statement instanceof DartBlock) {
-      List<DartStatement> blockStatements = ((DartBlock) statement).getStatements();
-      if (blockStatements.size() != 1) {
-        return null;
-      }
-      return blockStatements.get(0);
-    }
-    return statement;
-  }
-
-  /**
-   * @return given {@link DartStatement} if not {@link DartBlock}, all children
-   *         {@link DartStatement}s if {@link DartBlock}.
-   */
-  public static List<DartStatement> getStatements(DartStatement statement) {
-    if (statement instanceof DartBlock) {
-      return ((DartBlock) statement).getStatements();
-    }
-    return ImmutableList.of(statement);
-  }
-
-  /**
-   * @return the {@link DartThisExpression} if given node is name of {@link DartPropertyAccess} with
-   *         {@link DartThisExpression} qualifier. May be <code>null</code>.
-   */
-  public static DartThisExpression getThisQualifier(DartIdentifier node) {
-    if (node.getParent() instanceof DartPropertyAccess) {
-      DartPropertyAccess propertyAccess = (DartPropertyAccess) node.getParent();
-      if (propertyAccess.getName() == node
-          && propertyAccess.getQualifier() instanceof DartThisExpression) {
-        return (DartThisExpression) propertyAccess.getQualifier();
-      }
-    }
-    return null;
-  }
-
-  /**
-   * Return the type associated with the given type node, or <code>null</code> if the type could not
-   * be determined.
-   * 
-   * @param typeNode the type node whose type is to be returned
-   * @return the type associated with the given type node
-   */
-  public static Type getType(DartTypeNode typeNode) {
-    Type type = typeNode.getType();
-    if (type == null) {
-      DartNode parent = typeNode.getParent();
-      if (parent instanceof DartTypeNode) {
-        Type parentType = getType((DartTypeNode) parent);
-        if (parentType != null && parentType.getKind() == TypeKind.INTERFACE) {
-          int index = ((DartTypeNode) parent).getTypeArguments().indexOf(typeNode);
-          return ((InterfaceType) parentType).getArguments().get(index);
-        }
-      }
-    }
-    return type;
-  }
-
-  /**
-   * @return the {@link VariableElement} with {@link ElementKind#VARIABLE} if the given
-   *         {@link DartIdentifier} is the local variable reference, or <code>null</code> in the
-   *         other case.
-   */
-  public static VariableElement getVariableElement(DartIdentifier node) {
-    Element element = node.getElement();
-    if (ElementKind.of(element) == ElementKind.VARIABLE) {
-      return (VariableElement) element;
-    }
-    return null;
-  }
-
-  /**
-   * @return the {@link VariableElement} with {@link ElementKind#VARIABLE} or
-   *         {@link ElementKind#PARAMETER} if the given {@link DartIdentifier} is the reference to
-   *         local variable or parameter, or <code>null</code> in the other case.
-   */
-  public static VariableElement getVariableOrParameterElement(DartIdentifier node) {
-    Element element = node.getElement();
-    if (element instanceof VariableElement) {
-      return (VariableElement) element;
-    }
-    return null;
-  }
-
-  /**
-   * Return <code>true</code> if the given method is a constructor.
-   * 
-   * @param method the method being tested
-   * @return <code>true</code> if the given method is a constructor
-   */
-  public static boolean isConstructor(DartMethodDefinition method) {
-    MethodElement methodElement = method.getElement();
-    if (methodElement != null) {
-      return methodElement.isConstructor();
-    }
-    return isConstructor(((DartClass) method.getParent()).getClassName(), method);
-  }
-
-  /**
-   * Return <code>true</code> if the given method is a constructor.
-   * 
-   * @param className the name of the type containing the method definition
-   * @param method the method being tested
-   * @return <code>true</code> if the given method is a constructor
-   */
-  public static boolean isConstructor(String className, DartMethodDefinition method) {
-    if (method.getModifiers().isFactory()) {
-      return true;
-    }
-    DartExpression name = method.getName();
-    if (name instanceof DartIdentifier) {
-      return ((DartIdentifier) name).getName().equals(className);
-    } else if (name instanceof DartPropertyAccess) {
-      DartPropertyAccess property = (DartPropertyAccess) name;
-      DartNode qualifier = property.getQualifier();
-      if (qualifier instanceof DartIdentifier) {
-        return ((DartIdentifier) qualifier).getName().equals(className);
-      }
-    }
-    return false;
-  }
-
-  /**
-   * @return <code>true</code> if given {@link DartNode} is the name of some {@link DartDeclaration}
-   *         .
-   */
-  public static boolean isNameOfDeclaration(DartNode node) {
-    return node.getParent() instanceof DartDeclaration<?>
-        && ((DartDeclaration<?>) node.getParent()).getName() == node;
-  }
-
-  /**
-   * @return <code>true</code> if given {@link List}s are equals at given position.
-   */
-  private static <T> boolean allListsEqual(List<List<T>> lists, int position) {
-    T element = lists.get(0).get(position);
-    for (List<T> list : lists) {
-      if (list.get(position) != element) {
-        return false;
-      }
-    }
-    return true;
-  }
-
-  private static <T> List<T> getLongestListPrefix(List<List<T>> lists) {
-    if (lists.isEmpty()) {
-      return ImmutableList.of();
-    }
-    // prepare minimal length of all arrays
-    int minLength = lists.get(0).size();
-    for (List<T> list : lists) {
-      minLength = Math.min(minLength, list.size());
-    }
-    // find length of the common prefix
-    int length = -1;
-    for (int i = 0; i < minLength; i++) {
-      if (!allListsEqual(lists, i)) {
-        break;
-      }
-      length++;
-    }
-    // done
-    return lists.get(0).subList(0, length + 1);
-  }
-
-//  /**
-//   * Returns the closest ancestor of <code>node</code> whose type is <code>nodeType</code>, or
-//   * <code>null</code> if none.
-//   * <p>
-//   * <b>Warning:</b> This method does not stop at any boundaries like parentheses, statements, body
-//   * declarations, etc. The resulting node may be in a totally different scope than the given node.
-//   * Consider using one of the {@link ASTResolving}<code>.find(..)</code> methods instead.
-//   * </p>
-//   * 
-//   * @param node the node
-//   * @param nodeType the node type constant from {@link DartNode}
-//   * @return the closest ancestor of <code>node</code> whose type is <code>nodeType</code>, or
-//   *         <code>null</code> if none
-//   */
-//  public static DartNode getParent(DartNode node, int nodeType) {
-//    do {
-//      node = node.getParent();
-//    } while (node != null && node.getNodeType() != nodeType);
-//    return node;
-//  }
-//
-//  public static IProblem[] getProblems(DartNode node, int scope, int severity) {
-//    DartNode root = node.getRoot();
-//    if (!(root instanceof CompilationUnit)) {
-//      return EMPTY_PROBLEMS;
-//    }
-//    IProblem[] problems = ((CompilationUnit) root).getProblems();
-//    if (root == node) {
-//      return problems;
-//    }
-//    final int iterations = computeIterations(scope);
-//    List<IProblem> result = new ArrayList<IProblem>(5);
-//    for (int i = 0; i < problems.length; i++) {
-//      IProblem problem = problems[i];
-//      boolean consider = false;
-//      if ((severity & PROBLEMS) == PROBLEMS) {
-//        consider = true;
-//      } else if ((severity & WARNING) != 0) {
-//        consider = problem.isWarning();
-//      } else if ((severity & ERROR) != 0) {
-//        consider = problem.isError();
-//      }
-//      if (consider) {
-//        DartNode temp = node;
-//        int count = iterations;
-//        do {
-//          int nodeOffset = temp.getStartPosition();
-//          int problemOffset = problem.getSourceStart();
-//          if (nodeOffset <= problemOffset && problemOffset < nodeOffset + temp.getLength()) {
-//            result.add(problem);
-//            count = 0;
-//          } else {
-//            count--;
-//          }
-//        } while ((temp = temp.getParent()) != null && count > 0);
-//      }
-//    }
-//    return result.toArray(new IProblem[result.size()]);
-//  }
-//
-//  public static String getQualifier(Name name) {
-//    if (name.isQualifiedName()) {
-//      return ((QualifiedName) name).getQualifier().getFullyQualifiedName();
-//    }
-//    return ""; //$NON-NLS-1$
-//  }
-//
-//  /**
-//   * Returns the receiver's type binding of the given method invocation.
-//   * 
-//   * @param invocation method invocation to resolve type of
-//   * @return the type binding of the receiver
-//   */
-//  public static ITypeBinding getReceiverTypeBinding(MethodInvocation invocation) {
-//    ITypeBinding result = null;
-//    Expression exp = invocation.getExpression();
-//    if (exp != null) {
-//      return exp.resolveTypeBinding();
-//    } else {
-//      AbstractTypeDeclaration type =
-//          (AbstractTypeDeclaration) getParent(invocation, AbstractTypeDeclaration.class);
-//      if (type != null) {
-//        return type.resolveBinding();
-//      }
-//    }
-//    return result;
-//  }
-//
-//  public static String getSimpleNameIdentifier(Name name) {
-//    if (name.isQualifiedName()) {
-//      return ((QualifiedName) name).getName().getIdentifier();
-//    } else {
-//      return ((SimpleName) name).getIdentifier();
-//    }
-//  }
-//
-//  public static Name getTopMostName(Name name) {
-//    Name result = name;
-//    while (result.getParent() instanceof Name) {
-//      result = (Name) result.getParent();
-//    }
-//    return result;
-//  }
-//
-//  public static Type getTopMostType(Type type) {
-//    Type result = type;
-//    while (result.getParent() instanceof Type) {
-//      result = (Type) result.getParent();
-//    }
-//    return result;
-//  }
-//
-//  /**
-//   * Returns the type node for the given declaration.
-//   * 
-//   * @param declaration the declaration
-//   * @return the type node
-//   */
-//  public static Type getType(VariableDeclaration declaration) {
-//    if (declaration instanceof SingleVariableDeclaration) {
-//      return ((SingleVariableDeclaration) declaration).getType();
-//    } else if (declaration instanceof VariableDeclarationFragment) {
-//      DartNode parent = ((VariableDeclarationFragment) declaration).getParent();
-//      if (parent instanceof VariableDeclarationExpression) {
-//        return ((VariableDeclarationExpression) parent).getType();
-//      } else if (parent instanceof VariableDeclarationStatement) {
-//        return ((VariableDeclarationStatement) parent).getType();
-//      } else if (parent instanceof FieldDeclaration) {
-//        return ((FieldDeclaration) parent).getType();
-//      }
-//    }
-//    Assert.isTrue(false, "Unknown VariableDeclaration"); //$NON-NLS-1$
-//    return null;
-//  }
-//
-//  public static ITypeBinding getTypeBinding(CompilationUnit root, IType type)
-//      throws JavaModelException {
-//    if (type.isAnonymous()) {
-//      final IJavaElement parent = type.getParent();
-//      if (parent instanceof IField && Flags.isEnum(((IMember) parent).getFlags())) {
-//        final EnumConstantDeclaration constant =
-//            (EnumConstantDeclaration) NodeFinder.perform(
-//                root,
-//                ((ISourceReference) parent).getSourceRange());
-//        if (constant != null) {
-//          final AnonymousClassDeclaration declaration = constant.getAnonymousClassDeclaration();
-//          if (declaration != null) {
-//            return declaration.resolveBinding();
-//          }
-//        }
-//      } else {
-//        final ClassInstanceCreation creation =
-//            (ClassInstanceCreation) getParent(
-//                NodeFinder.perform(root, type.getNameRange()),
-//                ClassInstanceCreation.class);
-//        if (creation != null) {
-//          return creation.resolveTypeBinding();
-//        }
-//      }
-//    } else {
-//      final AbstractTypeDeclaration declaration =
-//          (AbstractTypeDeclaration) getParent(
-//              NodeFinder.perform(root, type.getNameRange()),
-//              AbstractTypeDeclaration.class);
-//      if (declaration != null) {
-//        return declaration.resolveBinding();
-//      }
-//    }
-//    return null;
-//  }
-//
-//  public static ITypeBinding getTypeBinding(Name node) {
-//    IBinding binding = node.resolveBinding();
-//    if (binding instanceof ITypeBinding) {
-//      return (ITypeBinding) binding;
-//    }
-//    return null;
-//  }
-//
-//  public static String getTypeName(Type type) {
-//    final StringBuffer buffer = new StringBuffer();
-//    ASTVisitor visitor = new ASTVisitor() {
-//      @Override
-//      public void endVisit(ArrayType node) {
-//        buffer.append("[]"); //$NON-NLS-1$
-//      }
-//
-//      @Override
-//      public boolean visit(PrimitiveType node) {
-//        buffer.append(node.getPrimitiveTypeCode().toString());
-//        return false;
-//      }
-//
-//      @Override
-//      public boolean visit(QualifiedName node) {
-//        buffer.append(node.getName().getIdentifier());
-//        return false;
-//      }
-//
-//      @Override
-//      public boolean visit(SimpleName node) {
-//        buffer.append(node.getIdentifier());
-//        return false;
-//      }
-//    };
-//    type.accept(visitor);
-//    return buffer.toString();
-//  }
-//
-//  public static IVariableBinding getVariableBinding(Name node) {
-//    IBinding binding = node.resolveBinding();
-//    if (binding instanceof IVariableBinding) {
-//      return (IVariableBinding) binding;
-//    }
-//    return null;
-//  }
-//
-//  /**
-//   * Returns true if a node at a given location is a body of a control statement. Such body nodes
-//   * are interesting as when replacing them, it has to be evaluates if a Block is needed instead.
-//   * E.g. <code> if (x) do(); -> if (x) { do1(); do2() } </code>
-//   * 
-//   * @param locationInParent Location of the body node
-//   * @return Returns true if the location is a body node location of a control statement.
-//   */
-//  public static boolean isControlStatementBody(StructuralPropertyDescriptor locationInParent) {
-//    return locationInParent == IfStatement.THEN_STATEMENT_PROPERTY
-//        || locationInParent == IfStatement.ELSE_STATEMENT_PROPERTY
-//        || locationInParent == ForStatement.BODY_PROPERTY
-//        || locationInParent == EnhancedForStatement.BODY_PROPERTY
-//        || locationInParent == WhileStatement.BODY_PROPERTY
-//        || locationInParent == DoStatement.BODY_PROPERTY;
-//  }
-//
-//  public static boolean isDeclaration(Name name) {
-//    if (name.isQualifiedName()) {
-//      return ((QualifiedName) name).getName().isDeclaration();
-//    } else {
-//      return ((SimpleName) name).isDeclaration();
-//    }
-//  }
-//
-//  /**
-//   * Returns true if this is an existing node, i.e. it was created as part of a parsing process of a
-//   * source code file. Returns false if this is a newly created node which has not yet been given a
-//   * source position.
-//   * 
-//   * @param node the node to be tested.
-//   * @return true if this is an existing node, false if not.
-//   */
-//  public static boolean isExistingNode(DartNode node) {
-//    return node.getStartPosition() != -1;
-//  }
-//
-//  public static boolean isLabel(SimpleName name) {
-//    int parentType = name.getParent().getNodeType();
-//    return parentType == DartNode.LABELED_STATEMENT
-//        || parentType == DartNode.BREAK_STATEMENT
-//        || parentType != DartNode.CONTINUE_STATEMENT;
-//  }
-//
-//  public static boolean isLiteral(Expression expression) {
-//    int type = expression.getNodeType();
-//    return type == DartNode.BOOLEAN_LITERAL
-//        || type == DartNode.CHARACTER_LITERAL
-//        || type == DartNode.NULL_LITERAL
-//        || type == DartNode.NUMBER_LITERAL
-//        || type == DartNode.STRING_LITERAL
-//        || type == DartNode.TYPE_LITERAL;
-//  }
-//
-//  /**
-//   * Returns <code>true</code> iff <code>parent</code> is a true ancestor of <code>node</code> (i.e.
-//   * returns <code>false</code> if <code>parent == node</code>).
-//   * 
-//   * @param node node to test
-//   * @param parent assumed parent
-//   * @return <code>true</code> iff <code>parent</code> is a true ancestor of <code>node</code>
-//   */
-//  public static boolean isParent(DartNode node, DartNode parent) {
-//    Assert.isNotNull(parent);
-//    do {
-//      node = node.getParent();
-//      if (node == parent) {
-//        return true;
-//      }
-//    } while (node != null);
-//    return false;
-//  }
-//
-//  public static boolean isSingleDeclaration(VariableDeclaration declaration) {
-//    Assert.isNotNull(declaration);
-//    if (declaration instanceof SingleVariableDeclaration) {
-//      return true;
-//    } else if (declaration instanceof VariableDeclarationFragment) {
-//      DartNode parent = declaration.getParent();
-//      if (parent instanceof VariableDeclarationExpression) {
-//        return ((VariableDeclarationExpression) parent).fragments().size() == 1;
-//      } else if (parent instanceof VariableDeclarationStatement) {
-//        return ((VariableDeclarationStatement) parent).fragments().size() == 1;
-//      }
-//    }
-//    return false;
-//  }
-//
-//  public static boolean isStatic(BodyDeclaration declaration) {
-//    return Modifier.isStatic(declaration.getModifiers());
-//  }
-//
-//  /**
-//   * Adds flags to the given node and all its descendants.
-//   * 
-//   * @param root The root node
-//   * @param flags The flags to set
-//   */
-//  public static void setFlagsToAST(DartNode root, final int flags) {
-//    root.accept(new GenericVisitor(true) {
-//      @Override
-//      protected boolean visitNode(DartNode node) {
-//        node.setFlags(node.getFlags() | flags);
-//        return true;
-//      }
-//    });
-//  }
-//
-//  private static int computeIterations(int flags) {
-//    switch (flags) {
-//      case NODE_ONLY:
-//        return 1;
-//      case INCLUDE_ALL_PARENTS:
-//        return Integer.MAX_VALUE;
-//      case INCLUDE_FIRST_PARENT:
-//        return 2;
-//      default:
-//        return 1;
-//    }
-//  }
-//
-//  private static int getOrderPreference(BodyDeclaration member, MembersOrderPreferenceCache store) {
-//    int memberType = member.getNodeType();
-//    int modifiers = member.getModifiers();
-//
-//    switch (memberType) {
-//      case DartNode.TYPE_DECLARATION:
-//      case DartNode.ENUM_DECLARATION:
-//      case DartNode.ANNOTATION_TYPE_DECLARATION:
-//        return store.getCategoryIndex(MembersOrderPreferenceCache.TYPE_INDEX) * 2;
-//      case DartNode.FIELD_DECLARATION:
-//        if (Modifier.isStatic(modifiers)) {
-//          int index = store.getCategoryIndex(MembersOrderPreferenceCache.STATIC_FIELDS_INDEX) * 2;
-//          if (Modifier.isFinal(modifiers)) {
-//            return index; // first final static, then static
-//          }
-//          return index + 1;
-//        }
-//        return store.getCategoryIndex(MembersOrderPreferenceCache.FIELDS_INDEX) * 2;
-//      case DartNode.INITIALIZER:
-//        if (Modifier.isStatic(modifiers)) {
-//          return store.getCategoryIndex(MembersOrderPreferenceCache.STATIC_INIT_INDEX) * 2;
-//        }
-//        return store.getCategoryIndex(MembersOrderPreferenceCache.INIT_INDEX) * 2;
-//      case DartNode.ANNOTATION_TYPE_MEMBER_DECLARATION:
-//        return store.getCategoryIndex(MembersOrderPreferenceCache.METHOD_INDEX) * 2;
-//      case DartNode.METHOD_DECLARATION:
-//        if (Modifier.isStatic(modifiers)) {
-//          return store.getCategoryIndex(MembersOrderPreferenceCache.STATIC_METHODS_INDEX) * 2;
-//        }
-//        if (((MethodDeclaration) member).isConstructor()) {
-//          return store.getCategoryIndex(MembersOrderPreferenceCache.CONSTRUCTORS_INDEX) * 2;
-//        }
-//        return store.getCategoryIndex(MembersOrderPreferenceCache.METHOD_INDEX) * 2;
-//      default:
-//        return 100;
-//    }
-//  }
-//
-//  /**
-//   * Returns whether an expression at the given location needs explicit boxing.
-//   * 
-//   * @param expression the expression
-//   * @return <code>true</code> iff an expression at the given location needs explicit boxing
-//   */
-//  private static boolean needsExplicitBoxing(Expression expression) {
-//    StructuralPropertyDescriptor locationInParent = expression.getLocationInParent();
-//    if (locationInParent == ParenthesizedExpression.EXPRESSION_PROPERTY) {
-//      return needsExplicitBoxing((ParenthesizedExpression) expression.getParent());
-//    }
-//
-//    if (locationInParent == ClassInstanceCreation.EXPRESSION_PROPERTY
-//        || locationInParent == FieldAccess.EXPRESSION_PROPERTY
-//        || locationInParent == MethodInvocation.EXPRESSION_PROPERTY) {
-//      return true;
-//    }
-//
-//    return false;
-//  }
-
-  private ASTNodes() {
-    // no instance;
-  }
-
-  /**
-   * Looks to see if the property access requires a getter.
-   * <p>
-   * A property access requires a getter if it is on the right hand side of an assignment, or if it
-   * is on the left hand side of an assignment and uses one of the assignment operators other than
-   * plain '='.
-   * <p>
-   * Note, that we don't check if given {@link DartNode} is actually field name.
-   */
-  public static boolean inGetterContext(DartNode node) {
-    if (node.getParent() instanceof DartBinaryExpression) {
-      DartBinaryExpression expr = (DartBinaryExpression) node.getParent();
-      if (expr.getArg1() == node && expr.getOperator() == Token.ASSIGN) {
-        return false;
-      }
-    }
-    return true;
-  }
-
-  /**
-   * Looks to see if the property access requires a setter.
-   * <p>
-   * Basically, this boils down to any property access on the left hand side of an assignment.
-   * <p>
-   * Keep in mind that an assignment of the form node = <expr> is the only kind of write-only
-   * expression. Other types of assignments also read the value and require a getter access.
-   * <p>
-   * Note, that we don't check if given {@link DartNode} is actually field name.
-   */
-  public static boolean inSetterContext(DartNode node) {
-    if (node.getParent() instanceof DartUnaryExpression) {
-      DartUnaryExpression expr = (DartUnaryExpression) node.getParent();
-      return expr.getArg() == node && expr.getOperator().isCountOperator();
-    }
-    if (node.getParent() instanceof DartBinaryExpression) {
-      DartBinaryExpression expr = (DartBinaryExpression) node.getParent();
-      return expr.getArg1() == node && expr.getOperator().isAssignmentOperator();
-    }
-    return false;
-  }
-
-  /**
-   * @return the {@link DartIdentifier} corresponding to the name of constructor.
-   */
-  public static DartIdentifier getConstructorNameNode(DartNewExpression node) {
-    DartNode constructor = node.getConstructor();
-    return getConstructorNameNode(constructor);
-  }
-
-  /**
-   * @return the {@link DartIdentifier} corresponding to the name of constructor.
-   */
-  private static DartIdentifier getConstructorNameNode(DartNode constructor) {
-    if (constructor instanceof DartPropertyAccess) {
-      return ((DartPropertyAccess) constructor).getName();
-    } else if (constructor instanceof DartTypeNode) {
-      return getConstructorNameNode(((DartTypeNode) constructor).getIdentifier());
-    } else {
-      return (DartIdentifier) constructor;
-    }
-  }
-  
-  /**
-   * @return <code>true</code> if given {@link DartNode} has {@link DartSuperExpression}.
-   */
-  public static boolean hasSuperInvocation(DartNode node) {
-    final AtomicBoolean result = new AtomicBoolean();
-    node.accept(new ASTVisitor<Void>() {
-      @Override
-      public Void visitSuperExpression(DartSuperExpression node) {
-        result.set(true);
-        return null;
-      }
-    });
-    return result.get();
-  }
-
-}
diff --git a/compiler/java/com/google/dart/compiler/ast/ASTVisitor.java b/compiler/java/com/google/dart/compiler/ast/ASTVisitor.java
deleted file mode 100644
index 6223fa0c..0000000
--- a/compiler/java/com/google/dart/compiler/ast/ASTVisitor.java
+++ /dev/null
@@ -1,411 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.ast;
-
-import java.util.List;
-
-/**
- * A visitor for abstract syntax tree.
- *
- * <pre>
- *
- * public R visitArrayAccess(DartArrayAccess node) {
- *   // Actions before visiting subnodes.
- *   node.visitChildren(this);
- *   // Actions after visiting subnodes.
- *   return node;
- * }
- * </pre>
- *
- * <p>
- * In addition, this visitor takes advantage of the AST-node class hierarchy and makes it easy to
- * perform an action for, for example, all statements:
- *
- * <pre>
- *
- * public R visitStatement(DartStatement node) {
- *   // Action that must be performed for all statements.
- * }
- * </pre>
- */
-public class ASTVisitor<R> {
-
-  public R visitNode(DartNode node) {
-    node.visitChildren(this);
-    return null;
-  }
-
-  public R visitNodeWithMetadata(DartNodeWithMetadata node) {
-    return visitNode(node);
-  }
-  
-  public R visitDirective(DartDirective node) {
-    return visitNodeWithMetadata(node);
-  }
-
-  public R visitInvocation(DartInvocation node) {
-    return visitExpression(node);
-  }
-
-  public R visitExportDirective(DartExportDirective node) {
-    return visitDirective(node);
-  }
-
-  public R visitExpression(DartExpression node) {
-    return visitNode(node);
-  }
-
-  public R visitStatement(DartStatement node) {
-    return visitNode(node);
-  }
-
-  public R visitLiteral(DartLiteral node) {
-    return visitExpression(node);
-  }
-
-  public R visitGotoStatement(DartGotoStatement node) {
-    return visitStatement(node);
-  }
-
-  public R visitSwitchMember(DartSwitchMember node) {
-    return visitNode(node);
-  }
-
-  public R visitDeclaration(DartDeclaration<?> node) {
-    return visitNodeWithMetadata(node);
-  }
-
-  public R visitClassMember(DartClassMember<?> node) {
-    return visitDeclaration(node);
-  }
-
-  public R visitComment(DartComment node) {
-    return visitNode(node);
-  }
-  
-  public R visitCommentNewName(DartCommentNewName node) {
-    return visitNode(node);
-  }
-  
-  public R visitCommentRefName(DartCommentRefName node) {
-    return visitNode(node);
-  }
-
-  public R visitAnnotation(DartAnnotation node) {
-    return visitNode(node);
-  }
-
-  public R visitArrayAccess(DartArrayAccess node) {
-    return visitExpression(node);
-  }
-
-  public R visitArrayLiteral(DartArrayLiteral node) {
-    return visitTypedLiteral(node);
-  }
-
-  public R visitBinaryExpression(DartBinaryExpression node) {
-    return visitExpression(node);
-  }
-
-  public R visitBlock(DartBlock node) {
-    return visitStatement(node);
-  }
-  
-  public R visitReturnBlock(DartReturnBlock node) {
-    return visitBlock(node);
-  }
-
-  public R visitBooleanLiteral(DartBooleanLiteral node) {
-    return visitLiteral(node);
-  }
-
-  public R visitAssertStatement(DartAssertStatement node) {
-    return visitStatement(node);
-  }
-  
-  public R visitBreakStatement(DartBreakStatement node) {
-    return visitGotoStatement(node);
-  }
-
-  public R visitFunctionObjectInvocation(DartFunctionObjectInvocation node) {
-    return visitInvocation(node);
-  }
-
-  public R visitMethodInvocation(DartMethodInvocation node) {
-    return visitInvocation(node);
-  }
-
-  public R visitUnqualifiedInvocation(DartUnqualifiedInvocation node) {
-    return visitInvocation(node);
-  }
-
-  public R visitSuperConstructorInvocation(DartSuperConstructorInvocation node) {
-    return visitInvocation(node);
-  }
-
-  public R visitCascadeExpression(DartCascadeExpression node) {
-    return visitExpression(node);
-  }
-
-  public R visitCase(DartCase node) {
-    return visitSwitchMember(node);
-  }
-
-  public R visitClass(DartClass node) {
-    return visitDeclaration(node);
-  }
-
-  public R visitConditional(DartConditional node) {
-    return visitExpression(node);
-  }
-
-  public R visitContinueStatement(DartContinueStatement node) {
-    return visitGotoStatement(node);
-  }
-
-  public R visitDefault(DartDefault node) {
-    return visitSwitchMember(node);
-  }
-
-  public R visitDoubleLiteral(DartDoubleLiteral node) {
-    return visitLiteral(node);
-  }
-
-  public R visitDoWhileStatement(DartDoWhileStatement node) {
-    return visitStatement(node);
-  }
-
-  public R visitEmptyStatement(DartEmptyStatement node) {
-    return visitStatement(node);
-  }
-
-  public R visitExprStmt(DartExprStmt node) {
-    return visitStatement(node);
-  }
-
-  public R visitField(DartField node) {
-    return visitClassMember(node);
-  }
-
-  public R visitFieldDefinition(DartFieldDefinition node) {
-    return visitNodeWithMetadata(node);
-  }
-
-  public R visitForInStatement(DartForInStatement node) {
-    return visitStatement(node);
-  }
-
-  public R visitForStatement(DartForStatement node) {
-    return visitStatement(node);
-  }
-
-  public R visitFunction(DartFunction node) {
-    return visitNode(node);
-  }
-
-  public R visitFunctionExpression(DartFunctionExpression node) {
-    return visitExpression(node);
-  }
-
-  public R visitFunctionTypeAlias(DartFunctionTypeAlias node) {
-    return visitDeclaration(node);
-  }
-  
-  public R visitClassTypeAlias(DartClassTypeAlias node) {
-    return visitDeclaration(node);
-  }
-
-  public R visitIdentifier(DartIdentifier node) {
-    return visitExpression(node);
-  }
-
-  public R visitIfStatement(DartIfStatement node) {
-    return visitStatement(node);
-  }
-
-  public R visitImportCombinator(ImportCombinator node) {
-    return visitNode(node);
-  } 
-
-  public R visitImportDirective(DartImportDirective node) {
-    return visitDirective(node);
-  }
-
-  public R visitImportHideCombinator(ImportHideCombinator node) {
-    return visitImportCombinator(node);
-  } 
-
-  public R visitImportShowCombinator(ImportShowCombinator node) {
-    return visitImportCombinator(node);
-  } 
-
-  public R visitInitializer(DartInitializer node) {
-    return visitNode(node);
-  }
-
-  public R visitIntegerLiteral(DartIntegerLiteral node) {
-    return visitLiteral(node);
-  }
-
-  public R visitLabel(DartLabel node) {
-    return visitStatement(node);
-  }
-
-  public R visitLibraryDirective(DartLibraryDirective node) {
-    return visitDirective(node);
-  }
-
-  public R visitTypedLiteral(DartTypedLiteral node) {
-    return visitExpression(node);
-  }
-  
-  public R visitMapLiteral(DartMapLiteral node) {
-    return visitTypedLiteral(node);
-  }
-
-  public R visitMapLiteralEntry(DartMapLiteralEntry node) {
-    return visitNode(node);
-  }
-
-  public R visitMethodDefinition(DartMethodDefinition node) {
-    return visitClassMember(node);
-  }
-
-  public R visitNativeDirective(DartNativeDirective node) {
-    return visitDirective(node);
-  }
-
-  public R visitNewExpression(DartNewExpression node) {
-    return visitInvocation(node);
-  }
-
-  public R visitNullLiteral(DartNullLiteral node) {
-    return visitLiteral(node);
-  }
-
-  public R visitParameter(DartParameter node) {
-    return visitDeclaration(node);
-  }
-
-  public R visitParameterizedTypeNode(DartParameterizedTypeNode node) {
-    return visitExpression(node);
-  }
-
-  public R visitParenthesizedExpression(DartParenthesizedExpression node) {
-    return visitExpression(node);
-  }
-
-  public R visitPartOfDirective(DartPartOfDirective node) {
-    return visitDirective(node);
-  }
-
-  public R visitPropertyAccess(DartPropertyAccess node) {
-    return visitExpression(node);
-  }
-
-  public R visitTypeNode(DartTypeNode node) {
-    return visitNode(node);
-  }
-
-  public R visitReturnStatement(DartReturnStatement node) {
-    return visitStatement(node);
-  }
-
-  public R visitSourceDirective(DartSourceDirective node) {
-    return visitDirective(node);
-  }
-
-  public R visitStringLiteral(DartStringLiteral node) {
-    return visitLiteral(node);
-  }
-
-  public R visitStringInterpolation(DartStringInterpolation node) {
-    return visitLiteral(node);
-  }
-
-  public R visitSuperExpression(DartSuperExpression node) {
-    return visitExpression(node);
-  }
-
-  public R visitSwitchStatement(DartSwitchStatement node) {
-    return visitStatement(node);
-  }
-
-  public R visitSyntheticErrorExpression(DartSyntheticErrorExpression node) {
-    return visitExpression(node);
-  }
-
-  public R visitSyntheticErrorIdentifier(DartSyntheticErrorIdentifier node) {
-    return visitIdentifier(node);
-  }
-
-  public R visitSyntheticErrorStatement(DartSyntheticErrorStatement node) {
-    return visitStatement(node);
-  }
-
-  public R visitThisExpression(DartThisExpression node) {
-    return visitExpression(node);
-  }
-
-  public R visitThrowExpression(DartThrowExpression node) {
-    return visitExpression(node);
-  }
-
-  public R visitCatchBlock(DartCatchBlock node) {
-    return visitStatement(node);
-  }
-
-  public R visitTryStatement(DartTryStatement node) {
-    return visitStatement(node);
-  }
-
-  public R visitUnaryExpression(DartUnaryExpression node) {
-    return visitExpression(node);
-  }
-
-  public R visitUnit(DartUnit node) {
-    return visitNode(node);
-  }
-
-  public R visitVariable(DartVariable node) {
-    return visitDeclaration(node);
-  }
-
-  public R visitVariableStatement(DartVariableStatement node) {
-    return visitStatement(node);
-  }
-
-  public R visitWhileStatement(DartWhileStatement node) {
-    return visitStatement(node);
-  }
-
-  public void visit(List<? extends DartNode> nodes) {
-    if (nodes != null) {
-      for (DartNode node : nodes) {
-        node.accept(this);
-      }
-    }
-  }
-
-  public R visitNamedExpression(DartNamedExpression node) {
-    return visitExpression(node);
-  }
-
-  public R visitTypeExpression(DartTypeExpression node) {
-    return visitExpression(node);
-  }
-
-  public R visitTypeParameter(DartTypeParameter node) {
-    return visitDeclaration(node);
-  }
-
-  public R visitNativeBlock(DartNativeBlock node) {
-    return visitBlock(node);
-  }
-
-  public R visitRedirectConstructorInvocation(DartRedirectConstructorInvocation node) {
-    return visitInvocation(node);
-  }
-}
diff --git a/compiler/java/com/google/dart/compiler/ast/DartAnnotation.java b/compiler/java/com/google/dart/compiler/ast/DartAnnotation.java
deleted file mode 100644
index ab44015..0000000
--- a/compiler/java/com/google/dart/compiler/ast/DartAnnotation.java
+++ /dev/null
@@ -1,52 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.ast;
-
-import java.util.List;
-
-
-/**
- * Instances of the class {@code DartAnnotation} represent metadata that can be associated with an
- * AST node.
- * 
- * <pre>
- * metadata ::=
- *     annotation*
- * 
- * annotation ::=
- *     '@' qualified ('.' identifier)? arguments?
- * </pre>
- */
-public class DartAnnotation extends DartNode {
-  private DartExpression name;
-
-  private NodeList<DartExpression> arguments = NodeList.create(this);
-
-  public DartAnnotation(DartExpression name, List<DartExpression> arguments) {
-    this.name = becomeParentOf(name);
-    if (arguments != null) {
-      this.arguments.addAll(arguments);
-    }
-  }
-
-  @Override
-  public <R> R accept(ASTVisitor<R> visitor) {
-    return visitor.visitAnnotation(this);
-  }
-
-  public DartExpression getName() {
-    return name;
-  }
-
-  public NodeList<DartExpression> getArguments() {
-    return arguments;
-  }
-
-  @Override
-  public void visitChildren(ASTVisitor<?> visitor) {
-    safelyVisitChild(name, visitor);
-    arguments.accept(visitor);
-  }
-}
diff --git a/compiler/java/com/google/dart/compiler/ast/DartArrayAccess.java b/compiler/java/com/google/dart/compiler/ast/DartArrayAccess.java
deleted file mode 100644
index 959ac36..0000000
--- a/compiler/java/com/google/dart/compiler/ast/DartArrayAccess.java
+++ /dev/null
@@ -1,81 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.ast;
-
-import com.google.dart.compiler.resolver.Element;
-import com.google.dart.compiler.resolver.MethodNodeElement;
-
-/**
- * Represents a Dart array access expression (a[b]).
- */
-public class DartArrayAccess extends DartExpression {
-
-  private DartExpression target;
-  private boolean isCascade;
-  private DartExpression key;
-  private MethodNodeElement element;
-
-  public DartArrayAccess(DartExpression target, DartExpression key) {
-    this(target, false, key);
-  }
-
-  public DartArrayAccess(DartExpression target, boolean isCascade, DartExpression key) {
-    this.target = becomeParentOf(target);
-    this.isCascade = isCascade;
-    this.key = becomeParentOf(key);
-  }
-
-  @Override
-  public boolean isAssignable() {
-    return true;
-  }
-
-  public boolean isCascade() {
-    return isCascade;
-  }
-
-  public DartExpression getKey() {
-    return key;
-  }
-
-  public DartExpression getTarget() {
-    return target;
-  }
-
-  public DartExpression getRealTarget() {
-    if (isCascade) {
-      DartNode ancestor = getParent();
-      while (!(ancestor instanceof DartCascadeExpression)) {
-        if (ancestor == null) {
-          return target;
-        }
-        ancestor = ancestor.getParent();
-      }
-      return ((DartCascadeExpression) ancestor).getTarget();
-    }
-    return target;
-  }
-
-  @Override
-  public void visitChildren(ASTVisitor<?> visitor) {
-    safelyVisitChild(target, visitor);
-    safelyVisitChild(key, visitor);
-  }
-
-  @Override
-  public <R> R accept(ASTVisitor<R> visitor) {
-    return visitor.visitArrayAccess(this);
-  }
-
-  @Override
-  public MethodNodeElement getElement() {
-    return element;
-  }
-
-  @Override
-  public void setElement(Element element) {
-    this.element = (MethodNodeElement) element;
-  }
-}
diff --git a/compiler/java/com/google/dart/compiler/ast/DartArrayLiteral.java b/compiler/java/com/google/dart/compiler/ast/DartArrayLiteral.java
deleted file mode 100644
index 5c9ad5f..0000000
--- a/compiler/java/com/google/dart/compiler/ast/DartArrayLiteral.java
+++ /dev/null
@@ -1,36 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.ast;
-
-import java.util.List;
-
-/**
- * Represents a Dart array literal value.
- */
-public class DartArrayLiteral extends DartTypedLiteral {
-
-  private final NodeList<DartExpression> expressions = NodeList.create(this);
-
-  public DartArrayLiteral(boolean isConst, List<DartTypeNode> typeArguments,
-                          List<DartExpression> expressions) {
-    super(isConst, typeArguments);
-    this.expressions.addAll(expressions);
-  }
-
-  public List<DartExpression> getExpressions() {
-    return expressions;
-  }
-
-  @Override
-  public void visitChildren(ASTVisitor<?> visitor) {
-    super.visitChildren(visitor);
-    expressions.accept(visitor);
-  }
-
-  @Override
-  public <R> R accept(ASTVisitor<R> visitor) {
-    return visitor.visitArrayLiteral(this);
-  }
-}
diff --git a/compiler/java/com/google/dart/compiler/ast/DartAssertStatement.java b/compiler/java/com/google/dart/compiler/ast/DartAssertStatement.java
deleted file mode 100644
index 91572a2..0000000
--- a/compiler/java/com/google/dart/compiler/ast/DartAssertStatement.java
+++ /dev/null
@@ -1,31 +0,0 @@
-// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.ast;
-
-/**
- * Represents a Dart 'assert' statement.
- */
-public class DartAssertStatement extends DartStatement {
-
-  private final DartExpression condition;
-
-  public DartAssertStatement(DartExpression condition) {
-    this.condition = becomeParentOf(condition);
-  }
-
-  public DartExpression getCondition() {
-    return condition;
-  }
-
-  @Override
-  public void visitChildren(ASTVisitor<?> visitor) {
-    safelyVisitChild(condition, visitor);
-  }
-
-  @Override
-  public <R> R accept(ASTVisitor<R> visitor) {
-    return visitor.visitAssertStatement(this);
-  }
-}
diff --git a/compiler/java/com/google/dart/compiler/ast/DartBinaryExpression.java b/compiler/java/com/google/dart/compiler/ast/DartBinaryExpression.java
deleted file mode 100644
index 25017d2..0000000
--- a/compiler/java/com/google/dart/compiler/ast/DartBinaryExpression.java
+++ /dev/null
@@ -1,70 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.ast;
-
-import com.google.dart.compiler.parser.Token;
-import com.google.dart.compiler.resolver.Element;
-import com.google.dart.compiler.resolver.MethodNodeElement;
-
-/**
- * Represents a Dart binary expression.
- */
-public class DartBinaryExpression extends DartExpression {
-
-  private final Token op;
-  private final int opOffset;
-  private DartExpression arg1;
-  private DartExpression arg2;
-  private MethodNodeElement element;
-
-  public DartBinaryExpression(Token op, int opOffset, DartExpression arg1, DartExpression arg2) {
-    this.opOffset = opOffset;
-    assert op.isBinaryOperator() : op;
-
-    this.op = op;
-    this.arg1 = becomeParentOf(arg1 != null ? arg1 : new DartSyntheticErrorExpression());
-    this.arg2 = becomeParentOf(arg2 != null ? arg2 : new DartSyntheticErrorExpression());
-  }
-
-  public DartExpression getArg1() {
-    return arg1;
-  }
-
-  public DartExpression getArg2() {
-    return arg2;
-  }
-
-  public Token getOperator() {
-    return op;
-  }
-  
-  /**
-   * @return the character offset of the {@link #getOperator()} token.
-   */
-  public int getOperatorOffset() {
-    return opOffset;
-  }
-
-  @Override
-  public void visitChildren(ASTVisitor<?> visitor) {
-    safelyVisitChild(arg1, visitor);
-    safelyVisitChild(arg2, visitor);
-  }
-
-  @Override
-  public <R> R accept(ASTVisitor<R> visitor) {
-    return visitor.visitBinaryExpression(this);
-  }
-
-  @Override
-  public MethodNodeElement getElement() {
-    return element;
-  }
-
-  @Override
-  public void setElement(Element element) {
-    this.element = (MethodNodeElement) element;
-  }
-}
diff --git a/compiler/java/com/google/dart/compiler/ast/DartBlock.java b/compiler/java/com/google/dart/compiler/ast/DartBlock.java
deleted file mode 100644
index 27d0d058..0000000
--- a/compiler/java/com/google/dart/compiler/ast/DartBlock.java
+++ /dev/null
@@ -1,45 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.ast;
-
-import java.util.List;
-
-/**
- * Represents a Dart statement block.
- */
-public class DartBlock extends DartStatement {
-
-  private final NodeList<DartStatement> statements = NodeList.create(this);
-
-  public DartBlock(List<DartStatement> statements) {
-    if (statements != null && !statements.isEmpty()) {
-      this.statements.addAll(statements);
-    }
-  }
-
-  public List<DartStatement> getStatements() {
-    return statements;
-  }
-
-  @Override
-  public boolean isAbruptCompletingStatement() {
-    for (DartStatement stmt : statements) {
-      if (stmt.isAbruptCompletingStatement()) {
-        return true;
-      }
-    }
-    return false;
-  }
-
-  @Override
-  public void visitChildren(ASTVisitor<?> visitor) {
-    statements.accept(visitor);
-  }
-
-  @Override
-  public <R> R accept(ASTVisitor<R> visitor) {
-    return visitor.visitBlock(this);
-  }
-}
diff --git a/compiler/java/com/google/dart/compiler/ast/DartBooleanLiteral.java b/compiler/java/com/google/dart/compiler/ast/DartBooleanLiteral.java
deleted file mode 100644
index cdf5160..0000000
--- a/compiler/java/com/google/dart/compiler/ast/DartBooleanLiteral.java
+++ /dev/null
@@ -1,34 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.ast;
-
-/**
- * Represents a Dart boolean literal value.
- */
-public class DartBooleanLiteral extends DartLiteral {
-
-  public static DartBooleanLiteral get(boolean value) {
-    return new DartBooleanLiteral(value);
-  }
-
-  private final boolean value;
-
-  private DartBooleanLiteral(boolean value) {
-    this.value = value;
-  }
-
-  public boolean getValue() {
-    return value;
-  }
-
-  @Override
-  public void visitChildren(ASTVisitor<?> visitor) {
-  }
-
-  @Override
-  public <R> R accept(ASTVisitor<R> visitor) {
-    return visitor.visitBooleanLiteral(this);
-  }
-}
diff --git a/compiler/java/com/google/dart/compiler/ast/DartBreakStatement.java b/compiler/java/com/google/dart/compiler/ast/DartBreakStatement.java
deleted file mode 100644
index 7d51c33..0000000
--- a/compiler/java/com/google/dart/compiler/ast/DartBreakStatement.java
+++ /dev/null
@@ -1,25 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.ast;
-
-/**
- * Represents a Dart 'break' statement.
- */
-public class DartBreakStatement extends DartGotoStatement {
-
-  public DartBreakStatement(DartIdentifier label) {
-    super(label);
-  }
-
-  @Override
-  public boolean isAbruptCompletingStatement() {
-    return true;
-  }
-
-  @Override
-  public <R> R accept(ASTVisitor<R> visitor) {
-    return visitor.visitBreakStatement(this);
-  }
-}
diff --git a/compiler/java/com/google/dart/compiler/ast/DartCascadeExpression.java b/compiler/java/com/google/dart/compiler/ast/DartCascadeExpression.java
deleted file mode 100644
index 6c9b2b8..0000000
--- a/compiler/java/com/google/dart/compiler/ast/DartCascadeExpression.java
+++ /dev/null
@@ -1,85 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.ast;
-
-import java.util.List;
-
-/**
- * Instances of the class {@code DartCascadeExpression} represent a sequence of cascaded expressions:
- * expressions that share a common target. There are three kinds of expressions that can be used in
- * a cascade expression: {@link DartArrayAccess}, {@link DartMethodInvocation} and {@link DartPropertyAccess}.
- * 
- * <pre>
- * cascadeExpression ::=
- *     {@link DartExpression conditionalExpression} cascadeSection*
- * 
- * cascadeSection ::=
- *     '..'  (cascadeSelector arguments*) (assignableSelector arguments*)* (assignmentOperator expressionWithoutCascade)?
- * 
- * cascadeSelector ::=
- *     '[ ' expression '] '
- *   | identifier
- * </pre>
- */
-public class DartCascadeExpression extends DartExpression {
-  /**
-   * The target of the cascade sections.
-   */
-  private DartExpression target;
-
-  /**
-   * The cascade sections sharing the common target.
-   */
-  private NodeList<DartExpression> cascadeSections = new NodeList<DartExpression>(this);
-
-  /**
-   * Initialize a newly created cascade expression.
-   * 
-   * @param target the target of the cascade sections
-   * @param cascadeSections the cascade sections sharing the common target
-   */
-  public DartCascadeExpression(DartExpression target, List<DartExpression> cascadeSections) {
-    this.target = becomeParentOf(target);
-    this.cascadeSections.addAll(cascadeSections);
-  }
-
-  @Override
-  public <R> R accept(ASTVisitor<R> visitor) {
-    return visitor.visitCascadeExpression(this);
-  }
-
-  /**
-   * Return the cascade sections sharing the common target.
-   * 
-   * @return the cascade sections sharing the common target
-   */
-  public NodeList<DartExpression> getCascadeSections() {
-    return cascadeSections;
-  }
-
-  /**
-   * Return the target of the cascade sections.
-   * 
-   * @return the target of the cascade sections
-   */
-  public DartExpression getTarget() {
-    return target;
-  }
-
-  /**
-   * Set the target of the cascade sections to the given expression.
-   * 
-   * @param target the target of the cascade sections
-   */
-  public void setTarget(DartExpression target) {
-    this.target = becomeParentOf(target);
-  }
-
-  @Override
-  public void visitChildren(ASTVisitor<?> visitor) {
-    safelyVisitChild(target, visitor);
-    cascadeSections.accept(visitor);
-  }
-}
diff --git a/compiler/java/com/google/dart/compiler/ast/DartCase.java b/compiler/java/com/google/dart/compiler/ast/DartCase.java
deleted file mode 100644
index 5285fd3..0000000
--- a/compiler/java/com/google/dart/compiler/ast/DartCase.java
+++ /dev/null
@@ -1,35 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.ast;
-
-import java.util.List;
-
-/**
- * Represents a Dart 'case' switch member.
- */
-public class DartCase extends DartSwitchMember {
-
-  private DartExpression expr;
-
-  public DartCase(DartExpression expr, List<DartLabel> labels, List<DartStatement> statements) {
-    super(labels, statements); 
-    this.expr = becomeParentOf(expr);
-  }
-
-  public DartExpression getExpr() {
-    return expr;
-  }
-
-  @Override
-  public void visitChildren(ASTVisitor<?> visitor) {
-    safelyVisitChild(expr, visitor);
-    super.visitChildren(visitor);
-  }
-
-  @Override
-  public <R> R accept(ASTVisitor<R> visitor) {
-    return visitor.visitCase(this);
-  }
-}
diff --git a/compiler/java/com/google/dart/compiler/ast/DartCatchBlock.java b/compiler/java/com/google/dart/compiler/ast/DartCatchBlock.java
deleted file mode 100644
index 6ab02f5..0000000
--- a/compiler/java/com/google/dart/compiler/ast/DartCatchBlock.java
+++ /dev/null
@@ -1,53 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.ast;
-
-/**
- * Represents a Dart 'catch' block.
- */
-public class DartCatchBlock extends DartStatement {
-  private final int onTokenOffset;
-  private final DartParameter exception;
-  private final DartParameter stackTrace;
-  private final DartBlock block;
-
-  public DartCatchBlock(DartBlock block,
-                        int onTokenOffset,
-                        DartParameter exception,
-                        DartParameter stackTrace) {
-    this.block = becomeParentOf(block);
-    this.onTokenOffset = onTokenOffset;
-    this.exception = becomeParentOf(exception);
-    this.stackTrace = becomeParentOf(stackTrace);
-  }
-
-  public int getOnTokenOffset() {
-    return onTokenOffset;
-  }
-
-  public DartParameter getException() {
-    return exception;
-  }
-
-  public DartParameter getStackTrace() {
-    return stackTrace;
-  }
-
-  public DartBlock getBlock() {
-    return block;
-  }
-
-  @Override
-  public void visitChildren(ASTVisitor<?> visitor) {
-    safelyVisitChild(exception, visitor);
-    safelyVisitChild(stackTrace, visitor);
-    safelyVisitChild(block, visitor);
-  }
-
-  @Override
-  public <R> R accept(ASTVisitor<R> visitor) {
-    return visitor.visitCatchBlock(this);
-  }
-}
diff --git a/compiler/java/com/google/dart/compiler/ast/DartClass.java b/compiler/java/com/google/dart/compiler/ast/DartClass.java
deleted file mode 100644
index ede1696..0000000
--- a/compiler/java/com/google/dart/compiler/ast/DartClass.java
+++ /dev/null
@@ -1,204 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.ast;
-
-import com.google.dart.compiler.resolver.ClassNodeElement;
-import com.google.dart.compiler.resolver.Element;
-
-import java.util.List;
-
-/**
- * Represents a Dart class.
- */
-public class DartClass extends DartDeclaration<DartIdentifier> {
-
-  private ClassNodeElement element;
-
-  private DartTypeNode superclass;
-
-  private final NodeList<DartNode> members = NodeList.create(this);
-  private final NodeList<DartTypeParameter> typeParameters = NodeList.create(this);
-  private final NodeList<DartTypeNode> interfaces = NodeList.create(this);
-  private final NodeList<DartTypeNode> mixins = NodeList.create(this);
-
-  private boolean isInterface;
-  private DartParameterizedTypeNode defaultClass;
-  private final Modifiers modifiers;
-
-  // If the Dart class is implemented by a native JS class the nativeName
-  // points to the JS class. Otherwise it is null.
-  private final DartStringLiteral nativeName;
-
-  private final int tokenOffset;
-  private final int tokenLength;
-  private final int defaultTokenOffset;
-  private final int implementsOffset;
-  private final int openBraceOffset;
-  private final int closeBraceOffset;
-
-  public DartClass(int tokenOffset, int tokenLength, DartIdentifier name,
-      DartStringLiteral nativeName, DartTypeNode superclass, int implementsOffset,
-      List<DartTypeNode> interfaces, List<DartTypeNode> mixins, int defaultTokenOffset,
-      int openBraceOffset, int closeBraceOffset, List<DartNode> members,
-      List<DartTypeParameter> typeParameters, DartParameterizedTypeNode defaultClass,
-      boolean isInterface, Modifiers modifiers) {
-    super(name);
-    this.tokenOffset = tokenOffset;
-    this.tokenLength = tokenLength;
-    this.nativeName = becomeParentOf(nativeName);
-    this.superclass = becomeParentOf(superclass);
-    this.defaultTokenOffset = defaultTokenOffset;
-    this.openBraceOffset = openBraceOffset;
-    this.closeBraceOffset = closeBraceOffset;
-    this.members.addAll(members);
-    this.typeParameters.addAll(typeParameters);
-    this.implementsOffset = implementsOffset;
-    this.interfaces.addAll(interfaces);
-    this.mixins.addAll(mixins);
-    this.defaultClass = becomeParentOf(defaultClass);
-    this.isInterface = isInterface;
-    this.modifiers = modifiers;
-  }
-
-  public boolean isInterface() {
-    return isInterface;
-  }
-
-  public Modifiers getModifiers() {
-    return modifiers;
-  }
-
-  public boolean isAbstract() {
-    if (modifiers.isAbstract()) {
-      return true;
-    }
-    for (DartNode node : members) {
-      if (node instanceof DartMethodDefinition) {
-        DartMethodDefinition methodDefinition = (DartMethodDefinition) node;
-        if (methodDefinition.getModifiers().isAbstract()) {
-          return true;
-        }
-      }
-      if (node instanceof DartFieldDefinition) {
-        DartFieldDefinition fieldDefinition = (DartFieldDefinition) node;
-        for (DartField field : fieldDefinition.getFields()) {
-          if (field.getModifiers().isAbstract()) {
-            return true;
-          }
-        }
-      }
-    }
-    return false;
-  }
-
-  public int getTokenOffset() {
-    return tokenOffset;
-  }
-  
-  public int getTokenLength() {
-    return tokenLength;
-  }
-  
-  public int getDefaultTokenOffset() {
-    return defaultTokenOffset;
-  }
-  
-  public int getOpenBraceOffset() {
-    return openBraceOffset;
-  }
-  
-  public int getCloseBraceOffset() {
-    return closeBraceOffset;
-  }
-
-  public List<DartNode> getMembers() {
-    return members;
-  }
-
-  public List<DartTypeParameter> getTypeParameters() {
-    return typeParameters;
-  }
-  
-  public int getImplementsOffset() {
-    return implementsOffset;
-  }
-
-  public List<DartTypeNode> getInterfaces() {
-    return interfaces;
-  }
-  
-  public NodeList<DartTypeNode> getMixins() {
-    return mixins;
-  }
-
-  public String getClassName() {
-    if (getName() == null) {
-      return null;
-    }
-    return getName().getName();
-  }
-
-  public DartTypeNode getSuperclass() {
-    return superclass;
-  }
-
-  public DartParameterizedTypeNode getDefaultClass() {
-    return defaultClass;
-  }
-
-  public Element getDefaultSymbol() {
-    if (defaultClass != null) {
-      return defaultClass.getType().getElement();
-    } else {
-      return null;
-    }
-  }
-
-  public Element getSuperSymbol() {
-    if (superclass != null) {
-      return superclass.getType().getElement();
-    } else {
-      return null;
-    }
-  }
-
-  @Override
-  public ClassNodeElement getElement() {
-    return element;
-  }
-
-  public void setDefaultClass(DartParameterizedTypeNode newName) {
-    defaultClass = becomeParentOf(newName);
-  }
-
-  public void setSuperclass(DartTypeNode newName) {
-    superclass = becomeParentOf(newName);
-  }
-
-  @Override
-  public void setElement(Element element) {
-    this.element = (ClassNodeElement) element;
-  }
-
-  public DartStringLiteral getNativeName() {
-    return nativeName;
-  }
-
-  @Override
-  public void visitChildren(ASTVisitor<?> visitor) {
-    super.visitChildren(visitor);
-    typeParameters.accept(visitor);
-    safelyVisitChild(superclass, visitor);
-    interfaces.accept(visitor);
-    mixins.accept(visitor);
-    safelyVisitChild(defaultClass, visitor);
-    members.accept(visitor);
-  }
-
-  @Override
-  public <R> R accept(ASTVisitor<R> visitor) {
-    return visitor.visitClass(this);
-  }
-}
diff --git a/compiler/java/com/google/dart/compiler/ast/DartClassMember.java b/compiler/java/com/google/dart/compiler/ast/DartClassMember.java
deleted file mode 100644
index 2e5a2bf..0000000
--- a/compiler/java/com/google/dart/compiler/ast/DartClassMember.java
+++ /dev/null
@@ -1,27 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.ast;
-
-import com.google.dart.compiler.resolver.NodeElement;
-
-/**
- * Base class for class members (fields and methods).
- */
-public abstract class DartClassMember<N extends DartExpression> extends DartDeclaration<N> {
-
-  private final Modifiers modifiers;
-
-  protected DartClassMember(N name, Modifiers modifiers) {
-    super(name);
-    this.modifiers = modifiers;
-  }
-
-  public Modifiers getModifiers() {
-    return modifiers;
-  }
-
-  @Override
-  public abstract NodeElement getElement();
-}
diff --git a/compiler/java/com/google/dart/compiler/ast/DartClassTypeAlias.java b/compiler/java/com/google/dart/compiler/ast/DartClassTypeAlias.java
deleted file mode 100644
index a5c35c0..0000000
--- a/compiler/java/com/google/dart/compiler/ast/DartClassTypeAlias.java
+++ /dev/null
@@ -1,88 +0,0 @@
-// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.ast;
-
-import com.google.dart.compiler.resolver.ClassNodeElement;
-import com.google.dart.compiler.resolver.Element;
-
-import java.util.List;
-
-/**
- * Instances of the class {@code DartClassTypeAlias} represent a class type alias.
- */
-public class DartClassTypeAlias extends DartDeclaration<DartIdentifier> {
-  private final NodeList<DartTypeParameter> typeParameters = NodeList.create(this);
-  private final Modifiers modifiers;
-  private final DartTypeNode superclass;
-  private final NodeList<DartTypeNode> mixins = NodeList.create(this);
-  private final NodeList<DartTypeNode> interfaces = NodeList.create(this);
-  private ClassNodeElement element;
-
-  public DartClassTypeAlias(DartIdentifier name, List<DartTypeParameter> typeParameters,
-      Modifiers modifiers, DartTypeNode superclass, List<DartTypeNode> mixins,
-      List<DartTypeNode> interfaces) {
-    super(name);
-    this.typeParameters.addAll(typeParameters);
-    this.modifiers = modifiers;
-    this.superclass = becomeParentOf(superclass);
-    this.mixins.addAll(mixins);
-    this.interfaces.addAll(interfaces);
-  }
-
-  public List<DartTypeParameter> getTypeParameters() {
-    return typeParameters;
-  }
-
-  public Modifiers getModifiers() {
-    return modifiers;
-  }
-
-  public boolean isAbstract() {
-    return modifiers.isAbstract();
-  }
-
-  public DartTypeNode getSuperclass() {
-    return superclass;
-  }
-
-  public NodeList<DartTypeNode> getMixins() {
-    return mixins;
-  }
-
-  public List<DartTypeNode> getInterfaces() {
-    return interfaces;
-  }
-
-  public String getClassName() {
-    if (getName() == null) {
-      return null;
-    }
-    return getName().getName();
-  }
-
-  @Override
-  public ClassNodeElement getElement() {
-    return element;
-  }
-
-  @Override
-  public void setElement(Element element) {
-    this.element = (ClassNodeElement) element;
-  }
-
-  @Override
-  public void visitChildren(ASTVisitor<?> visitor) {
-    super.visitChildren(visitor);
-    typeParameters.accept(visitor);
-    superclass.accept(visitor);
-    mixins.accept(visitor);
-    interfaces.accept(visitor);
-  }
-
-  @Override
-  public <R> R accept(ASTVisitor<R> visitor) {
-    return visitor.visitClassTypeAlias(this);
-  }
-}
diff --git a/compiler/java/com/google/dart/compiler/ast/DartComment.java b/compiler/java/com/google/dart/compiler/ast/DartComment.java
deleted file mode 100644
index 6f6e7d0..0000000
--- a/compiler/java/com/google/dart/compiler/ast/DartComment.java
+++ /dev/null
@@ -1,93 +0,0 @@
-// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.ast;
-
-import com.google.dart.compiler.Source;
-import com.google.dart.compiler.common.SourceInfo;
-
-import java.util.List;
-
-public class DartComment extends DartNode {
-  private final NodeList<DartCommentRefName> refNames = NodeList.create(this);
-  private final NodeList<DartCommentNewName> newNames = NodeList.create(this);
-
-  @SuppressWarnings("unused")
-  private static final long serialVersionUID = 6066713446767517627L;
-
-  public static enum Style {
-    END_OF_LINE, BLOCK, DART_DOC;
-  }
-
-  private Style style;
-
-  public DartComment(Source source, int start, int length, Style style) {
-    setSourceInfo(new SourceInfo(source, start, length));
-    this.style = style;
-  }
-
-  /**
-   * Return <code>true<code> if this comment is a block comment.
-   * 
-   * @return <code>true<code> if this comment is a block comment
-   */
-  public boolean isBlock() {
-    return style == Style.BLOCK;
-  }
-
-  /**
-   * Return <code>true<code> if this comment is a DartDoc comment.
-   * 
-   * @return <code>true<code> if this comment is a DartDoc comment
-   */
-  public boolean isDartDoc() {
-    return style == Style.DART_DOC;
-  }
-
-  /**
-   * Return <code>true<code> if this comment is an end-of-line comment.
-   * 
-   * @return <code>true<code> if this comment is an end-of-line comment
-   */
-  public boolean isEndOfLine() {
-    return style == Style.END_OF_LINE;
-  }
-
-  /**
-   * Adds <code>[id]</code> reference.
-   */
-  public void addRefName(DartCommentRefName name) {
-    refNames.add(name);
-  }
-
-  public NodeList<DartCommentRefName> getRefNames() {
-    return refNames;
-  }
-
-  /**
-   * Adds <code>[new Class]</code> or <b>[new Class.name]</b> reference.
-   */
-  public void addNewName(DartCommentNewName name) {
-    newNames.add(name);
-  }
-
-  /**
-   * @return the <code>[new Class]</code> or <b>[new Class.name]</b> references.
-   */
-  public List<DartCommentNewName> getNewNames() {
-    return newNames;
-  }
-
-  @Override
-  public void visitChildren(ASTVisitor<?> visitor) {
-    refNames.accept(visitor);
-    newNames.accept(visitor);
-  }
-
-  @Override
-  public <R> R accept(ASTVisitor<R> visitor) {
-    return visitor.visitComment(this);
-  }
-
-}
diff --git a/compiler/java/com/google/dart/compiler/ast/DartCommentNewName.java b/compiler/java/com/google/dart/compiler/ast/DartCommentNewName.java
deleted file mode 100644
index e1ef173..0000000
--- a/compiler/java/com/google/dart/compiler/ast/DartCommentNewName.java
+++ /dev/null
@@ -1,77 +0,0 @@
-// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.ast;
-
-import com.google.dart.compiler.resolver.ClassElement;
-import com.google.dart.compiler.resolver.ConstructorElement;
-import com.google.dart.compiler.util.StringInterner;
-
-/**
- * <code>[new Class.name]</code> in {@link DartComment}.
- */
-public final class DartCommentNewName extends DartNode {
-  private final String className;
-  private final int classOffset;
-  private final String constructorName;
-  private ClassElement classElement;
-  private final int constructorOffset;
-  private ConstructorElement constructorElement;
-
-  public DartCommentNewName(String className, int classOffset, String constructorName,
-      int constructorOffset) {
-    assert className != null;
-    assert constructorName != null;
-    this.className = StringInterner.intern(className);
-    this.classOffset = classOffset;
-    this.constructorName = StringInterner.intern(constructorName);
-    this.constructorOffset = constructorOffset;
-  }
-
-  @Override
-  public String toString() {
-    if (constructorName.isEmpty()) {
-      return className;
-    }
-    return className + "." + constructorName;
-  }
-
-  public void setElements(ClassElement classElement, ConstructorElement constructorElement) {
-    this.classElement = classElement;
-    this.constructorElement = constructorElement;
-  }
-
-  public String getClassName() {
-    return className;
-  }
-
-  public int getClassOffset() {
-    return classOffset;
-  }
-
-  public ClassElement getClassElement() {
-    return classElement;
-  }
-
-  public String getConstructorName() {
-    return constructorName;
-  }
-
-  public int getConstructorOffset() {
-    return constructorOffset;
-  }
-
-  public ConstructorElement getConstructorElement() {
-    return constructorElement;
-  }
-
-  @Override
-  public void visitChildren(ASTVisitor<?> visitor) {
-  }
-
-  @Override
-  public <R> R accept(ASTVisitor<R> visitor) {
-    return visitor.visitCommentNewName(this);
-  }
-}
diff --git a/compiler/java/com/google/dart/compiler/ast/DartCommentRefName.java b/compiler/java/com/google/dart/compiler/ast/DartCommentRefName.java
deleted file mode 100644
index 95a1bbd..0000000
--- a/compiler/java/com/google/dart/compiler/ast/DartCommentRefName.java
+++ /dev/null
@@ -1,49 +0,0 @@
-// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.ast;
-
-import com.google.dart.compiler.resolver.Element;
-import com.google.dart.compiler.util.StringInterner;
-
-/**
- * <code>[name]</code> in {@link DartComment}.
- */
-public final class DartCommentRefName extends DartNode {
-  private final String name;
-  private Element element;
-
-  public DartCommentRefName(String name) {
-    assert name != null;
-    this.name = StringInterner.intern(name);
-  }
-
-  @Override
-  public String toString() {
-    return name;
-  }
-
-  @Override
-  public Element getElement() {
-    return element;
-  }
-
-  @Override
-  public void setElement(Element element) {
-    this.element = element;
-  }
-
-  public String getName() {
-    return name;
-  }
-
-  @Override
-  public void visitChildren(ASTVisitor<?> visitor) {
-  }
-
-  @Override
-  public <R> R accept(ASTVisitor<R> visitor) {
-    return visitor.visitCommentRefName(this);
-  }
-}
diff --git a/compiler/java/com/google/dart/compiler/ast/DartConditional.java b/compiler/java/com/google/dart/compiler/ast/DartConditional.java
deleted file mode 100644
index 9e8a3d1..0000000
--- a/compiler/java/com/google/dart/compiler/ast/DartConditional.java
+++ /dev/null
@@ -1,46 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.ast;
-
-/**
- * Represents a Dart conditional expression.
- */
-public class DartConditional extends DartExpression {
-
-  private DartExpression condition;
-  private DartExpression elseExpr;
-  private DartExpression thenExpr;
-
-  public DartConditional(DartExpression condition, DartExpression thenExpr,
-      DartExpression elseExpr) {
-    this.condition = becomeParentOf(condition);
-    this.thenExpr = becomeParentOf(thenExpr);
-    this.elseExpr = becomeParentOf(elseExpr);
-  }
-
-  public DartExpression getCondition() {
-    return condition;
-  }
-
-  public DartExpression getElseExpression() {
-    return elseExpr;
-  }
-
-  public DartExpression getThenExpression() {
-    return thenExpr;
-  }
-
-  @Override
-  public void visitChildren(ASTVisitor<?> visitor) {
-    safelyVisitChild(condition, visitor);
-    safelyVisitChild(thenExpr, visitor);
-    safelyVisitChild(elseExpr, visitor);
-  }
-
-  @Override
-  public <R> R accept(ASTVisitor<R> visitor) {
-    return visitor.visitConditional(this);
-  }
-}
diff --git a/compiler/java/com/google/dart/compiler/ast/DartContinueStatement.java b/compiler/java/com/google/dart/compiler/ast/DartContinueStatement.java
deleted file mode 100644
index afe0816..0000000
--- a/compiler/java/com/google/dart/compiler/ast/DartContinueStatement.java
+++ /dev/null
@@ -1,25 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.ast;
-
-/**
- * Represents a Dart 'continue' statement.
- */
-public class DartContinueStatement extends DartGotoStatement {
-
-  public DartContinueStatement(DartIdentifier label) {
-    super(label);
-  }
-
-  @Override
-  public boolean isAbruptCompletingStatement() {
-    return true;
-  }
-
-  @Override
-  public <R> R accept(ASTVisitor<R> visitor) {
-    return visitor.visitContinueStatement(this);
-  }
-}
diff --git a/compiler/java/com/google/dart/compiler/ast/DartDeclaration.java b/compiler/java/com/google/dart/compiler/ast/DartDeclaration.java
deleted file mode 100644
index 35f3013..0000000
--- a/compiler/java/com/google/dart/compiler/ast/DartDeclaration.java
+++ /dev/null
@@ -1,55 +0,0 @@
-// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.ast;
-
-/**
- * Common supertype for most declarations. A declaration introduces a new name in a scope. Certain
- * tools, such as the IDE, need to know the location of this name, but the name should otherwise be
- * considered a part of the declaration, not an independent node. So the name is not visited when
- * traversing the AST.
- */
-public abstract class DartDeclaration<N extends DartExpression> extends DartNodeWithMetadata
-    implements HasObsoleteMetadata {
-
-  private N name; // Not visited.
-  private DartComment dartDoc;
-  private DartObsoleteMetadata obsoleteMetadata = DartObsoleteMetadata.EMPTY;
-
-  protected DartDeclaration(N name) {
-    this.name = becomeParentOf(name);
-  }
-
-  public final N getName() {
-    return name;
-  }
-
-  public final void setName(N newName) {
-    name = becomeParentOf(newName);
-  }
-
-  public DartComment getDartDoc() {
-    return dartDoc;
-  }
-
-  public void setDartDoc(DartComment dartDoc) {
-    // dartDoc is still parented by the containing DartUnit.
-    this.dartDoc = dartDoc;
-  }
-
-  public DartObsoleteMetadata getObsoleteMetadata() {
-    return obsoleteMetadata;
-  }
-
-  public void setObsoleteMetadata(DartObsoleteMetadata metadata) {
-    this.obsoleteMetadata = metadata;
-  }
-
-  @Override
-  public void visitChildren(ASTVisitor<?> visitor) {
-    safelyVisitChild(dartDoc, visitor);
-    super.visitChildren(visitor);
-    safelyVisitChild(name, visitor);
-  }
-}
diff --git a/compiler/java/com/google/dart/compiler/ast/DartDefault.java b/compiler/java/com/google/dart/compiler/ast/DartDefault.java
deleted file mode 100644
index 2ff46a2..0000000
--- a/compiler/java/com/google/dart/compiler/ast/DartDefault.java
+++ /dev/null
@@ -1,22 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.ast;
-
-import java.util.List;
-
-/**
- * Represents a Dart 'default' switch member.
- */
-public class DartDefault extends DartSwitchMember {
-
-  public DartDefault(List<DartLabel> labels, List<DartStatement> statements) {
-    super(labels, statements);
-  }
-
-  @Override
-  public <R> R accept(ASTVisitor<R> visitor) {
-    return visitor.visitDefault(this);
-  }
-}
diff --git a/compiler/java/com/google/dart/compiler/ast/DartDirective.java b/compiler/java/com/google/dart/compiler/ast/DartDirective.java
deleted file mode 100644
index 7c039c1..0000000
--- a/compiler/java/com/google/dart/compiler/ast/DartDirective.java
+++ /dev/null
@@ -1,27 +0,0 @@
-// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.ast;
-
-import com.google.dart.compiler.resolver.NodeElement;
-
-/**
- * Base class for directives.
- */
-public abstract class DartDirective extends DartNodeWithMetadata implements HasObsoleteMetadata {
-  private DartObsoleteMetadata obsoleteMetadata = DartObsoleteMetadata.EMPTY;
-
-  @Override
-  public NodeElement getElement() {
-    throw new UnsupportedOperationException(getClass().getSimpleName());
-  }
-
-  public DartObsoleteMetadata getObsoleteMetadata() {
-    return obsoleteMetadata;
-  }
-
-  public void setObsoleteMetadata(DartObsoleteMetadata metadata) {
-    this.obsoleteMetadata = metadata;
-  }
-}
diff --git a/compiler/java/com/google/dart/compiler/ast/DartDoWhileStatement.java b/compiler/java/com/google/dart/compiler/ast/DartDoWhileStatement.java
deleted file mode 100644
index a2a4269..0000000
--- a/compiler/java/com/google/dart/compiler/ast/DartDoWhileStatement.java
+++ /dev/null
@@ -1,38 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.ast;
-
-/**
- * Represents a Dart 'do/while' statement.
- */
-public class DartDoWhileStatement extends DartStatement {
-
-  private DartExpression condition;
-  private DartStatement body;
-
-  public DartDoWhileStatement(DartExpression condition, DartStatement body) {
-    this.condition = becomeParentOf(condition);
-    this.body = becomeParentOf(body);
-  }
-
-  public DartStatement getBody() {
-    return body;
-  }
-
-  public DartExpression getCondition() {
-    return condition;
-  }
-
-  @Override
-  public void visitChildren(ASTVisitor<?> visitor) {
-    safelyVisitChild(condition, visitor);
-    safelyVisitChild(body, visitor);
-  }
-
-  @Override
-  public <R> R accept(ASTVisitor<R> visitor) {
-    return visitor.visitDoWhileStatement(this);
-  }
-}
diff --git a/compiler/java/com/google/dart/compiler/ast/DartDoubleLiteral.java b/compiler/java/com/google/dart/compiler/ast/DartDoubleLiteral.java
deleted file mode 100644
index f4bbcac..0000000
--- a/compiler/java/com/google/dart/compiler/ast/DartDoubleLiteral.java
+++ /dev/null
@@ -1,34 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.ast;
-
-/**
- * Represents a Dart double literal value.
- */
-public class DartDoubleLiteral extends DartLiteral {
-
-  public static DartDoubleLiteral get(double x) {
-    return new DartDoubleLiteral(x);
-  }
-
-  private final double value;
-
-  private DartDoubleLiteral(double value) {
-    this.value = value;
-  }
-
-  public double getValue() {
-    return value;
-  }
-
-  @Override
-  public void visitChildren(ASTVisitor<?> visitor) {
-  }
-
-  @Override
-  public <R> R accept(ASTVisitor<R> visitor) {
-    return visitor.visitDoubleLiteral(this);
-  }
-}
diff --git a/compiler/java/com/google/dart/compiler/ast/DartEmptyStatement.java b/compiler/java/com/google/dart/compiler/ast/DartEmptyStatement.java
deleted file mode 100644
index 0adb02f..0000000
--- a/compiler/java/com/google/dart/compiler/ast/DartEmptyStatement.java
+++ /dev/null
@@ -1,20 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.ast;
-
-/**
- * Represents an empty Dart statement.
- */
-public class DartEmptyStatement extends DartStatement {
-
-  @Override
-  public void visitChildren(ASTVisitor<?> visitor) {
-  }
-
-  @Override
-  public <R> R accept(ASTVisitor<R> visitor) {
-    return visitor.visitEmptyStatement(this);
-  }
-}
diff --git a/compiler/java/com/google/dart/compiler/ast/DartExportDirective.java b/compiler/java/com/google/dart/compiler/ast/DartExportDirective.java
deleted file mode 100644
index e659d56..0000000
--- a/compiler/java/com/google/dart/compiler/ast/DartExportDirective.java
+++ /dev/null
@@ -1,41 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.ast;
-
-import java.util.List;
-
-/**
- * Implements the export directive.
- */
-public class DartExportDirective extends DartDirective {
-  private DartStringLiteral libraryUri;
-
-  private NodeList<ImportCombinator> combinators = new NodeList<ImportCombinator>(this);
-
-  public DartExportDirective(DartStringLiteral libraryUri, List<ImportCombinator> combinators) {
-    this.libraryUri = becomeParentOf(libraryUri);
-    this.combinators.addAll(combinators);
-  }
-
-  public DartStringLiteral getLibraryUri() {
-    return libraryUri;
-  }
-
-  public List<ImportCombinator> getCombinators() {
-    return combinators;
-  }
-
-  @Override
-  public void visitChildren(ASTVisitor<?> visitor) {
-    super.visitChildren(visitor);
-    safelyVisitChild(libraryUri, visitor);
-    combinators.accept(visitor);
-  }
-
-  @Override
-  public <R> R accept(ASTVisitor<R> visitor) {
-    return visitor.visitExportDirective(this);
-  }
-}
diff --git a/compiler/java/com/google/dart/compiler/ast/DartExprStmt.java b/compiler/java/com/google/dart/compiler/ast/DartExprStmt.java
deleted file mode 100644
index 72fcfc7..0000000
--- a/compiler/java/com/google/dart/compiler/ast/DartExprStmt.java
+++ /dev/null
@@ -1,36 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.ast;
-
-/**
- * Represents a Dart expression-as-statement.
- */
-public class DartExprStmt extends DartStatement {
-
-  private DartExpression expr;
-
-  public DartExprStmt(DartExpression expr) {
-    this.expr = becomeParentOf(expr);
-  }
-
-  public DartExpression getExpression() {
-    return expr;
-  }
-
-  @Override
-  public boolean isAbruptCompletingStatement() {
-    return expr instanceof DartThrowExpression;
-  }
-
-  @Override
-  public void visitChildren(ASTVisitor<?> visitor) {
-    safelyVisitChild(expr, visitor);
-  }
-
-  @Override
-  public <R> R accept(ASTVisitor<R> visitor) {
-    return visitor.visitExprStmt(this);
-  }
-}
diff --git a/compiler/java/com/google/dart/compiler/ast/DartExpression.java b/compiler/java/com/google/dart/compiler/ast/DartExpression.java
deleted file mode 100644
index 76c712a..0000000
--- a/compiler/java/com/google/dart/compiler/ast/DartExpression.java
+++ /dev/null
@@ -1,33 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.ast;
-
-
-/**
- * Abstract base class for Dart expressions.
- */
-public abstract class DartExpression extends DartNode {
-  
-  private Object invocationParameterId;
-
-  public boolean isAssignable() {
-    // By default you cannot assign to expressions.
-    return false;
-  }
-
-  /**
-   * @return the ID of parameter, {@link Integer} index of positional, {@link String} name if named.
-   */
-  public Object getInvocationParameterId() {
-    return invocationParameterId;
-  }
-
-  /**
-   * @see #getInvocationParameterId()
-   */
-  public void setInvocationParameterId(Object parameterId) {
-    this.invocationParameterId = parameterId;
-  }
-}
diff --git a/compiler/java/com/google/dart/compiler/ast/DartField.java b/compiler/java/com/google/dart/compiler/ast/DartField.java
deleted file mode 100644
index 654b770..0000000
--- a/compiler/java/com/google/dart/compiler/ast/DartField.java
+++ /dev/null
@@ -1,63 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.ast;
-
-import com.google.dart.compiler.resolver.Element;
-import com.google.dart.compiler.resolver.FieldNodeElement;
-
-/**
- * Represents a single field within a field definition.
- */
-public class DartField extends DartClassMember<DartIdentifier> {
-
-  private DartExpression value;
-  private FieldNodeElement element;
-  private DartMethodDefinition accessor;
-
-  public DartField(DartIdentifier name, Modifiers modifiers, DartMethodDefinition accessor,
-                   DartExpression value) {
-    super(name, modifiers);
-    this.accessor = becomeParentOf(accessor);
-    this.value = becomeParentOf(value);
-  }
-
-  public void setValue(DartExpression value) {
-    this.value = becomeParentOf(value);
-  }
-
-  public DartExpression getValue() {
-    return value;
-  }
-
-  public void setAccessor(DartMethodDefinition accessor) {
-    this.accessor = becomeParentOf(accessor);
-  }
-
-  public DartMethodDefinition getAccessor() {
-    return accessor;
-  }
-
-  @Override
-  public FieldNodeElement getElement() {
-    return element;
-  }
-
-  @Override
-  public void setElement(Element element) {
-    this.element = (FieldNodeElement) element;
-  }
-
-  @Override
-  public void visitChildren(ASTVisitor<?> visitor) {
-    super.visitChildren(visitor);
-    safelyVisitChild(accessor, visitor);
-    safelyVisitChild(value, visitor);
-  }
-
-  @Override
-  public <R> R accept(ASTVisitor<R> visitor) {
-    return visitor.visitField(this);
-  }
-}
diff --git a/compiler/java/com/google/dart/compiler/ast/DartFieldDefinition.java b/compiler/java/com/google/dart/compiler/ast/DartFieldDefinition.java
deleted file mode 100644
index 08078d8..0000000
--- a/compiler/java/com/google/dart/compiler/ast/DartFieldDefinition.java
+++ /dev/null
@@ -1,45 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.ast;
-
-import java.util.List;
-
-/**
- * Represents a Dart field definition.
- */
-public class DartFieldDefinition extends DartNodeWithMetadata {
-
-  private DartTypeNode typeNode;
-  private final NodeList<DartField> fields = NodeList.create(this);
-
-  public DartFieldDefinition(DartTypeNode typeNode, List<DartField> fields) {
-    this.setTypeNode(typeNode);
-    this.fields.addAll(fields);
-  }
-
-  public DartTypeNode getTypeNode() {
-    return typeNode;
-  }
-
-  public void setTypeNode(DartTypeNode typeNode) {
-    this.typeNode = becomeParentOf(typeNode);
-  }
-
-  public List<DartField> getFields() {
-    return fields;
-  }
-
-  @Override
-  public void visitChildren(ASTVisitor<?> visitor) {
-    super.visitChildren(visitor);
-    safelyVisitChild(typeNode, visitor);
-    fields.accept(visitor);
-  }
-
-  @Override
-  public <R> R accept(ASTVisitor<R> visitor) {
-    return visitor.visitFieldDefinition(this);
-  }
-}
diff --git a/compiler/java/com/google/dart/compiler/ast/DartForInStatement.java b/compiler/java/com/google/dart/compiler/ast/DartForInStatement.java
deleted file mode 100644
index 7dfb769..0000000
--- a/compiler/java/com/google/dart/compiler/ast/DartForInStatement.java
+++ /dev/null
@@ -1,64 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.ast;
-
-/**
- * Represents a Dart 'for (.. in ..)' statement.
- */
-public class DartForInStatement extends DartStatement {
-
-  private DartStatement setup;
-  private DartExpression iterable;
-  private final int closeParenOffset;
-  private DartStatement body;
-
-  public DartForInStatement(DartStatement setup,
-                            DartExpression iterable,
-                            int closeParenOffset,
-                            DartStatement body) {
-    this.setup = becomeParentOf(setup);
-    this.iterable = becomeParentOf(iterable);
-    this.closeParenOffset = closeParenOffset;
-    this.body = becomeParentOf(body);
-  }
-
-  public int getCloseParenOffset() {
-    return closeParenOffset;
-  }
-  
-  public DartStatement getBody() {
-    return body;
-  }
-
-  public DartExpression getIterable() {
-    return iterable;
-  }
-
-  public boolean introducesVariable() {
-    return setup instanceof DartVariableStatement;
-  }
-
-  public DartIdentifier getIdentifier() {
-    assert !introducesVariable();
-    return (DartIdentifier) ((DartExprStmt) setup).getExpression();
-  }
-
-  public DartVariableStatement getVariableStatement() {
-    assert introducesVariable();
-    return (DartVariableStatement) setup;
-  }
-
-  @Override
-  public void visitChildren(ASTVisitor<?> visitor) {
-    safelyVisitChild(setup, visitor);
-    safelyVisitChild(iterable, visitor);
-    safelyVisitChild(body, visitor);
-  }
-
-  @Override
-  public <R> R accept(ASTVisitor<R> visitor) {
-    return visitor.visitForInStatement(this);
-  }
-}
diff --git a/compiler/java/com/google/dart/compiler/ast/DartForStatement.java b/compiler/java/com/google/dart/compiler/ast/DartForStatement.java
deleted file mode 100644
index e9b04be..0000000
--- a/compiler/java/com/google/dart/compiler/ast/DartForStatement.java
+++ /dev/null
@@ -1,59 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.ast;
-
-/**
- * Represents a Dart 'for' statement.
- */
-public class DartForStatement extends DartStatement {
-
-  private DartStatement init;
-  private DartExpression condition;
-  private DartExpression increment;
-  private final int closeParenOffset;
-  private DartStatement body;
-
-  public DartForStatement(DartStatement init, DartExpression condition, DartExpression increment,
-      int closeParenOffset, DartStatement body) {
-    this.init = becomeParentOf(init);
-    this.condition = becomeParentOf(condition);
-    this.increment = becomeParentOf(increment);
-    this.closeParenOffset = closeParenOffset;
-    this.body = becomeParentOf(body);
-  }
-
-  public int getCloseParenOffset() {
-    return closeParenOffset;
-  }
-
-  public DartStatement getBody() {
-    return body;
-  }
-
-  public DartExpression getCondition() {
-    return condition;
-  }
-
-  public DartExpression getIncrement() {
-    return increment;
-  }
-
-  public DartStatement getInit() {
-    return init;
-  }
-
-  @Override
-  public void visitChildren(ASTVisitor<?> visitor) {
-    safelyVisitChild(init, visitor);
-    safelyVisitChild(condition, visitor);
-    safelyVisitChild(increment, visitor);
-    safelyVisitChild(body, visitor);
-  }
-
-  @Override
-  public <R> R accept(ASTVisitor<R> visitor) {
-    return visitor.visitForStatement(this);
-  }
-}
diff --git a/compiler/java/com/google/dart/compiler/ast/DartFunction.java b/compiler/java/com/google/dart/compiler/ast/DartFunction.java
deleted file mode 100644
index 628e45e..0000000
--- a/compiler/java/com/google/dart/compiler/ast/DartFunction.java
+++ /dev/null
@@ -1,75 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.ast;
-
-import java.util.List;
-
-/**
- * Represents a Dart function.
- */
-public class DartFunction extends DartNode {
-
-  private final NodeList<DartParameter> parameters = NodeList.create(this);
-  private final int parametersOpenParen;
-  private final int parametersOptionalOpen;
-  private final int parametersOptionalClose;
-  private final int parametersCloseParen;
-  private DartBlock body;
-  private DartTypeNode returnTypeNode;
-
-  public DartFunction(List<DartParameter> parameters, int parametersOpenParen, int parametersOptionalOpen,
-      int parametersOptionalClose, int parametersCloseParen, DartBlock body,
-      DartTypeNode returnTypeNode) {
-    this.parametersOpenParen = parametersOpenParen;
-    this.parametersOptionalOpen = parametersOptionalOpen;
-    this.parametersOptionalClose = parametersOptionalClose;
-    if (parameters != null && !parameters.isEmpty()) {
-      this.parameters.addAll(parameters);
-    }
-    this.parametersCloseParen = parametersCloseParen;
-    this.body = becomeParentOf(body);
-    this.returnTypeNode = becomeParentOf(returnTypeNode);
-  }
-
-  public DartBlock getBody() {
-    return body;
-  }
-
-  public List<DartParameter> getParameters() {
-    return parameters;
-  }
-
-  public int getParametersOptionalOpen() {
-    return parametersOptionalOpen;
-  }
-
-  public int getParametersOptionalClose() {
-    return parametersOptionalClose;
-  }
-  
-  public int getParametersOpenParen() {
-    return parametersOpenParen;
-  }
-  
-  public int getParametersCloseParen() {
-    return parametersCloseParen;
-  }
-
-  public DartTypeNode getReturnTypeNode() {
-    return returnTypeNode;
-  }
-
-  @Override
-  public void visitChildren(ASTVisitor<?> visitor) {
-    parameters.accept(visitor);
-    safelyVisitChild(body, visitor);
-    safelyVisitChild(returnTypeNode, visitor);
-  }
-
-  @Override
-  public <R> R accept(ASTVisitor<R> visitor) {
-    return visitor.visitFunction(this);
-  }
-}
diff --git a/compiler/java/com/google/dart/compiler/ast/DartFunctionExpression.java b/compiler/java/com/google/dart/compiler/ast/DartFunctionExpression.java
deleted file mode 100644
index b8e028b..0000000
--- a/compiler/java/com/google/dart/compiler/ast/DartFunctionExpression.java
+++ /dev/null
@@ -1,72 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.ast;
-
-import com.google.dart.compiler.resolver.Element;
-import com.google.dart.compiler.resolver.MethodElement;
-
-/**
- * Represents a Dart 'function' expression.
- */
-public class DartFunctionExpression extends DartExpression {
-
-  // Not visited. Similar to DartDeclaration, but DartDeclaration shouldn't be
-  // a statement or an expression.
-  private DartIdentifier name;
-
-  private final boolean isStmt;
-  private MethodElement element;
-  private DartFunction function;
-
-  public DartFunctionExpression(DartIdentifier name, DartFunction function, boolean isStmt) {
-    this.name = becomeParentOf(name);
-    this.function = becomeParentOf(function);
-    this.isStmt = isStmt;
-  }
-
-  public DartFunction getFunction() {
-    return function;
-  }
-
-  public String getFunctionName() {
-    if (name == null) {
-      return null;
-    }
-    return name.getName();
-  }
-
-  public DartIdentifier getName() {
-    return name;
-  }
-
-  @Override
-  public MethodElement getElement() {
-    return element;
-  }
-
-  public boolean isStatement() {
-    return isStmt;
-  }
-
-  public void setName(DartIdentifier newName) {
-    name = becomeParentOf(newName);
-  }
-
-  @Override
-  public void setElement(Element element) {
-    this.element = (MethodElement) element;
-  }
-
-  @Override
-  public void visitChildren(ASTVisitor<?> visitor) {
-    safelyVisitChild(name, visitor);
-    safelyVisitChild(function, visitor);
-  }
-
-  @Override
-  public <R> R accept(ASTVisitor<R> visitor) {
-    return visitor.visitFunctionExpression(this);
-  }
-}
diff --git a/compiler/java/com/google/dart/compiler/ast/DartFunctionObjectInvocation.java b/compiler/java/com/google/dart/compiler/ast/DartFunctionObjectInvocation.java
deleted file mode 100644
index 0ef2aaa..0000000
--- a/compiler/java/com/google/dart/compiler/ast/DartFunctionObjectInvocation.java
+++ /dev/null
@@ -1,36 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.ast;
-
-import java.util.List;
-
-/**
- * Function-object invocation AST node.
- */
-public class DartFunctionObjectInvocation extends DartInvocation {
-
-  private DartExpression target;
-
-  public DartFunctionObjectInvocation(DartExpression target, List<DartExpression> args) {
-    super(args);
-    this.target = becomeParentOf(target);
-  }
-
-  @Override
-  public DartExpression getTarget() {
-    return target;
-  }
-
-  @Override
-  public void visitChildren(ASTVisitor<?> visitor) {
-    safelyVisitChild(target, visitor);
-    visitor.visit(getArguments());
-  }
-
-  @Override
-  public <R> R accept(ASTVisitor<R> visitor) {
-    return visitor.visitFunctionObjectInvocation(this);
-  }
-}
diff --git a/compiler/java/com/google/dart/compiler/ast/DartFunctionTypeAlias.java b/compiler/java/com/google/dart/compiler/ast/DartFunctionTypeAlias.java
deleted file mode 100644
index e5b2423..0000000
--- a/compiler/java/com/google/dart/compiler/ast/DartFunctionTypeAlias.java
+++ /dev/null
@@ -1,69 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.ast;
-
-import com.google.dart.compiler.resolver.Element;
-import com.google.dart.compiler.resolver.FunctionAliasElement;
-
-import java.util.List;
-
-/**
- * Named function-type alias AST node.
- */
-public class DartFunctionTypeAlias extends DartDeclaration<DartIdentifier> {
-
-  private DartTypeNode returnTypeNode;
-  private final NodeList<DartParameter> parameters = NodeList.create(this);
-  private final NodeList<DartTypeParameter> typeParameters = NodeList.create(this);
-  private FunctionAliasElement element;
-
-  public DartFunctionTypeAlias(DartIdentifier name, DartTypeNode returnTypeNode,
-                               List<DartParameter> parameters,
-                               List<DartTypeParameter> typeParameters) {
-    super(name);
-    this.returnTypeNode = becomeParentOf(returnTypeNode);
-    this.parameters.addAll(parameters);
-    this.typeParameters.addAll(typeParameters);
-  }
-
-  public List<DartParameter> getParameters() {
-    return parameters;
-  }
-
-  public DartTypeNode getReturnTypeNode() {
-    return returnTypeNode;
-  }
-
-  public List<DartTypeParameter> getTypeParameters() {
-    return typeParameters;
-  }
-
-  @Override
-  public FunctionAliasElement getElement() {
-    return element;
-  }
-
-  public void setReturnTypeNode(DartTypeNode newReturnType) {
-    returnTypeNode = becomeParentOf(newReturnType);
-  }
-
-  @Override
-  public void setElement(Element element) {
-    this.element = (FunctionAliasElement) element;
-  }
-
-  @Override
-  public void visitChildren(ASTVisitor<?> visitor) {
-    super.visitChildren(visitor);
-    safelyVisitChild(returnTypeNode, visitor);
-    parameters.accept(visitor);
-    typeParameters.accept(visitor);
-  }
-
-  @Override
-  public <R> R accept(ASTVisitor<R> visitor) {
-    return visitor.visitFunctionTypeAlias(this);
-  }
-}
diff --git a/compiler/java/com/google/dart/compiler/ast/DartGotoStatement.java b/compiler/java/com/google/dart/compiler/ast/DartGotoStatement.java
deleted file mode 100644
index 212af3e..0000000
--- a/compiler/java/com/google/dart/compiler/ast/DartGotoStatement.java
+++ /dev/null
@@ -1,51 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.ast;
-
-import com.google.dart.compiler.resolver.Element;
-import com.google.dart.compiler.resolver.LabelElement;
-
-/**
- * Base class of {@link DartBreakStatement} and {@link DartContinueStatement}.
- */
-public abstract class DartGotoStatement extends DartStatement {
-
-  private DartIdentifier label;
-  private LabelElement element;
-
-  public DartGotoStatement(DartIdentifier label) {
-    this.label = becomeParentOf(label);
-  }
-
-  public DartIdentifier getLabel() {
-    return label;
-  }
-
-  public String getTargetName() {
-    if (label == null) {
-      return null;
-    }
-    return label.getName();
-  }
-
-  public void setLabel(DartIdentifier newLabel) {
-    label = newLabel;
-  }
-
-  @Override
-  public LabelElement getElement() {
-    return element;
-  }
-
-  @Override
-  public void setElement(Element element) {
-    this.element = (LabelElement) element;
-  }
-
-  @Override
-  public void visitChildren(ASTVisitor<?> visitor) {
-    safelyVisitChild(label, visitor);
-  }
-}
diff --git a/compiler/java/com/google/dart/compiler/ast/DartIdentifier.java b/compiler/java/com/google/dart/compiler/ast/DartIdentifier.java
deleted file mode 100644
index 46ff36f..0000000
--- a/compiler/java/com/google/dart/compiler/ast/DartIdentifier.java
+++ /dev/null
@@ -1,80 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.ast;
-
-import com.google.dart.compiler.resolver.Element;
-import com.google.dart.compiler.util.StringInterner;
-
-/**
- * Represents a Dart identifier expression.
- */
-public class DartIdentifier extends DartExpression {
-
-  private final String name;
-  private Element element;
-  private boolean resolutionAlreadyReportedThatTheMethodCouldNotBeFound;
-
-  public DartIdentifier(String name) {
-    assert name != null;
-    this.name = StringInterner.intern(name);
-  }
-
-  public DartIdentifier(DartIdentifier original) {
-    this.name = StringInterner.intern(original.name);
-  }
-
-  @Override
-  public Element getElement() {
-    return element;
-  }
-
-  @Override
-  // Note: final added for performance reasons.
-  public final String toString() {
-    return name;
-  }
-
-  @Override
-  public boolean isAssignable() {
-    return true;
-  }
-
-  public String getName() {
-    return name;
-  }
-
-  @Override
-  public void setElement(Element element) {
-    this.element = element;
-  }
-
-  /**
-   * Specifies that this name was not found it enclosing {@link Element}.
-   */
-  public void markResolutionAlreadyReportedThatTheMethodCouldNotBeFound() {
-    this.resolutionAlreadyReportedThatTheMethodCouldNotBeFound = true;
-  }
-  
-  /**
-   * @return <code>true</code> if we know that this name was not found in its enclosing
-   *         {@link Element}, and error was already reported.
-   */
-  public boolean isResolutionAlreadyReportedThatTheMethodCouldNotBeFound() {
-    return resolutionAlreadyReportedThatTheMethodCouldNotBeFound;
-  }
-
-  @Override
-  public final void visitChildren(ASTVisitor<?> visitor) {
-  }
-
-  @Override
-  public <R> R accept(ASTVisitor<R> visitor) {
-    return visitor.visitIdentifier(this);
-  }
-
-  public static boolean isPrivateName(String name) {
-    return name.startsWith("_");
-  }
-}
diff --git a/compiler/java/com/google/dart/compiler/ast/DartIfStatement.java b/compiler/java/com/google/dart/compiler/ast/DartIfStatement.java
deleted file mode 100644
index e75c659..0000000
--- a/compiler/java/com/google/dart/compiler/ast/DartIfStatement.java
+++ /dev/null
@@ -1,58 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.ast;
-
-/**
- * Represents a Dart 'if' statement.
- */
-public class DartIfStatement extends DartStatement {
-
-  private DartExpression condition;
-  private DartStatement thenStmt;
-  private DartStatement elseStmt;
-  private final int closeParenOffset;
-  private final int elseTokenOffset;
-
-  public DartIfStatement(DartExpression condition, int closeParenOffset, DartStatement thenStmt,
-      int elseTokenOffset, DartStatement elseStmt) {
-    this.condition = becomeParentOf(condition);
-    this.closeParenOffset = closeParenOffset;
-    this.thenStmt = becomeParentOf(thenStmt);
-    this.elseTokenOffset = elseTokenOffset;
-    this.elseStmt = becomeParentOf(elseStmt);
-  }
-
-  public DartExpression getCondition() {
-    return condition;
-  }
-
-  public int getCloseParenOffset() {
-    return closeParenOffset;
-  }
-
-  public DartStatement getThenStatement() {
-    return thenStmt;
-  }
-
-  public int getElseTokenOffset() {
-    return elseTokenOffset;
-  }
-
-  public DartStatement getElseStatement() {
-    return elseStmt;
-  }
-
-  @Override
-  public void visitChildren(ASTVisitor<?> visitor) {
-    safelyVisitChild(condition, visitor);
-    safelyVisitChild(thenStmt, visitor);
-    safelyVisitChild(elseStmt, visitor);
-  }
-
-  @Override
-  public <R> R accept(ASTVisitor<R> visitor) {
-    return visitor.visitIfStatement(this);
-  }
-}
diff --git a/compiler/java/com/google/dart/compiler/ast/DartImportDirective.java b/compiler/java/com/google/dart/compiler/ast/DartImportDirective.java
deleted file mode 100644
index 5c79e78..0000000
--- a/compiler/java/com/google/dart/compiler/ast/DartImportDirective.java
+++ /dev/null
@@ -1,94 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.ast;
-
-import java.util.List;
-
-/**
- * Implements the import directive.
- */
-public class DartImportDirective extends DartDirective {
-  private boolean obsoleteFormat;
-
-  private DartStringLiteral libraryUri;
-
-  private DartIdentifier prefix;
-
-  private NodeList<ImportCombinator> combinators = new NodeList<ImportCombinator>(this);
-
-  // TODO(brianwilkerson) Remove this field once the obsolete format is no longer supported.
-  private boolean exported;
-
-  private DartStringLiteral oldPrefix;
-
-  public DartImportDirective(DartStringLiteral libraryUri, DartIdentifier prefix, List<ImportCombinator> combinators) {
-    obsoleteFormat = false;
-    this.libraryUri = becomeParentOf(libraryUri);
-    this.prefix = becomeParentOf(prefix);
-    this.combinators.addAll(combinators);
-    this.exported = false;
-  }
-
-  public DartImportDirective(DartStringLiteral libraryUri, DartBooleanLiteral exported, List<ImportCombinator> combinators, DartStringLiteral prefix) {
-    obsoleteFormat = true;
-    this.libraryUri = becomeParentOf(libraryUri);
-    this.combinators.addAll(combinators);
-    this.oldPrefix = becomeParentOf(prefix);
-    this.exported = exported != null;
-  }
-
-  public DartStringLiteral getLibraryUri() {
-    return libraryUri;
-  }
-
-  public boolean isExported() {
-    // TODO(brianwilkerson) Remove this method once the obsolete format is no longer supported.
-    return exported;
-  }
-
-  public boolean isObsoleteFormat() {
-    // TODO(brianwilkerson) Remove this method once the obsolete format is no longer supported.
-    return obsoleteFormat;
-  }
-
-  public List<ImportCombinator> getCombinators() {
-    return combinators;
-  }
-
-  public String getPrefixValue() {
-    if (prefix != null) {
-      return prefix.getName();
-    }
-    // TODO(brianwilkerson) Remove this part once the obsolete format is no longer supported.
-    if (oldPrefix != null) {
-      return oldPrefix.getValue();
-    }
-    return null;
-  }
-  
-  @Deprecated
-  public DartStringLiteral getOldPrefix() {
-    // TODO(brianwilkerson) Remove this method once the obsolete format is no longer supported.
-    return oldPrefix;
-  }
-
-  public DartIdentifier getPrefix() {
-    return prefix;
-  }
-
-  @Override
-  public void visitChildren(ASTVisitor<?> visitor) {
-    super.visitChildren(visitor);
-    safelyVisitChild(libraryUri, visitor);
-    safelyVisitChild(prefix, visitor);
-    combinators.accept(visitor);
-    safelyVisitChild(oldPrefix, visitor);
-  }
-
-  @Override
-  public <R> R accept(ASTVisitor<R> visitor) {
-    return visitor.visitImportDirective(this);
-  }
-}
diff --git a/compiler/java/com/google/dart/compiler/ast/DartInitializer.java b/compiler/java/com/google/dart/compiler/ast/DartInitializer.java
deleted file mode 100644
index c9d324b..0000000
--- a/compiler/java/com/google/dart/compiler/ast/DartInitializer.java
+++ /dev/null
@@ -1,57 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.ast;
-
-/**
- * Represents a constructor initializer expression.
- */
-public class DartInitializer extends DartNode {
-
-  private DartIdentifier name;
-  private DartExpression value;
-
-  public DartInitializer(DartIdentifier name, DartExpression value) {
-    this.name = becomeParentOf(name);
-    this.value = becomeParentOf(value);
-  }
-
-  public String getInitializerName() {
-    if (name == null) {
-      return null;
-    }
-    return name.getName();
-  }
-
-  public DartIdentifier getName() {
-    return name;
-  }
-
-  public DartExpression getValue() {
-    return value;
-  }
-
-  /**
-   * Determines if initializer is an invocation.
-   * @return true if initializer is either super or redirected constructor invocation.
-   */
-  public boolean isInvocation() {
-    return name == null;
-  }
-
-  public void setName(DartIdentifier newName) {
-    name = becomeParentOf(newName);
-  }
-
-  @Override
-  public void visitChildren(ASTVisitor<?> visitor) {
-    safelyVisitChild(name, visitor);
-    safelyVisitChild(value, visitor);
-  }
-
-  @Override
-  public <R> R accept(ASTVisitor<R> visitor) {
-    return visitor.visitInitializer(this);
-  }
-}
diff --git a/compiler/java/com/google/dart/compiler/ast/DartIntegerLiteral.java b/compiler/java/com/google/dart/compiler/ast/DartIntegerLiteral.java
deleted file mode 100644
index ac25f82..0000000
--- a/compiler/java/com/google/dart/compiler/ast/DartIntegerLiteral.java
+++ /dev/null
@@ -1,40 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.ast;
-
-import java.math.BigInteger;
-
-/**
- * Represents a Dart integer literal value.
- */
-public class DartIntegerLiteral extends DartLiteral {
-
-  public static DartIntegerLiteral get(BigInteger x) {
-    return new DartIntegerLiteral(x);
-  }
-
-  public static DartIntegerLiteral one() {
-    return new DartIntegerLiteral(BigInteger.ONE);
-  }
-
-  private final BigInteger value;
-
-  private DartIntegerLiteral(BigInteger value) {
-    this.value = value;
-  }
-
-  public BigInteger getValue() {
-    return value;
-  }
-
-  @Override
-  public void visitChildren(ASTVisitor<?> visitor) {
-  }
-
-  @Override
-  public <R> R accept(ASTVisitor<R> visitor) {
-    return visitor.visitIntegerLiteral(this);
-  }
-}
diff --git a/compiler/java/com/google/dart/compiler/ast/DartInvocation.java b/compiler/java/com/google/dart/compiler/ast/DartInvocation.java
deleted file mode 100644
index 1a3a0a2..0000000
--- a/compiler/java/com/google/dart/compiler/ast/DartInvocation.java
+++ /dev/null
@@ -1,63 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.ast;
-
-import com.google.dart.compiler.resolver.Element;
-
-import java.util.List;
-
-/**
- * Common superclass for all invocation expressions. In
- * a Dart program, there are different kinds of invocation:
- * <ul>
- * <li> expression.identifier() is a method invocation, where the
- *      receiver is 'expression' and the method name 'identifier'.
- *      This invocation is represented as a DartMethodInvocation.
- *      Examples: A.foo(), this.foo(), super.foo(), bar().foo().
- * </li>
- *
- * <li> identifier() is an unqualified invocation. After the resolver has
- *      resolved 'identifier', the normalizer will transform the node to
- *      either a DartFunctionObjectInvocation or a DartMethodInvocation.
- *      This invocation is represented as a DartUnqualifiedInvocation.
- *      Examples: foo().
- * </li>
- *
- * <li> expression() is a function object invocation.
- *      This invocation is represented as a DartFunctionObjectInvocation.
- *      Examples: bar()(), (A.bar)(), bar[0](), (bar)().
- * </li>
- * </ul>
- *
- */
-public abstract class DartInvocation extends DartExpression {
-
-  private final NodeList<DartExpression> arguments = NodeList.create(this);
-  private Element element;
-
-  public DartInvocation(List<DartExpression> arguments) {
-    if (arguments != null && !arguments.isEmpty()) {
-      this.arguments.addAll(arguments);
-    }
-  }
-
-  public DartExpression getTarget() {
-    return null;
-  }
-
-  public List<DartExpression> getArguments() {
-    return arguments;
-  }
-
-  @Override
-  public Element getElement() {
-    return element;
-  }
-
-  @Override
-  public void setElement(Element element) {
-    this.element = element;
-  }
-}
diff --git a/compiler/java/com/google/dart/compiler/ast/DartLabel.java b/compiler/java/com/google/dart/compiler/ast/DartLabel.java
deleted file mode 100644
index 1efdbe3..0000000
--- a/compiler/java/com/google/dart/compiler/ast/DartLabel.java
+++ /dev/null
@@ -1,64 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.ast;
-
-import com.google.dart.compiler.resolver.Element;
-import com.google.dart.compiler.resolver.LabelElement;
-
-/**
- * Represents a Dart statement label.
- */
-public class DartLabel extends DartStatement {
-
-  // Not visited. Similar to DartDeclaration, but DartDeclaration shouldn't be
-  // a statement or an expression.
-  private DartIdentifier label;
-
-  private LabelElement element;
-
-  private DartStatement statement;
-
-  public DartLabel(DartIdentifier label, DartStatement statement) {
-    this.label = becomeParentOf(label);
-    this.statement = becomeParentOf(statement);
-  }
-
-  public DartIdentifier getLabel() {
-    return label;
-  }
-
-  public String getName() {
-    return label.getName();
-  }
-
-  public DartStatement getStatement() {
-    return statement;
-  }
-
-  @Override
-  public LabelElement getElement() {
-    return element;
-  }
-
-  public void setLabel(DartIdentifier newLabel) {
-    label = newLabel;
-  }
-
-  @Override
-  public void setElement(Element element) {
-    this.element = (LabelElement) element;
-  }
-
-  @Override
-  public void visitChildren(ASTVisitor<?> visitor) {
-    safelyVisitChild(label, visitor);
-    safelyVisitChild(statement, visitor);
-  }
-
-  @Override
-  public <R> R accept(ASTVisitor<R> visitor) {
-    return visitor.visitLabel(this);
-  }
-}
diff --git a/compiler/java/com/google/dart/compiler/ast/DartLibraryDirective.java b/compiler/java/com/google/dart/compiler/ast/DartLibraryDirective.java
deleted file mode 100644
index 3a27b6e..0000000
--- a/compiler/java/com/google/dart/compiler/ast/DartLibraryDirective.java
+++ /dev/null
@@ -1,47 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.ast;
-
-/**
- * Implements the library directive.
- */
-public class DartLibraryDirective extends DartDirective {
-  private DartExpression name;
-
-  public DartLibraryDirective(DartExpression name) {
-    this.name = becomeParentOf(name);
-  }
-
-  public DartExpression getName() {
-    return name;
-  }
-
-  public String getLibraryName() {
-    if (name == null) {
-      return null;
-    } else if (name instanceof DartStringLiteral) {
-      // TODO(brianwilkerson) Remove this case once the obsolete format is no longer supported.
-      return ((DartStringLiteral) name).getValue();
-    } else {
-      return name.toSource();
-    }
-  }
-
-  public boolean isObsoleteFormat() {
-    // TODO(brianwilkerson) Remove this method once the obsolete format is no longer supported.
-    return name instanceof DartStringLiteral;
-  }
-
-  @Override
-  public void visitChildren(ASTVisitor<?> visitor) {
-    super.visitChildren(visitor);
-    safelyVisitChild(name, visitor);
-  }
-
-  @Override
-  public <R> R accept(ASTVisitor<R> visitor) {
-    return visitor.visitLibraryDirective(this);
-  }
-}
diff --git a/compiler/java/com/google/dart/compiler/ast/DartLiteral.java b/compiler/java/com/google/dart/compiler/ast/DartLiteral.java
deleted file mode 100644
index 616fe29..0000000
--- a/compiler/java/com/google/dart/compiler/ast/DartLiteral.java
+++ /dev/null
@@ -1,11 +0,0 @@
-// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.ast;
-
-/**
- * Abstract base class for Dart literal values.
- */
-public abstract class DartLiteral extends DartExpression {
-}
diff --git a/compiler/java/com/google/dart/compiler/ast/DartMapLiteral.java b/compiler/java/com/google/dart/compiler/ast/DartMapLiteral.java
deleted file mode 100644
index 4027208..0000000
--- a/compiler/java/com/google/dart/compiler/ast/DartMapLiteral.java
+++ /dev/null
@@ -1,36 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.ast;
-
-import java.util.List;
-
-/**
- * Represents a Dart map literal value.
- */
-public class DartMapLiteral extends DartTypedLiteral {
-
-  private final NodeList<DartMapLiteralEntry> entries = NodeList.create(this);
-
-  public DartMapLiteral(boolean isConst, List<DartTypeNode> typeArguments,
-      List<DartMapLiteralEntry> entries) {
-    super(isConst, typeArguments);
-    this.entries.addAll(entries);
-  }
-
-  public List<DartMapLiteralEntry> getEntries() {
-    return entries;
-  }
-
-  @Override
-  public void visitChildren(ASTVisitor<?> visitor) {
-    super.visitChildren(visitor);
-    entries.accept(visitor);
-  }
-
-  @Override
-  public <R> R accept(ASTVisitor<R> visitor) {
-    return visitor.visitMapLiteral(this);
-  }
-}
diff --git a/compiler/java/com/google/dart/compiler/ast/DartMapLiteralEntry.java b/compiler/java/com/google/dart/compiler/ast/DartMapLiteralEntry.java
deleted file mode 100644
index f7ced38..0000000
--- a/compiler/java/com/google/dart/compiler/ast/DartMapLiteralEntry.java
+++ /dev/null
@@ -1,38 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.ast;
-
-/**
- * Represents an entry in a Dart map literal value.
- */
-public class DartMapLiteralEntry extends DartNode {
-
-  private DartExpression key;
-  private DartExpression value;
-
-  public DartMapLiteralEntry(DartExpression key, DartExpression value) {
-    this.key = becomeParentOf(key);
-    this.value = becomeParentOf(value);
-  }
-
-  public DartExpression getKey() {
-    return key;
-  }
-
-  public DartExpression getValue() {
-    return value;
-  }
-
-  @Override
-  public void visitChildren(ASTVisitor<?> visitor) {
-    safelyVisitChild(key, visitor);
-    safelyVisitChild(value, visitor);
-  }
-
-  @Override
-  public <R> R accept(ASTVisitor<R> visitor) {
-    return visitor.visitMapLiteralEntry(this);
-  }
-}
diff --git a/compiler/java/com/google/dart/compiler/ast/DartMethodDefinition.java b/compiler/java/com/google/dart/compiler/ast/DartMethodDefinition.java
deleted file mode 100644
index c0092de..0000000
--- a/compiler/java/com/google/dart/compiler/ast/DartMethodDefinition.java
+++ /dev/null
@@ -1,143 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.ast;
-
-import com.google.dart.compiler.resolver.Element;
-import com.google.dart.compiler.resolver.MethodNodeElement;
-
-import java.util.Collections;
-import java.util.List;
-
-/**
- * Represents a Dart method definition.
- */
-public class DartMethodDefinition extends DartClassMember<DartExpression> {
-
-  protected DartFunction function;
-  private MethodNodeElement element;
-
-  public static DartMethodDefinition create(DartExpression name,
-                                            DartFunction function,
-                                            Modifiers modifiers,
-                                            List<DartInitializer> initializers) {
-    if (initializers == null) {
-      return new DartMethodDefinition(name, function, modifiers);
-    } else {
-      return new DartMethodWithInitializersDefinition(name, function, modifiers,
-                                                      initializers);
-    }
-  }
-
-  public static DartMethodDefinition create(DartExpression name,
-                                            DartFunction function,
-                                            Modifiers modifiers,
-                                            DartTypeNode redirectedTypeName,
-                                            DartIdentifier redirectedConstructorName) {
-    if (redirectedTypeName == null) {
-      return new DartMethodDefinition(name, function, modifiers);
-    } else {
-      return new DartMethodWithRedirectionDefinition(name, function, modifiers, redirectedTypeName,
-                                                     redirectedConstructorName);
-    }
-  }
-
-  private DartMethodDefinition(DartExpression name, DartFunction function, Modifiers modifiers) {
-    super(name, modifiers);
-    this.function = becomeParentOf(function);
-  }
-
-  public DartFunction getFunction() {
-    return function;
-  }
-
-  @Override
-  public MethodNodeElement getElement() {
-    return element;
-  }
-
-  @Override
-  public void setElement(Element element) {
-    this.element = (MethodNodeElement) element;
-  }
-
-  public List<DartInitializer> getInitializers() {
-    return Collections.emptyList();
-  }
-
-  public DartTypeNode getRedirectedTypeName() {
-    return null;
-  }
-
-  public DartIdentifier getRedirectedConstructorName() {
-    return null;
-  }
-
-  @Override
-  public void visitChildren(ASTVisitor<?> visitor) {
-    super.visitChildren(visitor);
-    safelyVisitChild(function, visitor);
-  }
-
-  @Override
-  public <R> R accept(ASTVisitor<R> visitor) {
-    return visitor.visitMethodDefinition(this);
-  }
-
-  private static class DartMethodWithInitializersDefinition extends DartMethodDefinition {
-
-    private final NodeList<DartInitializer> initializers = NodeList.create(this);
-
-    DartMethodWithInitializersDefinition(DartExpression name,
-                                         DartFunction function,
-                                         Modifiers modifiers,
-                                         List<DartInitializer> initializers) {
-      super(name, function, modifiers);
-      this.initializers.addAll(initializers);
-    }
-
-    @Override
-    public List<DartInitializer> getInitializers() {
-      return initializers;
-    }
-
-    @Override
-    public void visitChildren(ASTVisitor<?> visitor) {
-      super.visitChildren(visitor);
-      initializers.accept(visitor);
-    }
-  }
-
-  private static class DartMethodWithRedirectionDefinition extends DartMethodDefinition {
-    private DartTypeNode redirectedTypeName;
-    private DartIdentifier redirectedConstructorName;
-
-    DartMethodWithRedirectionDefinition(DartExpression name,
-                                         DartFunction function,
-                                         Modifiers modifiers,
-                                         DartTypeNode redirectedTypeName,
-                                         DartIdentifier redirectedConstructorName) {
-      super(name, function, modifiers);
-      this.redirectedTypeName = becomeParentOf(redirectedTypeName);
-      this.redirectedConstructorName = becomeParentOf(redirectedConstructorName);
-    }
-
-    @Override
-    public DartTypeNode getRedirectedTypeName() {
-      return redirectedTypeName;
-    }
-
-    @Override
-    public DartIdentifier getRedirectedConstructorName() {
-      return redirectedConstructorName;
-    }
-
-    @Override
-    public void visitChildren(ASTVisitor<?> visitor) {
-      super.visitChildren(visitor);
-      safelyVisitChild(redirectedTypeName, visitor);
-      safelyVisitChild(redirectedConstructorName, visitor);
-    }
-  }
-}
diff --git a/compiler/java/com/google/dart/compiler/ast/DartMethodInvocation.java b/compiler/java/com/google/dart/compiler/ast/DartMethodInvocation.java
deleted file mode 100644
index 4f3b0cd..0000000
--- a/compiler/java/com/google/dart/compiler/ast/DartMethodInvocation.java
+++ /dev/null
@@ -1,89 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.ast;
-
-import java.util.List;
-
-/**
- * Method invocation AST node. The name of the method must not be null. The receiver is an
- * expression, super, or a classname.
- * <p>
- * {@link DartMethodInvocation} may be created at the parsing time not only for invocation of actual
- * method, but also for invocation of function object in some object. For example:
- * 
- * <pre>
- *  class A {
- *    Function run;
- *  }
- *  test(A a) {
- *    a.run();
- *  }
- * </pre>
- */
-public class DartMethodInvocation extends DartInvocation {
-
-  private DartExpression target;
-  private boolean isCascade;
-  private DartIdentifier functionName;
-
-  public DartMethodInvocation(DartExpression target,
-      boolean isCascade,
-      DartIdentifier functionName,
-      List<DartExpression> args) {
-    super(args);
-    functionName.getClass(); // Quick null-check.
-    this.target = becomeParentOf(target);
-    this.isCascade = isCascade;
-    this.functionName = becomeParentOf(functionName);
-  }
-
-  @Override
-  public DartExpression getTarget() {
-    return target;
-  }
-
-  public DartExpression getRealTarget() {
-    if (isCascade) {
-      DartNode ancestor = getParent();
-      while (!(ancestor instanceof DartCascadeExpression)) {
-        if (ancestor == null) {
-          return target;
-        }
-        ancestor = ancestor.getParent();
-      }
-      return ((DartCascadeExpression) ancestor).getTarget();
-    }
-    return target;
-  }
-
-  public String getFunctionNameString() {
-    return functionName.getName();
-  }
-
-  public boolean isCascade() {
-    return isCascade;
-  }
-
-  public DartIdentifier getFunctionName() {
-    return functionName;
-  }
-
-  public void setFunctionName(DartIdentifier newName) {
-    newName.getClass(); // Quick null-check.
-    functionName = becomeParentOf(newName);
-  }
-
-  @Override
-  public void visitChildren(ASTVisitor<?> visitor) {
-    safelyVisitChild(target, visitor);
-    safelyVisitChild(functionName, visitor);
-    visitor.visit(getArguments());
-  }
-
-  @Override
-  public <R> R accept(ASTVisitor<R> visitor) {
-    return visitor.visitMethodInvocation(this);
-  }
-}
diff --git a/compiler/java/com/google/dart/compiler/ast/DartNamedExpression.java b/compiler/java/com/google/dart/compiler/ast/DartNamedExpression.java
deleted file mode 100644
index 434348c..0000000
--- a/compiler/java/com/google/dart/compiler/ast/DartNamedExpression.java
+++ /dev/null
@@ -1,38 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.ast;
-
-/**
- * Represents a labeled expression (used in named method arguments).
- */
-public class DartNamedExpression extends DartExpression {
-
-  private DartIdentifier name;
-  private DartExpression expression;
-
-  public DartNamedExpression(DartIdentifier ident, DartExpression expression) {
-    this.name = becomeParentOf(ident);
-    this.expression = becomeParentOf(expression);
-  }
-
-  public DartIdentifier getName() {
-    return name;
-  }
-
-  public DartExpression getExpression() {
-    return expression;
-  }
-
-  @Override
-  public void visitChildren(ASTVisitor<?> visitor) {
-    safelyVisitChild(name, visitor);
-    safelyVisitChild(expression, visitor);
-  }
-
-  @Override
-  public <R> R accept(ASTVisitor<R> visitor) {
-    return visitor.visitNamedExpression(this);
-  }
-}
diff --git a/compiler/java/com/google/dart/compiler/ast/DartNativeBlock.java b/compiler/java/com/google/dart/compiler/ast/DartNativeBlock.java
deleted file mode 100644
index 100a956..0000000
--- a/compiler/java/com/google/dart/compiler/ast/DartNativeBlock.java
+++ /dev/null
@@ -1,33 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.ast;
-
-
-/**
- * Unofficial Dart native block for built in native invocations.
- */
-public class DartNativeBlock extends DartBlock {
-
-  private final DartExpression body;
-
-  public DartNativeBlock(DartExpression body) {
-    super(null);
-    this.body = body;
-  }
-  
-  public DartExpression getBody() {
-    return body;
-  }
-
-  @Override
-  public void visitChildren(ASTVisitor<?> visitor) {
-    safelyVisitChild(body, visitor);
-  }
-
-  @Override
-  public <R> R accept(ASTVisitor<R> visitor) {
-    return visitor.visitNativeBlock(this);
-  }
-}
diff --git a/compiler/java/com/google/dart/compiler/ast/DartNativeDirective.java b/compiler/java/com/google/dart/compiler/ast/DartNativeDirective.java
deleted file mode 100644
index fb4d998..0000000
--- a/compiler/java/com/google/dart/compiler/ast/DartNativeDirective.java
+++ /dev/null
@@ -1,31 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.ast;
-
-/**
- * Implements the #native directive.
- */
-public class DartNativeDirective extends DartDirective {
-  private DartStringLiteral nativeUri;
-
-  public DartNativeDirective(DartStringLiteral nativeUri) {
-    this.nativeUri = becomeParentOf(nativeUri);
-  }
-
-  public DartStringLiteral getNativeUri() {
-    return nativeUri;
-  }
-
-  @Override
-  public void visitChildren(ASTVisitor<?> visitor) {
-    super.visitChildren(visitor);
-    safelyVisitChild(nativeUri, visitor);
-  }
-
-  @Override
-  public <R> R accept(ASTVisitor<R> visitor) {
-    return visitor.visitNativeDirective(this);
-  }
-}
diff --git a/compiler/java/com/google/dart/compiler/ast/DartNewExpression.java b/compiler/java/com/google/dart/compiler/ast/DartNewExpression.java
deleted file mode 100644
index c2b2a2d..0000000
--- a/compiler/java/com/google/dart/compiler/ast/DartNewExpression.java
+++ /dev/null
@@ -1,65 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.ast;
-
-import com.google.dart.compiler.resolver.ConstructorNodeElement;
-import com.google.dart.compiler.resolver.Element;
-import com.google.dart.compiler.type.Type;
-
-import java.util.List;
-
-/**
- * Represents a Dart 'new' expression.
- */
-public class DartNewExpression extends DartInvocation {
-
-  private DartNode constructor;
-  private ConstructorNodeElement element;
-  private final boolean isConst;
-
-  public DartNewExpression(DartNode constructor, List<DartExpression> args, boolean isConst) {
-    super(args);
-    this.constructor = becomeParentOf(constructor);
-    this.isConst = isConst;
-  }
-
-  public DartNode getConstructor() {
-    return constructor;
-  }
-
-  @Override
-  public Type getType() {
-    return constructor.getType();
-  }
-
-  public boolean isConst() {
-    return isConst;
-  }
-
-  @Override
-  public ConstructorNodeElement getElement() {
-    return element;
-  }
-
-  public void setConstructor(DartExpression newConstructor) {
-    constructor = becomeParentOf(newConstructor);
-  }
-
-  @Override
-  public void setElement(Element element) {
-    this.element = (ConstructorNodeElement) element;
-  }
-
-  @Override
-  public void visitChildren(ASTVisitor<?> visitor) {
-    safelyVisitChild(constructor, visitor);
-    visitor.visit(getArguments());
-  }
-
-  @Override
-  public <R> R accept(ASTVisitor<R> visitor) {
-    return visitor.visitNewExpression(this);
-  }
-}
diff --git a/compiler/java/com/google/dart/compiler/ast/DartNode.java b/compiler/java/com/google/dart/compiler/ast/DartNode.java
deleted file mode 100644
index 5079d1b..0000000
--- a/compiler/java/com/google/dart/compiler/ast/DartNode.java
+++ /dev/null
@@ -1,125 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.ast;
-
-import com.google.dart.compiler.common.AbstractNode;
-import com.google.dart.compiler.resolver.Element;
-import com.google.dart.compiler.type.Type;
-import com.google.dart.compiler.util.DefaultTextOutput;
-
-import java.util.List;
-
-/**
- * Base class for all Dart AST nodes.
- */
-public abstract class DartNode extends AbstractNode {
-  private DartNode parent;
-  private Type type;
-
-  public final String toSource() {
-    DefaultTextOutput out = new DefaultTextOutput(false);
-    accept(new DartToSourceVisitor(out));
-    return out.toString();
-  }
-
-  public Element getElement() {
-    return null;
-  }
-
-  public void setElement(Element element) {
-    throw new UnsupportedOperationException(getClass().getSimpleName());
-  }
-
-  public void setType(Type type) {
-    this.type = type;
-  }
-
-  public Type getType() {
-    return type;
-  }
-
-  @Override
-  public String toString() {
-    return this.toSource();
-  }
-
-  /**
-   * Returns this node's parent node, or <code>null</code> if this is the
-   * root node.
-   * <p>
-   * Note that the relationship between an AST node and its parent node
-   * may change over the lifetime of a node.
-   *
-   * @return the parent of this node, or <code>null</code> if none
-   */
-  public final DartNode getParent() {
-    return parent;
-  }
-
-  /**
-   * Return the node at the root of this node's AST structure. Note that this
-   * method's performance is linear with respect to the depth of the node in
-   * the AST structure (O(depth)).
-   *
-   * @return the node at the root of this node's AST structure
-   */
-  public final DartNode getRoot() {
-    DartNode root = this;
-    DartNode parent = getParent();
-    while (parent != null) {
-      root = parent;
-      parent = root.getParent();
-    }
-    return root;
-  }
-
-  protected <T extends DartNode> T becomeParentOf(T child) {
-    if (child != null) {
-      DartNode node = child; // Java 7 access rules require a temp of a concrete type.
-      node.setParent(this);
-    }
-    return child;
-  }
-
-  protected <L extends List<? extends DartNode>> L becomeParentOf(L children) {
-    if (children != null) {
-      for (DartNode child : children) {
-        child.setParent(this);
-      }
-    }
-    return children;
-  }
-
-  private void setParent(DartNode newParent) {
-    parent = newParent;
-  }
-
-  public abstract void visitChildren(ASTVisitor<?> visitor);
-
-  public abstract <R> R accept(ASTVisitor<R> visitor);
-
-  @Override
-  public DartNode clone() {
-    // TODO (fabiomfv) - Implement proper cloning when strictly needed.
-    return this;
-  }
-
-  public String getObjectIdentifier(){
-    return super.toString();
-  }
-
-  /**
-   * If the given child is not <code>null</code>, use the given visitor to visit it.
-   * 
-   * @param child the child to be visited
-   * @param visitor the visitor that will be used to visit the child
-   */
-  protected void safelyVisitChild(DartNode child, ASTVisitor<?> visitor) {
-    if (child != null) {
-      child.accept(visitor);
-    }
-  }
-  
-}
diff --git a/compiler/java/com/google/dart/compiler/ast/DartNodeWithMetadata.java b/compiler/java/com/google/dart/compiler/ast/DartNodeWithMetadata.java
deleted file mode 100644
index 995a0ae..0000000
--- a/compiler/java/com/google/dart/compiler/ast/DartNodeWithMetadata.java
+++ /dev/null
@@ -1,32 +0,0 @@
-// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.ast;
-
-import java.util.List;
-
-/**
- * The abstract class {@code DartNodeWithMetadata} defines the behavior of nodes that can have
- * metadata associated with them.
- */
-public abstract class DartNodeWithMetadata extends DartNode {
-  private NodeList<DartAnnotation> metadata = NodeList.create(this);
-
-  protected DartNodeWithMetadata() {
-    super();
-  }
-
-  public NodeList<DartAnnotation> getMetadata() {
-    return metadata;
-  }
-
-  public void setMetadata(List<DartAnnotation> metadata) {
-    this.metadata.addAll(metadata);
-  }
-
-  @Override
-  public void visitChildren(ASTVisitor<?> visitor) {
-    metadata.accept(visitor);
-  }
-}
diff --git a/compiler/java/com/google/dart/compiler/ast/DartNullLiteral.java b/compiler/java/com/google/dart/compiler/ast/DartNullLiteral.java
deleted file mode 100644
index 0a6486b..0000000
--- a/compiler/java/com/google/dart/compiler/ast/DartNullLiteral.java
+++ /dev/null
@@ -1,27 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.ast;
-
-/**
- * Represents a Dart 'null' literal value.
- */
-public class DartNullLiteral extends DartLiteral {
-
-  public static DartNullLiteral get() {
-    return new DartNullLiteral();
-  }
-
-  private DartNullLiteral() {
-  }
-
-  @Override
-  public void visitChildren(ASTVisitor<?> visitor) {
-  }
-
-  @Override
-  public <R> R accept(ASTVisitor<R> visitor) {
-    return visitor.visitNullLiteral(this);
-  }
-}
diff --git a/compiler/java/com/google/dart/compiler/ast/DartObsoleteMetadata.java b/compiler/java/com/google/dart/compiler/ast/DartObsoleteMetadata.java
deleted file mode 100644
index 45eeed9..0000000
--- a/compiler/java/com/google/dart/compiler/ast/DartObsoleteMetadata.java
+++ /dev/null
@@ -1,36 +0,0 @@
-// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.ast;
-
-/**
- * Some metadata information attached to the {@link DartDeclaration}. This has been superseded by
- * the metadata defined in the specification and will be removed in the near future.
- */
-public class DartObsoleteMetadata {
-  public static final DartObsoleteMetadata EMPTY = new DartObsoleteMetadata(false, false);
-  private boolean deprecated;
-  private boolean override;
-
-  private DartObsoleteMetadata(boolean deprecated, boolean override) {
-    this.deprecated = deprecated;
-    this.override = override;
-  }
-
-  public DartObsoleteMetadata makeDeprecated() {
-    return new DartObsoleteMetadata(true, override);
-  }
-
-  public DartObsoleteMetadata makeOverride() {
-    return new DartObsoleteMetadata(deprecated, true);
-  }
-
-  public boolean isDeprecated() {
-    return deprecated;
-  }
-
-  public boolean isOverride() {
-    return override;
-  }
-}
diff --git a/compiler/java/com/google/dart/compiler/ast/DartParameter.java b/compiler/java/com/google/dart/compiler/ast/DartParameter.java
deleted file mode 100644
index a620a2d..0000000
--- a/compiler/java/com/google/dart/compiler/ast/DartParameter.java
+++ /dev/null
@@ -1,102 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.ast;
-
-import com.google.common.base.Preconditions;
-import com.google.dart.compiler.resolver.Element;
-import com.google.dart.compiler.resolver.VariableElement;
-
-import java.util.List;
-
-/**
- * Represents a Dart function parameter.
- */
-public class DartParameter extends DartDeclaration<DartExpression> {
-
-  private VariableElement element;
-  private DartTypeNode typeNode;
-  private final NodeList<DartParameter> functionParameters;
-  private DartExpression defaultExpr;
-  private final Modifiers modifiers;
-
-  public DartParameter(DartExpression name,
-                       DartTypeNode typeNode,
-                       List<DartParameter> functionParameters,
-                       DartExpression defaultExpr,
-                       Modifiers modifiers) {
-    super(name);
-    Preconditions.checkArgument(name instanceof DartIdentifier
-      || name instanceof DartPropertyAccess, "name");
-    this.typeNode = becomeParentOf(typeNode);
-    if (functionParameters != null) {
-      this.functionParameters = NodeList.create(this);
-      this.functionParameters.addAll(functionParameters);
-    } else {
-      this.functionParameters = null;
-    }
-    this.defaultExpr = becomeParentOf(defaultExpr);
-    this.modifiers = modifiers;
-  }
-
-  public DartExpression getDefaultExpr() {
-    return defaultExpr;
-  }
-
-  public String getParameterName() {
-    // TODO(fabiomfv) remove instanceof (http://b/issue?id=4729144)
-    if (getName() instanceof DartIdentifier) {
-      return ((DartIdentifier)getName()).getName();
-    }
-    return ((DartPropertyAccess)getName()).getPropertyName();
-  }
-
-  @Override
-  public VariableElement getElement() {
-    return element;
-  }
-
-  public List<DartParameter> getFunctionParameters() {
-    return functionParameters;
-  }
-
-  public DartTypeNode getTypeNode() {
-    return typeNode;
-  }
-
-  public Modifiers getModifiers() {
-    return modifiers;
-  }
-
-  public DartNode getQualifier() {
-    if (getName() instanceof DartPropertyAccess) {
-      return ((DartPropertyAccess)getName()).getQualifier();
-    }
-    return null;
-  }
-
-  @Override
-  public void setElement(Element element) {
-    this.element = (VariableElement) element;
-  }
-
-  public void setTypeNode(DartTypeNode typeNode) {
-    this.typeNode = becomeParentOf(typeNode);
-  }
-
-  @Override
-  public void visitChildren(ASTVisitor<?> visitor) {
-    super.visitChildren(visitor);
-    safelyVisitChild(typeNode, visitor);
-    safelyVisitChild(defaultExpr, visitor);
-    if (functionParameters != null) {
-      functionParameters.accept(visitor);
-    }
-  }
-
-  @Override
-  public <R> R accept(ASTVisitor<R> visitor) {
-    return visitor.visitParameter(this);
-  }
-}
diff --git a/compiler/java/com/google/dart/compiler/ast/DartParameterizedTypeNode.java b/compiler/java/com/google/dart/compiler/ast/DartParameterizedTypeNode.java
deleted file mode 100644
index 60ecdf2..0000000
--- a/compiler/java/com/google/dart/compiler/ast/DartParameterizedTypeNode.java
+++ /dev/null
@@ -1,40 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.ast;
-
-import java.util.List;
-
-public class DartParameterizedTypeNode extends DartExpression {
-  private DartExpression expression;
-  private final NodeList<DartTypeParameter> typeParameters = NodeList.create(this);
-
-  public DartParameterizedTypeNode(DartExpression expression, List<DartTypeParameter> typeParameters) {
-    setExpression(expression);
-    this.typeParameters.addAll(typeParameters);
-  }
-
-  @Override
-  public <R> R accept(ASTVisitor<R> visitor) {
-    return visitor.visitParameterizedTypeNode(this);
-  }
-
-  public DartExpression getExpression() {
-    return expression;
-  }
-
-  public List<DartTypeParameter> getTypeParameters() {
-    return typeParameters;
-  }
-
-  public void setExpression(DartExpression expression) {
-    this.expression = expression;
-  }
-
-  @Override
-  public void visitChildren(ASTVisitor<?> visitor) {
-    safelyVisitChild(expression, visitor);
-    typeParameters.accept(visitor);
-  }
-}
diff --git a/compiler/java/com/google/dart/compiler/ast/DartParenthesizedExpression.java b/compiler/java/com/google/dart/compiler/ast/DartParenthesizedExpression.java
deleted file mode 100644
index 2a1a157..0000000
--- a/compiler/java/com/google/dart/compiler/ast/DartParenthesizedExpression.java
+++ /dev/null
@@ -1,35 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.ast;
-
-/**
- * Represents a Dart parenthesized expression.
- */
-public class DartParenthesizedExpression extends DartExpression {
-
-  private DartExpression expression;
-
-  public DartParenthesizedExpression(DartExpression expression) {
-    this.expression = becomeParentOf(expression);
-  }
-
-  public DartExpression getExpression() {
-    return expression;
-  }
-
-  public void setExpression(DartExpression newExpression) {
-    expression = newExpression;
-  }
-
-  @Override
-  public void visitChildren(ASTVisitor<?> visitor) {
-    safelyVisitChild(expression, visitor);
-  }
-
-  @Override
-  public <R> R accept(ASTVisitor<R> visitor) {
-    return visitor.visitParenthesizedExpression(this);
-  }
-}
diff --git a/compiler/java/com/google/dart/compiler/ast/DartPartOfDirective.java b/compiler/java/com/google/dart/compiler/ast/DartPartOfDirective.java
deleted file mode 100644
index 9d55581..0000000
--- a/compiler/java/com/google/dart/compiler/ast/DartPartOfDirective.java
+++ /dev/null
@@ -1,41 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.ast;
-
-/**
- * Implements the "part of" directive.
- */
-public class DartPartOfDirective extends DartDirective {
-  private final int ofOffset;
-  private final DartExpression name;
-
-  public DartPartOfDirective(int ofOffset, DartExpression name) {
-    this.ofOffset = ofOffset;
-    this.name = becomeParentOf(name);
-  }
-
-  public int getOfOffset() {
-    return ofOffset;
-  }
-
-  public DartExpression getName() {
-    return name;
-  }
-
-  public String getLibraryName() {
-    return name == null ? null : name.toSource();
-  }
-
-  @Override
-  public void visitChildren(ASTVisitor<?> visitor) {
-    super.visitChildren(visitor);
-    safelyVisitChild(name, visitor);
-  }
-
-  @Override
-  public <R> R accept(ASTVisitor<R> visitor) {
-    return visitor.visitPartOfDirective(this);
-  }
-}
diff --git a/compiler/java/com/google/dart/compiler/ast/DartPlainVisitor.java b/compiler/java/com/google/dart/compiler/ast/DartPlainVisitor.java
deleted file mode 100644
index 3d68e63..0000000
--- a/compiler/java/com/google/dart/compiler/ast/DartPlainVisitor.java
+++ /dev/null
@@ -1,144 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.ast;
-
-import java.util.List;
-
-public interface DartPlainVisitor<R> {
-
-  void visit(List<? extends DartNode> nodes);
-
-  R visitArrayAccess(DartArrayAccess node);
-
-  R visitArrayLiteral(DartArrayLiteral node);
-
-  R visitBinaryExpression(DartBinaryExpression node);
-
-  R visitBlock(DartBlock node);
-
-  R visitBooleanLiteral(DartBooleanLiteral node);
-
-  R visitBreakStatement(DartBreakStatement node);
-
-  R visitFunctionObjectInvocation(DartFunctionObjectInvocation node);
-
-  R visitMethodInvocation(DartMethodInvocation node);
-
-  R visitSuperConstructorInvocation(DartSuperConstructorInvocation node);
-
-  R visitCase(DartCase node);
-
-  R visitClass(DartClass node);
-
-  R visitConditional(DartConditional node);
-
-  R visitContinueStatement(DartContinueStatement node);
-
-  R visitDefault(DartDefault node);
-
-  R visitDoubleLiteral(DartDoubleLiteral node);
-
-  R visitDoWhileStatement(DartDoWhileStatement node);
-
-  R visitEmptyStatement(DartEmptyStatement node);
-
-  R visitExprStmt(DartExprStmt node);
-
-  R visitField(DartField node);
-
-  R visitFieldDefinition(DartFieldDefinition node);
-
-  R visitForInStatement(DartForInStatement node);
-
-  R visitForStatement(DartForStatement node);
-
-  R visitFunction(DartFunction node);
-
-  R visitFunctionExpression(DartFunctionExpression node);
-
-  R visitFunctionTypeAlias(DartFunctionTypeAlias node);
-
-  R visitIdentifier(DartIdentifier node);
-
-  R visitIfStatement(DartIfStatement node);
-
-  R visitImportDirective(DartImportDirective node);
-
-  R visitInitializer(DartInitializer node);
-
-  R visitIntegerLiteral(DartIntegerLiteral node);
-
-  R visitLabel(DartLabel node);
-
-  R visitLibraryDirective(DartLibraryDirective node);
-
-  R visitMapLiteral(DartMapLiteral node);
-
-  R visitMapLiteralEntry(DartMapLiteralEntry node);
-
-  R visitMethodDefinition(DartMethodDefinition node);
-
-  R visitNativeDirective(DartNativeDirective node);
-
-  R visitNewExpression(DartNewExpression node);
-
-  R visitNullLiteral(DartNullLiteral node);
-
-  R visitParameter(DartParameter node);
-
-  R visitParameterizedTypeNode(DartParameterizedTypeNode node);
-
-  R visitParenthesizedExpression(DartParenthesizedExpression node);
-
-  R visitPropertyAccess(DartPropertyAccess node);
-
-  R visitTypeNode(DartTypeNode node);
-
-  R visitReturnStatement(DartReturnStatement node);
-
-  R visitSourceDirective(DartSourceDirective node);
-
-  R visitStringLiteral(DartStringLiteral node);
-
-  R visitStringInterpolation(DartStringInterpolation node);
-
-  R visitSuperExpression(DartSuperExpression node);
-
-  R visitSwitchStatement(DartSwitchStatement node);
-
-  R visitSyntheticErrorExpression(DartSyntheticErrorExpression node);
-
-  R visitSyntheticErrorStatement(DartSyntheticErrorStatement node);
-
-  R visitThisExpression(DartThisExpression node);
-
-  R visitThrowExpression(DartThrowExpression node);
-
-  R visitCatchBlock(DartCatchBlock node);
-
-  R visitTryStatement(DartTryStatement node);
-
-  R visitUnaryExpression(DartUnaryExpression node);
-
-  R visitUnit(DartUnit node);
-
-  R visitUnqualifiedInvocation(DartUnqualifiedInvocation node);
-
-  R visitVariable(DartVariable node);
-
-  R visitVariableStatement(DartVariableStatement node);
-
-  R visitWhileStatement(DartWhileStatement node);
-
-  R visitNamedExpression(DartNamedExpression node);
-
-  R visitTypeExpression(DartTypeExpression node);
-
-  R visitTypeParameter(DartTypeParameter node);
-
-  R visitNativeBlock(DartNativeBlock node);
-
-  R visitRedirectConstructorInvocation(DartRedirectConstructorInvocation node);
-}
diff --git a/compiler/java/com/google/dart/compiler/ast/DartPropertyAccess.java b/compiler/java/com/google/dart/compiler/ast/DartPropertyAccess.java
deleted file mode 100644
index 9c1c903..0000000
--- a/compiler/java/com/google/dart/compiler/ast/DartPropertyAccess.java
+++ /dev/null
@@ -1,87 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.ast;
-
-import com.google.dart.compiler.resolver.Element;
-
-/**
- * Represents a Dart property access expression (a.b).
- */
-public class DartPropertyAccess extends DartExpression {
-
-  private DartNode qualifier;
-  private boolean isCascade;
-  private DartIdentifier name;
-
-  public DartPropertyAccess(DartNode qualifier, DartIdentifier name) {
-    this(qualifier, false, name);
-  }
-
-  public DartPropertyAccess(DartNode qualifier, boolean isCascade, DartIdentifier name) {
-    this.qualifier = becomeParentOf(qualifier);
-    this.isCascade = isCascade;
-    this.name = becomeParentOf(name);
-  }
-
-  @Override
-  public boolean isAssignable() {
-    return true;
-  }
-
-  public boolean isCascade() {
-    return isCascade;
-  }
-
-  public String getPropertyName() {
-    return name.getName();
-  }
-
-  public DartIdentifier getName() {
-    return name;
-  }
-
-  public DartNode getQualifier() {
-    return qualifier;
-  }
-
-  public DartNode getRealTarget() {
-    if (isCascade) {
-      DartNode ancestor = getParent();
-      while (!(ancestor instanceof DartCascadeExpression)) {
-        if (ancestor == null) {
-          return qualifier;
-        }
-        ancestor = ancestor.getParent();
-      }
-      return ((DartCascadeExpression) ancestor).getTarget();
-    }
-    return qualifier;
-  }
-
-  public void setName(DartIdentifier newName) {
-    name = becomeParentOf(newName);
-  }
-
-  @Override
-  public void setElement(Element element) {
-    name.setElement(element);
-  }
-
-  @Override
-  public Element getElement() {
-    return name.getElement();
-  }
-
-  @Override
-  public void visitChildren(ASTVisitor<?> visitor) {
-    safelyVisitChild(qualifier, visitor);
-    safelyVisitChild(name, visitor);
-  }
-
-  @Override
-  public <R> R accept(ASTVisitor<R> visitor) {
-    return visitor.visitPropertyAccess(this);
-  }
-}
diff --git a/compiler/java/com/google/dart/compiler/ast/DartRedirectConstructorInvocation.java b/compiler/java/com/google/dart/compiler/ast/DartRedirectConstructorInvocation.java
deleted file mode 100644
index 3697326..0000000
--- a/compiler/java/com/google/dart/compiler/ast/DartRedirectConstructorInvocation.java
+++ /dev/null
@@ -1,49 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.ast;
-
-import com.google.dart.compiler.resolver.ConstructorNodeElement;
-import com.google.dart.compiler.resolver.Element;
-
-import java.util.List;
-
-/**
- * Redirected constructor invocation AST node.
- */
-public class DartRedirectConstructorInvocation extends DartInvocation {
-
-  private DartIdentifier name;
-  private ConstructorNodeElement element;
-
-  public DartRedirectConstructorInvocation(DartIdentifier name, List<DartExpression> args) {
-    super(args);
-    this.name = becomeParentOf(name);
-  }
-
-  public DartIdentifier getName() {
-    return name;
-  }
-
-  @Override
-  public void setElement(Element element) {
-    this.element = (ConstructorNodeElement) element;
-  }
-
-  @Override
-  public ConstructorNodeElement getElement() {
-    return element;
-  }
-
-  @Override
-  public void visitChildren(ASTVisitor<?> visitor) {
-    safelyVisitChild(name, visitor);
-    visitor.visit(getArguments());
-  }
-
-  @Override
-  public <R> R accept(ASTVisitor<R> visitor) {
-    return visitor.visitRedirectConstructorInvocation(this);
-  }
-}
diff --git a/compiler/java/com/google/dart/compiler/ast/DartReturnBlock.java b/compiler/java/com/google/dart/compiler/ast/DartReturnBlock.java
deleted file mode 100644
index 2ab69ce..0000000
--- a/compiler/java/com/google/dart/compiler/ast/DartReturnBlock.java
+++ /dev/null
@@ -1,29 +0,0 @@
-// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-package com.google.dart.compiler.ast;
-
-import com.google.common.collect.Lists;
-
-/**
- * Represents a Dart block containing a single return statement.
- */
-public class DartReturnBlock extends DartBlock {
-  private final DartExpression value;
-
-  public DartReturnBlock(DartExpression value) {
-    super(Lists.<DartStatement> newArrayList(new DartReturnStatement(value)));
-    this.value = value;
-    // Set the source information for the synthesized node.
-    getStatements().get(0).setSourceInfo(value.getSourceInfo());
-  }
-
-  @Override
-  public <R> R accept(ASTVisitor<R> visitor) {
-    return visitor.visitReturnBlock(this);
-  }
-
-  public DartExpression getValue() {
-    return value;
-  }
-}
diff --git a/compiler/java/com/google/dart/compiler/ast/DartReturnStatement.java b/compiler/java/com/google/dart/compiler/ast/DartReturnStatement.java
deleted file mode 100644
index 8148fcc..0000000
--- a/compiler/java/com/google/dart/compiler/ast/DartReturnStatement.java
+++ /dev/null
@@ -1,36 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.ast;
-
-/**
- * Represents a Dart 'return' statement.
- */
-public class DartReturnStatement extends DartStatement {
-
-  private DartExpression value;
-
-  public DartReturnStatement(DartExpression value) {
-    this.value = becomeParentOf(value);
-  }
-
-  public DartExpression getValue() {
-    return value;
-  }
-
-  @Override
-  public boolean isAbruptCompletingStatement() {
-    return true;
-  }
-
-  @Override
-  public void visitChildren(ASTVisitor<?> visitor) {
-    safelyVisitChild(value, visitor);
-  }
-
-  @Override
-  public <R> R accept(ASTVisitor<R> visitor) {
-    return visitor.visitReturnStatement(this);
-  }
-}
diff --git a/compiler/java/com/google/dart/compiler/ast/DartSourceDirective.java b/compiler/java/com/google/dart/compiler/ast/DartSourceDirective.java
deleted file mode 100644
index 427f006..0000000
--- a/compiler/java/com/google/dart/compiler/ast/DartSourceDirective.java
+++ /dev/null
@@ -1,31 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.ast;
-
-/**
- * Implements the #source directive.
- */
-public class DartSourceDirective extends DartDirective {
-  private DartStringLiteral sourceUri;
-
-  public DartSourceDirective(DartStringLiteral sourceUri) {
-    this.sourceUri = becomeParentOf(sourceUri);
-  }
-
-  public DartStringLiteral getSourceUri() {
-    return sourceUri;
-  }
-
-  @Override
-  public void visitChildren(ASTVisitor<?> visitor) {
-    super.visitChildren(visitor);
-    safelyVisitChild(sourceUri, visitor);
-  }
-
-  @Override
-  public <R> R accept(ASTVisitor<R> visitor) {
-    return visitor.visitSourceDirective(this);
-  }
-}
diff --git a/compiler/java/com/google/dart/compiler/ast/DartStatement.java b/compiler/java/com/google/dart/compiler/ast/DartStatement.java
deleted file mode 100644
index e069415..0000000
--- a/compiler/java/com/google/dart/compiler/ast/DartStatement.java
+++ /dev/null
@@ -1,14 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.ast;
-
-/**
- * Abstract base class for Dart statement objects.
- */
-public abstract class DartStatement extends DartNode {
-  public boolean isAbruptCompletingStatement() {
-    return false;
-  }
-}
diff --git a/compiler/java/com/google/dart/compiler/ast/DartStringInterpolation.java b/compiler/java/com/google/dart/compiler/ast/DartStringInterpolation.java
deleted file mode 100644
index 143f156..0000000
--- a/compiler/java/com/google/dart/compiler/ast/DartStringInterpolation.java
+++ /dev/null
@@ -1,55 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.ast;
-
-import com.google.common.base.Preconditions;
-
-import java.util.List;
-
-/**
- * Represents a Dart string interpolation of the form: "1 ${a} 2 ${b} 3".
- */
-public class DartStringInterpolation extends DartLiteral {
-
-  /**
-   * Literal string portions. The interpolation alternates between strings and
-   * expressions. We preserve the invariant that {@code string.size() =
-   * expressions.size() + 1}. Empty string constants are used to represent
-   * adjacent expressions (e.g. $"${a} ${b}${c}" is represented by 4 strings
-   * ("", " ", "", "") and 3 expressions (#(){a}, #(){b}, #(){c}).
-   */
-  private final NodeList<DartStringLiteral> strings = NodeList.create(this);;
-
-  /** Embedded expressions (see {@link strings} for details). */
-  private final NodeList<DartExpression> expressions = NodeList.create(this);
-
-  public DartStringInterpolation(List<DartStringLiteral> strings,
-      List<DartExpression> expressions) {
-    Preconditions.checkNotNull(strings);
-    Preconditions.checkNotNull(expressions);
-    Preconditions.checkArgument(strings.size() == expressions.size() + 1);
-    this.strings.addAll(strings);
-    this.expressions.addAll(expressions);
-  }
-
-  public List<DartStringLiteral> getStrings() {
-    return strings;
-  }
-
-  public List<DartExpression> getExpressions() {
-    return expressions;
-  }
-
-  @Override
-  public void visitChildren(ASTVisitor<?> visitor) {
-    strings.accept(visitor);
-    expressions.accept(visitor);
-  }
-
-  @Override
-  public <R> R accept(ASTVisitor<R> visitor) {
-    return visitor.visitStringInterpolation(this);
-  }
-}
diff --git a/compiler/java/com/google/dart/compiler/ast/DartStringLiteral.java b/compiler/java/com/google/dart/compiler/ast/DartStringLiteral.java
deleted file mode 100644
index 9aacf4e..0000000
--- a/compiler/java/com/google/dart/compiler/ast/DartStringLiteral.java
+++ /dev/null
@@ -1,69 +0,0 @@
-// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.ast;
-
-import com.google.common.collect.ImmutableList;
-import com.google.dart.compiler.resolver.Element;
-import com.google.dart.compiler.util.StringInterner;
-
-import java.util.List;
-
-/**
- * Represents a Dart string literal value.
- */
-public class DartStringLiteral extends DartLiteral {
-  
-  private Element element;
-
-  public static DartStringLiteral get(String x) {
-    return new DartStringLiteral(x, null);
-  }
-
-  public static DartStringLiteral get(String x, List<DartStringLiteral> parts) {
-    return new DartStringLiteral(x, parts);
-  }
-
-  private final String value;
-  private final List<DartStringLiteral> parts;
-
-  private DartStringLiteral(String value, List<DartStringLiteral> parts) {
-    this.value = StringInterner.intern(value);
-    this.parts = parts;
-  }
-
-  public String getValue() {
-    return value;
-  }
-
-  /**
-   * @return the adjacent literals (separated only by whitespace) which consist this
-   *         {@link DartStringLiteral}.
-   */
-  public List<DartStringLiteral> getParts() {
-    if (parts == null) {
-      return ImmutableList.of(this);
-    }
-    return parts;
-  }
-  
-  @Override
-  public void setElement(Element element) {
-    this.element = element;
-  }
-  
-  @Override
-  public Element getElement() {
-    return element;
-  }
-
-  @Override
-  public void visitChildren(ASTVisitor<?> visitor) {
-  }
-
-  @Override
-  public <R> R accept(ASTVisitor<R> visitor) {
-    return visitor.visitStringLiteral(this);
-  }
-}
diff --git a/compiler/java/com/google/dart/compiler/ast/DartSuperConstructorInvocation.java b/compiler/java/com/google/dart/compiler/ast/DartSuperConstructorInvocation.java
deleted file mode 100644
index ddf3a0e..0000000
--- a/compiler/java/com/google/dart/compiler/ast/DartSuperConstructorInvocation.java
+++ /dev/null
@@ -1,60 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.ast;
-
-import com.google.dart.compiler.resolver.ConstructorNodeElement;
-import com.google.dart.compiler.resolver.Element;
-
-import java.util.List;
-
-/**
- * Super constructor invocation AST node.
- */
-public class DartSuperConstructorInvocation extends DartInvocation {
-
-  private DartIdentifier name;
-  private ConstructorNodeElement element;
-
-  public DartSuperConstructorInvocation(DartIdentifier name, List<DartExpression> args) {
-    super(args);
-    this.name = becomeParentOf(name);
-  }
-
-  public String getConstructorName() {
-    if (name == null) {
-      return null;
-    }
-    return name.getName();
-  }
-
-  public DartIdentifier getName() {
-    return name;
-  }
-
-  public void setName(DartIdentifier newName) {
-    name = becomeParentOf(newName);
-  }
-
-  @Override
-  public void setElement(Element element) {
-    this.element = (ConstructorNodeElement) element;
-  }
-
-  @Override
-  public ConstructorNodeElement getElement() {
-    return element;
-  }
-
-  @Override
-  public void visitChildren(ASTVisitor<?> visitor) {
-    safelyVisitChild(name, visitor);
-    visitor.visit(getArguments());
-  }
-
-  @Override
-  public <R> R accept(ASTVisitor<R> visitor) {
-    return visitor.visitSuperConstructorInvocation(this);
-  }
-}
diff --git a/compiler/java/com/google/dart/compiler/ast/DartSuperExpression.java b/compiler/java/com/google/dart/compiler/ast/DartSuperExpression.java
deleted file mode 100644
index aa30b0e..0000000
--- a/compiler/java/com/google/dart/compiler/ast/DartSuperExpression.java
+++ /dev/null
@@ -1,42 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.ast;
-
-import com.google.dart.compiler.resolver.Element;
-import com.google.dart.compiler.resolver.SuperElement;
-
-/**
- * Represents a Dart 'super' expression.
- */
-public class DartSuperExpression extends DartExpression {
-
-  private SuperElement element;
-
-  public static DartSuperExpression get() {
-    return new DartSuperExpression();
-  }
-
-  private DartSuperExpression() {
-  }
-
-  @Override
-  public void setElement(Element element) {
-    this.element = (SuperElement) element;
-  }
-
-  @Override
-  public SuperElement getElement() {
-    return element;
-  }
-
-  @Override
-  public void visitChildren(ASTVisitor<?> visitor) {
-  }
-
-  @Override
-  public <R> R accept(ASTVisitor<R> visitor) {
-    return visitor.visitSuperExpression(this);
-  }
-}
diff --git a/compiler/java/com/google/dart/compiler/ast/DartSwitchMember.java b/compiler/java/com/google/dart/compiler/ast/DartSwitchMember.java
deleted file mode 100644
index 6bc889d..0000000
--- a/compiler/java/com/google/dart/compiler/ast/DartSwitchMember.java
+++ /dev/null
@@ -1,35 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.ast;
-
-import java.util.List;
-
-/**
- * Represents a Dart 'switch' member ('case' or 'default').
- */
-public abstract class DartSwitchMember extends DartNode {
-
-  private final NodeList<DartStatement> statements = NodeList.create(this);
-  private final NodeList<DartLabel> labels = NodeList.create(this);
-
-  public DartSwitchMember(List<DartLabel> labels, List<DartStatement> statements) {
-    this.labels.addAll(labels);
-    this.statements.addAll(statements);
-  }
-
-  public List<DartStatement> getStatements() {
-    return statements;
-  }
-
-  public List<DartLabel> getLabels() {
-    return labels;
-  }
-
-  @Override
-  public void visitChildren(ASTVisitor<?> visitor) {
-    labels.accept(visitor);
-    statements.accept(visitor);
-  }
-}
diff --git a/compiler/java/com/google/dart/compiler/ast/DartSwitchStatement.java b/compiler/java/com/google/dart/compiler/ast/DartSwitchStatement.java
deleted file mode 100644
index 985ec00..0000000
--- a/compiler/java/com/google/dart/compiler/ast/DartSwitchStatement.java
+++ /dev/null
@@ -1,40 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.ast;
-
-import java.util.List;
-
-/**
- * Represents a Dart 'switch' statement.
- */
-public class DartSwitchStatement extends DartStatement {
-
-  private DartExpression expression;
-  private final NodeList<DartSwitchMember> members = NodeList.create(this);
-
-  public DartSwitchStatement(DartExpression expression, List<DartSwitchMember> members) {
-    this.expression = becomeParentOf(expression);
-    this.members.addAll(members);
-  }
-
-  public DartExpression getExpression() {
-    return expression;
-  }
-
-  public List<DartSwitchMember> getMembers() {
-    return members;
-  }
-
-  @Override
-  public void visitChildren(ASTVisitor<?> visitor) {
-    safelyVisitChild(expression, visitor);
-    members.accept(visitor);
-  }
-
-  @Override
-  public <R> R accept(ASTVisitor<R> visitor) {
-    return visitor.visitSwitchStatement(this);
-  }
-}
diff --git a/compiler/java/com/google/dart/compiler/ast/DartSyntheticErrorExpression.java b/compiler/java/com/google/dart/compiler/ast/DartSyntheticErrorExpression.java
deleted file mode 100644
index d2d31b9..0000000
--- a/compiler/java/com/google/dart/compiler/ast/DartSyntheticErrorExpression.java
+++ /dev/null
@@ -1,33 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-package com.google.dart.compiler.ast;
-
-/**
- * An expression node representing an unparseable expression.
- */
-public class DartSyntheticErrorExpression extends DartExpression {
-
-  private final String tokenString;
-
-  public DartSyntheticErrorExpression() {
-    this(null);
-  }
-
-  public DartSyntheticErrorExpression(String tokenString) {
-    this.tokenString = tokenString;
-  }
-
-  @Override
-  public <R> R accept(ASTVisitor<R> visitor) {
-    return visitor.visitSyntheticErrorExpression(this);
-  }
-
-  public String getTokenString() {
-    return tokenString;
-  }
-
-  @Override
-  public void visitChildren(ASTVisitor<?> visitor) {
-  }
-}
diff --git a/compiler/java/com/google/dart/compiler/ast/DartSyntheticErrorIdentifier.java b/compiler/java/com/google/dart/compiler/ast/DartSyntheticErrorIdentifier.java
deleted file mode 100644
index 55f780f..0000000
--- a/compiler/java/com/google/dart/compiler/ast/DartSyntheticErrorIdentifier.java
+++ /dev/null
@@ -1,29 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file
-package com.google.dart.compiler.ast;
-
-/**
- * This node is created by the parser when it cannot find a proper identifier token in the input
- * stream.  The token might not have been consumed, or was a reserved word, so the name of the
- * identifier is left blank.
- */
-public class DartSyntheticErrorIdentifier extends DartIdentifier {
-
-  private final String tokenString;
-
-  public DartSyntheticErrorIdentifier() {
-    super("");
-    this.tokenString = "";
-  }
-
-  @Override
-  public <R> R accept(ASTVisitor<R> visitor) {
-    return visitor.visitSyntheticErrorIdentifier(this);
-  }
-
-  public String getTokenString() {
-    return tokenString;
-  }
-
-}
diff --git a/compiler/java/com/google/dart/compiler/ast/DartSyntheticErrorStatement.java b/compiler/java/com/google/dart/compiler/ast/DartSyntheticErrorStatement.java
deleted file mode 100644
index 5b7c5c4..0000000
--- a/compiler/java/com/google/dart/compiler/ast/DartSyntheticErrorStatement.java
+++ /dev/null
@@ -1,33 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-package com.google.dart.compiler.ast;
-
-/**
- * A statement node representing an unparseable statement.
- */
-public class DartSyntheticErrorStatement extends DartStatement {
-
-  private final String tokenString;
-
-  public DartSyntheticErrorStatement() {
-    this(null);
-  }
-
-  public DartSyntheticErrorStatement(String tokenString) {
-    this.tokenString = tokenString;
-  }
-
-  @Override
-  public <R> R accept(ASTVisitor<R> visitor) {
-    return visitor.visitSyntheticErrorStatement(this);
-  }
-
-  public String getTokenString() {
-    return tokenString;
-  }
-
-  @Override
-  public void visitChildren(ASTVisitor<?> visitor) {
-  }
-}
diff --git a/compiler/java/com/google/dart/compiler/ast/DartThisExpression.java b/compiler/java/com/google/dart/compiler/ast/DartThisExpression.java
deleted file mode 100644
index 07097bf..0000000
--- a/compiler/java/com/google/dart/compiler/ast/DartThisExpression.java
+++ /dev/null
@@ -1,27 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.ast;
-
-/**
- * Represents a Dart 'this' expression.
- */
-public class DartThisExpression extends DartExpression {
-
-  public static DartThisExpression get() {
-    return new DartThisExpression();
-  }
-
-  private DartThisExpression() {
-  }
-
-  @Override
-  public void visitChildren(ASTVisitor<?> visitor) {
-  }
-
-  @Override
-  public <R> R accept(ASTVisitor<R> visitor) {
-    return visitor.visitThisExpression(this);
-  }
-}
diff --git a/compiler/java/com/google/dart/compiler/ast/DartThrowExpression.java b/compiler/java/com/google/dart/compiler/ast/DartThrowExpression.java
deleted file mode 100644
index 7904d41..0000000
--- a/compiler/java/com/google/dart/compiler/ast/DartThrowExpression.java
+++ /dev/null
@@ -1,31 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.ast;
-
-/**
- * Represents a Dart 'throw' expression.
- */
-public class DartThrowExpression extends DartExpression {
-
-  private DartExpression exception;
-
-  public DartThrowExpression(DartExpression exception) {
-    this.exception = becomeParentOf(exception);
-  }
-
-  public DartExpression getException() {
-    return exception;
-  }
-
-  @Override
-  public void visitChildren(ASTVisitor<?> visitor) {
-    safelyVisitChild(exception, visitor);
-  }
-
-  @Override
-  public <R> R accept(ASTVisitor<R> visitor) {
-    return visitor.visitThrowExpression(this);
-  }
-}
diff --git a/compiler/java/com/google/dart/compiler/ast/DartToSourceVisitor.java b/compiler/java/com/google/dart/compiler/ast/DartToSourceVisitor.java
deleted file mode 100644
index d7c2597..0000000
--- a/compiler/java/com/google/dart/compiler/ast/DartToSourceVisitor.java
+++ /dev/null
@@ -1,1050 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.ast;
-
-import com.google.dart.compiler.util.TextOutput;
-
-import java.util.Iterator;
-import java.util.List;
-
-/**
- * Used by {@link DartNode} to generate Dart source from an AST subtree.
- */
-public class DartToSourceVisitor extends ASTVisitor<Void> {
-
-  private final TextOutput out;
-
-  public DartToSourceVisitor(TextOutput out) {
-    this.out = out;
-  }
-
-  @Override
-  public Void visitUnit(DartUnit x) {
-    p("// unit " + x.getSourceName());
-    nl();
-    return super.visitUnit(x);
-  }
-
-  @Override
-  public Void visitComment(DartComment node) {
-    return null;
-  }
-
-  @Override
-  public Void visitNativeBlock(DartNativeBlock x) {
-    p("native;");
-    return null;
-  }
-
-  private void accept(DartNode x) {
-    x.accept(this);
-  }
-
-  private void acceptList(List<? extends DartNode> xs) {
-    for (DartNode x : xs) {
-      x.accept(this);
-    }
-  }
-
-  private void pTypeParameters(List<DartTypeParameter> typeParameters) {
-    if (typeParameters != null && !typeParameters.isEmpty()) {
-      p("<");
-      boolean first = true;
-      for (DartNode node : typeParameters) {
-        if (!first) {
-          p(", ");
-        }
-        accept(node);
-        first = false;
-      }
-      p(">");
-    }
-  }
-
-  @Override
-  public Void visitLibraryDirective(DartLibraryDirective node) {
-    if (node.isObsoleteFormat()) {
-      p("#library(");
-      accept(node.getName());
-      p(");");
-      nl();
-    } else {
-      p("library ");
-      accept(node.getName());
-      p(";");
-      nl();
-    }
-    return null;
-  }
-
-  @SuppressWarnings("deprecation")
-  @Override
-  public Void visitImportDirective(DartImportDirective node) {
-    if (node.isObsoleteFormat()) {
-      p("#import(");
-      accept(node.getLibraryUri());
-      if (node.getOldPrefix() != null) {
-        p(", prefix : ");
-        accept(node.getOldPrefix());
-      }
-      p(");");
-      nl();
-    } else {
-      p("import ");
-      accept(node.getLibraryUri());
-      if (node.getPrefix() != null) {
-        p(" as ");
-        accept(node.getPrefix());
-      }
-      for (ImportCombinator combinator : node.getCombinators()) {
-        accept(combinator);
-      }
-      if (node.isExported()) {
-        p(" & export");
-      }
-      p(";");
-      nl();
-    }
-    return null;
-  }
-
-  @Override
-  public Void visitFunctionTypeAlias(DartFunctionTypeAlias x) {
-    p("typedef ");
-
-    if (x.getReturnTypeNode() != null) {
-      accept(x.getReturnTypeNode());
-    }
-
-    p(" ");
-    accept(x.getName());
-    pTypeParameters(x.getTypeParameters());
-
-    p("(");
-    printSeparatedByComma(x.getParameters());
-    p(")");
-
-    p(";");
-    nl();
-    nl();
-    return null;
-  }
-
-  @Override
-  public Void visitClass(DartClass x) {
-    if (x.isInterface()) {
-      p("interface ");
-    } else {
-      p("class ");
-    }
-    accept(x.getName());
-    pTypeParameters(x.getTypeParameters());
-
-    if (x.getSuperclass() != null) {
-      p(" extends ");
-      accept(x.getSuperclass());
-    }
-
-    List<DartTypeNode> interfaces = x.getInterfaces();
-    if (interfaces != null && !interfaces.isEmpty()) {
-      if (x.isInterface()) {
-        p(" extends ");
-      } else {
-        p(" implements ");
-      }
-      boolean first = true;
-      for (DartTypeNode cls : interfaces) {
-        if (!first) {
-          p(", ");
-        }
-        accept(cls);
-        first = false;
-      }
-    }
-
-    if (x.getNativeName() != null) {
-      p(" native ");
-      accept(x.getNativeName());
-    }
-
-    if (x.getDefaultClass() != null) {
-      p(" default ");
-      accept(x.getDefaultClass());
-    }
-
-    p(" {");
-    nl();
-    indent();
-
-    acceptList(x.getMembers());
-
-    outdent();
-    p("}");
-    nl();
-    nl();
-    return null;
-  }
-
-  @Override
-  public Void visitTypeNode(DartTypeNode x) {
-    accept(x.getIdentifier());
-    List<DartTypeNode> arguments = x.getTypeArguments();
-    if (arguments != null && !arguments.isEmpty()) {
-      p("<");
-      printSeparatedByComma(arguments);
-      p(">");
-    }
-    return null;
-  }
-
-  @Override
-  public Void visitTypeParameter(DartTypeParameter x) {
-    accept(x.getName());
-    DartTypeNode bound = x.getBound();
-    if (bound != null) {
-      p(" extends ");
-      accept(bound);
-    }
-    return null;
-  }
-
-  @Override
-  public Void visitFieldDefinition(DartFieldDefinition x) {
-    Modifiers modifiers = x.getFields().get(0).getModifiers();
-    if (modifiers.isAbstractField()) {
-      pAbstractField(x);
-    } else {
-      pFieldModifiers(x);
-      if (x.getTypeNode() != null) {
-        accept(x.getTypeNode());
-        p(" ");
-      } else {
-        if (!modifiers.isFinal()) {
-          p("var ");
-        }
-      }
-      printSeparatedByComma(x.getFields());
-      p(";");
-    }
-
-    nl();
-
-    return null;
-  }
-
-  @Override
-  public Void visitField(DartField x) {
-    accept(x.getName());
-    if (x.getValue() != null) {
-      p(" = ");
-      accept(x.getValue());
-    }
-    return null;
-  }
-
-  @Override
-  public Void visitParameter(DartParameter x) {
-    if (x.getModifiers().isFinal()) {
-      p("final ");
-    }
-    if (x.getTypeNode() != null) {
-      accept(x.getTypeNode());
-      p(" ");
-    }
-    accept(x.getName());
-    if (x.getFunctionParameters() != null) {
-      p("(");
-      printSeparatedByComma(x.getFunctionParameters());
-      p(")");
-    }
-    if (x.getDefaultExpr() != null) {
-      if (x.getModifiers().isOptional()) {
-        p(" = ");
-      }
-      if (x.getModifiers().isNamed()) {
-        p(" : ");
-      }
-      accept(x.getDefaultExpr());
-    }
-    return null;
-  }
-
-  @Override
-  public Void visitMethodDefinition(DartMethodDefinition x) {
-    nl();
-    pMethodModifiers(x);
-    // return type
-    DartFunction func = x.getFunction();
-    if (func.getReturnTypeNode() != null) {
-      accept(func.getReturnTypeNode());
-      p(" ");
-    }
-    // special methods
-    if (x.getModifiers().isOperator()) {
-      p("operator ");
-    } else if (x.getModifiers().isGetter()) {
-      p("get ");
-    } else if (x.getModifiers().isSetter()) {
-      p("set ");
-    }
-    // name
-    pFunctionDeclaration(x.getName(), func, !x.getModifiers().isGetter());
-    p(" ");
-    // initializers
-    List<DartInitializer> inits = x.getInitializers();
-    if (!inits.isEmpty()) {
-      p(": ");
-      for (int i = 0; i < inits.size(); ++i) {
-        accept(inits.get(i));
-        if (i < inits.size() - 1) {
-          p(", ");
-        }
-      }
-    }
-    // body
-    if (x.getFunction().getBody() != null) {
-      accept(x.getFunction().getBody());
-    } else if (x.getRedirectedTypeName() != null) {
-      p(" = ");
-      accept(x.getRedirectedTypeName());
-      if (x.getRedirectedConstructorName() != null) {
-        p(".");
-        accept(x.getRedirectedConstructorName());
-      }
-      p(";");
-      nl();
-    } else {
-      p(";");
-      nl();
-    }
-    // done
-    return null;
-  }
-
-  @Override
-  public Void visitInitializer(DartInitializer x) {
-    if (!x.isInvocation()) {
-      p("this.");
-      p(x.getInitializerName());
-      p(" = ");
-    }
-    accept(x.getValue());
-    return null;
-  }
-
-  private void pBlock(DartBlock x, boolean newline) {
-    p("{");
-    nl();
-
-    indent();
-    acceptList(x.getStatements());
-    outdent();
-
-    p("}");
-    if (newline) {
-      nl();
-    }
-  }
-
-  private void pFunctionDeclaration(DartNode name, DartFunction x, boolean includeParameters) {
-    if (name != null) {
-      accept(name);
-    }
-    if (includeParameters) {
-      p("(");
-      pFormalParameters(x.getParameters());
-      p(")");
-    }
-  }
-
-  private void pFormalParameters(List<DartParameter> params) {
-    boolean first = true, hasPositional = false, hasNamed = false;
-    for (DartParameter param : params) {
-      if (!first) {
-        p(", ");
-      }
-      if (!hasPositional && param.getModifiers().isOptional()) {
-        hasPositional = true;
-        p("[");
-      }
-      if (!hasNamed && param.getModifiers().isNamed()) {
-        hasNamed = true;
-        p("{");
-      }
-      accept(param);
-      first = false;
-    }
-    if (hasPositional) {
-      p("]");
-    }
-    if (hasNamed) {
-      p("}");
-    }
-  }
-  
-  @Override
-  public Void visitAssertStatement(DartAssertStatement x) {
-    p("assert(");
-    accept(x.getCondition());
-    p(");");
-    return null;
-  }
-
-  @Override
-  public Void visitBlock(DartBlock x) {
-    pBlock(x, true);
-    return null;
-  }
-
-  @Override
-  public Void visitIfStatement(DartIfStatement x) {
-    p("if (");
-    accept(x.getCondition());
-    p(") ");
-    pIfBlock(x.getThenStatement(), x.getElseStatement() == null);
-    if (x.getElseStatement() != null) {
-      p(" else ");
-      pIfBlock(x.getElseStatement(), true);
-    }
-    return null;
-  }
-
-  @Override
-  public Void visitSwitchStatement(DartSwitchStatement x) {
-    p("switch (");
-    accept(x.getExpression());
-    p(") {");
-    nl();
-
-    indent();
-    acceptList(x.getMembers());
-    outdent();
-
-    p("}");
-    nl();
-    return null;
-  }
-
-  @Override
-  public Void visitCase(DartCase x) {
-    p("case ");
-    accept(x.getExpr());
-    p(":");
-    nl();
-    indent();
-    acceptList(x.getStatements());
-    outdent();
-    return null;
-  }
-
-  @Override
-  public Void visitDefault(DartDefault x) {
-    p("default:");
-    nl();
-    indent();
-    acceptList(x.getStatements());
-    outdent();
-    return null;
-  }
-
-  @Override
-  public Void visitWhileStatement(DartWhileStatement x) {
-    p("while (");
-    accept(x.getCondition());
-    p(") ");
-    pIfBlock(x.getBody(), true);
-    return null;
-  }
-
-  @Override
-  public Void visitDoWhileStatement(DartDoWhileStatement x) {
-    p("do ");
-    pIfBlock(x.getBody(), false);
-    p(" while (");
-    accept(x.getCondition());
-    p(");");
-    nl();
-    return null;
-  }
-
-  @Override
-  public Void visitForStatement(DartForStatement x) {
-    p("for (");
-
-    // Setup
-    DartStatement setup = x.getInit();
-    if (setup != null) {
-      if (setup instanceof DartVariableStatement) {
-        // Special case to avoid an extra semicolon & newline after the var
-        // statement.
-        p("var ");
-        printSeparatedByComma(((DartVariableStatement) setup).getVariables());
-      } else {
-        // Plain old expression.
-        assert setup instanceof DartExprStmt;
-        accept(((DartExprStmt) setup).getExpression());
-      }
-    }
-    p("; ");
-
-    // Condition
-    if (x.getCondition() != null) {
-      accept(x.getCondition());
-    }
-    p("; ");
-
-    // Next
-    if (x.getIncrement() != null) {
-      accept(x.getIncrement());
-    }
-    p(") ");
-
-    // Body
-    accept(x.getBody());
-    nl();
-    return null;
-  }
-
-  @Override
-  public Void visitForInStatement(DartForInStatement x) {
-    p("for (");
-    if (x.introducesVariable()) {
-      DartTypeNode type = x.getVariableStatement().getTypeNode();
-      if (type != null) {
-        accept(type);
-        p(" ");
-      } else {
-        p("var ");
-      }
-      printSeparatedByComma(x.getVariableStatement().getVariables());
-    } else {
-      accept(x.getIdentifier());
-    }
-
-    p(" in ");
-
-    // iterable
-    accept(x.getIterable());
-    p(") ");
-
-    // Body
-    accept(x.getBody());
-    nl();
-    return null;
-  }
-
-  @Override
-  public Void visitContinueStatement(DartContinueStatement x) {
-    p("continue");
-    if (x.getTargetName() != null) {
-      p(" " + x.getTargetName());
-    }
-    p(";");
-    nl();
-    return null;
-  }
-
-  @Override
-  public Void visitBreakStatement(DartBreakStatement x) {
-    p("break");
-    if (x.getTargetName() != null) {
-      p(" " + x.getTargetName());
-    }
-    p(";");
-    nl();
-    return null;
-  }
-
-  @Override
-  public Void visitReturnStatement(DartReturnStatement x) {
-    p("return");
-    if (x.getValue() != null) {
-      p(" ");
-      accept(x.getValue());
-    }
-    p(";");
-    nl();
-    return null;
-  }
-
-  @Override
-  public Void visitTryStatement(DartTryStatement x) {
-    p("try ");
-    accept(x.getTryBlock());
-    acceptList(x.getCatchBlocks());
-    if (x.getFinallyBlock() != null) {
-      p("finally ");
-      accept(x.getFinallyBlock());
-    }
-    return null;
-  }
-
-  @Override
-  public Void visitCatchBlock(DartCatchBlock x) {
-    DartParameter catchParameter = x.getException();
-    DartTypeNode type = catchParameter.getTypeNode();
-    if (type != null) {
-      p("on ");
-      accept(type);
-      p(" ");
-    }
-    p("catch (");
-    accept(catchParameter.getName());
-    if (x.getStackTrace() != null) {
-      p(", ");
-      accept(x.getStackTrace());
-    }
-    p(") ");
-    accept(x.getBlock());
-    return null;
-  }
-
-  @Override
-  public Void visitThrowExpression(DartThrowExpression x) {
-    p("throw");
-    if (x.getException() != null) {
-      p(" ");
-      accept(x.getException());
-    }
-    return null;
-  }
-
-  @Override
-  public Void visitVariableStatement(DartVariableStatement x) {
-    if (x.getTypeNode() != null) {
-      accept(x.getTypeNode());
-      p(" ");
-    } else {
-      p("var ");
-    }
-    printSeparatedByComma(x.getVariables());
-    p(";");
-    nl();
-    return null;
-  }
-
-  @Override
-  public Void visitVariable(DartVariable x) {
-    accept(x.getName());
-    if (x.getValue() != null) {
-      p(" = ");
-      accept(x.getValue());
-    }
-    return null;
-  }
-
-  @Override
-  public Void visitEmptyStatement(DartEmptyStatement x) {
-    p(";");
-    nl();
-    return null;
-  }
-
-  @Override
-  public Void visitLabel(DartLabel x) {
-    p(x.getName());
-    p(": ");
-    accept(x.getStatement());
-    return null;
-  }
-
-  @Override
-  public Void visitExprStmt(DartExprStmt x) {
-    accept(x.getExpression());
-    p(";");
-    nl();
-    return null;
-  }
-
-  @Override
-  public Void visitBinaryExpression(DartBinaryExpression x) {
-    accept(x.getArg1());
-    p(" ");
-    p(x.getOperator().getSyntax());
-    p(" ");
-    accept(x.getArg2());
-    return null;
-  }
-
-  @Override
-  public Void visitConditional(DartConditional x) {
-    accept(x.getCondition());
-    p(" ? ");
-    accept(x.getThenExpression());
-    p(" : ");
-    accept(x.getElseExpression());
-    return null;
-  }
-
-  @Override
-  public Void visitUnaryExpression(DartUnaryExpression x) {
-    if (x.isPrefix()) {
-      p(x.getOperator().getSyntax());
-    }
-    accept(x.getArg());
-    if (!x.isPrefix()) {
-      p(x.getOperator().getSyntax());
-    }
-    return null;
-  }
-
-  @Override
-  public Void visitPropertyAccess(DartPropertyAccess x) {
-    if (x.getQualifier() != null) {
-      accept(x.getQualifier());
-    }
-    if (x.isCascade()) {
-      p("..");
-    } else {
-      p(".");
-    }
-    p(x.getPropertyName());
-    return null;
-  }
-
-  @Override
-  public Void visitCascadeExpression(DartCascadeExpression x) {
-    accept(x.getTarget());
-    acceptList(x.getCascadeSections());
-    return null;
-  }
-
-  @Override
-  public Void visitArrayAccess(DartArrayAccess x) {
-    if (x.isCascade()) {
-      p("..");
-    } else {
-      accept(x.getTarget());
-    }
-    p("[");
-    accept(x.getKey());
-    p("]");
-    return null;
-  }
-
-  private void pArgs(List<? extends DartNode> args) {
-    p("(");
-    printSeparatedByComma(args);
-    p(")");
-  }
-
-  @Override
-  public Void visitUnqualifiedInvocation(DartUnqualifiedInvocation x) {
-    accept(x.getTarget());
-    pArgs(x.getArguments());
-    return null;
-  }
-
-  @Override
-  public Void visitFunctionObjectInvocation(DartFunctionObjectInvocation x) {
-    accept(x.getTarget());
-    pArgs(x.getArguments());
-    return null;
-  }
-
-  @Override
-  public Void visitMethodInvocation(DartMethodInvocation x) {
-    if (x.isCascade()) {
-      p("..");
-    } else {
-      accept(x.getTarget());
-      p(".");
-    }
-    accept(x.getFunctionName());
-    pArgs(x.getArguments());
-    return null;
-  }
-
-  @Override
-  public Void visitSyntheticErrorExpression(DartSyntheticErrorExpression node) {
-    p("[error: " + node.getTokenString() + "]");
-    return null;
-  }
-
-  @Override
-  public Void visitSyntheticErrorStatement(DartSyntheticErrorStatement node) {
-    p("[error: " + node.getTokenString() + "]");
-    return null;
-  }
-
-  @Override
-  public Void visitThisExpression(DartThisExpression x) {
-    p("this");
-    return null;
-  }
-
-  @Override
-  public Void visitSuperExpression(DartSuperExpression x) {
-    p("super");
-    return null;
-  }
-
-  @Override
-  public Void visitSuperConstructorInvocation(DartSuperConstructorInvocation x) {
-    p("super");
-    if (x.getName() != null) {
-      p(".");
-      accept(x.getName());
-    }
-    pArgs(x.getArguments());
-    return null;
-  }
-
-  @Override
-  public Void visitNewExpression(DartNewExpression x) {
-    if (x.isConst()) {
-      p("const ");
-    } else {
-      p("new ");
-    }
-    accept(x.getConstructor());
-    pArgs(x.getArguments());
-    return null;
-  }
-
-  @Override
-  public Void visitFunctionExpression(DartFunctionExpression x) {
-    DartFunction func = x.getFunction();
-    if (func.getReturnTypeNode() != null) {
-      accept(func.getReturnTypeNode());
-      p(" ");
-    }
-    DartIdentifier name = x.getName();
-    pFunctionDeclaration(name, x.getFunction(), true);
-    p(" ");
-    if (x.getFunction().getBody() != null) {
-      pBlock(x.getFunction().getBody(), false);
-    }
-    return null;
-  }
-
-  @Override
-  public Void visitIdentifier(DartIdentifier x) {
-    p(x.getName());
-    return null;
-  }
-
-  @Override
-  public Void visitNullLiteral(DartNullLiteral x) {
-    p("null");
-    return null;
-  }
-
-  @Override
-  public Void visitRedirectConstructorInvocation(DartRedirectConstructorInvocation x) {
-    p("this");
-    if (x.getName() != null) {
-      p(".");
-      accept(x.getName());
-    }
-    pArgs(x.getArguments());
-    return null;
-  }
-
-  @Override
-  public Void visitStringLiteral(DartStringLiteral x) {
-    if (x.getValue() == null) {
-      return null;
-    }
-    p("\"");
-    // 'replaceAll' takes regular expressions as first argument and parses the second argument
-    // for captured groups. We must escape backslashes twice: once to escape them in the source
-    // code and once for the regular expression parser.
-    String escaped = x.getValue().replaceAll("\\\\", "\\\\\\\\");
-    escaped = escaped.replaceAll("\"", "\\\\\"");
-    escaped = escaped.replaceAll("'", "\\\\'");
-    escaped = escaped.replaceAll("\\n", "\\\\n");
-    // In the replacement string '$' is used to refer to captured groups. We have to escape the
-    // dollar.
-    escaped = escaped.replaceAll("\\$", "\\\\\\$");
-    p(escaped);
-    p("\"");
-    return null;
-  }
-
-  @Override
-  public Void visitStringInterpolation(DartStringInterpolation x) {
-    p("\"");
-    // do not use the default visitor recursion, instead alternate strings and
-    // expressions:
-    Iterator<DartExpression> eIter = x.getExpressions().iterator();
-    boolean first = true;
-    for (DartStringLiteral lit : x.getStrings()) {
-      if (first) {
-        first = false;
-      } else {
-        p("${");
-        assert eIter.hasNext() : "DartStringInterpolation invariant broken.";
-        accept(eIter.next());
-        p("}");
-      }
-      p(lit.getValue().replaceAll("\"", "\\\""));
-    }
-    p("\"");
-    return null;
-  }
-
-  @Override
-  public Void visitBooleanLiteral(DartBooleanLiteral x) {
-    p(Boolean.toString(x.getValue()));
-    return null;
-  }
-
-  @Override
-  public Void visitIntegerLiteral(DartIntegerLiteral x) {
-    p(x.getValue().toString());
-    return null;
-  }
-
-  @Override
-  public Void visitDoubleLiteral(DartDoubleLiteral x) {
-    p(Double.toString(x.getValue()));
-    return null;
-  }
-
-  @Override
-  public Void visitArrayLiteral(DartArrayLiteral x) {
-    List<DartTypeNode> typeArguments = x.getTypeArguments();
-    if (typeArguments != null && typeArguments.size() > 0) {
-      p("<");
-      printSeparatedByComma(typeArguments);
-      p(">");
-    }
-    p("[");
-    printSeparatedByComma(x.getExpressions());
-    p("]");
-    return null;
-  }
-
-  @Override
-  public Void visitMapLiteral(DartMapLiteral x) {
-    List<DartTypeNode> typeArguments = x.getTypeArguments();
-    if (typeArguments != null && typeArguments.size() > 0) {
-      p("<");
-      printSeparatedByComma(typeArguments);
-      p(">");
-    }
-    p("{");
-    List<DartMapLiteralEntry> entries = x.getEntries();
-    for (int i = 0; i < entries.size(); ++i) {
-      DartMapLiteralEntry entry = entries.get(i);
-      accept(entry);
-      if (i < entries.size() - 1) {
-        p(", ");
-      }
-    }
-    p("}");
-    return null;
-  }
-
-  @Override
-  public Void visitMapLiteralEntry(DartMapLiteralEntry x) {
-    // Always quote keys just to be safe. This could be optimized to only quote
-    // unsafe identifiers.
-    accept(x.getKey());
-    p(" : ");
-    accept(x.getValue());
-    return null;
-  }
-
-  @Override
-  public Void visitParameterizedTypeNode(DartParameterizedTypeNode x) {
-    accept(x.getExpression());
-    if (!x.getTypeParameters().isEmpty()) {
-      p("<");
-      printSeparatedByComma(x.getTypeParameters());
-      p(">");
-    }
-    return null;
-  }
-
-  @Override
-  public Void visitParenthesizedExpression(DartParenthesizedExpression x) {
-    p("(");
-    accept(x.getExpression());
-    p(")");
-    return null;
-  }
-
-  @Override
-  public Void visitNamedExpression(DartNamedExpression x) {
-    accept(x.getName());
-    p(":");
-    accept(x.getExpression());
-    return null;
-  }
-
-  private void pAbstractField(DartFieldDefinition x) {
-    accept(x.getFields().get(0).getAccessor());
-  }
-
-  private void pIfBlock(DartStatement stmt, boolean newline) {
-    if (stmt instanceof DartBlock) {
-      pBlock((DartBlock) stmt, newline);
-    } else {
-      p("{");
-      nl();
-      indent();
-      accept(stmt);
-      outdent();
-      p("}");
-      if (newline) {
-        nl();
-      }
-    }
-  }
-
-  private void printSeparatedByComma(List<? extends DartNode> nodes) {
-    boolean first = true;
-    for (DartNode node : nodes) {
-      if (!first) {
-        p(", ");
-      }
-      accept(node);
-      first = false;
-    }
-  }
-
-  private void pFieldModifiers(DartFieldDefinition field) {
-    Modifiers modifiers = field.getFields().get(0).getModifiers();
-    if (modifiers.isStatic()) {
-      p("static ");
-    }
-    if (modifiers.isFinal()) {
-      p("final ");
-    }
-  }
-
-  private void pMethodModifiers(DartMethodDefinition method) {
-    if (method.getModifiers().isConstant()) {
-      p("const ");
-    }
-    if (method.getModifiers().isStatic()) {
-      p("static ");
-    }
-    if (method.getModifiers().isAbstract()) {
-      p("abstract ");
-    }
-    if (method.getModifiers().isFactory()) {
-      p("factory ");
-    }
-  }
-
-  private void p(String x) {
-    out.print(x);
-  }
-
-  private void nl() {
-    out.newline();
-  }
-
-  private void indent() {
-    out.indentIn();
-  }
-
-  private void outdent() {
-    out.indentOut();
-  }
-}
diff --git a/compiler/java/com/google/dart/compiler/ast/DartTryStatement.java b/compiler/java/com/google/dart/compiler/ast/DartTryStatement.java
deleted file mode 100644
index 14f542f..0000000
--- a/compiler/java/com/google/dart/compiler/ast/DartTryStatement.java
+++ /dev/null
@@ -1,48 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.ast;
-
-import java.util.List;
-
-/**
- * Represents a Dart 'try/catch' statement.
- */
-public class DartTryStatement extends DartStatement {
-
-  private DartBlock tryBlock;
-  private final NodeList<DartCatchBlock> catchBlocks = NodeList.create(this);
-  private DartBlock finallyBlock;
-
-  public DartTryStatement(DartBlock tryBlock, List<DartCatchBlock> catchBlocks,
-      DartBlock finallyBlock) {
-    this.tryBlock = becomeParentOf(tryBlock);
-    this.catchBlocks.addAll(catchBlocks);
-    this.finallyBlock = becomeParentOf(finallyBlock);
-  }
-
-  public List<DartCatchBlock> getCatchBlocks() {
-    return catchBlocks;
-  }
-
-  public DartBlock getFinallyBlock() {
-    return finallyBlock;
-  }
-
-  public DartBlock getTryBlock() {
-    return tryBlock;
-  }
-
-  @Override
-  public void visitChildren(ASTVisitor<?> visitor) {
-    safelyVisitChild(tryBlock, visitor);
-    catchBlocks.accept(visitor);
-    safelyVisitChild(finallyBlock, visitor);
-  }
-
-  @Override
-  public <R> R accept(ASTVisitor<R> visitor) {
-    return visitor.visitTryStatement(this);
-  }
-}
diff --git a/compiler/java/com/google/dart/compiler/ast/DartTypeExpression.java b/compiler/java/com/google/dart/compiler/ast/DartTypeExpression.java
deleted file mode 100644
index 9d2a22a..0000000
--- a/compiler/java/com/google/dart/compiler/ast/DartTypeExpression.java
+++ /dev/null
@@ -1,31 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.ast;
-
-/**
- * Represents a type expression at the right hand side of an 'is'.
- */
-public class DartTypeExpression extends DartExpression {
-
-  private DartTypeNode typeNode;
-
-  public DartTypeExpression(DartTypeNode type) {
-    this.typeNode = becomeParentOf(type);
-  }
-
-  public DartTypeNode getTypeNode() {
-    return typeNode;
-  }
-
-  @Override
-  public void visitChildren(ASTVisitor<?> visitor) {
-    safelyVisitChild(typeNode, visitor);
-  }
-
-  @Override
-  public <R> R accept(ASTVisitor<R> visitor) {
-    return visitor.visitTypeExpression(this);
-  }
-}
diff --git a/compiler/java/com/google/dart/compiler/ast/DartTypeNode.java b/compiler/java/com/google/dart/compiler/ast/DartTypeNode.java
deleted file mode 100644
index 6c3db0d..0000000
--- a/compiler/java/com/google/dart/compiler/ast/DartTypeNode.java
+++ /dev/null
@@ -1,44 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.ast;
-
-import java.util.List;
-
-/**
- * Representation of a Dart type name.
- */
-public class DartTypeNode extends DartNode {
-
-  private DartNode identifier;
-  private NodeList<DartTypeNode> typeArguments = NodeList.create(this);
-
-  public DartTypeNode(DartNode identifier) {
-    this(identifier, null);
-  }
-
-  public DartTypeNode(DartNode identifier, List<DartTypeNode> typeArguments) {
-    this.identifier = becomeParentOf(identifier);
-    this.typeArguments.addAll(typeArguments);
-  }
-
-  public DartNode getIdentifier() {
-    return identifier;
-  }
-
-  public List<DartTypeNode> getTypeArguments() {
-    return typeArguments;
-  }
-
-  @Override
-  public void visitChildren(ASTVisitor<?> visitor) {
-    safelyVisitChild(identifier, visitor);
-    typeArguments.accept(visitor);
-  }
-
-  @Override
-  public <R> R accept(ASTVisitor<R> visitor) {
-    return visitor.visitTypeNode(this);
-  }
-}
diff --git a/compiler/java/com/google/dart/compiler/ast/DartTypeParameter.java b/compiler/java/com/google/dart/compiler/ast/DartTypeParameter.java
deleted file mode 100644
index 38ff641..0000000
--- a/compiler/java/com/google/dart/compiler/ast/DartTypeParameter.java
+++ /dev/null
@@ -1,40 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.ast;
-
-import com.google.dart.compiler.resolver.Element;
-
-/**
- * Represents a type parameter in a class or interface declaration.
- */
-public class DartTypeParameter extends DartDeclaration<DartIdentifier> {
-
-  private DartTypeNode bound;
-
-  public DartTypeParameter(DartIdentifier name, DartTypeNode bound) {
-    super(name);
-    this.bound = becomeParentOf(bound);
-  }
-
-  public DartTypeNode getBound() {
-    return bound;
-  }
-
-  @Override
-  public void visitChildren(ASTVisitor<?> visitor) {
-    super.visitChildren(visitor);
-    safelyVisitChild(bound, visitor);
-  }
-
-  @Override
-  public <R> R accept(ASTVisitor<R> visitor) {
-    return visitor.visitTypeParameter(this);
-  }
-  
-  @Override
-  public Element getElement() {
-    return getName().getElement();
-  }
-}
diff --git a/compiler/java/com/google/dart/compiler/ast/DartTypedLiteral.java b/compiler/java/com/google/dart/compiler/ast/DartTypedLiteral.java
deleted file mode 100644
index 28015cd..0000000
--- a/compiler/java/com/google/dart/compiler/ast/DartTypedLiteral.java
+++ /dev/null
@@ -1,37 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.ast;
-
-import com.google.dart.compiler.type.InterfaceType;
-
-import java.util.List;
-
-public abstract class DartTypedLiteral extends DartExpression {
-  private final boolean isConst;
-  private final NodeList<DartTypeNode> typeArguments = NodeList.create(this);
-
-  DartTypedLiteral(boolean isConst, List<DartTypeNode> typeArguments) {
-    this.isConst = isConst;
-    this.typeArguments.addAll(typeArguments);
-  }
-
-  public boolean isConst() {
-    return isConst;
-  }
-
-  public List<DartTypeNode> getTypeArguments() {
-    return typeArguments;
-  }
-
-  @Override
-  public InterfaceType getType() {
-    return (InterfaceType) super.getType();
-  }
-
-  @Override
-  public void visitChildren(ASTVisitor<?> visitor) {
-    typeArguments.accept(visitor);
-  }
-}
diff --git a/compiler/java/com/google/dart/compiler/ast/DartUnaryExpression.java b/compiler/java/com/google/dart/compiler/ast/DartUnaryExpression.java
deleted file mode 100644
index 0356f64..0000000
--- a/compiler/java/com/google/dart/compiler/ast/DartUnaryExpression.java
+++ /dev/null
@@ -1,65 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.ast;
-
-import com.google.dart.compiler.parser.Token;
-import com.google.dart.compiler.resolver.Element;
-import com.google.dart.compiler.resolver.MethodNodeElement;
-
-/**
- * Represents a Dart unary expression.
- */
-public class DartUnaryExpression extends DartExpression {
-
-  private final Token operator;
-  private final int operatorOffset;
-  private DartExpression arg;
-  private final boolean isPrefix;
-  private MethodNodeElement element;
-
-  public DartUnaryExpression(Token operator, int operatorOffset, DartExpression arg, boolean isPrefix) {
-    assert operator.isUnaryOperator() || operator == Token.SUB || operator == Token.CONDITIONAL;
-    this.operator = operator;
-    this.operatorOffset = operatorOffset;
-    this.arg = becomeParentOf(arg);
-    this.isPrefix = isPrefix;
-  }
-
-  public DartExpression getArg() {
-    return arg;
-  }
-
-  public Token getOperator() {
-    return operator;
-  }
-
-  public int getOperatorOffset() {
-    return operatorOffset;
-  }
-
-  public boolean isPrefix() {
-    return isPrefix;
-  }
-
-  @Override
-  public void visitChildren(ASTVisitor<?> visitor) {
-    safelyVisitChild(arg, visitor);
-  }
-
-  @Override
-  public <R> R accept(ASTVisitor<R> visitor) {
-    return visitor.visitUnaryExpression(this);
-  }
-
-  @Override
-  public MethodNodeElement getElement() {
-    return element;
-  }
-
-  @Override
-  public void setElement(Element element) {
-    this.element = (MethodNodeElement) element;
-  }
-}
diff --git a/compiler/java/com/google/dart/compiler/ast/DartUnit.java b/compiler/java/com/google/dart/compiler/ast/DartUnit.java
deleted file mode 100644
index 8959f52..0000000
--- a/compiler/java/com/google/dart/compiler/ast/DartUnit.java
+++ /dev/null
@@ -1,171 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.ast;
-
-import com.google.common.collect.Sets;
-import com.google.dart.compiler.DartSource;
-
-import java.util.List;
-import java.util.Set;
-
-/**
- * Represents a Dart compilation unit.
- */
-public class DartUnit extends DartNode {
-
-  @SuppressWarnings("unused")
-  private static final long serialVersionUID = -3407637869012712127L;
-
-  private LibraryUnit library;
-  private final NodeList<DartDirective> directives = NodeList.create(this);
-  private final NodeList<DartNode> topLevelNodes = NodeList.create(this);
-  private final NodeList<DartComment> comments = NodeList.create(this);
-  private final DartSource source;
-  private final boolean isDiet;
-  
-  private boolean hasParseErrors;
-
-  public DartUnit(DartSource source, boolean isDiet) {
-    this.source = source;
-    this.isDiet = isDiet;
-  }
-
-  public String getSourceName() {
-    return source.getName();
-  }
-
-  public List<DartComment> getComments() {
-    return comments;
-  }
-
-  public void setLibrary(LibraryUnit library) {
-    this.library = library;
-  }
-
-  public LibraryUnit getLibrary() {
-    return library;
-  }
-
-  public List<DartNode> getTopLevelNodes() {
-    return topLevelNodes;
-  }
-
-  @Override
-  public void visitChildren(ASTVisitor<?> visitor) {
-    directives.accept(visitor);
-    topLevelNodes.accept(visitor);
-  }
-
-  @Override
-  public <R> R accept(ASTVisitor<R> visitor) {
-    return visitor.visitUnit(this);
-  }
-
-  /**
-   * Whether this is an diet unit, meaning it contains no method bodies.
-   */
-  public boolean isDiet() {
-    return isDiet;
-  }
-
-  public void setHasParseErrors(boolean hasParseErrors) {
-    this.hasParseErrors = hasParseErrors;
-  }
-  
-  public boolean hasParseErrors() {
-    return hasParseErrors;
-  }
-
-  /**
-   * Answer the receiver's directives, not <code>null</code>.
-   */
-  public List<DartDirective> getDirectives() {
-    return directives;
-  }
-
-  /**
-   * @return the names of top-level declarations.
-   */
-  public Set<String> getTopDeclarationNames() {
-    Set<String> topLevelSymbols = Sets.newHashSet();
-    for (DartNode node : getTopLevelNodes()) {
-      if (node instanceof DartClass) {
-        DartIdentifier name = ((DartClass) node).getName();
-        topLevelSymbols.add(name.getName());
-      }
-      if (node instanceof DartFunctionTypeAlias) {
-        DartIdentifier name = ((DartFunctionTypeAlias) node).getName();
-        topLevelSymbols.add(name.getName());
-      }
-      if (node instanceof DartMethodDefinition) {
-        DartExpression name = ((DartMethodDefinition) node).getName();
-        if (name instanceof DartIdentifier) {
-          topLevelSymbols.add(((DartIdentifier) name).getName());
-        }
-      }
-      if (node instanceof DartFieldDefinition) {
-        DartFieldDefinition fieldDefinition = (DartFieldDefinition) node;
-        List<DartField> fields = fieldDefinition.getFields();
-        for (DartField variable : fields) {
-          topLevelSymbols.add(variable.getName().getName());
-        }
-      }
-    }
-    return topLevelSymbols;
-  }
-
-  /**
-   * @return the {@link Set} of names of all declarations.
-   */
-  public Set<String> getDeclarationNames() {
-    final Set<String> symbols = Sets.newHashSet();
-    accept(new ASTVisitor<Void>() {
-      @Override
-      public Void visitFunctionTypeAlias(DartFunctionTypeAlias node) {
-        symbols.add(node.getName().getName());
-        return super.visitFunctionTypeAlias(node);
-      }
-
-      @Override
-      public Void visitClass(DartClass node) {
-        symbols.add(node.getClassName());
-        return super.visitClass(node);
-      }
-
-      @Override
-      public Void visitTypeParameter(DartTypeParameter node) {
-        symbols.add(node.getName().getName());
-        return super.visitTypeParameter(node);
-      }
-
-      @Override
-      public Void visitField(DartField node) {
-        symbols.add(node.getName().getName());
-        return super.visitField(node);
-      }
-
-      @Override
-      public Void visitMethodDefinition(DartMethodDefinition node) {
-        if (node.getName() instanceof DartIdentifier) {
-          symbols.add(((DartIdentifier) node.getName()).getName());
-        }
-        return super.visitMethodDefinition(node);
-      }
-
-      @Override
-      public Void visitParameter(DartParameter node) {
-        symbols.add(node.getParameterName());
-        return super.visitParameter(node);
-      }
-
-      @Override
-      public Void visitVariable(DartVariable node) {
-        symbols.add(node.getVariableName());
-        return super.visitVariable(node);
-      }
-    });
-    return symbols;
-  }
-}
\ No newline at end of file
diff --git a/compiler/java/com/google/dart/compiler/ast/DartUnqualifiedInvocation.java b/compiler/java/com/google/dart/compiler/ast/DartUnqualifiedInvocation.java
deleted file mode 100644
index 54db3f2..0000000
--- a/compiler/java/com/google/dart/compiler/ast/DartUnqualifiedInvocation.java
+++ /dev/null
@@ -1,45 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.ast;
-
-import com.google.dart.compiler.resolver.Element;
-import com.google.dart.compiler.resolver.FieldElement;
-import com.google.dart.compiler.resolver.MethodElement;
-import com.google.dart.compiler.resolver.VariableElement;
-
-import java.util.List;
-
-/**
- * Unqualified function invocation AST node.
- * <p>
- * {@link DartUnqualifiedInvocation} may be invocation of real method, or invocation of function
- * object in field, or invocation of function object in variable. So, its {@link Element} may be
- * {@link MethodElement}, or {@link FieldElement}, or {@link VariableElement}.
- */
-public class DartUnqualifiedInvocation extends DartInvocation {
-
-  private DartIdentifier target;
-
-  public DartUnqualifiedInvocation(DartIdentifier target, List<DartExpression> args) {
-    super(args);
-    this.target = becomeParentOf(target);
-  }
-
-  @Override
-  public DartIdentifier getTarget() {
-    return target;
-  }
-
-  @Override
-  public void visitChildren(ASTVisitor<?> visitor) {
-    safelyVisitChild(target, visitor);
-    visitor.visit(getArguments());
-  }
-
-  @Override
-  public <R> R accept(ASTVisitor<R> visitor) {
-    return visitor.visitUnqualifiedInvocation(this);
-  }
-}
diff --git a/compiler/java/com/google/dart/compiler/ast/DartVariable.java b/compiler/java/com/google/dart/compiler/ast/DartVariable.java
deleted file mode 100644
index 491dd27..0000000
--- a/compiler/java/com/google/dart/compiler/ast/DartVariable.java
+++ /dev/null
@@ -1,52 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.ast;
-
-import com.google.dart.compiler.resolver.Element;
-import com.google.dart.compiler.resolver.VariableElement;
-
-/**
- * Represents a single variable declaration in a {@link DartVariableStatement}.
- */
-public class DartVariable extends DartDeclaration<DartIdentifier> {
-
-  private VariableElement element;
-
-  private DartExpression value;
-
-  public DartVariable(DartIdentifier name, DartExpression value) {
-    super(name);
-    this.value = becomeParentOf(value);
-  }
-
-  public String getVariableName() {
-    return getName().getName();
-  }
-
-  @Override
-  public VariableElement getElement() {
-    return element;
-  }
-
-  public DartExpression getValue() {
-    return value;
-  }
-
-  @Override
-  public void setElement(Element element) {
-    this.element = (VariableElement) element;
-  }
-
-  @Override
-  public void visitChildren(ASTVisitor<?> visitor) {
-    super.visitChildren(visitor);
-    safelyVisitChild(value, visitor);
-  }
-
-  @Override
-  public <R> R accept(ASTVisitor<R> visitor) {
-    return visitor.visitVariable(this);
-  }
-}
diff --git a/compiler/java/com/google/dart/compiler/ast/DartVariableStatement.java b/compiler/java/com/google/dart/compiler/ast/DartVariableStatement.java
deleted file mode 100644
index a0f322c..0000000
--- a/compiler/java/com/google/dart/compiler/ast/DartVariableStatement.java
+++ /dev/null
@@ -1,50 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.ast;
-
-import java.util.List;
-
-/**
- * Represents a Dart 'var' statement.
- */
-public class DartVariableStatement extends DartStatement {
-
-  private final NodeList<DartVariable> vars = NodeList.create(this);
-  private DartTypeNode typeNode;
-  private final Modifiers modifiers;
-
-  public DartVariableStatement(List<DartVariable> vars, DartTypeNode type) {
-    this(vars, type, Modifiers.NONE);
-  }
-
-  public DartVariableStatement(List<DartVariable> vars, DartTypeNode type, Modifiers modifiers) {
-    this.vars.addAll(vars);
-    this.typeNode = becomeParentOf(type);
-    this.modifiers = modifiers;
-  }
-
-  public List<DartVariable> getVariables() {
-    return vars;
-  }
-
-  public DartTypeNode getTypeNode() {
-    return typeNode;
-  }
-
-  public Modifiers getModifiers() {
-    return modifiers;
-  }
-
-  @Override
-  public void visitChildren(ASTVisitor<?> visitor) {
-    safelyVisitChild(typeNode, visitor);
-    vars.accept(visitor);
-  }
-
-  @Override
-  public <R> R accept(ASTVisitor<R> visitor) {
-    return visitor.visitVariableStatement(this);
-  }
-}
diff --git a/compiler/java/com/google/dart/compiler/ast/DartWhileStatement.java b/compiler/java/com/google/dart/compiler/ast/DartWhileStatement.java
deleted file mode 100644
index aaa975e..0000000
--- a/compiler/java/com/google/dart/compiler/ast/DartWhileStatement.java
+++ /dev/null
@@ -1,44 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.ast;
-
-/**
- * Represents a Dart 'while' statement.
- */
-public class DartWhileStatement extends DartStatement {
-
-  private DartExpression condition;
-  private final int closeParenOffset;
-  private DartStatement body;
-
-  public DartWhileStatement(DartExpression condition, int closeParenOffset, DartStatement body) {
-    this.condition = becomeParentOf(condition);
-    this.closeParenOffset = closeParenOffset;
-    this.body = becomeParentOf(body);
-  }
-
-  public DartStatement getBody() {
-    return body;
-  }
-
-  public DartExpression getCondition() {
-    return condition;
-  }
-  
-  public int getCloseParenOffset() {
-    return closeParenOffset;
-  }
-
-  @Override
-  public void visitChildren(ASTVisitor<?> visitor) {
-    safelyVisitChild(condition, visitor);
-    safelyVisitChild(body, visitor);
-  }
-
-  @Override
-  public <R> R accept(ASTVisitor<R> visitor) {
-    return visitor.visitWhileStatement(this);
-  }
-}
diff --git a/compiler/java/com/google/dart/compiler/ast/HasObsoleteMetadata.java b/compiler/java/com/google/dart/compiler/ast/HasObsoleteMetadata.java
deleted file mode 100644
index b1648aa..0000000
--- a/compiler/java/com/google/dart/compiler/ast/HasObsoleteMetadata.java
+++ /dev/null
@@ -1,12 +0,0 @@
-// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.ast;
-
-public interface HasObsoleteMetadata {
-
-  DartObsoleteMetadata getObsoleteMetadata();
-
-  void setObsoleteMetadata(DartObsoleteMetadata metadata);
-}
diff --git a/compiler/java/com/google/dart/compiler/ast/ImportCombinator.java b/compiler/java/com/google/dart/compiler/ast/ImportCombinator.java
deleted file mode 100644
index 3836e18..0000000
--- a/compiler/java/com/google/dart/compiler/ast/ImportCombinator.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (c) 2012, the Dart project authors.
- * 
- * Licensed under the Eclipse Public License v1.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.eclipse.org/legal/epl-v10.html
- * 
- * 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.dart.compiler.ast;
-
-/**
- * Instances of the class <code>ImportCombinator</code> represent a combinator associated with an
- * import directive.
- * 
- * <pre>
- * importCombinator ::=
- *     {@link ImportHideCombinator importHideCombinator}
- *   | {@link ImportShowCombinator importShowCombinator}
- * </pre>
- */
-public abstract class ImportCombinator extends DartNode {
-  /**
-   * Initialize a newly created import combinator.
-   */
-  public ImportCombinator() {
-    super();
-  }
-}
diff --git a/compiler/java/com/google/dart/compiler/ast/ImportHideCombinator.java b/compiler/java/com/google/dart/compiler/ast/ImportHideCombinator.java
deleted file mode 100644
index 5742b59..0000000
--- a/compiler/java/com/google/dart/compiler/ast/ImportHideCombinator.java
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Copyright (c) 2012, the Dart project authors.
- * 
- * Licensed under the Eclipse Public License v1.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.eclipse.org/legal/epl-v10.html
- * 
- * 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.dart.compiler.ast;
-
-import java.util.List;
-
-/**
- * Instances of the class <code>ImportHideCombinator</code> represent a combinator that restricts
- * the names being imported to those that are not in a given list.
- * 
- * <pre>
- * importHideCombinator ::=
- *     'hide:' {@link DartArrayLiteral listLiteral}
- * </pre>
- */
-public class ImportHideCombinator extends ImportCombinator {
-  /**
-   * The list of names from the library that are hidden by this combinator.
-   */
-  private NodeList<DartIdentifier> hiddenNames = new NodeList<DartIdentifier>(this);
-
-  /**
-   * Initialize a newly created import show combinator.
-   */
-  public ImportHideCombinator() {
-    super();
-  }
-
-  /**
-   * Initialize a newly created import show combinator.
-   * 
-   * @param hiddenNames the list of names from the library that are hidden by this combinator
-   */
-  public ImportHideCombinator(List<DartIdentifier> hiddenNames) {
-    this.hiddenNames.addAll(hiddenNames);
-  }
-
-  @Override
-  public <R> R accept(ASTVisitor<R> visitor) {
-    return visitor.visitImportHideCombinator(this);
-  }
-
-  /**
-   * Return the list of names from the library that are hidden by this combinator.
-   * 
-   * @return the list of names from the library that are hidden by this combinator
-   */
-  public NodeList<DartIdentifier> getHiddenNames() {
-    return hiddenNames;
-  }
-
-  @Override
-  public void visitChildren(ASTVisitor<?> visitor) {
-    if (hiddenNames != null) {
-      hiddenNames.accept(visitor);
-    }
-  }
-}
diff --git a/compiler/java/com/google/dart/compiler/ast/ImportShowCombinator.java b/compiler/java/com/google/dart/compiler/ast/ImportShowCombinator.java
deleted file mode 100644
index cb6920e..0000000
--- a/compiler/java/com/google/dart/compiler/ast/ImportShowCombinator.java
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Copyright (c) 2012, the Dart project authors.
- * 
- * Licensed under the Eclipse Public License v1.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.eclipse.org/legal/epl-v10.html
- * 
- * 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.dart.compiler.ast;
-
-import java.util.List;
-
-/**
- * Instances of the class <code>ImportShowCombinator</code> represent a combinator that restricts
- * the names being imported to those in a given list.
- * 
- * <pre>
- * importShowCombinator ::=
- *     'show:' {@link DartArrayLiteral listLiteral}
- * </pre>
- */
-public class ImportShowCombinator extends ImportCombinator {
-  /**
-   * The list of names from the library that are made visible by this combinator.
-   */
-  private NodeList<DartIdentifier> shownNames = new NodeList<DartIdentifier>(this);
-
-  /**
-   * Initialize a newly created import show combinator.
-   */
-  public ImportShowCombinator() {
-    super();
-  }
-
-  /**
-   * Initialize a newly created import show combinator.
-   * 
-   * @param shownNames the list of names from the library that are made visible by this combinator
-   */
-  public ImportShowCombinator(List<DartIdentifier> shownNames) {
-    this.shownNames.addAll(shownNames);
-  }
-
-  @Override
-  public <R> R accept(ASTVisitor<R> visitor) {
-    return visitor.visitImportShowCombinator(this);
-  }
-
-  /**
-   * Return the list of names from the library that are made visible by this combinator.
-   * 
-   * @return the list of names from the library that are made visible by this combinator
-   */
-  public NodeList<DartIdentifier> getShownNames() {
-    return shownNames;
-  }
-
-  @Override
-  public void visitChildren(ASTVisitor<?> visitor) {
-    if (shownNames != null) {
-      shownNames.accept(visitor);
-    }
-  }
-}
diff --git a/compiler/java/com/google/dart/compiler/ast/LibraryExport.java b/compiler/java/com/google/dart/compiler/ast/LibraryExport.java
deleted file mode 100644
index 98c2ffd..0000000
--- a/compiler/java/com/google/dart/compiler/ast/LibraryExport.java
+++ /dev/null
@@ -1,72 +0,0 @@
-// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.ast;
-
-import com.google.common.collect.Sets;
-import com.google.dart.compiler.common.SourceInfo;
-
-import java.util.List;
-import java.util.Set;
-
-/**
- * Information about export - {@link LibraryUnit} and show/hide names.
- */
-public class LibraryExport {
-  private final SourceInfo sourceInfo;
-  private final LibraryUnit library;
-  private final Set<String> showNames;
-  private final Set<String> hideNames;
-
-  public LibraryExport(SourceInfo sourceInfo, LibraryUnit library,
-      List<ImportCombinator> combinators) {
-    this.sourceInfo = sourceInfo;
-    this.library = library;
-    this.showNames = createCombinatorsSet(combinators, true);
-    this.hideNames = createCombinatorsSet(combinators, false);
-  }
-
-  public SourceInfo getSourceInfo() {
-    return sourceInfo;
-  }
-
-  public LibraryUnit getLibrary() {
-    return library;
-  }
-
-  public boolean isVisible(String name) {
-    if (hideNames.contains(name)) {
-      return false;
-    }
-    if (!showNames.isEmpty()) {
-      return showNames.contains(name);
-    }
-    return true;
-  }
-
-  private static Set<String> createCombinatorsSet(List<ImportCombinator> combinators, boolean show) {
-    Set<String> result = Sets.newHashSet();
-    for (ImportCombinator combinator : combinators) {
-      // show
-      if (show && combinator instanceof ImportShowCombinator) {
-        ImportShowCombinator showCombinator = (ImportShowCombinator) combinator;
-        for (DartIdentifier showName : showCombinator.getShownNames()) {
-          if (showName != null) {
-            result.add(showName.getName());
-          }
-        }
-      }
-      // hide
-      if (!show && combinator instanceof ImportHideCombinator) {
-        ImportHideCombinator hideCombinator = (ImportHideCombinator) combinator;
-        for (DartIdentifier hideName : hideCombinator.getHiddenNames()) {
-          if (hideName != null) {
-            result.add(hideName.getName());
-          }
-        }
-      }
-    }
-    return result;
-  }
-}
diff --git a/compiler/java/com/google/dart/compiler/ast/LibraryImport.java b/compiler/java/com/google/dart/compiler/ast/LibraryImport.java
deleted file mode 100644
index 300093d..0000000
--- a/compiler/java/com/google/dart/compiler/ast/LibraryImport.java
+++ /dev/null
@@ -1,70 +0,0 @@
-// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.ast;
-
-import com.google.common.collect.Sets;
-
-import java.util.List;
-import java.util.Set;
-
-/**
- * Information about import - prefix and {@link LibraryUnit}.
- */
-public class LibraryImport {
-  private final LibraryUnit library;
-  private final String prefix;
-  private final Set<String> showNames;
-  private final Set<String> hideNames;
-
-  public LibraryImport(LibraryUnit library, String prefix, List<ImportCombinator> combinators) {
-    this.library = library;
-    this.prefix = prefix;
-    this.showNames = createCombinatorsSet(combinators, true);
-    this.hideNames = createCombinatorsSet(combinators, false);
-  }
-
-  public LibraryUnit getLibrary() {
-    return library;
-  }
-
-  public String getPrefix() {
-    return prefix;
-  }
-
-  public boolean isVisible(String name) {
-    if (hideNames.contains(name)) {
-      return false;
-    }
-    if (!showNames.isEmpty()) {
-      return showNames.contains(name);
-    }
-    return true;
-  }
-
-  private static Set<String> createCombinatorsSet(List<ImportCombinator> combinators, boolean show) {
-    Set<String> result = Sets.newHashSet();
-    for (ImportCombinator combinator : combinators) {
-      // show
-      if (show && combinator instanceof ImportShowCombinator) {
-        ImportShowCombinator showCombinator = (ImportShowCombinator) combinator;
-        for (DartIdentifier showName : showCombinator.getShownNames()) {
-          if (showName != null) {
-            result.add(showName.getName());
-          }
-        }
-      }
-      // hide
-      if (!show && combinator instanceof ImportHideCombinator) {
-        ImportHideCombinator hideCombinator = (ImportHideCombinator) combinator;
-        for (DartIdentifier hideName : hideCombinator.getHiddenNames()) {
-          if (hideName != null) {
-            result.add(hideName.getName());
-          }
-        }
-      }
-    }
-    return result;
-  }
-}
diff --git a/compiler/java/com/google/dart/compiler/ast/LibraryNode.java b/compiler/java/com/google/dart/compiler/ast/LibraryNode.java
deleted file mode 100644
index c9ce360..0000000
--- a/compiler/java/com/google/dart/compiler/ast/LibraryNode.java
+++ /dev/null
@@ -1,67 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.ast;
-
-import com.google.common.collect.ImmutableList;
-import com.google.dart.compiler.common.AbstractNode;
-import com.google.dart.compiler.util.apache.StringUtils;
-
-import java.util.List;
-
-/**
- * An element in a library.
- */
-public class LibraryNode extends AbstractNode {
-
-  private final String text;
-  private final String prefix;
-  private final List<ImportCombinator> combinators;
-  private final boolean exported;
-
-  /**
-   * Construct a new library node instance
-   *
-   * @param manifest the library manifest declaration (not <code>null</code>)
-   * @param text the text comprising the node (not <code>null</code>)
-   */
-  public LibraryNode(String text) {
-    this.text = StringUtils.trim(text);
-    this.prefix = null;
-    this.combinators = ImmutableList.<ImportCombinator>of();
-    this.exported = false;
-  }
-
-  public LibraryNode(DartImportDirective importDirective) {
-    setSourceInfo(importDirective.getSourceInfo());
-    this.text = StringUtils.trim(importDirective.getLibraryUri().getValue());
-    this.prefix = importDirective.getPrefixValue();
-    this.combinators = importDirective.getCombinators();
-    this.exported = importDirective.isExported();
-  }
-
-  public LibraryNode(DartExportDirective exportDirective) {
-    setSourceInfo(exportDirective.getSourceInfo());
-    this.text = StringUtils.trim(exportDirective.getLibraryUri().getValue());
-    this.prefix = null;
-    this.combinators = exportDirective.getCombinators();
-    this.exported = false;
-  }
-  
-  public String getText() {
-    return text;
-  }
-
-  public String getPrefix() {
-    return prefix;
-  }
-  
-  public List<ImportCombinator> getCombinators() {
-    return combinators;
-  }
-  
-  public boolean isExported() {
-    return exported;
-  }
-}
diff --git a/compiler/java/com/google/dart/compiler/ast/LibraryUnit.java b/compiler/java/com/google/dart/compiler/ast/LibraryUnit.java
deleted file mode 100644
index 9700c84..0000000
--- a/compiler/java/com/google/dart/compiler/ast/LibraryUnit.java
+++ /dev/null
@@ -1,314 +0,0 @@
-// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.ast;
-
-import com.google.common.base.Objects;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.Lists;
-import com.google.common.collect.Sets;
-import com.google.dart.compiler.DartCompiler;
-import com.google.dart.compiler.DartCompilerContext;
-import com.google.dart.compiler.DartSource;
-import com.google.dart.compiler.LibraryDeps;
-import com.google.dart.compiler.LibrarySource;
-import com.google.dart.compiler.resolver.Elements;
-import com.google.dart.compiler.resolver.LibraryElement;
-
-import java.io.IOException;
-import java.io.Reader;
-import java.io.Writer;
-import java.util.Collection;
-import java.util.LinkedHashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.ConcurrentSkipListMap;
-
-/**
- * Represents the parsed source from a {@link LibrarySource}.
- */
-public class LibraryUnit {
-  private final LibrarySource libSource;
-  private final LibraryNode selfSourcePath;
-  private final List<LibraryNode> importPaths = Lists.newArrayList();
-  private final List<LibraryNode> exportPaths = Lists.newArrayList();
-  private final List<LibraryNode> sourcePaths = Lists.newArrayList();
-  private final List<LibraryNode> nativePaths = Lists.newArrayList();
-
-  private final Map<String, DartUnit> units = new ConcurrentSkipListMap<String, DartUnit>();
-  private final List<LibraryImport> imports = Lists.newArrayList();
-  private final List<LibraryExport> exports = Lists.newArrayList();
-
-  private final LibraryElement element;
-
-  private LibraryDeps deps;
-
-  private LibraryNode entryNode;
-  private DartUnit selfDartUnit;
-
-  private String name;
-
-  private DartExpression entryPoint;
-
-  private int sourceCount;
-
-  public void setName(String name) {
-    this.name = name;
-  }
-
-  public String getName() {
-    return name;
-  }
-
-  public LibraryUnit(LibrarySource libSource) {
-    assert libSource != null;
-    this.libSource = libSource;
-    element = Elements.libraryElement(this);
-
-    // get the name part of the path, since it needs to be relative
-    // TODO(jbrosenberg): change this to use lazy init
-    // Note: We don't want an encoded relative path.
-    String self = libSource.getUri().getSchemeSpecificPart();
-    int lastSlash;
-    if ((lastSlash = self.lastIndexOf('/')) > -1) {
-      self = self.substring(lastSlash + 1);
-    }
-    selfSourcePath = new LibraryNode(self);
-  }
-
-  public void addImportPath(LibraryNode path) {
-    assert path != null;
-    importPaths.add(path);
-  }
-  
-  public void addExportPath(LibraryNode path) {
-    assert path != null;
-    exportPaths.add(path);
-  }
-
-  public void addSourcePath(LibraryNode path) {
-    assert path != null;
-    sourcePaths.add(path);
-    sourceCount++;
-  }
-
-  public int getSourceCount() {
-    return sourceCount;
-  }
-
-  public void addNativePath(LibraryNode path) {
-    assert path != null;
-    nativePaths.add(path);
-  }
-
-  public void putUnit(DartUnit unit) {
-    unit.setLibrary(this);
-    units.put(unit.getSourceName(), unit);
-  }
-
-  public DartUnit getUnit(String sourceName) {
-    return units.get(sourceName);
-  }
-
-  public void addImport(LibraryUnit unit, LibraryNode node) {
-    if (unit != null) {
-      if (node != null) {
-        imports.add(new LibraryImport(unit, node.getPrefix(), node.getCombinators()));
-      } else {
-        imports.add(new LibraryImport(unit, null, ImmutableList.<ImportCombinator> of()));
-      }
-    }
-  }
-  
-  public void addExport(LibraryUnit unit, LibraryNode node) {
-    if (unit != null) {
-      if (node != null) {
-        exports.add(new LibraryExport(node.getSourceInfo(), unit, node.getCombinators()));
-      }
-    }
-  }
-
-  public Collection<LibraryUnit> getLibrariesWithPrefix(String prefixToMatch) {
-    List<LibraryUnit> result = Lists.newArrayList();
-    for (LibraryImport libraryImport : imports) {
-      if (Objects.equal(libraryImport.getPrefix(), prefixToMatch)) {
-        result.add(libraryImport.getLibrary());
-      }
-    }
-    return result;
-  }
-
-  public LibraryElement getElement() {
-    return element;
-  }
-
-  public Iterable<DartUnit> getUnits() {
-    return units.values();
-  }
-
-  public Iterable<LibraryImport> getImports() {
-    return imports;
-  }
-  
-  public List<LibraryExport> getExports() {
-    return exports;
-  }
-
-  public Iterable<LibraryUnit> getImportedLibraries() {
-    LinkedHashSet<LibraryUnit> libraries = Sets.newLinkedHashSet();
-    for (LibraryImport libraryImport : imports) {
-      libraries.add(libraryImport.getLibrary());
-    }
-    return libraries;
-  }
-
-  public boolean hasImport(LibraryUnit unit) {
-    for (LibraryImport libraryImport : imports) {
-      if (libraryImport.getPrefix() == null && Objects.equal(libraryImport.getLibrary(), unit)) {
-        return true;
-      }
-    }
-    return false;
-//    return imports.contains(new LibraryImport(unit, null, ImmutableList.<ImportCombinator> of()));
-  }
-
-  public DartExpression getEntryPoint() {
-    return entryPoint;
-  }
-
-  public void setEntryPoint(DartExpression entry) {
-    this.entryPoint = entry;
-  }
-
-  public DartUnit getSelfDartUnit() {
-    return this.selfDartUnit;
-  }
-
-  public void setSelfDartUnit(DartUnit unit) {
-    this.selfDartUnit = unit;
-    // set DartObsoleteMetadata for LibraryElement
-    if (unit != null) {
-      List<DartDirective> directives = unit.getDirectives();
-      if (!directives.isEmpty() && directives.get(0) instanceof DartLibraryDirective) {
-        DartLibraryDirective libraryDirective = (DartLibraryDirective) directives.get(0);
-        Elements.setLibraryMetadata(element, libraryDirective.getObsoleteMetadata());
-      }
-    }
-  }
-
-  /**
-   * Return a collection of paths to {@link LibrarySource}s upon which this library or application
-   * depends.
-   * 
-   * @return the paths (not <code>null</code>, contains no <code>null</code>)
-   */
-  public Iterable<LibraryNode> getImportPaths() {
-    return importPaths;
-  }
-  
-  public Iterable<LibraryNode> getExportPaths() {
-    return exportPaths;
-  }
-
-  /**
-   * Return all prefixes used by this library.
-   */
-  public Set<String> getPrefixes() {
-    Set<String> result = Sets.newTreeSet();
-    for (LibraryImport libraryImport : imports) {
-      String prefix = libraryImport.getPrefix();
-      if (prefix != null) {
-        result.add(prefix);
-      }
-    }
-    return result;
-  }
-
-  /**
-   * Return the path for dart source that corresponds to the same dart file as this library unit.
-   * This is added to the set of sourcePaths for this unit.
-   * 
-   * @return the self source path for this unit.
-   */
-  public LibraryNode getSelfSourcePath() {
-    return selfSourcePath;
-  }
-
-  /**
-   * Answer the source associated with this unit
-   * 
-   * @return the library source (not <code>null</code>)
-   */
-  public LibrarySource getSource() {
-    return libSource;
-  }
-
-  /**
-   * Return a collection of paths to {@link DartSource}s that are included in this library or
-   * application.
-   * 
-   * @return the paths (not <code>null</code>, contains no <code>null</code>)
-   */
-  public Iterable<LibraryNode> getSourcePaths() {
-    return sourcePaths;
-  }
-
-  /**
-   * Returns a collection of paths to native {@link DartSource}s that are included in this library.
-   * 
-   * @return the paths (not <code>null</code>, contains no <code>null</code>)
-   */
-  public Iterable<LibraryNode> getNativePaths() {
-    return nativePaths;
-  }
-
-  /**
-   * Return the declared entry method, if any
-   * 
-   * @return the entry method or <code>null</code> if not defined
-   */
-  public LibraryNode getEntryNode() {
-    return entryNode;
-  }
-
-  /**
-   * Set the declared entry method.
-   * 
-   * @param libraryNode the entry method or <code>null</code> if none
-   */
-  public void setEntryNode(LibraryNode libraryNode) {
-    this.entryNode = libraryNode;
-  }
-
-  /**
-   * Gets the dependencies associated with this library. If no dependencies artifact exists, or the
-   * file is invalid, it will return an empty deps object.
-   */
-  public LibraryDeps getDeps(DartCompilerContext context) throws IOException {
-    if (deps != null) {
-      return deps;
-    }
-
-    Reader reader = context.getArtifactReader(libSource, "", DartCompiler.EXTENSION_DEPS);
-    if (reader != null) {
-      deps = LibraryDeps.fromReader(reader);
-      reader.close();
-    }
-
-    if (deps == null) {
-      deps = new LibraryDeps();
-    }
-    return deps;
-  }
-
-  /**
-   * Writes this library's associated dependencies.
-   */
-  public void writeDeps(DartCompilerContext context) throws IOException {
-    Writer writer = context.getArtifactWriter(libSource, "", DartCompiler.EXTENSION_DEPS);
-    deps.write(writer);
-    writer.close();
-  }
-}
diff --git a/compiler/java/com/google/dart/compiler/ast/Modifiers.java b/compiler/java/com/google/dart/compiler/ast/Modifiers.java
deleted file mode 100644
index 4d9dea9..0000000
--- a/compiler/java/com/google/dart/compiler/ast/Modifiers.java
+++ /dev/null
@@ -1,110 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.ast;
-
-/**
- * Methods for working with modifier bits on various nodes.
- */
-public class Modifiers {
-
-  public static final Modifiers NONE = new Modifiers();
-
-  // Sorting this list would be confusing when adding new modifiers,
-  // as each one depends on the previously declared one.
-  // TODO(ngeoffray): Make this an enum.
-  private static final int FLAG_STATIC = 1;
-  private static final int FLAG_CONSTANT = FLAG_STATIC << 1;
-  private static final int FLAG_FACTORY = FLAG_CONSTANT << 1;
-  private static final int FLAG_ABSTRACT = FLAG_FACTORY << 1;
-  private static final int FLAG_GETTER = FLAG_ABSTRACT << 1;
-  private static final int FLAG_SETTER = FLAG_GETTER << 1;
-  private static final int FLAG_OPERATOR = FLAG_SETTER << 1;
-  private static final int FLAG_NATIVE = FLAG_OPERATOR << 1;
-  private static final int FLAG_INLINABLE = FLAG_NATIVE << 1;
-  private static final int FLAG_ABSTRACTFIELD = FLAG_INLINABLE << 1;
-  private static final int FLAG_REDIRECTEDCONSTRUCTOR = FLAG_ABSTRACTFIELD << 1;
-  private static final int FLAG_FINAL = FLAG_REDIRECTEDCONSTRUCTOR << 1;
-  private static final int FLAG_OPTIONAL = FLAG_FINAL << 1;
-  private static final int FLAG_NAMED = FLAG_OPTIONAL << 1;
-  private static final int FLAG_INITIALIZED = FLAG_NAMED << 1;
-  private static final int FLAG_EXTERNAL = FLAG_INITIALIZED << 1;
-
-  private final int value;
-
-  public boolean isStatic() { return is(FLAG_STATIC); }
-  public boolean isConstant() { return is(FLAG_CONSTANT); }
-  public boolean isFactory() { return is(FLAG_FACTORY); }
-  public boolean isAbstract() { return is(FLAG_ABSTRACT); }
-  public boolean isGetter() { return is(FLAG_GETTER); }
-  public boolean isSetter() { return is(FLAG_SETTER); }
-  public boolean isOperator() { return is(FLAG_OPERATOR); }
-  public boolean isNative() { return is(FLAG_NATIVE); }
-  public boolean isInlinable() { return is(FLAG_INLINABLE); }
-  public boolean isAbstractField() { return is(FLAG_ABSTRACTFIELD); }
-  public boolean isRedirectedConstructor() { return is(FLAG_REDIRECTEDCONSTRUCTOR); }
-  public boolean isFinal() { return is(FLAG_FINAL); }
-  public boolean isOptional() { return is(FLAG_OPTIONAL); }
-  public boolean isNamed() { return is(FLAG_NAMED); }
-  public boolean isInitialized() { return is(FLAG_INITIALIZED); }
-  public boolean isExternal() { return is(FLAG_EXTERNAL); }
-
-  public Modifiers makeStatic() { return make(FLAG_STATIC); }
-  public Modifiers makeConstant() { return make(FLAG_CONSTANT); }
-  public Modifiers makeFactory() { return make(FLAG_FACTORY); }
-  public Modifiers makeAbstract() { return make(FLAG_ABSTRACT); }
-  public Modifiers makeGetter() { return make(FLAG_GETTER); }
-  public Modifiers makeSetter() { return make(FLAG_SETTER); }
-  public Modifiers makeOperator() { return make(FLAG_OPERATOR); }
-  public Modifiers makeNative() { return make(FLAG_NATIVE); }
-  public Modifiers makeInlinable() { return make(FLAG_INLINABLE); }
-  public Modifiers makeAbstractField() { return make(FLAG_ABSTRACTFIELD); }
-  public Modifiers makeRedirectedConstructor() { return make(FLAG_REDIRECTEDCONSTRUCTOR); }
-  public Modifiers makeFinal() { return make(FLAG_FINAL); }
-  public Modifiers makeOptional() { return make(FLAG_OPTIONAL); }
-  public Modifiers makeNamed() { return make(FLAG_NAMED); }
-  public Modifiers makeInitialized() { return make(FLAG_INITIALIZED); }
-  public Modifiers makeExternal() { return make(FLAG_EXTERNAL); }
-
-  public Modifiers removeStatic() { return remove(FLAG_STATIC); }
-  public Modifiers removeConstant() { return remove(FLAG_CONSTANT); }
-  public Modifiers removeFactory() { return remove(FLAG_FACTORY); }
-  public Modifiers removeAbstract() { return remove(FLAG_ABSTRACT); }
-  public Modifiers removeGetter() { return remove(FLAG_GETTER); }
-  public Modifiers removeSetter() { return remove(FLAG_SETTER); }
-  public Modifiers removeOperator() { return remove(FLAG_OPERATOR); }
-  public Modifiers removeNative() { return remove(FLAG_NATIVE); }
-  public Modifiers removeInlinable() { return remove(FLAG_INLINABLE); }
-  public Modifiers removeAbstractField() { return remove(FLAG_ABSTRACTFIELD); }
-  public Modifiers removeRedirectedConstructor() { return remove(FLAG_REDIRECTEDCONSTRUCTOR); }
-  public Modifiers removeFinal() { return remove(FLAG_FINAL); }
-  public Modifiers removeOptional() { return remove(FLAG_OPTIONAL); }
-  public Modifiers removeNamed() { return remove(FLAG_NAMED); }
-  public Modifiers removeIniitalized() { return remove(FLAG_INITIALIZED); }
-  public Modifiers removeExternal() { return remove(FLAG_EXTERNAL); }
-
-  public boolean is(int flag) {
-    return (value & flag) != 0;
-  }
-
-  public boolean is(Modifiers modifier) {
-    return is(modifier.value);
-  }
-
-  public Modifiers make(int flag) {
-    return new Modifiers(value | flag);
-  }
-
-  public Modifiers remove(int flag) {
-    return new Modifiers(value & ~flag);
-  }
-
-  private Modifiers() {
-    this.value = 0;
-  }
-
-  private Modifiers(int value) {
-    this.value = value;
-  }
-}
diff --git a/compiler/java/com/google/dart/compiler/ast/NodeList.java b/compiler/java/com/google/dart/compiler/ast/NodeList.java
deleted file mode 100644
index 8eda6ba..0000000
--- a/compiler/java/com/google/dart/compiler/ast/NodeList.java
+++ /dev/null
@@ -1,99 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.ast;
-
-import com.google.common.collect.Lists;
-
-import java.util.AbstractList;
-import java.util.Collection;
-import java.util.List;
-
-/**
- * Instances of the class <code>NodeList</code> represent a list of AST nodes that have a common
- * parent.
- */
-public class NodeList<E extends DartNode> extends AbstractList<E> {
-  /**
-   * @return the new instance of {@link NodeList} with correct type argument.
-   */
-  public static <E extends DartNode> NodeList<E> create(DartNode owner) {
-    return new NodeList<E>(owner);
-  }
-
-  /**
-   * The underlying list in which the nodes of this list are stored.
-   */
-  private List<E> elements = null;
-
-  /**
-   * The node that is the parent of each of the elements in the list.
-   */
-  private final DartNode owner;
-
-  /**
-   * Initialize a newly created list of nodes to be empty.
-   *
-   * @param owner the node that is the parent of each of the elements in the list
-   */
-  public NodeList(DartNode owner) {
-    this.owner = owner;
-  }
-
-  /**
-   * Use the given visitor to visit each of the nodes in this list.
-   *
-   * @param visitor the visitor to be used to visit the elements of this list
-   */
-  public void accept(ASTVisitor<?> visitor) {
-    if (elements != null) {
-      for (int i = 0, size = elements.size(); i < size; i++) {
-        elements.get(i).accept(visitor);
-      }
-    }
-  }
-
-  @Override
-  public void add(int index, E element) {
-    if (elements == null) {
-      elements = Lists.newArrayListWithCapacity(2);
-    }
-    elements.add(element);
-    owner.becomeParentOf(element);
-  }
-
-  @Override
-  public boolean addAll(Collection<? extends E> c) {
-    if (c != null) {
-      return super.addAll(c);
-    }
-    return false;
-  }
-
-  @Override
-  public E get(int index) {
-    if (elements == null) {
-      throw new IndexOutOfBoundsException(Integer.toString(index));
-    }
-    return elements.get(index);
-  }
-
-  @Override
-  public E set(int index, E element) {
-    if (elements == null) {
-      elements = Lists.newArrayListWithCapacity(index + 1);
-    }
-    E result = elements.set(index, element);
-    owner.becomeParentOf(element);
-    return result;
-  }
-
-  @Override
-  public int size() {
-    if (elements == null) {
-      return 0;
-    }
-    return elements.size();
-  }
-}
diff --git a/compiler/java/com/google/dart/compiler/common/AbstractNode.java b/compiler/java/com/google/dart/compiler/common/AbstractNode.java
deleted file mode 100644
index 43ebdaf..0000000
--- a/compiler/java/com/google/dart/compiler/common/AbstractNode.java
+++ /dev/null
@@ -1,23 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.common;
-
-/**
- * Abstract base class for nodes that carry source information.
- */
-public class AbstractNode implements HasSourceInfo, HasSourceInfoSetter {
-
-  private SourceInfo sourceInfo = SourceInfo.UNKNOWN;
-
-  @Override
-  public final SourceInfo getSourceInfo() {
-    return sourceInfo;
-  }
-
-  @Override
-  public final void setSourceInfo(SourceInfo sourceInfo) {
-    this.sourceInfo = sourceInfo;
-  }
-}
diff --git a/compiler/java/com/google/dart/compiler/common/HasSourceInfo.java b/compiler/java/com/google/dart/compiler/common/HasSourceInfo.java
deleted file mode 100644
index a09552c..0000000
--- a/compiler/java/com/google/dart/compiler/common/HasSourceInfo.java
+++ /dev/null
@@ -1,17 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.common;
-
-/**
- * Abstract view of a class that has source info.
- */
-public interface HasSourceInfo {
-
-  /**
-   * @return the {@link SourceInfo} associated with this object. May be {@link SourceInfo#UNKNOWN}
-   *         but not <code>null</code>.
-   */
-  SourceInfo getSourceInfo();
-}
diff --git a/compiler/java/com/google/dart/compiler/common/HasSourceInfoSetter.java b/compiler/java/com/google/dart/compiler/common/HasSourceInfoSetter.java
deleted file mode 100644
index 6d41942..0000000
--- a/compiler/java/com/google/dart/compiler/common/HasSourceInfoSetter.java
+++ /dev/null
@@ -1,16 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.common;
-
-/**
- * Object for which you can set new {@link SourceInfo}.
- */
-public interface HasSourceInfoSetter {
-
-  /**
-   * Set the {@link SourceInfo} associated with this object. May only be called only once.
-   */
-  void setSourceInfo(SourceInfo sourceInfo);
-}
diff --git a/compiler/java/com/google/dart/compiler/common/SourceInfo.java b/compiler/java/com/google/dart/compiler/common/SourceInfo.java
deleted file mode 100644
index e3c7428..0000000
--- a/compiler/java/com/google/dart/compiler/common/SourceInfo.java
+++ /dev/null
@@ -1,184 +0,0 @@
-// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.common;
-
-import com.google.common.base.Preconditions;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.Lists;
-import com.google.common.collect.MapMaker;
-import com.google.dart.compiler.Source;
-
-import java.io.BufferedReader;
-import java.io.IOException;
-import java.io.Serializable;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-
-/**
- * Contains {@link Source} and location information for AST nodes.
- * <p>
- * Each node in the subtree (other than the contrived nodes) carries source range(s) information
- * relating back to positions in the given source (the given source itself is not remembered with
- * the AST). The source range usually begins at the first character of the first token corresponding
- * to the node; leading whitespace and comments are <b>not</b> included. The source range usually
- * extends through the last character of the last token corresponding to the node; trailing
- * whitespace and comments are <b>not</b> included. There are a handful of exceptions (including the
- * various body declarations). Source ranges nest properly: the source range for a child is always
- * within the source range of its parent, and the source ranges of sibling nodes never overlap.
- */
-public final class SourceInfo implements Serializable {
-  private static final long serialVersionUID = 1L;
-
-  /**
-   * The unknown {@link SourceInfo}.
-   */
-  public static final SourceInfo UNKNOWN = new SourceInfo(null, 0, 0);
-
-  private static final Map<Source, LinesInfo> lines = new MapMaker().weakKeys().makeMap();
-
-  private final Source source;
-  private final int offset;
-  private final int length;
-
-  public SourceInfo(Source source, int offset, int length) {
-    Preconditions.checkArgument(offset != -1 && length >= 0 || offset == -1 && length == 0);
-    this.source = source;
-    this.offset = offset;
-    this.length = length;
-  }
-
-  /**
-   * @return the {@link LinesInfo}, may be empty if some {@link Exception} happens, but not
-   *         <code>null</code>.
-   */
-  private static LinesInfo getLinesInfo(Source source) {
-    LinesInfo linesInfo = lines.get(source);
-    if (linesInfo == null) {
-      linesInfo = createLinesInfo(source);
-      lines.put(source, linesInfo);
-    }
-    return linesInfo;
-  }
-
-  /**
-   * @return the new {@link LinesInfo}, may be empty if some {@link Exception} happens, but not
-   *         <code>null</code>.
-   */
-  private static LinesInfo createLinesInfo(Source source) {
-    BufferedReader reader = null;
-    try {
-      reader = new BufferedReader(source.getSourceReader());
-      int offset = 0;
-      List<Integer> lineOffsets = Lists.newArrayList(0);
-      while (true) {
-        int charValue = reader.read();
-        if (charValue == -1) {
-          break;
-        }
-        offset++;
-        char c = (char) charValue;
-        if (c == '\n') {
-          lineOffsets.add(offset);
-        }
-      }
-      return new LinesInfo(lineOffsets);
-    } catch (Throwable e) {
-      return new LinesInfo(ImmutableList.of(0));
-    } finally {
-      if (reader != null) {
-        try {
-          reader.close();
-        } catch (IOException e) {
-          // Ignored
-        }
-      }
-    }
-  }
-
-  /**
-   * @return the {@link Source}.
-   */
-  public Source getSource() {
-    return source;
-  }
-
-  /**
-   * @return the 0-based character index in the {@link Source}, may <code>-1</code> if no source
-   *         information is recorded.
-   */
-  public int getOffset() {
-    return offset;
-  }
-
-  /**
-   * @return a (possibly 0) length of this node in the {@link Source}, may <code>0</code> if no
-   *         source position information is recorded.
-   */
-  public int getLength() {
-    return length;
-  }
-
-  /**
-   * @return the 0-based character index in the {@link Source}, result of {@link #getOffset()} plus
-   *         {@link #getLength()}.
-   */
-  public int getEnd() {
-    return offset + length;
-  }
-
-  /**
-   * @return a 1-based line number in the {@link Source} indicating where the source fragment
-   *         begins. May be <code>0</code> if line not found.
-   */
-  public int getLine() {
-    if (source == null) {
-      return 0;
-    }
-    return 1 + getLinesInfo(source).getLineOfOffset(offset);
-  }
-
-  /**
-   * @return a 1-based column number in the {@link Source} indicating where the source fragment
-   *         begins. May be <code>0</code> if column not found.
-   */
-  public int getColumn() {
-    if (source == null) {
-      return 0;
-    }
-    return 1 + getLinesInfo(source).getColumnOfOffset(offset);
-  }
-
-  /**
-   * Container for information about lines in some {@link Source}.
-   */
-  private static class LinesInfo {
-    private final List<Integer> lineOffsets;
-
-    public LinesInfo(List<Integer> lineOffsets) {
-      this.lineOffsets = lineOffsets;
-    }
-
-    int getLineOffset(int line) {
-      if (line < 0) {
-        return 0;
-      }
-      return lineOffsets.get(line);
-    }
-
-    int getLineOfOffset(int offset) {
-      int index = Collections.binarySearch(lineOffsets, offset);
-      if (index >= 0) {
-        return index;
-      }
-      return -(2 + index);
-    }
-
-    int getColumnOfOffset(int offset) {
-      int line = getLineOfOffset(offset);
-      return offset - getLineOffset(line);
-    }
-  }
-}
diff --git a/compiler/java/com/google/dart/compiler/metrics/CompilerMetrics.java b/compiler/java/com/google/dart/compiler/metrics/CompilerMetrics.java
deleted file mode 100644
index 3f7d938..0000000
--- a/compiler/java/com/google/dart/compiler/metrics/CompilerMetrics.java
+++ /dev/null
@@ -1,197 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.metrics;
-
-import java.io.PrintStream;
-import java.lang.management.ManagementFactory;
-import java.lang.management.ThreadMXBean;
-import java.util.concurrent.atomic.AtomicLong;
-
-/**
- * Collection of compiler metrics.
- */
-public final class CompilerMetrics {
-  // TODO: Consider refactoring this class so each subsystem has it own metrics class.
-
-  public static long getCPUTime() {
-    return System.currentTimeMillis() * 1000000;
-  }
-  /**
-   * Returns the current thread's CPU time or -1 if this is not supported.
-   */
-  public static long getThreadTime() {
-    ThreadMXBean threadMXBean = ManagementFactory.getThreadMXBean();
-    if (threadMXBean.isThreadCpuTimeSupported()) {
-      return threadMXBean.getCurrentThreadCpuTime();
-    }
-
-    return -1;
-  }
-
-  private static double nanoToMillis(long nanoTime) {
-    return nanoTime / 1000000.0d;
-  }
-  private AtomicLong charactersParsed = new AtomicLong();
-  private AtomicLong charactersParsedExcludingComments = new AtomicLong();
-  private long compileLibrariesTime = 0L;
-  private long compileLibrariesTimeStart = 0L;
-  private AtomicLong linesParsed = new AtomicLong();
-  private AtomicLong linesParsedExcludingComments = new AtomicLong();
-
-  private long milliEndTime = -1;
-  private final long milliStartTime;
-  
-  private long nanoParseWallTime = 0;
-  private AtomicLong nanoTotalParseTime = new AtomicLong();
-  private long nativeLibCharCount;
-
-  // Parser metrics
-  private AtomicLong unitsParsed = new AtomicLong();
-
-  private long updateAndResolveTime = 0L;
-
-  // Timing metrics for complete stages
-  private long updateAndResolveTimeStart = 0L;
-
-  public CompilerMetrics() {
-    this.milliStartTime = System.currentTimeMillis();
-  }
-
-  /**
-   * Accumulate more parsing time. TODO: Once the parser gets cleaned up we should be able to
-   * integrate this with unit parsed.
-   */
-  public void addParseTimeNano(long nanoTotalParseTime) {
-    this.nanoTotalParseTime.addAndGet(nanoTotalParseTime);
-  }
-
-  public void addParseWallTimeNano( long nanoWallParseTime) {
-    this.nanoParseWallTime = nanoWallParseTime;
-  }
-
-  public void done() {
-    if (milliEndTime == -1) {
-      milliEndTime = System.currentTimeMillis();
-    }
-  }
-
-  public void endCompileLibrariesTime() {
-    compileLibrariesTime = System.currentTimeMillis() - compileLibrariesTimeStart;
-  }
-
-  public void endUpdateAndResolveTime() {
-    updateAndResolveTime = System.currentTimeMillis() - updateAndResolveTimeStart;
-  }
-
-  public long getCompileLibrariesTime() {
-    return compileLibrariesTime;
-  }
-
-  public long getJSNativeLibCharSize() {
-    return nativeLibCharCount;
-  }
-
-  public double getLinesPerMS() {
-    return getNumLinesParsed() / getTotalCompilationTime();
-  }
-
-  public double getNonCommentLinesPerMS() {
-    return getNumNonCommentLines() / getTotalCompilationTime();
-  }
-
-  public long getNumCharsParsed() {
-    return charactersParsed.get();
-  }
-
-  public long getNumLinesParsed() {
-    return linesParsed.get();
-  }
-
-  public long getNumNonCommentChars() {
-    return charactersParsedExcludingComments.get();
-  }
-
-  public long getNumNonCommentLines() {
-    return linesParsedExcludingComments.get();
-  }
-
-  public double getNumUnitsParsed() {
-    return unitsParsed.get();
-  }
-
-  public double getParseTime() {
-    return nanoToMillis(nanoTotalParseTime.get());
-  }
-
-  public double getParseWallTime() {
-    return nanoToMillis(nanoParseWallTime);
-  }
-
-  public double getPercentCharsConsumedByNativeLibraries() {
-    return (getJSNativeLibCharSize() / getNumCharsParsed()) * 100d;
-  }
-
-  public double getPercentTimeParsing() {
-    return getParseTime() / getTotalCompilationTime();
-  }
-  
-  public double getTimeSpentPerUnit() {
-    if (getNumUnitsParsed() == 0) {
-      return 0;
-    }
-    return getTotalCompilationTime() / getNumUnitsParsed();
-  }
-  
-  public double getTotalCompilationTime() {
-    return milliEndTime - milliStartTime;
-  }
-  
-  public long getUpdateAndResolveTime() {
-    return updateAndResolveTime;
-  }
-  
-  public void startCompileLibrariesTime() {
-    compileLibrariesTimeStart = System.currentTimeMillis();
-  }
-  
-  public void startUpdateAndResolveTime() {
-    updateAndResolveTimeStart = System.currentTimeMillis();
-  }
-  
-  public void unitParsed(int charactersParsed, int charactersParsedExcludingComments,
-      int linesParsed, int linesParsedExcludingComments) {
-    this.unitsParsed.incrementAndGet();
-    this.charactersParsed.addAndGet(charactersParsed);
-    this.charactersParsedExcludingComments.addAndGet(charactersParsedExcludingComments);
-    this.linesParsed.addAndGet(linesParsed);
-    this.linesParsedExcludingComments.addAndGet(linesParsedExcludingComments);
-  }
-  
-  /**
-   * Writes the metrics to the {@link PrintStream}.
-   */
-  public void write(PrintStream out) {
-    /* This is mainly for the metrics system.  Units should be encoded in
-     * the label name and end up as the benchmark names.
-     */
-    done();
-    out.format("Compile-time-total-ms          : %1$.2f%n", getTotalCompilationTime());
-    out.format("# Update-and-resolve-time-ms     : %d\n", getUpdateAndResolveTime());
-    out.format("# Compile-libraries-time-ms      : %d\n", getCompileLibrariesTime());
-    out.println("# Compile-time-unit-average-ms  : " + getTimeSpentPerUnit());
-    out.format("# Parse-wall-time-ms             : %1$.2f%n", getParseWallTime());
-    out.format("# Parse-time-ms                  : %1$.2f%n", getParseTime());
-    out.println("# Parsed-units                   : " + getNumUnitsParsed());
-    out.println("# Parsed-src-chars               : " + getNumCharsParsed());
-    out.println("# Parsed-src-lines               : " + getNumLinesParsed());
-    out.println("# Parsed-code-chars              : " + getNumNonCommentChars());
-    out.println("# Parsed-code-lines              : " + getNumNonCommentLines());
-    double jsNativeLibCharSize = (getJSNativeLibCharSize() == -1) ? 0 : getJSNativeLibCharSize();
-    out.println("# Output-js-native-lib-chars     : " + jsNativeLibCharSize );
-    out.println("# Processed-total-lines-ms       : " + getLinesPerMS());
-    out.println("# Processed-code-lines-ms        : " + getNonCommentLinesPerMS());
-    out.println("# Ratio-parsing-compile-percent  : " + getPercentTimeParsing() * 100);
-  }
-}
diff --git a/compiler/java/com/google/dart/compiler/metrics/DartEventType.java b/compiler/java/com/google/dart/compiler/metrics/DartEventType.java
deleted file mode 100644
index c6b2ec3..0000000
--- a/compiler/java/com/google/dart/compiler/metrics/DartEventType.java
+++ /dev/null
@@ -1,51 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.metrics;
-
-import com.google.dart.compiler.metrics.Tracer.EventType;
-
-/**
- * Dart events for SpeedTracer.
- */
-public enum DartEventType implements EventType {
-  ADD_OUTOFDATE("MistyRose"),
-  BUILD_LIB_SCOPES("violet"),
-  COMPILE("green"),
-  COMPILE_APP("gray"),
-  COMPILE_LIBRARIES("brown"),
-  EXEC_PHASE("blue"),
-  IMPORT_EMBEDDED_LIBRARIES("purple"),
-  IS_SOURCE_OUTOFDATE("Chartreuse"),
-  SCANNER("GoldenRod"),
-  PARSE("red"),
-  PARSE_OUTOFDATE("LightCoral"),
-  RESOLVE_LIBRARIES("black"),
-  TIMESTAMP_OUTOFDATE("LightSteelBlue"),
-  UPDATE_LIBRARIES("yellow"),
-  UPDATE_RESOLVE("orange"),
-  WRITE_METRICS("LightChiffon");
-
-  final String cssColor;
-  final String name;
-
-  DartEventType(String cssColor) {
-    this(null, cssColor);
-  }
-
-  DartEventType(String name, String cssColor) {
-    this.name = name;
-    this.cssColor = cssColor;
-  }
-
-  @Override
-  public String getColor() {
-    return cssColor;
-  }
-
-  @Override
-  public String getName() {
-    return name == null ? toString() : name;
-  }
-}
diff --git a/compiler/java/com/google/dart/compiler/metrics/JvmMetrics.java b/compiler/java/com/google/dart/compiler/metrics/JvmMetrics.java
deleted file mode 100644
index 5123ed6..0000000
--- a/compiler/java/com/google/dart/compiler/metrics/JvmMetrics.java
+++ /dev/null
@@ -1,249 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.metrics;
-
-import java.io.PrintStream;
-import java.lang.management.CompilationMXBean;
-import java.lang.management.GarbageCollectorMXBean;
-import java.lang.management.ManagementFactory;
-import java.lang.management.MemoryMXBean;
-import java.lang.management.MemoryPoolMXBean;
-import java.lang.management.MemoryUsage;
-import java.util.List;
-import java.util.StringTokenizer;
-
-/**
- * A class to report jvm/jmx statistics
- */
-public class JvmMetrics {
-  
-  private static int TABULAR_COLON_POS = 40;
-  private static long ONE_KILO_BYTE = 1L << 10L;
-  private static long ONE_MEGA_BYTE = 1L << 20L;
-  private static long ONE_GIGA_BYTE = 1L << 30L;
-  
-  public static void maybeWriteJvmMetrics(PrintStream out, String options) {
-    if (options == null) {
-      return;
-    }
-    
-    boolean verboseMode = false;
-    boolean prettyMode = false;
-    StringTokenizer st = new StringTokenizer(options,":");
-    // options are grouped in order 'detail:format:types'
-    if (st.hasMoreTokens()) {
-      String mode = st.nextToken();
-      if (mode.equalsIgnoreCase("verbose")) {
-        verboseMode = true;
-      }
-    }
-
-    if (st.hasMoreTokens()) {
-      String mode = st.nextToken();
-      if (mode.equalsIgnoreCase("pretty")) {
-        prettyMode = true;
-      }
-    }
-
-    if (st.hasMoreTokens()) {
-      while (st.hasMoreTokens()) {
-        String types = st.nextToken();
-        StringTokenizer typeSt = new StringTokenizer(types,",");
-        while (typeSt.hasMoreElements()) {
-          String type = typeSt.nextToken();
-          writeMetrics(out, type, verboseMode, prettyMode);
-        }
-      }
-    } else {
-      // the default
-      writeMetrics(out, "all", verboseMode, prettyMode);
-    }
-  }
-
-  private static void writeMetrics(PrintStream out, String type, boolean verbose, boolean pretty) {
-    
-    if (type.equals("gc") || type.equalsIgnoreCase("all")) {
-      writeGarbageCollectionStats(out, verbose, pretty);
-    }
-    if (type.equals("mem") || type.equalsIgnoreCase("all")) {
-      writeMemoryMetrics(out, verbose, pretty);
-    }
-    if (type.equals("jit") || type.equalsIgnoreCase("all")) {
-      writeJitMetrics(out, verbose, pretty);
-    }
-  }
-
-  private static void writeJitMetrics(PrintStream out, boolean verbose, boolean pretty) {
-    
-    CompilationMXBean cBean = ManagementFactory.getCompilationMXBean();
-    
-    String name;
-    if (verbose) {
-      name = cBean.getName();
-    } else {
-      name = "total";
-    }
-    
-    if (pretty) {
-      out.println("\nJIT Stats");
-      out.println(String.format("\t%s jit time: %d ms", name, cBean.getTotalCompilationTime()));
-    } else {
-      out.println(normalizeTabularColonPos(String.format("%s-jit-time-ms : %d", normalizeName(name),
-                                                       cBean.getTotalCompilationTime())));
-    }
-  }
-
-  private static void writeOverallMemoryUsage(PrintStream out, MemoryUsage usage, 
-                                               String prefix, boolean pretty) {
-    if (pretty) {
-      out.format("\t%s\n", prefix);
-      out.format("\t\tavailable         : %s\n", formatBytes(usage.getMax()));
-      out.format("\t\tcurrent           : %s\n", formatBytes(usage.getUsed()));
-    } else {
-      prefix = normalizeName(prefix);
-      out.println(normalizeTabularColonPos(String.format(prefix + "-available-bytes : %d",
-                                                       usage.getMax())));
-      out.println(normalizeTabularColonPos(String.format(prefix + "-current-bytes : %d",
-                                                       usage.getUsed())));
-    }
-  }
-  
-  private static void writePoolMemoryUsage(PrintStream out, MemoryUsage usage, 
-                                           MemoryUsage peakUsage, String prefix, boolean pretty) {
-    if (pretty) {
-      out.format("\t\tavailable         : %s\n", formatBytes(usage.getMax()));
-      out.format("\t\tpeak              : %s\n", formatBytes(peakUsage.getUsed()));
-      out.format("\t\tcurrent           : %s\n", formatBytes(usage.getUsed()));
-    } else {
-      out.println(normalizeTabularColonPos(String.format(prefix + "-available-bytes : %d",
-                                                       usage.getMax())));
-      out.println(normalizeTabularColonPos(String.format(prefix + "-peak-bytes : %d",
-                                                       peakUsage.getUsed())));
-      out.println(normalizeTabularColonPos(String.format(prefix + "-current-bytes : %d",
-                                                       usage.getUsed())));
-    }
-  }
-  
-  private static void writeMemoryMetrics(PrintStream out, boolean verbose, boolean pretty) {
-    if (pretty) {
-      out.println("\nMemory usage");
-    }
-    
-    // only show overall stats in verbose mode
-    if (verbose) {
-      MemoryMXBean overallMemBean = ManagementFactory.getMemoryMXBean();
-      MemoryUsage usage = overallMemBean.getHeapMemoryUsage();
-      writeOverallMemoryUsage(out, usage, "Heap", pretty);
-      
-      usage = overallMemBean.getNonHeapMemoryUsage();
-      writeOverallMemoryUsage(out, usage, "Non-heap", pretty);
-    }
-    
-    if (verbose) {
-      List<MemoryPoolMXBean> mpBeans = ManagementFactory.getMemoryPoolMXBeans();
-      for (MemoryPoolMXBean mpBean : mpBeans) {
-        MemoryUsage currentUsage = mpBean.getUsage();
-        MemoryUsage peakUsage = mpBean.getPeakUsage();
-        if (pretty) {
-          out.println("\tPool " + mpBean.getName());
-          writePoolMemoryUsage(out, currentUsage, peakUsage, null, true);
-        } else {
-          writePoolMemoryUsage(out, currentUsage, peakUsage, 
-                                      "mem-pool-" + normalizeName(mpBean.getName()), false);
-        }
-      }
-    } else {
-      long available = 0;
-      long current = 0;
-      long peak = 0;
-      List<MemoryPoolMXBean> mpBeans = ManagementFactory.getMemoryPoolMXBeans();
-      for (MemoryPoolMXBean mpBean : mpBeans) {
-        MemoryUsage currentUsage = mpBean.getUsage();
-        available += currentUsage.getMax();
-        current += currentUsage.getUsed();
-        MemoryUsage peakUsage = mpBean.getPeakUsage();
-        peak += peakUsage.getUsed();
-      }
-      MemoryUsage summaryUsage = new MemoryUsage(0, current, current, available);
-      MemoryUsage summaryPeakUsage = new MemoryUsage(0, peak, peak, peak);
-      if (pretty) {
-        out.format("\tAggregate of %d memory pools\n", mpBeans.size());
-        writePoolMemoryUsage(out, summaryUsage, summaryPeakUsage, null, true);
-      } else {
-        writePoolMemoryUsage(out, summaryUsage, summaryPeakUsage,
-                                     "mem", false);
-      }
-    }
-  }
-  
-  private static void writeGarbageCollectionStats(PrintStream out, boolean verbose, boolean pretty) {
-    List<GarbageCollectorMXBean> gcBeans = ManagementFactory.getGarbageCollectorMXBeans();
-    
-    if (verbose) {
-      if (pretty) {
-        out.println("\nGarbage collection stats");
-        for (GarbageCollectorMXBean gcBean : gcBeans) {
-          out.println("\tCollector " + gcBean.getName());
-          out.format("\t\tcollection count   : %d\n", gcBean.getCollectionCount());
-          out.format("\t\tcollection time    : %d ms\n", gcBean.getCollectionTime());
-        }
-      } else {
-        for (GarbageCollectorMXBean gcBean : gcBeans) {
-          String name = normalizeName(gcBean.getName());
-          out.println(normalizeTabularColonPos(String.format("gc-" + name + "-collection-count : %d", 
-                      gcBean.getCollectionCount())));
-          out.println(normalizeTabularColonPos(String.format("gc-" + name + "-collection-time-ms : %d",
-                      gcBean.getCollectionTime())));
-        }
-      }
-    } else {
-      long collectionCount = 0;
-      long collectionTime = 0;
-      int collectorCount = gcBeans.size();
-      for (GarbageCollectorMXBean gcBean : gcBeans) {
-        collectionCount += gcBean.getCollectionCount();
-        collectionTime += gcBean.getCollectionTime();
-      }
-      if (pretty) {
-        out.println("\nGarbage collection stats");
-        out.format("\tAggregate of %d collectors\n", collectorCount);
-        out.format("\t\tcollection count   : %d\n", collectionCount);
-        out.format("\t\tcollection time    : %d ms\n", collectionTime);
-      } else {
-          String name = normalizeName("aggregate");
-          out.println(normalizeTabularColonPos(String.format("gc-" + name + "-collection-count : %d", 
-                      collectionCount)));
-          out.println(normalizeTabularColonPos(String.format("gc-" + name + "-collection-time-ms : %d",
-                      collectionTime)));
-      }
-    }
-  }
-
-  private static String normalizeName(String name) {
-    return name.replace(" ","_").toLowerCase();
-  }
-  
-  private static String normalizeTabularColonPos(String string) {
-    StringBuilder sb = new StringBuilder(string);
-    int index = sb.indexOf(":");
-    for (;index < TABULAR_COLON_POS;++index) {
-      sb.insert(index, ' ');
-    }
-    return sb.toString();
-  }
-  
-  private static String formatBytes(long numBytes) {
-    if (numBytes < ONE_KILO_BYTE) {
-      return String.format("%d B", numBytes);
-    } else if (numBytes < ONE_MEGA_BYTE) {
-      return String.format("%d KB", numBytes / ONE_KILO_BYTE);
-    } else if (numBytes < ONE_GIGA_BYTE) {
-      return String.format("%d MB", numBytes / ONE_MEGA_BYTE);
-    } else {
-      return String.format("%d GB", numBytes / ONE_GIGA_BYTE);
-    }
-  }
-  
-}
diff --git a/compiler/java/com/google/dart/compiler/metrics/SpeedTracerEventType.java b/compiler/java/com/google/dart/compiler/metrics/SpeedTracerEventType.java
deleted file mode 100644
index 6c84f1b..0000000
--- a/compiler/java/com/google/dart/compiler/metrics/SpeedTracerEventType.java
+++ /dev/null
@@ -1,33 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.metrics;
-
-import com.google.dart.compiler.metrics.Tracer.EventType;
-
-/**
- * Represents a type of event whose performance is tracked while running.
- */
-public enum SpeedTracerEventType implements EventType {
-  GC("Garbage Collection", "Plum"),
-  OVERHEAD("Speedtracer Overhead","Black");
-
-  final String cssColor;
-  final String name;
-
-  SpeedTracerEventType(String name, String cssColor) {
-    this.name = name;
-    this.cssColor = cssColor;
-  }
-
-  @Override
-  public String getColor() {
-    return cssColor;
-  }
-
-  @Override
-  public String getName() {
-    return name;
-  }
-}
diff --git a/compiler/java/com/google/dart/compiler/metrics/Tracer.java b/compiler/java/com/google/dart/compiler/metrics/Tracer.java
deleted file mode 100644
index 9103026..0000000
--- a/compiler/java/com/google/dart/compiler/metrics/Tracer.java
+++ /dev/null
@@ -1,959 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.metrics;
-
-import org.json.JSONException;
-import org.json.JSONObject;
-import org.json.JSONArray;
-
-import java.io.BufferedWriter;
-import java.io.FileWriter;
-import java.io.IOException;
-import java.io.Writer;
-import java.lang.management.GarbageCollectorMXBean;
-import java.lang.management.ManagementFactory;
-import java.lang.management.OperatingSystemMXBean;
-import java.lang.management.ThreadMXBean;
-import java.lang.reflect.Method;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-import java.util.Map;
-import java.util.Stack;
-import java.util.concurrent.BlockingQueue;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.LinkedBlockingQueue;
-import java.util.concurrent.TimeUnit;
-
-/**
- * Logs performance metrics for internal development purposes. The output is
- * formatted so it can be opened directly in the SpeedTracer Chrome extension.
- * This class formats events using SpeedTracer's custom event feature. The html
- * file output can be viewed by using Chrome to open the file on a Chrome
- * browser that has the SpeedTracer extension installed.
- * 
- * <p>
- * Enable logging by setting the system property {@code dart.speedtracerlog} to
- * the output file path.
- * </p>
- * 
- * NB: This class has been copied almost verbatim from the gwt source tree
- */
-public final class Tracer {
-
-  // Log file name (logging is enabled if this is non-null)
-  private static final String logFile = System.getProperty("dart.speedtracerlog");
-
-  // Allow a system property to override the default output format
-  private static final String defaultFormatString = System.getProperty("dart.speedtracerformat");
-
-  // Use cumulative multi-threaded process cpu time instead of wall time
-  private static final boolean logProcessCpuTime =
-      getBooleanProperty("dart.speedtracer.logProcessCpuTime");
-
-  // Use per thread cpu time instead of wall time. If logProcessCpuTime is set,
-  // then this can remain false - we only need one or the other.
-  private static final boolean logThreadCpuTime =
-      getBooleanProperty("dart.speedtracer.logThreadCpuTime");
-
-  // Turn on logging summarizing gc time during an event
-  private static final boolean logGcTime = getBooleanProperty("dart.speedtracer.logGcTime");
-
-  // Turn on logging estimating overhead used for speedtracer logging.
-  private static final boolean logOverheadTime =
-      getBooleanProperty("dart.speedtracer.logOverheadTime");
-
-  static {
-    // verify configuration
-    if (logProcessCpuTime && logThreadCpuTime) {
-      throw new RuntimeException("System properties are misconfigured: "
-          + "Specify one or the other of 'dart.speedtracer.logProcessCpuTime' "
-          + "or 'dart.speedtracer.logThreadCpuTime', not both.");
-    }
-  }
-
-  /**
-   * Represents a node in a tree of SpeedTracer events.
-   */
-  public class TraceEvent {
-    protected final EventType type;
-    List<TraceEvent> children;
-    List<String> data;
-
-    long elapsedDurationNanos;
-    long elapsedStartTimeNanos;
-
-    long processCpuDurationNanos;
-    long processCpuStartTimeNanos;
-
-    long threadCpuDurationNanos;
-    long threadCpuStartTimeNanos;
-
-    TraceEvent() {
-      if (enabled) {
-        threadCpuTimeKeeper.resetTimeBase();
-        recordStartTime();
-        this.data = new ArrayList<String>();
-        this.children = new ArrayList<TraceEvent>();
-      } else {
-        this.processCpuStartTimeNanos = 0L;
-        this.threadCpuStartTimeNanos = 0L;
-        this.elapsedStartTimeNanos = 0L;
-        this.data = null;
-        this.children = null;
-      }
-      this.type = null;
-    }
-
-    TraceEvent(TraceEvent parent, EventType type, String... data) {
-
-      if (parent != null) {
-        parent.children.add(this);
-      }
-      this.type = type;
-      assert (data.length % 2 == 0);
-      recordStartTime();
-      this.data = new ArrayList<String>();
-      this.data.addAll(Arrays.asList(data));
-      this.children = new ArrayList<TraceEvent>();
-    }
-
-    /**
-     * @param data key/value pairs to add to JSON object.
-     */
-    public void addData(String... data) {
-      if (data != null) {
-        assert (data.length % 2 == 0);
-        this.data.addAll(Arrays.asList(data));
-      }
-    }
-
-    /**
-     * Signals the end of the current event.
-     */
-    public void end(String... data) {
-      endImpl(this, data);
-    }
-
-    /**
-     * Returns the event duration, in nanoseconds, for the log file. Depending
-     * on system properties, this will measured in elapsed time, process CPU
-     * time, or thread CPU time.
-     */
-    public long getDurationNanos() {
-      return logProcessCpuTime ? processCpuDurationNanos : (logThreadCpuTime
-          ? threadCpuDurationNanos : elapsedDurationNanos);
-    }
-
-    public long getElapsedDurationNanos() {
-      return this.elapsedDurationNanos;
-    }
-
-    public long getElapsedStartTimeNanos() {
-      return this.elapsedStartTimeNanos;
-    }
-
-    /**
-     * Returns the event start time, normalized in nanoseconds, for the log
-     * file. Depending on system properties, this will be normalized based on
-     * elapsed time, process CPU time, or thread CPU time.
-     */
-    public long getStartTimeNanos() {
-      return logProcessCpuTime ? processCpuStartTimeNanos : (logThreadCpuTime
-          ? threadCpuStartTimeNanos : elapsedStartTimeNanos);
-    }
-
-    public EventType getType() {
-      return type;
-    }
-
-    @Override
-    public String toString() {
-      return type.getName();
-    }
-
-    /**
-     * Extends the durations of the current event by the durations of the
-     * specified event.
-     */
-    void extendDuration(TraceEvent refEvent) {
-      elapsedDurationNanos += refEvent.elapsedDurationNanos;
-      processCpuDurationNanos += refEvent.processCpuDurationNanos;
-      threadCpuDurationNanos += refEvent.threadCpuDurationNanos;
-    }
-
-    /**
-     * Sets the start time of this event to start immediately after the
-     * specified event ends.
-     */
-    void setStartsAfter(TraceEvent refEvent) {
-      elapsedStartTimeNanos = refEvent.elapsedStartTimeNanos + refEvent.elapsedDurationNanos;
-      processCpuStartTimeNanos =
-          refEvent.processCpuStartTimeNanos + refEvent.processCpuDurationNanos;
-      threadCpuStartTimeNanos = refEvent.threadCpuStartTimeNanos + refEvent.threadCpuDurationNanos;
-    }
-
-    JSONObject toJson() throws JSONException {
-      JSONObject json = new JSONObject();
-      json.put("type", -2);
-      json.put("typeName", type.getName());
-      json.put("color", type.getColor());
-      double startMs = convertToMilliseconds(getStartTimeNanos());
-      json.put("time", startMs);
-      double durationMs = convertToMilliseconds(getDurationNanos());
-      json.put("duration", durationMs);
-
-      JSONObject jsonData = new JSONObject();
-      for (int i = 0; i < data.size(); i += 2) {
-        jsonData.put(data.get(i), data.get(i + 1));
-      }
-      json.put("data", jsonData);
-
-      JSONArray jsonChildren = new JSONArray();
-      for (TraceEvent child : children) {
-        jsonChildren.put(child.toJson());
-      }
-      json.put("children", jsonChildren);
-
-      return json;
-    }
-
-    /**
-     * Records the duration of this event based on the current time and the
-     * event's recorded start time.
-     */
-    void updateDuration() {
-      long elapsedEndTimeNanos = elapsedTimeKeeper.normalizedTimeNanos();
-      assert (elapsedEndTimeNanos >= elapsedStartTimeNanos);
-      elapsedDurationNanos = elapsedEndTimeNanos - elapsedStartTimeNanos;
-
-      // don't bother making expensive time keeping method calls unless
-      // necessary
-      if (logProcessCpuTime) {
-        long processCpuEndTimeNanos = processCpuTimeKeeper.normalizedTimeNanos();
-        assert (processCpuEndTimeNanos >= processCpuStartTimeNanos);
-        processCpuDurationNanos = processCpuEndTimeNanos - processCpuStartTimeNanos;
-      } else if (logThreadCpuTime) {
-        long threadCpuEndTimeNanos = threadCpuTimeKeeper.normalizedTimeNanos();
-        assert (threadCpuEndTimeNanos >= threadCpuStartTimeNanos);
-        threadCpuDurationNanos = threadCpuEndTimeNanos - threadCpuStartTimeNanos;
-      }
-    }
-
-    /**
-     * Marks the start time for this event. Three different time measurements
-     * are used:
-     * <ol>
-     * <li>Elapsed (wall-clock) time</li>
-     * <li>Process CPU time</li>
-     * <li>Thread CPU time</li>
-     * </ol>
-     */
-    private void recordStartTime() {
-      elapsedStartTimeNanos = elapsedTimeKeeper.normalizedTimeNanos();
-
-      // don't bother making expensive time keeping method calls unless
-      // necessary
-      if (logProcessCpuTime) {
-        processCpuStartTimeNanos = processCpuTimeKeeper.normalizedTimeNanos();
-      } else if (logThreadCpuTime) {
-        threadCpuStartTimeNanos = threadCpuTimeKeeper.normalizedTimeNanos();
-      }
-    }
-  }
-
-  /**
-   * Enumerated types for logging events implement this interface.
-   */
-  public interface EventType {
-    String getColor();
-
-    String getName();
-  }
-
-  static enum Format {
-    /**
-     * Standard SpeedTracer log that includes JSON wrapped in HTML that will
-     * launch a SpeedTracer monitor session.
-     */
-    HTML,
-
-    /**
-     * Only the JSON data without any HTML wrappers.
-     */
-    RAW
-  }
-
-  /**
-   * A dummy implementation to do nothing if logging has not been turned on.
-   */
-  private class DummyEvent extends TraceEvent {
-    @Override
-    public void addData(String... data) {
-      // do nothing
-    }
-
-    @Override
-    public void end(String... data) {
-      // do nothing
-    }
-
-    @Override
-    public String toString() {
-      return "Dummy";
-    }
-  }
-
-  /**
-   * Provides functionality specific to garbage collection events.
-   */
-  private class GcEvent extends TraceEvent {
-    private TraceEvent refEvent;
-
-    /**
-     * Constructs an event that represents garbage collection metrics.
-     * 
-     * @param refEvent the event during which the garbage collections took place
-     * @param gcType the garbage collector type
-     * @param collectionCount the total number of collections for this garbage
-     *        collector type
-     * @param durationNanos the total elapsed time spent in garbage collection
-     *        during the span of {@code refEvent}
-     */
-    GcEvent(TraceEvent refEvent, String gcType, long collectionCount, long durationNanos) {
-      super(null, SpeedTracerEventType.GC, "Collector Type", gcType, "Cumulative Collection Count",
-          Long.toString(collectionCount));
-
-      this.refEvent = refEvent;
-      // GarbageCollectorMXBean can only provide elapsed time, so that's all we
-      // record
-      this.elapsedDurationNanos = durationNanos;
-    }
-
-    /**
-     * Returns elapsed duration since that is the only duration we can measure
-     * for garbage collection events.
-     */
-    @Override
-    public long getDurationNanos() {
-      return getElapsedDurationNanos();
-    }
-
-    /**
-     * Returns a start time so that this event ends with its {@code refEvent}.
-     */
-    @Override
-    public long getElapsedStartTimeNanos() {
-      return refEvent.getElapsedStartTimeNanos() + refEvent.getElapsedDurationNanos()
-          - getElapsedDurationNanos();
-    }
-
-    /**
-     * Returns a start time so that this event ends with its {@code refEvent}.
-     */
-    @Override
-    public long getStartTimeNanos() {
-      return refEvent.getStartTimeNanos() + refEvent.getDurationNanos() - getDurationNanos();
-    }
-  }
-
-  /**
-   * Time keeper which uses wall time.
-   */
-  private class ElapsedNormalizedTimeKeeper {
-
-    private final long zeroTimeMillis;
-
-    public ElapsedNormalizedTimeKeeper() {
-      zeroTimeMillis = System.currentTimeMillis();
-    }
-
-    public long normalizedTimeNanos() {
-      return (System.currentTimeMillis() - zeroTimeMillis) * 1000000L;
-    }
-
-    public long zeroTimeMillis() {
-      return zeroTimeMillis;
-    }
-  }
-
-  /**
-   * Time keeper which uses process cpu time. This can be greater than wall
-   * time, since it is cumulative over the multiple threads of a process.
-   */
-  private class ProcessNormalizedTimeKeeper {
-    private final OperatingSystemMXBean osMXBean;
-    private final Method getProcessCpuTimeMethod;
-    private final long zeroTimeNanos;
-    private final long zeroTimeMillis;
-
-    public ProcessNormalizedTimeKeeper() {
-      try {
-        osMXBean = ManagementFactory.getOperatingSystemMXBean();
-        /*
-         * Find this method by reflection, since it's part of the Sun
-         * implementation for OperatingSystemMXBean, and we can't always assume
-         * that com.sun.management.OperatingSystemMXBean will be available.
-         */
-        getProcessCpuTimeMethod = osMXBean.getClass().getMethod("getProcessCpuTime");
-        getProcessCpuTimeMethod.setAccessible(true);
-        zeroTimeNanos = (Long) getProcessCpuTimeMethod.invoke(osMXBean);
-        zeroTimeMillis = (long) convertToMilliseconds(zeroTimeNanos);
-      } catch (Exception ex) {
-        throw new RuntimeException(ex);
-      }
-    }
-
-    public long normalizedTimeNanos() {
-      try {
-        return (Long) getProcessCpuTimeMethod.invoke(osMXBean) - zeroTimeNanos;
-      } catch (Exception ex) {
-        throw new RuntimeException(ex);
-      }
-    }
-
-    public long zeroTimeMillis() {
-      return zeroTimeMillis;
-    }
-  }
-
-  /**
-   * Time keeper which uses per thread cpu time. It is assumed that individual
-   * events logged will be single threaded, and that top-level events will call
-   * {@link #resetTimeBase()} prior to logging time. The resettable time base is
-   * needed since each individual thread starts its timing at 0, regardless of
-   * when the thread is created. So we reset the time base at the beginning of
-   * an event, so that we can generate a chronologically representative output,
-   * although the relation to wall time is actually compressed within a logged
-   * event (thread cpu time does not include wait time, etc.).
-   */
-  private class ThreadNormalizedTimeKeeper {
-
-    private final ThreadMXBean threadMXBean;
-    private final ThreadLocal<Long> resettableTimeBase = new ThreadLocal<Long>();
-    private final long zeroTimeNanos;
-    private final long zeroTimeMillis;
-
-    public ThreadNormalizedTimeKeeper() {
-      threadMXBean = ManagementFactory.getThreadMXBean();
-      if (!threadMXBean.isCurrentThreadCpuTimeSupported()) {
-        throw new RuntimeException("Current thread cpu time not supported");
-      }
-      zeroTimeNanos = System.nanoTime();
-      zeroTimeMillis = (long) convertToMilliseconds(zeroTimeNanos);
-    }
-
-    public long normalizedTimeNanos() {
-      return threadMXBean.getCurrentThreadCpuTime() + resettableTimeBase.get();
-    }
-
-    public void resetTimeBase() {
-      /*
-       * Since all threads start individually at time 0L, we use this to offset
-       * each event's time so we can generate chronological output.
-       */
-      resettableTimeBase.set(System.nanoTime() - zeroTimeNanos
-          - threadMXBean.getCurrentThreadCpuTime());
-    }
-
-    public long zeroTimeMillis() {
-      return zeroTimeMillis;
-    }
-  }
-
-  /**
-   * Initializes the singleton on demand.
-   */
-  private static class LazySpeedTracerLoggerHolder {
-    public static Tracer singleton = new Tracer();
-  }
-
-  /**
-   * Thread that converts log requests to JSON in the background.
-   */
-  private class LogWriterThread extends Thread {
-    private static final int FLUSH_TIMER_MSECS = 10000;
-    private final String fileName;
-    private final BlockingQueue<TraceEvent> threadEventQueue;
-    private final Writer writer;
-
-    public LogWriterThread(Writer writer, String fileName, final BlockingQueue<TraceEvent> eventQueue) {
-      super();
-      this.writer = writer;
-      this.fileName = fileName;
-      this.threadEventQueue = eventQueue;
-    }
-
-    @Override
-    public void run() {
-      long nextFlush = System.currentTimeMillis() + FLUSH_TIMER_MSECS;
-      try {
-        while (true) {
-          TraceEvent event =
-              threadEventQueue.poll(nextFlush - System.currentTimeMillis(), TimeUnit.MILLISECONDS);
-          if (event == null) {
-            // ignore.
-          } else if (event == shutDownSentinel) {
-            break;
-          } else if (event == flushSentinel) {
-            writer.flush();
-            flushLatch.countDown();
-          } else {
-            JSONObject json = event.toJson();
-            json.write(writer);
-            writer.write('\n');
-          }
-          if (System.currentTimeMillis() >= nextFlush) {
-            writer.flush();
-            nextFlush = System.currentTimeMillis() + FLUSH_TIMER_MSECS;
-          }
-        }
-        // All queued events have been written.
-        if (outputFormat.equals(Format.HTML)) {
-          writer.write("</div></body></html>\n");
-        }
-        writer.close();
-      } catch (InterruptedException ignored) {
-      } catch (IOException e) {
-        System.err.println("Unable to write to dart.speedtracerlog '"
-            + (fileName == null ? "" : fileName) + "'");
-        e.printStackTrace();
-      } catch (JSONException e) {
-        // TODO(jat): Auto-generated catch block
-        e.printStackTrace();
-      } finally {
-        shutDownLatch.countDown();
-      }
-    }
-  }
-
-  /**
-   * Records a LOG_MESSAGE type of SpeedTracer event.
-   */
-  private class MarkTimelineEvent extends TraceEvent {
-    public MarkTimelineEvent(TraceEvent parent) {
-      super();
-      if (parent != null) {
-        parent.children.add(this);
-      }
-    }
-
-    @Override
-    JSONObject toJson() throws JSONException {
-      JSONObject json = new JSONObject();
-      json.put("type", 11);
-      double startMs = convertToMilliseconds(getStartTimeNanos());
-      json.put("time", startMs);
-      json.put("duration", 0.0);
-      JSONObject jsonData = new JSONObject();
-      for (int i = 0; i < data.size(); i += 2) {
-        jsonData.put(data.get(i), data.get(i + 1));
-      }
-      json.put("data", jsonData);
-      return json;
-    }
-  }
-
-  /**
-   * Annotate the current event on the top of the stack with more information.
-   * The method expects key, value pairs, so there must be an even number of
-   * parameters.
-   * 
-   * @param data JSON property, value pair to add to current event.
-   */
-  public static void addData(String... data) {
-    Tracer.get().addDataImpl(data);
-  }
-
-  /**
-   * Create a new global instance. Force the zero time to be recorded and the
-   * log to be opened if the default logging is turned on with the <code>
-   * -Ddart.speedtracerlog</code> VM property.
-   * 
-   * This method is only intended to be called once.
-   */
-  public static void init() {
-    get();
-  }
-
-  /**
-   * Returns true if the trace output file is configured. This is intended to be
-   * the quickest possible check, statically determined.
-   */
-  public static boolean canTrace() {
-    return logFile != null;
-  }
-
-  /**
-   * Adds a LOG_MESSAGE SpeedTracer event to the log. This represents a single
-   * point in time and has a special representation in the SpeedTracer UI.
-   */
-  public static void markTimeline(String message) {
-    Tracer.get().markTimelineImpl(message);
-  }
-
-  /**
-   * Signals that a new event has started. You must end each event for each
-   * corresponding call to {@code start}. You may nest timing calls.
-   * 
-   * @param type the type of event
-   * @param data a set of key-value pairs (each key is followed by its value)
-   *        that contain additional information about the event
-   * @return an Event object to be ended by the caller
-   */
-  public static TraceEvent start(EventType type, String... data) {
-    return Tracer.get().startImpl(type, data);
-  }
-
-  private static double convertToMilliseconds(long nanos) {
-    return nanos / 1000000.0d;
-  }
-  
-  /**
-   * Convenience method for ending event, which might possibly be null.
-   */
-  public static void end(TraceEvent event, String... data) {
-    if (event != null) {
-      event.end(data);
-    }
-  }
-
-  /**
-   * For accessing the logger as a singleton, you can retrieve the global
-   * instance. It is prudent, but not necessary to first initialize the
-   * singleton with a call to {@link #init()} to set the base time.
-   * 
-   * @return the current global {@link Tracer} instance.
-   */
-  private static Tracer get() {
-    return LazySpeedTracerLoggerHolder.singleton;
-  }
-
-  private static boolean getBooleanProperty(String propName) {
-    try {
-      return System.getProperty(propName) != null;
-    } catch (RuntimeException ruEx) {
-      return false;
-    }
-  }
-
-  private final boolean enabled;
-
-  private final DummyEvent dummyEvent = new DummyEvent();
-
-  private BlockingQueue<TraceEvent> eventsToWrite;
-
-  private final boolean fileLoggingEnabled;
-
-  private CountDownLatch flushLatch;
-
-  private TraceEvent flushSentinel;
-
-  private Format outputFormat;
-
-  private ThreadLocal<Stack<TraceEvent>> pendingEvents;
-
-  private CountDownLatch shutDownLatch;
-
-  private TraceEvent shutDownSentinel;
-
-  private List<GarbageCollectorMXBean> gcMXBeans;
-
-  private Map<String, Long> lastGcTimes;
-
-  private final ElapsedNormalizedTimeKeeper elapsedTimeKeeper;
-
-  private final ProcessNormalizedTimeKeeper processCpuTimeKeeper;
-
-  private final ThreadNormalizedTimeKeeper threadCpuTimeKeeper;
-
-  /**
-   * Constructor intended for unit testing.
-   * 
-   * @param writer alternative {@link Writer} to send speed tracer output.
-   */
-  Tracer(Writer writer, Format format) {
-    enabled = true;
-    fileLoggingEnabled = true;
-    outputFormat = format;
-    eventsToWrite = openLogWriter(writer, "");
-    pendingEvents = initPendingEvents();
-    elapsedTimeKeeper = new ElapsedNormalizedTimeKeeper();
-    processCpuTimeKeeper = new ProcessNormalizedTimeKeeper();
-    threadCpuTimeKeeper = new ThreadNormalizedTimeKeeper();
-    shutDownSentinel = new DummyEvent();
-    flushSentinel = new DummyEvent();
-    shutDownLatch = new CountDownLatch(1);
-  }
-
-  private Tracer() {
-    fileLoggingEnabled = logFile != null;
-    enabled = fileLoggingEnabled;
-
-    if (enabled) {
-      elapsedTimeKeeper = new ElapsedNormalizedTimeKeeper();
-      processCpuTimeKeeper = new ProcessNormalizedTimeKeeper();
-      threadCpuTimeKeeper = new ThreadNormalizedTimeKeeper();
-
-      if (fileLoggingEnabled) {
-        // Allow a system property to override the default output format
-        Format format = Format.HTML;
-        if (defaultFormatString != null) {
-          for (Format value : Format.values()) {
-            if (value.name().toLowerCase().equals(defaultFormatString.toLowerCase())) {
-              format = value;
-              break;
-            }
-          }
-        }
-        outputFormat = format;
-        eventsToWrite = openDefaultLogWriter();
-
-        shutDownSentinel = new TraceEvent();
-        flushSentinel = new TraceEvent();
-        shutDownLatch = new CountDownLatch(1);
-      }
-
-      if (logGcTime) {
-        gcMXBeans = ManagementFactory.getGarbageCollectorMXBeans();
-        lastGcTimes = new ConcurrentHashMap<String, Long>();
-      }
-
-      pendingEvents = initPendingEvents();
-    } else {
-      elapsedTimeKeeper = null;
-      processCpuTimeKeeper = null;
-      threadCpuTimeKeeper = null;
-    }
-  }
-
-  public void addDataImpl(String... data) {
-    Stack<TraceEvent> threadPendingEvents = pendingEvents.get();
-    if (threadPendingEvents.isEmpty()) {
-      throw new IllegalStateException("Tried to add data to an event that never started!");
-    }
-
-    TraceEvent currentEvent = threadPendingEvents.peek();
-    currentEvent.addData(data);
-  }
-
-  public void markTimelineImpl(String message) {
-    Stack<TraceEvent> threadPendingEvents = pendingEvents.get();
-    TraceEvent parent = null;
-    if (!threadPendingEvents.isEmpty()) {
-      parent = threadPendingEvents.peek();
-    }
-    TraceEvent newEvent = new MarkTimelineEvent(parent);
-    threadPendingEvents.push(newEvent);
-    newEvent.end("message", message);
-  }
-
-  void addGcEvents(TraceEvent refEvent) {
-    // we're not sending GC events to the dartboard, so we only record them
-    // to file
-    if (!fileLoggingEnabled) {
-      return;
-    }
-
-    for (GarbageCollectorMXBean gcMXBean : gcMXBeans) {
-      String gcName = gcMXBean.getName();
-      Long lastGcTime = lastGcTimes.get(gcName);
-      long currGcTime = gcMXBean.getCollectionTime();
-      if (lastGcTime == null) {
-        lastGcTime = 0L;
-      }
-      if (currGcTime > lastGcTime) {
-        // create a new event
-        long gcDurationNanos = (currGcTime - lastGcTime) * 1000000L;
-        TraceEvent gcEvent =
-            new GcEvent(refEvent, gcName, gcMXBean.getCollectionCount(), gcDurationNanos);
-
-        eventsToWrite.add(gcEvent);
-        lastGcTimes.put(gcName, currGcTime);
-      }
-    }
-  }
-
-  void addOverheadEvent(TraceEvent refEvent) {
-    TraceEvent overheadEvent = new TraceEvent(refEvent, SpeedTracerEventType.OVERHEAD);
-    // measure the time between the end of refEvent and now
-    overheadEvent.setStartsAfter(refEvent);
-    overheadEvent.updateDuration();
-
-    refEvent.extendDuration(overheadEvent);
-  }
-
-  void endImpl(TraceEvent event, String... data) {
-    if (!enabled) {
-      return;
-    }
-
-    if (data.length % 2 == 1) {
-      throw new IllegalArgumentException("Unmatched data argument");
-    }
-
-    Stack<TraceEvent> threadPendingEvents = pendingEvents.get();
-    if (threadPendingEvents.isEmpty()) {
-      throw new IllegalStateException("Tried to end an event that never started!");
-    }
-    TraceEvent currentEvent = threadPendingEvents.pop();
-    currentEvent.updateDuration();
-
-    while (currentEvent != event && !threadPendingEvents.isEmpty()) {
-      // Missed a closing end for one or more frames! Try to sync back up.
-      currentEvent.addData("Missed",
-          "This event was closed without an explicit call to Event.end()");
-      currentEvent = threadPendingEvents.pop();
-      currentEvent.updateDuration();
-    }
-
-    if (threadPendingEvents.isEmpty() && currentEvent != event) {
-      currentEvent.addData("Missed", "Fell off the end of the threadPending events");
-    }
-
-    if (logGcTime) {
-      addGcEvents(currentEvent);
-    }
-
-    currentEvent.addData(data);
-
-    if (logOverheadTime) {
-      addOverheadEvent(currentEvent);
-    }
-
-    if (threadPendingEvents.isEmpty()) {
-      if (fileLoggingEnabled) {
-        eventsToWrite.add(currentEvent);
-      }
-    }
-  }
-
-  /**
-   * Notifies the background thread to finish processing all data in the queue.
-   * Blocks the current thread until the data is flushed in the Log Writer
-   * thread.
-   */
-  void flush() {
-    if (!fileLoggingEnabled) {
-      return;
-    }
-
-    try {
-      // Wait for the other thread to drain the queue.
-      flushLatch = new CountDownLatch(1);
-      eventsToWrite.add(flushSentinel);
-      flushLatch.await();
-    } catch (InterruptedException e) {
-      // Ignored
-    }
-  }
-
-  TraceEvent startImpl(EventType type, String... data) {
-    if (!enabled) {
-      return dummyEvent;
-    }
-
-    if (data.length % 2 == 1) {
-      throw new IllegalArgumentException("Unmatched data argument");
-    }
-
-    Stack<TraceEvent> threadPendingEvents = pendingEvents.get();
-    TraceEvent parent = null;
-    if (!threadPendingEvents.isEmpty()) {
-      parent = threadPendingEvents.peek();
-    } else {
-      // reset the thread CPU time base for top-level events (so events can be
-      // properly sequenced chronologically)
-      threadCpuTimeKeeper.resetTimeBase();
-    }
-
-    TraceEvent newEvent = new TraceEvent(parent, type, data);
-    // Add a field to the top level event in order to track the base time
-    // so we can re-normalize the data
-    if (threadPendingEvents.size() == 0) {
-      long baseTime =
-          logProcessCpuTime ? processCpuTimeKeeper.zeroTimeMillis() : (logThreadCpuTime
-              ? threadCpuTimeKeeper.zeroTimeMillis() : elapsedTimeKeeper.zeroTimeMillis());
-      newEvent.addData("baseTime", "" + baseTime);
-    }
-    threadPendingEvents.push(newEvent);
-    return newEvent;
-  }
-
-  private ThreadLocal<Stack<TraceEvent>> initPendingEvents() {
-    return new ThreadLocal<Stack<TraceEvent>>() {
-      @Override
-      protected Stack<TraceEvent> initialValue() {
-        return new Stack<TraceEvent>();
-      }
-    };
-  }
-
-  private BlockingQueue<TraceEvent> openDefaultLogWriter() {
-    Writer writer = null;
-    if (enabled) {
-      try {
-        writer = new BufferedWriter(new FileWriter(logFile));
-        return openLogWriter(writer, logFile);
-      } catch (IOException e) {
-        System.err.println("Unable to open dart.speedtracerlog '" + logFile + "'");
-        e.printStackTrace();
-      }
-    }
-    return null;
-  }
-
-  private BlockingQueue<TraceEvent> openLogWriter(final Writer writer, final String fileName) {
-    try {
-      if (outputFormat.equals(Format.HTML)) {
-        writer.write("<HTML isdump=\"true\"><body>"
-            + "<style>body {font-family:Helvetica; margin-left:15px;}</style>"
-            + "<h2>Performance dump from GWT</h2>"
-            + "<div>This file contains data that can be viewed with the "
-            + "<a href=\"http://code.google.com/speedtracer\">SpeedTracer</a> "
-            + "extension under the <a href=\"http://chrome.google.com/\">"
-            + "Chrome</a> browser.</div><p><span id=\"info\">"
-            + "(You must install the SpeedTracer extension to open this file)</span></p>"
-            + "<div style=\"display: none\" id=\"traceData\" version=\"0.17\">\n");
-      }
-    } catch (IOException e) {
-      System.err.println("Unable to write to dart.speedtracerlog '"
-          + (fileName == null ? "" : fileName) + "'");
-      e.printStackTrace();
-      return null;
-    }
-
-    final BlockingQueue<TraceEvent> eventQueue = new LinkedBlockingQueue<TraceEvent>();
-
-    Runtime.getRuntime().addShutdownHook(new Thread() {
-      @Override
-      public void run() {
-        try {
-          // Wait for the other thread to drain the queue.
-          eventQueue.add(shutDownSentinel);
-          shutDownLatch.await();
-        } catch (InterruptedException e) {
-          // Ignored
-        }
-      }
-    });
-
-    // Background thread to write SpeedTracer events to log
-    Thread logWriterWorker = new LogWriterThread(writer, fileName, eventQueue);
-
-    // Lower than normal priority.
-    logWriterWorker.setPriority((Thread.MIN_PRIORITY + Thread.NORM_PRIORITY) / 2);
-
-    /*
-     * This thread must be daemon, otherwise shutdown hooks would never begin to
-     * run, and an app wouldn't finish.
-     */
-    logWriterWorker.setDaemon(true);
-    logWriterWorker.setName("SpeedTracerLogger writer");
-    logWriterWorker.start();
-    return eventQueue;
-  }
-}
diff --git a/compiler/java/com/google/dart/compiler/parser/AbstractParser.java b/compiler/java/com/google/dart/compiler/parser/AbstractParser.java
deleted file mode 100644
index 6295eb1..0000000
--- a/compiler/java/com/google/dart/compiler/parser/AbstractParser.java
+++ /dev/null
@@ -1,257 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.parser;
-
-import com.google.common.collect.Lists;
-import com.google.common.collect.Maps;
-import com.google.common.collect.Sets;
-import com.google.dart.compiler.DartCompilationError;
-import com.google.dart.compiler.ErrorCode;
-import com.google.dart.compiler.parser.DartScanner.Location;
-
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-/**
- * Abstract base class for sharing common utility methods between implementation
- * classes, like {@link DartParser}.
- */
-abstract class AbstractParser {
-
-  private final TerminalAnnotationsCache terminalAnnotationsCache = new TerminalAnnotationsCache();
-  protected final ParserContext ctx;
-  private int lastErrorPosition = Integer.MIN_VALUE;
-
-  protected AbstractParser(ParserContext ctx) {
-    this.ctx = ctx;
-  }
-
-  protected boolean EOS() {
-    return match(Token.EOS) || match(Token.ILLEGAL);
-  }
-
-  private static class TerminalAnnotationsCache {
-    private Map<String, Class<?>> classes;
-    private Map<String, List<Token>> methods;
-
-    private void init(StackTraceElement[] stackTrace) {
-      // This method, she is slow.
-      if (classes == null) {
-        classes = Maps.newHashMap();
-        methods = Maps.newHashMap();
-      }
-
-      for (StackTraceElement frame : stackTrace) {
-        Class<?> thisClass = classes.get(frame.getClassName());
-        if (thisClass == null) {
-          try {
-            thisClass = Class.forName(frame.getClassName());
-
-            for (java.lang.reflect.Method method : thisClass
-                .getDeclaredMethods()) {
-              List<Token> tokens = methods.get(method.getName());
-              if (tokens == null) {
-                tokens = Lists.newArrayList();
-                methods.put(thisClass.getName() + "." + method.getName(), tokens);
-              }
-              // look for annotations
-              Terminals terminalsAnnotation = method
-                  .getAnnotation(Terminals.class);
-              if (terminalsAnnotation != null) {
-                for (Token token : terminalsAnnotation.tokens()) {
-                  tokens.add(token);
-                }
-              }
-            }
-          } catch (ClassNotFoundException e) {
-            // ignored
-          }
-          classes.put(frame.getClassName(), null);
-        }
-      }
-    }
-
-    public Set<Token> terminalsForStack(StackTraceElement[] stackTrace) {
-      Set<Token> results = Sets.newHashSet();
-      for (StackTraceElement frame: stackTrace) {
-        List<Token> found = methods.get(frame.getClassName() + "." + frame.getMethodName());
-        if (found !=  null) {
-          results.addAll(found);
-        }
-      }
-      return results;
-    }
-  }
-
-  /**
-   * Uses reflection to walk up the stack and look for @Terminals method
-   * annotations. It gathers up the tokens in these annotations and returns them
-   * to the caller. This is intended for use in parser recovery, so that we
-   * don't accidentally consume a token that could be used to complete a
-   * non-terminal higher up in the stack.
-   */
-  protected Set<Token> collectTerminalAnnotations() {
-    StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace();
-    // Get methods for every class and associated Terminals annotations & stick them in a hash
-    terminalAnnotationsCache.init(stackTrace);
-    // Create the set of terminals to return
-    return terminalAnnotationsCache.terminalsForStack(stackTrace);
-  }
-
-  /**
-   * If the expectedToken is encountered it is consumed and <code>true</code> is returned.
-   * If the expectedToken is not found, an error is reported.
-   * The token will only be consumed if it is not among the set of tokens that can be handled
-   * by a method currently on the stack.  See the {@link Terminals annotation}
-   *
-   * @param expectedToken The token to expect next in the stream.
-   */
-  protected boolean expect(Token expectedToken) {
-    if (!optional(expectedToken)) {
-
-      /*
-       * Save the current token, then advance to make sure that we have the
-       * right position.
-       */
-      Token actualToken = peek(0);
-
-      Set<Token> possibleTerminals = collectTerminalAnnotations();
-
-      ctx.begin();
-      ctx.advance();
-      reportUnexpectedToken(position(), expectedToken, actualToken);
-      // Don't consume tokens someone else could use to cleanly terminate the
-      // statement.
-      if (possibleTerminals.contains(actualToken)) {
-        ctx.rollback();
-        return false;
-      }
-      ctx.done(null);
-
-      // Recover from the middle of string interpolation
-      if (actualToken.equals(Token.STRING_EMBED_EXP_START)
-          || actualToken.equals(Token.STRING_EMBED_EXP_END)) {
-        while (!EOS()) {
-          Token nextToken = next();
-          if (nextToken.equals(Token.STRING_LAST_SEGMENT)) {
-            break;
-          }
-          next();
-        }
-      }
-      return false;
-    }
-    return true;
-  }
-
-  protected Location peekTokenLocation(int n) {
-    assert (n >= 0);
-    return ctx.peekTokenLocation(n);
-  }
-
-  protected String getPeekTokenValue(int n) {
-    assert (n >= 0);
-    String value = ctx.peekTokenString(n);
-    return value;
-  }
-
-  protected boolean match(Token token) {
-    return peek(0) == token;
-  }
-
-  protected Token next() {
-    ctx.advance();
-    return ctx.getCurrentToken();
-  }
-
-  protected boolean optionalPseudoKeyword(String keyword) {
-    if (!peekPseudoKeyword(0, keyword)) {
-      return false;
-    }
-    next();
-    return true;
-  }
-
-  protected boolean optional(Token token) {
-    if (peek(0) != token) {
-      return false;
-    }
-    next();
-    return true;
-  }
-
-  protected Token peek(int n) {
-    return ctx.peek(n);
-  }
-
-  protected boolean peekPseudoKeyword(int n, String keyword) {
-    return (peek(n) == Token.IDENTIFIER)
-        && keyword.equals(getPeekTokenValue(n));
-  }
-
-  protected int position() {
-    DartScanner.Location tokenLocation = ctx.getTokenLocation();
-    return tokenLocation != null ? tokenLocation.getBegin() : 0;
-  }
-
-  /**
-   * Report a syntax error, unless an error has already been reported at the
-   * given or a later position.
-   */
-  protected void reportError(int position,
-                             ErrorCode errorCode, Object... arguments) {
-    DartScanner.Location location = ctx.getTokenLocation();
-    if (location.getBegin() <= lastErrorPosition) {
-      return;
-    }
-    DartCompilationError dartError = new DartCompilationError(ctx.getSource(),
-        location, errorCode, arguments);
-    lastErrorPosition = position;
-    ctx.error(dartError);
-  }
-
-  /**
-   * Even though you pass a 'Position' to {@link #reportError} above, it only
-   * uses that to prevent logging more than one error at that position. This
-   * method actually uses the passed position to create the error event.
-   */
-  protected void reportErrorAtPosition(int startPosition,
-                                       int endPosition,
-                                       ErrorCode errorCode, Object... arguments) {
-    DartScanner.Location location = ctx.getTokenLocation();
-    if (location.getBegin() <= lastErrorPosition) {
-      return;
-    }
-    DartCompilationError dartError = new DartCompilationError(ctx.getSource(),
-        new Location(startPosition, endPosition), errorCode, arguments);
-    ctx.error(dartError);
-  }
-
-  protected void reportUnexpectedToken(int position,
-                                       Token expected, Token actual) {
-    if (expected == Token.EOS) {
-      reportError(position, ParserErrorCode.EXPECTED_EOS, actual);
-    } else if (expected == Token.IDENTIFIER) {
-      reportError(position, ParserErrorCode.INVALID_IDENTIFIER, actual);
-    } else if (expected == null) {
-      reportError(position, ParserErrorCode.UNEXPECTED_TOKEN, actual);
-    } else {
-      reportError(position, ParserErrorCode.EXPECTED_TOKEN, actual, expected);
-    }
-  }
-
-  protected void setPeek(int n, Token token) {
-    assert n == 0; // so far, n is always zero
-    ctx.replaceNextToken(token);
-  }
-
-  protected boolean consume(Token token) {
-    boolean result = (peek(0) == token);
-    assert (result);
-    next();
-    return result;
-  }
-}
diff --git a/compiler/java/com/google/dart/compiler/parser/CompletionHooksParserBase.java b/compiler/java/com/google/dart/compiler/parser/CompletionHooksParserBase.java
deleted file mode 100644
index 0c52488..0000000
--- a/compiler/java/com/google/dart/compiler/parser/CompletionHooksParserBase.java
+++ /dev/null
@@ -1,482 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.parser;
-
-import com.google.dart.compiler.common.HasSourceInfo;
-
-/**
- * This class exists to enforce constraints on begin calls so code
- * completion works.
- * <p>
- * In particular, it prevents {@link #begin()} from being called directly,
- * ensuring that callers must use appropriate {@code beginFoo} methods.
- * <p>
- * These hooks serve two purposes:
- * <ol>
- * <li>remember start positions to set source location information on AST
- * nodes
- * <li>provide an event mechanism that is useful for an IDE operating on code
- * being edited - for example, for error recovery or code completion
- * </ol>
- * <p>
- * Every call to {@code beginFoo} must be balanced with exactly one call
- * to either {@link #rollback()} or {@link #done(Object)}.  Between those
- * calls, there may be an arbitrary number of calls to
- * {@link #doneWithoutConsuming(Object)} to set AST node positions based on
- * the current position on the stack.
- */
-public abstract class CompletionHooksParserBase extends AbstractParser {
-
-  /*
-   * Guards the parser from infinite loops and recursion.
-   * THIS CLASS IS FOR DEBUG/INTERNAL USE ONLY.
-   * TODO (fabiomfv) - remove before release.
-   */
-  private class TerminationGuard {
-
-    /*
-     * Loosely, determines the maximum number of non-terminals 'visited' without
-     * advancing on input. It does not need to be a precise number, just to have
-     * an upper bound on the 'space' the parser can consume before declaring
-     * it is not making progress.
-     */
-    private static final int THRESHOLD = 1000;
-
-    private int maxPositionRange = Integer.MIN_VALUE;
-    private int minPositionRange = Integer.MAX_VALUE;
-    private int threshold = THRESHOLD;
-
-    /*
-     * Guard against parser termination bugs. Called from begin().
-     * If the parser does not consume tokens it is an indication that it is not
-     * making progress. Look at the stack in the exception for hints of
-     * productions at fault. Called from begin()
-     */
-    public boolean assertProgress() {
-      int currentPosition = position();
-      if (currentPosition > maxPositionRange) {
-        minPositionRange = maxPositionRange;
-        maxPositionRange = currentPosition;
-        threshold = THRESHOLD;
-      } else if (currentPosition < minPositionRange) {
-        minPositionRange = currentPosition;
-        threshold = THRESHOLD;
-      }
-      if (threshold-- <= 0) {
-        StringBuilder sb = new StringBuilder();
-        sb.append("Parser failed to make progress after many tries. File a " +
-          "bug and attach this callstack and error output.\n");
-        sb.append("Scanner State: ");
-        sb.append(ctx.toString());
-        sb.append("\n");
-        sb.append("Input range [");
-        sb.append(minPositionRange);
-        sb.append(",");
-        sb.append(maxPositionRange);
-        sb.append("]\n");
-        throw new AssertionError(sb.toString());
-      }
-      return true;
-    }
-  }
-
-  /**
-   * Guards against termination bugs. For debugging purposes only.
-   * See {@link TerminationGuard} for details.
-   */
-  private TerminationGuard guard = new TerminationGuard();
-
-  /**
-   * Set the context the parser will use.
-   *
-   * @param ctx the {@link ParserContext} to use
-   */
-  public CompletionHooksParserBase(ParserContext ctx) {
-    super(ctx);
-  }
-
-  protected void beginArgumentDefinitionTest() {
-    begin();
-  }
-
-  protected void beginArrayLiteral() {
-    begin();
-  }
-  
-  protected void beginAssertStatement() {
-    begin();
-  }
-
-  protected void beginBinaryExpression() {
-    begin();
-  }
-
-  protected void beginBlock() {
-    begin();
-  }
-
-  protected void beginBreakStatement() {
-    begin();
-  }
-
-  protected void beginCatchClause() {
-    begin();
-  }
-
-  protected void beginCatchParameter() {
-    begin();
-  }
-
-  protected void beginClassBody() {
-    begin();
-  }
-
-  protected void beginClassMember() {
-    begin();
-  }
-
-  protected void beginCompilationUnit() {
-    begin();
-  }
-
-  protected void beginConditionalExpression() {
-    begin();
-  }
-
-  protected void beginConstExpression() {
-    begin();
-  }
-
-  protected void beginConstructor() {
-    begin();
-  }
-
-  protected void beginConstructorNamePart() {
-    begin();
-  }
-
-  protected void beginContinueStatement() {
-    begin();
-  }
-
-  protected void beginDoStatement() {
-    begin();
-  }
-
-  protected void beginEmptyStatement() {
-    begin();
-  }
-
-  protected void beginEntryPoint() {
-    begin();
-  }
-
-  protected void beginExportDirective() {
-    begin();
-  }
-
-  protected void beginExpression() {
-    begin();
-  }
-
-  protected void beginExpressionList() {
-    begin();
-  }
-
-  protected void beginExpressionStatement() {
-    begin();
-  }
-
-  protected void beginFieldInitializerOrRedirectedConstructor() {
-    begin();
-  }
-
-  protected void beginFinalDeclaration() {
-    begin();
-  }
-
-  protected void beginForInitialization() {
-    begin();
-  }
-
-  protected void beginFormalParameter() {
-    begin();
-  }
-
-  protected void beginFormalParameterList() {
-    begin();
-  }
-
-  protected void beginForStatement() {
-    begin();
-  }
-
-  protected void beginFunctionDeclaration() {
-    begin();
-  }
-
-  protected void beginFunctionLiteral() {
-    begin();
-  }
-
-  protected void beginFunctionStatementBody() {
-    begin();
-  }
-
-  protected void beginClassTypeInterface() {
-    begin();
-  }
-  
-  protected void beginFunctionTypeInterface() {
-    begin();
-  }
-
-  protected void beginIdentifier() {
-    begin();
-  }
-
-  protected void beginIfStatement() {
-    begin();
-  }
-
-  protected void beginImportDirective() {
-    begin();
-  }
-  
-  protected void beginImportCombinator() {
-    begin();
-  }
-
-  protected void beginInitializer() {
-    begin();
-  }
-
-  protected void beginTypeExpression() {
-    begin();
-  }
-
-  protected void beginLabel() {
-    begin();
-  }
-
-  protected void beginLibraryDirective() {
-    begin();
-  }
-
-  protected void beginLiteral() {
-    begin();
-  }
-
-  protected void beginMapLiteral() {
-    begin();
-  }
-
-  protected void beginMapLiteralEntry() {
-    begin();
-  }
-
-  protected void beginMetadata() {
-    begin();
-  }
-
-  protected void beginMethodName() {
-    begin();
-  }
-
-  protected void beginNativeBody() {
-    begin();
-  }
-
-  protected void beginNativeDirective() {
-    begin();
-  }
-
-  protected void beginNewExpression() {
-    begin();
-  }
-
-  protected void beginOperatorName() {
-    begin();
-  }
-
-  protected void beginParameter() {
-    begin();
-  }
-
-  protected void beginParameterName() {
-    begin();
-  }
-
-  protected void beginParenthesizedExpression() {
-    begin();
-  }
-
-  protected void beginPartDirective() {
-    begin();
-  }
-
-  protected void beginPartOfDirective() {
-    begin();
-  }
-
-  protected void beginPostfixExpression() {
-    begin();
-  }
-
-  protected void beginQualifiedIdentifier() {
-    begin();
-  }
-
-  protected void beginReturnStatement() {
-    begin();
-  }
-
-  protected void beginReturnType() {
-    begin();
-  }
-
-  protected void beginSelectorExpression() {
-    begin();
-  }
-
-  protected void beginSourceDirective() {
-    begin();
-  }
-
-  protected void beginSpreadExpression() {
-    begin();
-  }
-
-  protected void beginStringInterpolation() {
-    begin();
-  }
-
-  protected void beginStringSegment() {
-    begin();
-  }
-
-  protected void beginSuperExpression() {
-    begin();
-  }
-
-  protected void beginSuperInitializer() {
-    begin();
-  }
-
-  protected void beginSwitchMember() {
-    begin();
-  }
-
-  protected void beginSwitchStatement() {
-    begin();
-  }
-
-  protected void beginThisExpression() {
-    begin();
-  }
-
-  protected void beginThrowExpression() {
-    begin();
-  }
-
-  protected void beginTopLevelElement() {
-    begin();
-  }
-
-  protected void beginTryStatement() {
-    begin();
-  }
-
-  protected void beginTypeAnnotation() {
-    begin();
-  }
-
-  protected void beginTypeArguments() {
-    begin();
-  }
-
-  protected void beginTypeFunctionOrVariable() {
-    begin();
-  }
-
-  protected void beginTypeParameter() {
-    begin();
-  }
-
-  protected void beginUnaryExpression() {
-    begin();
-  }
-
-  protected void beginVarDeclaration() {
-    begin();
-  }
-
-  protected void beginVariableDeclaration() {
-    begin();
-  }
-
-  protected void beginWhileStatement() {
-    begin();
-  }
-
-  /**
-   * Terminates a grammatical structure, saving the source location in the
-   * supplied AST node.
-   *
-   * @param <T> type of the AST node
-   * @param result the AST node to return, if any - if it implements
-   *     {@link HasSourceInfo}, the source location is set based on the
-   *     current position and the start of this grammatical structure
-   * @return the supplied AST node (may be null)
-   */
-  protected <T> T done(T result) {
-    return ctx.done(result);
-  }
-
-  /**
-   * Saves the current source location in the supplied AST node, used for
-   * subcomponents of the AST. This may only be called within an active
-   * {@link #begin()} call, which must still be terminated with either
-   * {@link #done(Object)} or {@link #rollback()}.
-   *
-   * @param <T> type of the AST node
-   * @param result the AST node to return - if it implements
-   *    {@link HasSourceInfo}, the source location is set based on the
-   *    current position and the start of this grammatical structure
-   * @return the supplied AST node
-   */
-  protected <T> T doneWithoutConsuming(T result) {
-    return ctx.doneWithoutConsuming(result);
-  }
-
-  /**
-   * Terminates an attempt to parse a grammatical structure, rolling back to the
-   * state as of the previous {@link #begin()} call and removing the saved
-   * state.
-   */
-  protected void rollback() {
-    ctx.rollback();
-  }
-
-  /**
-   * This should only be called when the parser is looking ahead to decide how
-   * to parse something, and this will always be rolled back without any other {@link #begin()}
-   * statements being called.
-   */
-  protected void startLookahead() {
-    begin();
-  }
-
-  /**
-   * Begin a grammatical structure, saving the current location to later set in
-   * an AST node. This may be followed by zero or more
-   * {@link #doneWithoutConsuming(Object)} calls, and is terminated by exactly
-   * one {@link #done(Object)} or {@link #rollback()} call.
-   */
-  private void begin() {
-    assert guard.assertProgress();
-    ctx.begin();
-  }
-}
diff --git a/compiler/java/com/google/dart/compiler/parser/DartParser.java b/compiler/java/com/google/dart/compiler/parser/DartParser.java
deleted file mode 100644
index cd5728a..0000000
--- a/compiler/java/com/google/dart/compiler/parser/DartParser.java
+++ /dev/null
@@ -1,5688 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.parser;
-
-import com.google.common.annotations.VisibleForTesting;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.io.CharStreams;
-import com.google.dart.compiler.DartCompilationError;
-import com.google.dart.compiler.DartCompilerListener;
-import com.google.dart.compiler.DartSource;
-import com.google.dart.compiler.ErrorCode;
-import com.google.dart.compiler.ErrorSeverity;
-import com.google.dart.compiler.InternalCompilerException;
-import com.google.dart.compiler.LibrarySource;
-import com.google.dart.compiler.PackageLibraryManager;
-import com.google.dart.compiler.Source;
-import com.google.dart.compiler.ast.DartAnnotation;
-import com.google.dart.compiler.ast.DartArrayAccess;
-import com.google.dart.compiler.ast.DartArrayLiteral;
-import com.google.dart.compiler.ast.DartAssertStatement;
-import com.google.dart.compiler.ast.DartBinaryExpression;
-import com.google.dart.compiler.ast.DartBlock;
-import com.google.dart.compiler.ast.DartBooleanLiteral;
-import com.google.dart.compiler.ast.DartBreakStatement;
-import com.google.dart.compiler.ast.DartCascadeExpression;
-import com.google.dart.compiler.ast.DartCase;
-import com.google.dart.compiler.ast.DartCatchBlock;
-import com.google.dart.compiler.ast.DartClass;
-import com.google.dart.compiler.ast.DartClassTypeAlias;
-import com.google.dart.compiler.ast.DartConditional;
-import com.google.dart.compiler.ast.DartContinueStatement;
-import com.google.dart.compiler.ast.DartDeclaration;
-import com.google.dart.compiler.ast.DartDefault;
-import com.google.dart.compiler.ast.DartDirective;
-import com.google.dart.compiler.ast.DartDoWhileStatement;
-import com.google.dart.compiler.ast.DartDoubleLiteral;
-import com.google.dart.compiler.ast.DartEmptyStatement;
-import com.google.dart.compiler.ast.DartExportDirective;
-import com.google.dart.compiler.ast.DartExprStmt;
-import com.google.dart.compiler.ast.DartExpression;
-import com.google.dart.compiler.ast.DartField;
-import com.google.dart.compiler.ast.DartFieldDefinition;
-import com.google.dart.compiler.ast.DartForInStatement;
-import com.google.dart.compiler.ast.DartForStatement;
-import com.google.dart.compiler.ast.DartFunction;
-import com.google.dart.compiler.ast.DartFunctionExpression;
-import com.google.dart.compiler.ast.DartFunctionObjectInvocation;
-import com.google.dart.compiler.ast.DartFunctionTypeAlias;
-import com.google.dart.compiler.ast.DartIdentifier;
-import com.google.dart.compiler.ast.DartIfStatement;
-import com.google.dart.compiler.ast.DartImportDirective;
-import com.google.dart.compiler.ast.DartInitializer;
-import com.google.dart.compiler.ast.DartIntegerLiteral;
-import com.google.dart.compiler.ast.DartLabel;
-import com.google.dart.compiler.ast.DartLibraryDirective;
-import com.google.dart.compiler.ast.DartMapLiteral;
-import com.google.dart.compiler.ast.DartMapLiteralEntry;
-import com.google.dart.compiler.ast.DartMethodDefinition;
-import com.google.dart.compiler.ast.DartMethodInvocation;
-import com.google.dart.compiler.ast.DartNamedExpression;
-import com.google.dart.compiler.ast.DartNativeBlock;
-import com.google.dart.compiler.ast.DartNativeDirective;
-import com.google.dart.compiler.ast.DartNewExpression;
-import com.google.dart.compiler.ast.DartNode;
-import com.google.dart.compiler.ast.DartNodeWithMetadata;
-import com.google.dart.compiler.ast.DartNullLiteral;
-import com.google.dart.compiler.ast.DartParameter;
-import com.google.dart.compiler.ast.DartParameterizedTypeNode;
-import com.google.dart.compiler.ast.DartParenthesizedExpression;
-import com.google.dart.compiler.ast.DartPartOfDirective;
-import com.google.dart.compiler.ast.DartPropertyAccess;
-import com.google.dart.compiler.ast.DartRedirectConstructorInvocation;
-import com.google.dart.compiler.ast.DartReturnBlock;
-import com.google.dart.compiler.ast.DartReturnStatement;
-import com.google.dart.compiler.ast.DartSourceDirective;
-import com.google.dart.compiler.ast.DartStatement;
-import com.google.dart.compiler.ast.DartStringInterpolation;
-import com.google.dart.compiler.ast.DartStringLiteral;
-import com.google.dart.compiler.ast.DartSuperConstructorInvocation;
-import com.google.dart.compiler.ast.DartSuperExpression;
-import com.google.dart.compiler.ast.DartSwitchMember;
-import com.google.dart.compiler.ast.DartSwitchStatement;
-import com.google.dart.compiler.ast.DartSyntheticErrorExpression;
-import com.google.dart.compiler.ast.DartSyntheticErrorIdentifier;
-import com.google.dart.compiler.ast.DartSyntheticErrorStatement;
-import com.google.dart.compiler.ast.DartThisExpression;
-import com.google.dart.compiler.ast.DartThrowExpression;
-import com.google.dart.compiler.ast.DartTryStatement;
-import com.google.dart.compiler.ast.DartTypeExpression;
-import com.google.dart.compiler.ast.DartTypeNode;
-import com.google.dart.compiler.ast.DartTypeParameter;
-import com.google.dart.compiler.ast.DartUnaryExpression;
-import com.google.dart.compiler.ast.DartUnit;
-import com.google.dart.compiler.ast.DartUnqualifiedInvocation;
-import com.google.dart.compiler.ast.DartVariable;
-import com.google.dart.compiler.ast.DartVariableStatement;
-import com.google.dart.compiler.ast.DartWhileStatement;
-import com.google.dart.compiler.ast.HasObsoleteMetadata;
-import com.google.dart.compiler.ast.ImportCombinator;
-import com.google.dart.compiler.ast.ImportHideCombinator;
-import com.google.dart.compiler.ast.ImportShowCombinator;
-import com.google.dart.compiler.ast.LibraryNode;
-import com.google.dart.compiler.ast.LibraryUnit;
-import com.google.dart.compiler.ast.Modifiers;
-import com.google.dart.compiler.metrics.CompilerMetrics;
-import com.google.dart.compiler.parser.DartScanner.Location;
-import com.google.dart.compiler.resolver.Elements;
-import com.google.dart.compiler.util.Lists;
-import com.google.dart.compiler.util.apache.StringUtils;
-
-import java.io.IOException;
-import java.io.Reader;
-import java.math.BigInteger;
-import java.text.Normalizer;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-
-/**
- * The Dart parser. Parses a single compilation unit and produces a {@link DartUnit}.
- * The grammar rules are taken from Dart.g revision 557.
- */
-public class DartParser extends CompletionHooksParserBase {
-
-  private final Source source;
-  private final String sourceCode;
-  private final boolean isDietParse;
-  private final Set<String> prefixes;
-  private boolean allowNativeKeyword;
-  private final Set<Integer> errorHistory = new HashSet<Integer>();
-  private boolean isParsingInterface;
-  private boolean isTopLevelAbstract;
-  private int topLevelAbstractModifierPosition;
-  private boolean isParsingClass;
-  private int errorCount = 0;
-  
-  /**
-   * Determines the maximum number of errors before terminating the parser. See
-   * {@link #reportError(int, ErrorCode, Object...)}.
-   */
-  final int MAX_DEFAULT_ERRORS = Short.MAX_VALUE;
-
-  // Pseudo-keywords that should also be valid identifiers.
-  private static final String ABSTRACT_KEYWORD = "abstract";
-  private static final String AS_KEYWORD = "as";
-  private static final String CALL_KEYWORD = "call";
-  public static final String DYNAMIC_KEYWORD = "dynamic";
-  private static final String EXPORT_KEYWORD = "export";
-  private static final String EXTERNAL_KEYWORD = "external";
-  private static final String FACTORY_KEYWORD = "factory";
-  private static final String GETTER_KEYWORD = "get";
-  private static final String HIDE_KEYWORD = "hide";
-  private static final String IMPLEMENTS_KEYWORD = "implements";
-  private static final String IMPORT_KEYWORD = "import";
-  private static final String INTERFACE_KEYWORD = "interface";
-  private static final String LIBRARY_KEYWORD = "library";
-  private static final String NATIVE_KEYWORD = "native";
-  private static final String OF_KEYWORD = "of";
-  private static final String ON_KEYWORD = "on";
-  private static final String OPERATOR_KEYWORD = "operator";
-  private static final String PART_KEYWORD = "part";
-  private static final String PREFIX_KEYWORD = "prefix";
-  private static final String SETTER_KEYWORD = "set";
-  private static final String SHOW_KEYWORD = "show";
-  private static final String STATIC_KEYWORD = "static";
-  private static final String TYPEDEF_KEYWORD = "typedef";
-  // does not exist in specification
-  private static final String PATCH_KEYWORD = "patch";
-
-
-  public static final String[] PSEUDO_KEYWORDS = {
-    ABSTRACT_KEYWORD,
-    AS_KEYWORD,
-    DYNAMIC_KEYWORD,
-    EXPORT_KEYWORD,
-    EXTERNAL_KEYWORD,
-    FACTORY_KEYWORD,
-    GETTER_KEYWORD,
-    IMPLEMENTS_KEYWORD,
-    IMPORT_KEYWORD,
-    LIBRARY_KEYWORD,
-    OPERATOR_KEYWORD,
-    PART_KEYWORD,
-    SETTER_KEYWORD,
-    STATIC_KEYWORD,
-    TYPEDEF_KEYWORD
-  };
-  public static final Set<String> PSEUDO_KEYWORDS_SET = ImmutableSet.copyOf(PSEUDO_KEYWORDS);
-
-  public static final String[] RESERVED_WORDS = {
-      "break",
-      "case",
-      "catch",
-      "class",
-      "const",
-      "continue",
-      "default",
-      "do",
-      "else",
-      "extends",
-      "false",
-      "final",
-      "finally",
-      "for",
-      "if",
-      "in",
-      "is",
-      "new",
-      "null",
-      "return",
-      "rethrow",
-      "super",
-      "switch",
-      "this",
-      "throw",
-      "true",
-      "try",
-      "var",
-      "void",
-      "while"};
-  public static final Set<String> RESERVED_WORDS_SET = ImmutableSet.copyOf(RESERVED_WORDS);
-
-  public DartParser(Source source,
-                    String sourceCode,
-                    boolean isDietParse,
-                    Set<String> prefixes,
-                    DartCompilerListener listener,
-                    CompilerMetrics compilerMetrics) {
-    super(new DartParserCommentsHelper.CommentParserContext(source, sourceCode, listener, compilerMetrics));
-    this.source = source;
-    this.sourceCode = sourceCode;
-    this.isDietParse = isDietParse;
-    this.prefixes = prefixes;
-    this.allowNativeKeyword = source != null && PackageLibraryManager.isDartUri(source.getUri());
-    // check Unicode normalization
-    {
-      int indexOfDifference = StringUtils.indexOfDifference(sourceCode,
-          Normalizer.normalize(sourceCode, Normalizer.Form.NFC));
-      if (indexOfDifference != -1) {
-        DartCompilationError error = new DartCompilationError(source, new Location(
-            indexOfDifference, indexOfDifference + 1),
-            ParserErrorCode.INVALID_UNICODE_NORMALIZATION);
-        ctx.error(error);
-      }
-    }
-  }
-
-  public static String read(Source source) throws IOException {
-    return read(source.getSourceReader());
-  }
-
-  public static String read(Reader reader) throws IOException {
-    try {
-      return CharStreams.toString(reader);
-    } finally {
-      reader.close();
-    }
-  }
-
-  /**
-   * A flag indicating whether function expressions are allowed.  See
-   * {@link #setAllowFunctionExpression(boolean)}.
-   */
-  private boolean allowFunctionExpression = true;
-
-  /**
-   * 'break' (with no labels) and 'continue' stmts are not valid
-   * just anywhere, they must be inside a loop or a case stmt.
-   *
-   * A break with a label may be valid and is allowed through and
-   * checked in the resolver.
-   */
-  private boolean inLoopStatement = false;
-  private boolean inCaseStatement = false;
-
-  /**
-   * Set the {@link #allowFunctionExpression} flag indicating whether function expressions are
-   * allowed, returning the old value. This is required to avoid ambiguity in a few places in the
-   * grammar.
-   *
-   * @param allow true if function expressions are allowed, false if not
-   * @return previous value of the flag, which should be restored
-   */
-  private boolean setAllowFunctionExpression(boolean allow) {
-    boolean old = allowFunctionExpression;
-    allowFunctionExpression = allow;
-    return old;
-  }
-
-  /**
-   * <pre>
-   * compilationUnit
-   *     : libraryDeclaration? topLevelDefinition* EOF
-   *     ;
-   *
-   * libraryDeclaration
-   *     : libraryDirective? importDirective* sourceDirective* resourceDirective* nativeDirective*
-   *
-   * topLevelDefinition
-   *     : classDefinition
-   *     | interfaceDefinition
-   *     | functionTypeAlias
-   *     | methodOrConstructorDeclaration functionStatementBody
-   *     | type? getOrSet identifier formalParameterList functionStatementBody
-   *     | CONST type? staticConstDeclarationList ';'
-   *     | variableDeclaration ';'
-   *     ;
-   * </pre>
-   */
-  @Terminals(tokens={Token.EOS, Token.CLASS, Token.LIBRARY, Token.IMPORT, Token.SOURCE,
-      Token.RESOURCE, Token.NATIVE})
-  public DartUnit parseUnit() {
-    DartSource dartSource = (DartSource) source;
-    
-    errorCount = 0;
-    
-    try {
-      beginCompilationUnit();
-      ctx.unitAboutToCompile(dartSource, isDietParse);
-      DartUnit unit = new DartUnit(dartSource, isDietParse);
-      List<DartAnnotation> metadata = parseMetadata();
-
-      // parse any directives at the beginning of the source
-      metadata = parseDirectives(unit, metadata);
-
-      while (!EOS()) {
-        DartNodeWithMetadata node = null;
-        beginTopLevelElement();
-        isParsingClass = isParsingInterface = false;
-        // Check for ABSTRACT_KEYWORD.
-        isTopLevelAbstract = false;
-        topLevelAbstractModifierPosition = 0;
-        if (isBuiltInSpecial() && optionalPseudoKeyword(ABSTRACT_KEYWORD)) {
-          isTopLevelAbstract = true;
-          topLevelAbstractModifierPosition = position();
-        }
-        // skip "patch" before "class"
-        if (peek(1) == Token.CLASS && optionalPseudoKeyword(PATCH_KEYWORD)) {
-        }
-        // Parse top level element.
-        if (optional(Token.CLASS)) {
-          isParsingClass = true;
-          node = done(parseClass());
-        } else if (peekPseudoKeyword(0, INTERFACE_KEYWORD) && peek(1).equals(Token.IDENTIFIER)) {
-          consume(Token.IDENTIFIER);
-          isParsingInterface = true;
-          reportError(position(), ParserErrorCode.DEPRECATED_INTERFACE);
-          node = done(parseClass());
-        } else if (peekPseudoKeyword(0, TYPEDEF_KEYWORD)
-            && (peek(1).equals(Token.IDENTIFIER) || peek(1).equals(Token.VOID))) {
-          consume(Token.IDENTIFIER);
-          node = done(parseTypeAlias());
-        } else if (looksLikeDirective()) {
-          reportErrorWithoutAdvancing(ParserErrorCode.DIRECTIVE_OUT_OF_ORDER);
-          metadata = parseDirectives(unit, metadata);
-        } else {
-          node = done(parseFieldOrMethod(false));
-        }
-        // Parsing was successful, add node.
-        if (node != null) {
-          unit.getTopLevelNodes().add(node);
-          setMetadata(node, metadata);
-          metadata = parseMetadata();
-          // Only "class" can be top-level abstract element.
-          if (isTopLevelAbstract && !isParsingClass) {
-            int abstractPositionEnd = topLevelAbstractModifierPosition + ABSTRACT_KEYWORD.length();
-            Location location = new Location(topLevelAbstractModifierPosition, abstractPositionEnd);
-            reportError(new DartCompilationError(source, location,
-                ParserErrorCode.ABSTRACT_TOP_LEVEL_ELEMENT));
-          }
-        }
-      }
-      expect(Token.EOS);
-      // add comments
-      {
-        List<int[]> commentLocs = ((DartParserCommentsHelper.CommentParserContext) ctx).getCommentLocs();
-        DartParserCommentsHelper.addComments(unit, source, sourceCode, commentLocs);
-      }
-      // done
-      unit.setHasParseErrors(errorCount != 0);
-      return done(unit);
-    } catch (StringInterpolationParseError exception) {
-      throw new InternalCompilerException("Failed to parse " + source.getUri(), exception);
-    }
-  }
-
-  /**
-   * Set the metadata associated with the given node to the given annotations.
-   * 
-   * @param node the node with which the metadata is to be associated
-   * @param metadata the metadata to be associated with the node
-   */
-  private void setMetadata(DartNodeWithMetadata node, List<DartAnnotation> annotations) {
-    if (node instanceof DartFieldDefinition) {
-      DartFieldDefinition fieldDefinition = (DartFieldDefinition) node;
-      List<DartField> fields = fieldDefinition.getFields();
-      for (DartField field : fields) {
-        setMetadata(field, annotations);
-      }
-      return;
-    }
-    if (annotations != null && !annotations.isEmpty()) {
-      node.setMetadata(annotations);
-      if (node instanceof HasObsoleteMetadata) {
-        HasObsoleteMetadata declaration = (HasObsoleteMetadata) node;
-        for (int i = 0, size = annotations.size(); i < size; i++) {
-          DartAnnotation annotation = annotations.get(i);
-          DartExpression nameNode = annotation.getName();
-          if (nameNode instanceof DartIdentifier) {
-            String name = ((DartIdentifier) nameNode).getName();
-            if (name.equals("deprecated")) {
-              declaration.setObsoleteMetadata(declaration.getObsoleteMetadata().makeDeprecated());
-            } else if (name.equals("override")) {
-              declaration.setObsoleteMetadata(declaration.getObsoleteMetadata().makeOverride());
-            }
-          }
-        }
-      }
-    }
-  }
-
-  private boolean looksLikeDirective() {
-    if (!isBuiltInSpecial()) {
-      return false;
-    }
-    switch(peek(0)) {
-      case LIBRARY:
-      case IMPORT:
-      case SOURCE:
-      case RESOURCE:
-      case NATIVE:
-        return true;
-    }
-    return peekPseudoKeyword(0, LIBRARY_KEYWORD) || peekPseudoKeyword(0, IMPORT_KEYWORD) || peekPseudoKeyword(0, PART_KEYWORD);
-  }
-
-  /**
-   * 'interface' and 'typedef' are valid to use as names of fields and methods, so you can't
-   * just blindly recover when you see them in any context.  This does a further test to make
-   * sure they are followed by another identifier.  This would be illegal as a field or method
-   * definition, as you cannot use 'interface' or 'typedef' as a type name.
-   */
-  private boolean looksLikeTopLevelKeyword() {
-    if (peek(0).equals(Token.CLASS)) {
-      return true;
-    }
-    if (peekPseudoKeyword(0, INTERFACE_KEYWORD)
-        && peek(1).equals(Token.IDENTIFIER)) {
-      return true;
-    } else if (peekPseudoKeyword(0, TYPEDEF_KEYWORD)
-        && (peek(1).equals(Token.IDENTIFIER) || peek(1).equals(Token.VOID))) {
-      return true;
-    }
-    return false;
-  }
-
-  /**
-   * A version of the parser which only parses the directives of a library.
-   *
-   * TODO(jbrosenberg): consider parsing the whole file here, in order to avoid
-   * duplicate work.  Probably requires removing use of LibraryUnit's, etc.
-   * Also, this minimal parse does have benefit in the incremental compilation
-   * case.
-   */
-  @SuppressWarnings("deprecation")
-  public LibraryUnit preProcessLibraryDirectives(LibrarySource source) {
-    beginCompilationUnit();
-    LibraryUnit libUnit = new LibraryUnit(source);
-    parseMetadata();
-    if (peekPseudoKeyword(0, LIBRARY_KEYWORD)) {
-      DartLibraryDirective libraryDirective = parseLibraryDirective();
-      libUnit.setName(libraryDirective.getLibraryName());
-      parseMetadata();
-    }
-    while (peekPseudoKeyword(0, IMPORT_KEYWORD) || peekPseudoKeyword(0, EXPORT_KEYWORD)) {
-      if (peekPseudoKeyword(0, IMPORT_KEYWORD)) {
-        DartImportDirective importDirective = parseImportDirective();
-        LibraryNode importPath = new LibraryNode(importDirective);
-        importPath.setSourceInfo(importDirective.getSourceInfo());
-        libUnit.addImportPath(importPath);
-      }
-      if (peekPseudoKeyword(0, EXPORT_KEYWORD)) {
-        DartExportDirective exportDirective = parseExportDirective();
-        LibraryNode importPath = new LibraryNode(exportDirective);
-        importPath.setSourceInfo(exportDirective.getSourceInfo());
-        libUnit.addExportPath(importPath);
-      }
-      parseMetadata();
-    }
-    while (peekPseudoKeyword(0, PART_KEYWORD)) {
-      if (peekPseudoKeyword(1, OF_KEYWORD)) {
-        parsePartOfDirective();
-      } else {
-        DartSourceDirective sourceDirective = parsePartDirective();
-        LibraryNode sourcePath = new LibraryNode(sourceDirective.getSourceUri().getValue());
-        sourcePath.setSourceInfo(sourceDirective.getSourceInfo());
-        libUnit.addSourcePath(sourcePath);
-      }
-      parseMetadata();
-    }
-    //
-    // The code below is obsolete. We do not make any effort to find duplications between the old
-    // and the new syntax because support for the old syntax will be removed very soon.
-    //
-    if (peek(0) == Token.LIBRARY) {
-      beginLibraryDirective();
-      DartLibraryDirective libDirective = done(parseObsoleteLibraryDirective());
-      libUnit.setName(libDirective.getLibraryName());
-      parseMetadata();
-    }
-    while (peek(0) == Token.IMPORT) {
-      beginImportDirective();
-      DartImportDirective importDirective = done(parseObsoleteImportDirective());
-      LibraryNode importPath;
-      if (importDirective.getOldPrefix() != null) {
-        importPath =
-            new LibraryNode(importDirective);
-      } else {
-        importPath = new LibraryNode(importDirective.getLibraryUri().getValue());
-      }
-      importPath.setSourceInfo(importDirective.getSourceInfo());
-      libUnit.addImportPath(importPath);
-      parseMetadata();
-    }
-    while (peek(0) == Token.SOURCE) {
-      beginSourceDirective();
-      DartSourceDirective sourceDirective = done(parseSourceDirective());
-      LibraryNode sourcePath = new LibraryNode(sourceDirective.getSourceUri().getValue());
-      sourcePath.setSourceInfo(sourceDirective.getSourceInfo());
-      libUnit.addSourcePath(sourcePath);
-      parseMetadata();
-    }
-    while (peek(0) == Token.RESOURCE) {
-      parseResourceDirective();
-      parseMetadata();
-    }
-    while (peek(0) == Token.NATIVE) {
-      beginNativeDirective();
-      DartNativeDirective nativeDirective = done(parseNativeDirective());
-      LibraryNode nativePath = new LibraryNode(nativeDirective.getNativeUri().getValue());
-      nativePath.setSourceInfo(nativeDirective.getSourceInfo());
-      libUnit.addNativePath(nativePath);
-      parseMetadata();
-    }
-
-    // add ourselves to the list of sources, so inline dart code will be parsed
-    libUnit.addSourcePath(libUnit.getSelfSourcePath());
-    return done(libUnit);
-  }
-
-  private List<DartAnnotation> parseDirectives(DartUnit unit, List<DartAnnotation> metadata) {
-    boolean hasLibraryDirective = false;
-    if (peekPseudoKeyword(0, LIBRARY_KEYWORD)) {
-      DartLibraryDirective libraryDirective = parseLibraryDirective();
-      for (DartDirective directive : unit.getDirectives()) {
-        if (directive instanceof DartLibraryDirective) {
-          reportError(position(), ParserErrorCode.ONLY_ONE_LIBRARY_DIRECTIVE);
-          break;
-        }
-      }
-      unit.getDirectives().add(libraryDirective);
-      hasLibraryDirective = true;
-      setMetadata(libraryDirective, metadata);
-      metadata = parseMetadata();
-    }
-    while (peekPseudoKeyword(0, IMPORT_KEYWORD) || peekPseudoKeyword(0, EXPORT_KEYWORD)) {
-      if (peekPseudoKeyword(0, IMPORT_KEYWORD)) {
-        DartImportDirective importDirective = parseImportDirective();
-        unit.getDirectives().add(importDirective);
-        setMetadata(importDirective, metadata);
-        metadata = parseMetadata();
-      } else {
-        DartExportDirective exportDirective = parseExportDirective();
-        unit.getDirectives().add(exportDirective);
-        if (!hasLibraryDirective) {
-          reportError(exportDirective, ParserErrorCode.EXPORT_WITHOUT_LIBRARY_DIRECTIVE);
-        }
-        setMetadata(exportDirective, metadata);
-        metadata = parseMetadata();
-      }
-    }
-    while (peekPseudoKeyword(0, PART_KEYWORD)) {
-      if (peekPseudoKeyword(1, OF_KEYWORD)) {
-        DartPartOfDirective partOfDirective = parsePartOfDirective();
-        unit.getDirectives().add(partOfDirective);
-        setMetadata(partOfDirective, metadata);
-        metadata = parseMetadata();
-      } else {
-        DartSourceDirective partDirective = parsePartDirective();
-        unit.getDirectives().add(partDirective);
-        setMetadata(partDirective, metadata);
-        metadata = parseMetadata();
-      }
-    }
-    //
-    // The code below is obsolete. We do not make any effort to find duplications between the old
-    // and the new syntax because support for the old syntax will be removed very soon.
-    //
-    if (peek(0) == Token.LIBRARY) {
-      beginLibraryDirective();
-      DartLibraryDirective libraryDirective = parseObsoleteLibraryDirective();
-      for (DartDirective directive : unit.getDirectives()) {
-        if (directive instanceof DartLibraryDirective) {
-          reportError(position(), ParserErrorCode.ONLY_ONE_LIBRARY_DIRECTIVE);
-          break;
-        }
-      }
-      unit.getDirectives().add(libraryDirective);
-      done(libraryDirective);
-      setMetadata(libraryDirective, metadata);
-      metadata = parseMetadata();
-    }
-    while (peek(0) == Token.IMPORT) {
-      beginImportDirective();
-      DartImportDirective importDirective = parseObsoleteImportDirective();
-      unit.getDirectives().add(done(importDirective));
-      setMetadata(importDirective, metadata);
-      metadata = parseMetadata();
-    }
-    while (peek(0) == Token.SOURCE) {
-      beginSourceDirective();
-      DartSourceDirective sourceDirective = parseSourceDirective();
-      unit.getDirectives().add(done(sourceDirective));
-      setMetadata(sourceDirective, metadata);
-      metadata = parseMetadata();
-    }
-    while (peek(0) == Token.RESOURCE) {
-      parseResourceDirective();
-    }
-    while (peek(0) == Token.NATIVE) {
-      beginNativeDirective();
-      DartNativeDirective nativeDirective = parseNativeDirective();
-      unit.getDirectives().add(done(nativeDirective));
-      setMetadata(nativeDirective, metadata);
-      metadata = parseMetadata();
-    }
-    return metadata;
-  }
-
-  private DartLibraryDirective parseLibraryDirective() {
-    beginLibraryDirective();
-    next(); // "library"
-    DartExpression libraryName = parseLibraryName();
-    expect(Token.SEMICOLON);
-    return done(new DartLibraryDirective(libraryName));
-  }
-
-  private DartExpression parseLibraryName() {
-    beginQualifiedIdentifier();
-    DartExpression libraryName = parseIdentifier();
-    while (optional(Token.PERIOD)) {
-      beginQualifiedIdentifier();
-      DartIdentifier identifier = parseIdentifier();
-      libraryName = done(new DartPropertyAccess(libraryName, identifier));
-    }
-    return done(libraryName);
-  }
-
-  private DartLibraryDirective parseObsoleteLibraryDirective() {
-    expect(Token.LIBRARY);
-    reportDeprecatedError(position(), ParserErrorCode.DEPRECATED_LIBRARY_DIRECTIVE);
-    expect(Token.LPAREN);
-    beginLiteral();
-    expect(Token.STRING);
-    DartStringLiteral libname = done(DartStringLiteral.get(ctx.getTokenString()));
-    expectCloseParen();
-    expect(Token.SEMICOLON);
-    return new DartLibraryDirective(libname);
-  }
-
-  protected DartExportDirective parseExportDirective() {
-    beginExportDirective();
-    next(); // "export"
-    DartStringLiteral libUri = parseUri();
-
-    List<ImportCombinator> combinators = new ArrayList<ImportCombinator>();
-    while (peekPseudoKeyword(0, HIDE_KEYWORD) || peekPseudoKeyword(0, SHOW_KEYWORD)) {
-      beginImportCombinator();
-      if (optionalPseudoKeyword(HIDE_KEYWORD)) {
-        List<DartIdentifier> hiddenNames = parseIdentifierList();
-        combinators.add(done(new ImportHideCombinator(hiddenNames)));
-      } else if (optionalPseudoKeyword(SHOW_KEYWORD)) {
-        List<DartIdentifier> shownNames = parseIdentifierList();
-        combinators.add(done(new ImportShowCombinator(shownNames)));
-      }
-    }
-
-    if (!optional(Token.SEMICOLON)) {
-      // If there is no semicolon, then we probably don't want to consume the next token. It might
-      // make sense to advance to the next valid token for a directive or top-level declaration, but
-      // our recovery mechanism isn't quite sophisticated enough for that.
-      reportUnexpectedToken(position(), Token.SEMICOLON, peek(0));
-    }
-    return done(new DartExportDirective(libUri, combinators));
-  }
-
-  protected DartImportDirective parseImportDirective() {
-    beginImportDirective();
-    next(); // "import"
-    DartStringLiteral libUri = parseUri();
-    // allow "native" if we have "dart-ext:" import
-    if (StringUtils.startsWith(libUri.getValue(), "dart-ext:")) {
-      allowNativeKeyword = true;
-    }
-    
-    DartIdentifier prefix = null;
-    if (peek(0) == Token.IDENTIFIER && "as".equals(ctx.peekTokenString(0))) {
-      ctx.advance();
-      prefix = parseIdentifier();
-      if (prefix instanceof DartSyntheticErrorIdentifier) {
-        if (peekPseudoKeyword(1, HIDE_KEYWORD) || peekPseudoKeyword(1, SHOW_KEYWORD)
-            || peek(1) == Token.BIT_AND || peek(1) == Token.COLON) {
-          next();
-        }
-      }
-    }
-
-    List<ImportCombinator> combinators = new ArrayList<ImportCombinator>();
-    while (peekPseudoKeyword(0, HIDE_KEYWORD) || peekPseudoKeyword(0, SHOW_KEYWORD)) {
-      if (optionalPseudoKeyword(HIDE_KEYWORD)) {
-        List<DartIdentifier> hiddenNames = parseIdentifierList();
-        combinators.add(new ImportHideCombinator(hiddenNames));
-      } else if (optionalPseudoKeyword(SHOW_KEYWORD)) {
-        List<DartIdentifier> shownNames = parseIdentifierList();
-        combinators.add(new ImportShowCombinator(shownNames));
-      }
-    }
-
-    if (!optional(Token.SEMICOLON)) {
-      // If there is no semicolon, then we probably don't want to consume the next token. It might
-      // make sense to advance to the next valid token for a directive or top-level declaration, but
-      // our recovery mechanism isn't quite sophisticated enough for that.
-      reportUnexpectedToken(position(), Token.SEMICOLON, peek(0));
-    }
-    return done(new DartImportDirective(libUri, prefix, combinators));
-  }
-
-  /**
-   * Parse a comma-separated list of identifiers.
-   *
-   * @return the identifiers that were parsed
-   */
-  private List<DartIdentifier> parseIdentifierList() {
-    ArrayList<DartIdentifier> identifiers = new ArrayList<DartIdentifier>();
-    identifiers.add(parseIdentifier());
-    while (optional(Token.COMMA)) {
-      identifiers.add(parseIdentifier());
-    }
-    return identifiers;
-  }
-
-  protected DartImportDirective parseObsoleteImportDirective() {
-    expect(Token.IMPORT);
-    reportDeprecatedError(position(), ParserErrorCode.DEPRECATED_IMPORT_DIRECTIVE);
-    expect(Token.LPAREN);
-    
-    DartStringLiteral libUri = parseUri();
-    
-    // allow "native" if we have "dart-ext:" import
-    if (StringUtils.startsWith(libUri.getValue(), "dart-ext:")) {
-      allowNativeKeyword = true;
-    }
-    
-    DartBooleanLiteral export = null;
-    List<ImportCombinator> combinators = new ArrayList<ImportCombinator>();
-    DartStringLiteral prefix = null;
-    if (optional(Token.COMMA)) {
-      if (optionalPseudoKeyword(PREFIX_KEYWORD)) {
-        expect(Token.COLON);
-        beginLiteral();
-        expect(Token.STRING);
-        String id = ctx.getTokenString();
-        // The specification requires the value of this string be a valid identifier
-        if(id == null || !id.matches("[_a-zA-Z]([_A-Za-z0-9]*)")) {
-          reportError(position(), ParserErrorCode.EXPECTED_PREFIX_IDENTIFIER);
-        }
-        prefix = done(DartStringLiteral.get(ctx.getTokenString()));
-      } else {
-        reportError(position(), ParserErrorCode.EXPECTED_PREFIX_KEYWORD);
-      }
-    }
-    expectCloseParen();
-    expect(Token.SEMICOLON);
-    return new DartImportDirective(libUri, export, combinators, prefix);
-  }
-
-  private DartSourceDirective parsePartDirective() {
-    beginPartDirective();
-    next(); // "part"
-    beginLiteral();
-    expect(Token.STRING);
-    DartStringLiteral partUri = done(DartStringLiteral.get(ctx.getTokenString()));
-    expect(Token.SEMICOLON);
-    return done(new DartSourceDirective(partUri));
-  }
-
-  private DartSourceDirective parseSourceDirective() {
-    expect(Token.SOURCE);
-    reportDeprecatedError(position(), ParserErrorCode.DEPRECATED_SOURCE_DIRECTIVE);
-    expect(Token.LPAREN);
-    DartStringLiteral sourceUri = parseUri();
-    expectCloseParen();
-    expect(Token.SEMICOLON);
-    return new DartSourceDirective(sourceUri);
-  }
-
-  private DartPartOfDirective parsePartOfDirective() {
-    beginPartOfDirective();
-    next(); // "part"
-    next(); // "of"
-    int ofOffset=  position();
-    DartExpression libraryName = parseLibraryName();
-    expect(Token.SEMICOLON);
-    return done(new DartPartOfDirective(ofOffset, libraryName));
-  }
-
-  private void parseResourceDirective() {
-    expect(Token.RESOURCE);
-    reportError(position(), ParserErrorCode.DEPRECATED_RESOURCE_DIRECTIVE);
-    expect(Token.LPAREN);
-    @SuppressWarnings("unused")
-    DartStringLiteral sourceUri = parseUri();
-    expectCloseParen();
-    expect(Token.SEMICOLON);
-  }
-
-  private DartNativeDirective parseNativeDirective() {
-    expect(Token.NATIVE);
-    expect(Token.LPAREN);
-    DartStringLiteral nativeUri = parseUri();
-    expect(Token.RPAREN);
-    expect(Token.SEMICOLON);
-    return new DartNativeDirective(nativeUri);
-  }
-
-  private List<DartAnnotation> parseMetadata() {
-    List<DartAnnotation> metadata = new ArrayList<DartAnnotation>();
-    while (match(Token.AT)) {
-      beginMetadata();
-      next();
-      beginQualifiedIdentifier();
-      DartExpression name = parseQualified(true);
-      if (optional(Token.PERIOD)) {
-        name = new DartPropertyAccess(name, parseIdentifier());
-      }
-      done(name);
-      List<DartExpression> arguments = null;
-      if (match(Token.LPAREN)) {
-        arguments = parseArguments();
-      }
-      metadata.add(done(new DartAnnotation(name, arguments)));
-    }
-    return metadata;
-  }
-
-  /**
-   * <pre>
-   * typeParameter
-   *     : identifier (EXTENDS type)?
-   *     ;
-   *
-   * typeParameters
-   *     : '<' typeParameter (',' typeParameter)* '>'
-   *     ;
-   * </pre>
-   */
-  @Terminals(tokens={Token.GT, Token.COMMA})
-  private List<DartTypeParameter> parseTypeParameters() {
-    List<DartTypeParameter> types = new ArrayList<DartTypeParameter>();
-    expect(Token.LT);
-    do {
-      DartTypeParameter typeParameter = parseTypeParameter();
-      types.add(typeParameter);
-
-    } while (optional(Token.COMMA));
-    expect(Token.GT);
-    return types;
-  }
-
-  /**
-   * Parses single {@link DartTypeParameter} for {@link #parseTypeParameters()}.
-   */
-  private DartTypeParameter parseTypeParameter() {
-    beginTypeParameter();
-    List<DartAnnotation> metadata = parseMetadata();
-    DartIdentifier name = parseIdentifier();
-    if (PSEUDO_KEYWORDS_SET.contains(name.getName())) {
-      reportError(name, ParserErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE_VARIABLE_NAME);
-    }
-    // Try to parse bound.
-    DartTypeNode bound = null;
-    if (peek(0) != Token.EOS && peek(0) != Token.COMMA && peek(0) != Token.GT) {
-      if (optional(Token.EXTENDS)) {
-        // OK, this is EXTENDS, parse type.
-        bound = parseTypeAnnotation();
-      } else if (looksLikeTopLevelKeyword()) {
-        return done(new DartTypeParameter(name, bound));
-      } else if (peek(0) == Token.IDENTIFIER && (peek(1) == Token.COMMA || peek(1) == Token.GT)) {
-        // <X exte{cursor}>
-        // User tries to type "extends", but it is not finished yet.
-        // Report problem and try to continue.
-        next();
-        reportError(position(), ParserErrorCode.EXPECTED_EXTENDS);
-      } else if (peek(0) == Token.IDENTIFIER
-          && peek(1) == Token.IDENTIFIER
-          && (peek(2) == Token.COMMA || peek(2) == Token.GT)) {
-        // <X somethingLikeExtends Type>
-        // User mistyped word "extends" or it is not finished yet.
-        // Report problem and try to continue.
-        next();
-        reportError(position(), ParserErrorCode.EXPECTED_EXTENDS);
-        bound = parseTypeAnnotation();
-      } else {
-        // Something else, restart parsing from next top level element.
-        next();
-        reportError(position(), ParserErrorCode.EXPECTED_EXTENDS);
-      }
-    }
-    // Ready to create DartTypeParameter.
-    DartTypeParameter parameter = new DartTypeParameter(name, bound);
-    parameter.setMetadata(metadata);
-    return done(parameter);
-  }
-
-  private List<DartTypeParameter> parseTypeParametersOpt() {
-    return (peek(0) == Token.LT)
-        ? parseTypeParameters()
-        : Collections.<DartTypeParameter>emptyList();
-  }
-
-  /**
-   * <pre>
-   * classDefinition
-   *     : CLASS identifier typeParameters? superclass? interfaces?
-   *       '{' classMemberDefinition* '}'
-   *     ;
-   *
-   * superclass
-   *     : EXTENDS type
-   *     ;
-   *
-   * interfaces
-   *     : IMPLEMENTS typeList
-   *     ;
-   *
-   * superinterfaces
-   *     : EXTENDS typeList
-   *     ;
-   *
-   * classMemberDefinition
-   *     : declaration ';'
-   *     | methodDeclaration blockOrNative
-   *
-   * interfaceDefinition
-   *     : INTERFACE identifier typeParameters? superinterfaces?
-   *       (DEFAULT type)? '{' (interfaceMemberDefinition)* '}'
-   *     ;
-   * </pre>
-   */
-  private DartDeclaration<?> parseClass() {
-    beginClassBody();
-    
-    int tokenOffset = ctx.getTokenLocation().getBegin();
-    int tokenLength = ctx.getTokenLocation().getEnd() - tokenOffset;
-
-    // Parse modifiers.
-    Modifiers modifiers = Modifiers.NONE;
-    if (isTopLevelAbstract) {
-      modifiers = modifiers.makeAbstract();
-    }
-
-    DartIdentifier name = parseIdentifier();
-    if (name.getName().equals("")) {
-      // something went horribly wrong.
-      if (peek(0).equals(Token.LBRACE)) {
-        parseBlock();
-      }
-      return done(null);
-    }
-    if (PSEUDO_KEYWORDS_SET.contains(name.getName())) {
-      reportError(name, ParserErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE_NAME);
-    }
-    List<DartTypeParameter> typeParameters = parseTypeParametersOpt();
-
-    // Parse the extends and implements clauses.
-    DartTypeNode superType = null;
-    int withOffset = -1;
-    int implementsOffset = -1;
-    List<DartTypeNode> mixins = null;
-    List<DartTypeNode> interfaces = null;
-    if (isParsingInterface) {
-      if (optional(Token.EXTENDS)) {
-        interfaces = parseTypeAnnotationList();
-      }
-    } else {
-      boolean foundClause = true;
-      while (foundClause) {
-        if (optional(Token.EXTENDS)) {
-          if (mixins != null) {
-            reportErrorAtPosition(withOffset, withOffset + "with".length(),
-                ParserErrorCode.WITH_BEFORE_EXTENDS);
-          }
-          if (interfaces != null) {
-            reportErrorAtPosition(implementsOffset, implementsOffset + "implements".length(),
-                ParserErrorCode.IMPLEMENTS_BEFORE_EXTENDS);
-          }
-          if (superType == null) {
-            superType = parseTypeAnnotation();
-          } else {
-            reportError(position(), ParserErrorCode.MULTIPLE_EXTENDS_CLAUSES);
-            parseTypeAnnotation();
-          }
-        } else if (optional(Token.WITH)) {
-          if (mixins == null) {
-            withOffset = position();
-            mixins = parseTypeAnnotationList();
-            if (interfaces != null) {
-              reportErrorAtPosition(implementsOffset, implementsOffset + "implements".length(),
-                  ParserErrorCode.IMPLEMENTS_BEFORE_WITH);
-            }
-          } else {
-            reportError(position(), ParserErrorCode.MULTIPLE_WITH_CLAUSES);
-            parseTypeAnnotationList();
-          }
-        } else if (optionalPseudoKeyword(IMPLEMENTS_KEYWORD)) {
-          if (interfaces == null) {
-            implementsOffset = position();
-            interfaces = parseTypeAnnotationList();
-          } else {
-            reportError(position(), ParserErrorCode.MULTIPLE_IMPLEMENTS_CLAUSES);
-            parseTypeAnnotationList();
-          }
-        } else {
-          foundClause = false;
-        }
-      }
-      if (mixins != null && superType == null) {
-        reportErrorAtPosition(withOffset, withOffset + "with".length(),
-            ParserErrorCode.WITH_WITHOUT_EXTENDS);
-      }
-    }
-    
-    // Deal with factory clause for interfaces.
-    DartParameterizedTypeNode defaultClass = null;
-    int defaultTokenOffset = -1;
-    if (isParsingInterface &&
-        (optionalDeprecatedFactory() || optional(Token.DEFAULT))) {
-      defaultTokenOffset = position();
-      beginTypeAnnotation();
-      DartExpression qualified = parseQualified(false);
-      List<DartTypeParameter> defaultTypeParameters = parseTypeParametersOpt();
-      defaultClass = doneWithoutConsuming(new DartParameterizedTypeNode(qualified,
-                                                                        defaultTypeParameters));
-    }
-
-    // Deal with native clause for classes.
-    DartStringLiteral nativeName = null;
-    if (optionalPseudoKeyword(NATIVE_KEYWORD)) {
-      if (isParsingInterface) {
-        reportError(position(), ParserErrorCode.NATIVE_ONLY_CLASS);
-      }
-      if (!allowNativeKeyword) {
-        reportError(position(), ParserErrorCode.NATIVE_ONLY_CORE_LIB);
-      }
-      beginLiteral();
-      if (expect(Token.STRING)) {
-        nativeName = done(DartStringLiteral.get(ctx.getTokenString()));
-      }
-      modifiers = modifiers.makeNative();
-    }
-
-    // Parse the members.
-    int openBraceOffset = -1;
-    int closeBraceOffset = -1;
-    List<DartNode> members = new ArrayList<DartNode>();
-    if (optional(Token.LBRACE)) {
-      openBraceOffset = ctx.getTokenLocation().getBegin();
-      parseClassOrInterfaceBody(members);
-      expectCloseBrace(true);
-      closeBraceOffset = ctx.getTokenLocation().getBegin();
-    } else {
-      reportErrorWithoutAdvancing(ParserErrorCode.EXPECTED_CLASS_DECLARATION_LBRACE);
-    }
-
-    if (isParsingInterface) {
-      return done(new DartClass(tokenOffset, tokenLength, name, null, superType, implementsOffset,
-          interfaces, mixins, defaultTokenOffset, openBraceOffset, closeBraceOffset, members,
-          typeParameters, defaultClass, true, Modifiers.NONE));
-    } else {
-      return done(new DartClass(tokenOffset, tokenLength, name, nativeName, superType,
-          implementsOffset, interfaces, mixins, defaultTokenOffset, openBraceOffset,
-          closeBraceOffset, members, typeParameters, null, false, modifiers));
-    }
-  }
-
-  /**
-   * Helper for {@link #parseClass()}.
-   *
-   * classMemberDefinition*
-   */
-  @Terminals(tokens={Token.RBRACE, Token.SEMICOLON})
-  private void parseClassOrInterfaceBody(List<DartNode> members) {
-    while (!match(Token.RBRACE) && !EOS() && !looksLikeTopLevelKeyword()) {
-      List<DartAnnotation> metadata = parseMetadata();
-      DartNodeWithMetadata member = parseFieldOrMethod(true);
-      if (member != null) {
-        setMetadata(member, metadata);
-        members.add(member);
-      }
-      // Recover at a semicolon
-      if (optional(Token.SEMICOLON)) {
-        reportUnexpectedToken(position(), null, Token.SEMICOLON);
-      }
-    }
-  }
-
-  private boolean optionalDeprecatedFactory() {
-    if (optionalPseudoKeyword(FACTORY_KEYWORD)) {
-      reportError(position(), ParserErrorCode.DEPRECATED_USE_OF_FACTORY_KEYWORD);
-      return true;
-    }
-    return false;
-  }
-
-  private List<DartTypeNode> parseTypeAnnotationList() {
-    List<DartTypeNode> result = new ArrayList<DartTypeNode>();
-    do {
-      result.add(parseTypeAnnotation());
-    } while (optional(Token.COMMA));
-    return result;
-  }
-
-  /**
-   * Look ahead to detect if we are seeing ident [ TypeParameters ] "(".
-   * We need this lookahead to distinguish between the optional return type
-   * and the alias name of a function type alias.
-   * Token position remains unchanged.
-   *
-   * @return true if the next tokens should be parsed as a type
-   */
-  private boolean isFunctionTypeAliasName() {
-    beginFunctionTypeInterface();
-    try {
-      if (peek(0) == Token.IDENTIFIER && peek(1) == Token.LPAREN) {
-        return true;
-      }
-      if (peek(0) == Token.IDENTIFIER && peek(1) == Token.LT) {
-        consume(Token.IDENTIFIER);
-        // isTypeParameter leaves the position advanced if it matches
-        if (isTypeParameter() && peek(0) == Token.LPAREN) {
-          return true;
-        }
-      }
-      return false;
-    } finally {
-      rollback();
-    }
-  }
-
-  /**
-   * Returns true if the current and next tokens can be parsed as type
-   * parameters. Current token position is not saved and restored.
-   */
-  private boolean isTypeParameter() {
-    if (peek(0) == Token.LT) {
-      // We are possibly looking at type parameters. Find closing ">".
-      consume(Token.LT);
-      int nestingLevel = 1;
-      while (nestingLevel > 0) {
-        switch (peek(0)) {
-          case LT:
-            nestingLevel++;
-            break;
-          case GT:
-            nestingLevel--;
-            break;
-          case SAR:   // >>
-            nestingLevel -= 2;
-            break;
-          case COMMA:
-          case EXTENDS:
-          case IDENTIFIER:
-            break;
-          default:
-            // We are looking at something other than type parameters.
-            return false;
-        }
-        next();
-        if (nestingLevel < 0) {
-          return false;
-        }
-      }
-    }
-    return true;
-  }
-
-  /**
-   * Parse a type alias.
-   * 
-   * <pre>
-   * typeAlias ::=
-   *     'typedef' typeAliasBody
-   * 
-   * typeAliasBody ::=
-   *     classTypeAlias
-   *   | functionTypeAlias
-   *
-   * classTypeAlias ::=
-   *     identifier typeParameters? '=' 'abstract'? mixinApplication
-   * 
-   * mixinApplication ::=
-   *     qualified withClause implementsClause? ';'
-   *
-   * functionTypeAlias ::=
-   *     functionPrefix typeParameterList? formalParameterList ';'
-   *
-   * functionPrefix ::=
-   *     returnType? name
-   * </pre>
-   * 
-   * @return the type alias that was parsed
-   */
-  private DartNodeWithMetadata parseTypeAlias() {
-    if (match(Token.IDENTIFIER)) {
-      Token next = peek(1);
-      if (next == Token.LT) {
-        int offset = skipTypeArguments(1, new DepthCounter());
-        next = peek(offset);
-        if (next != null && next == Token.ASSIGN) {
-          return parseClassTypeAlias();
-        }
-      } else if (next == Token.ASSIGN) {
-        return parseClassTypeAlias();
-      }
-    }
-    return parseFunctionTypeAlias();
-  }
-
-  /**
-   * Parse a class type alias.
-   * 
-   * <pre>
-   * classTypeAlias ::=
-   *     identifier typeParameters? '=' 'abstract'? mixinApplication
-   * 
-   * mixinApplication ::=
-   *     type withClause implementsClause? ';'
-   * </pre>
-   * 
-   * @return the class type alias that was parsed
-   */
-  private DartClassTypeAlias parseClassTypeAlias() {
-    beginClassTypeInterface();
-
-    DartIdentifier name = parseIdentifier();
-    if (PSEUDO_KEYWORDS_SET.contains(name.getName())) {
-      reportError(name, ParserErrorCode.BUILT_IN_IDENTIFIER_AS_TYPEDEF_NAME);
-    }
-    List<DartTypeParameter> typeParameters = parseTypeParametersOpt();
-    
-    expect(Token.ASSIGN);
-
-    Modifiers modifiers = Modifiers.NONE;
-    if (optionalPseudoKeyword(ABSTRACT_KEYWORD)) {
-      modifiers = modifiers.makeAbstract();
-    }
-
-    DartTypeNode superType = parseTypeAnnotation();
-
-    List<DartTypeNode> mixins = null;
-    if (optional(Token.WITH)) {
-      mixins = parseTypeAnnotationList();
-    }
-
-    List<DartTypeNode> interfaces = null;
-    if (optionalPseudoKeyword(IMPLEMENTS_KEYWORD)) {
-      interfaces = parseTypeAnnotationList();
-    }
-
-    expect(Token.SEMICOLON);
-    return done(new DartClassTypeAlias(name, typeParameters, modifiers, superType, mixins,
-        interfaces));
-  }
-  
-  /**
-   * Parse a function type alias.
-   * 
-   * <pre>
-   * functionTypeAlias ::=
-   *     functionPrefix typeParameterList? formalParameterList ';'
-   *
-   * functionPrefix ::=
-   *     returnType? name
-   * </pre>
-   * 
-   * @return the function type alias that was parsed
-   */
-  private DartFunctionTypeAlias parseFunctionTypeAlias() {
-    beginFunctionTypeInterface();
-    
-    DartTypeNode returnType = null;
-    if (peek(0) == Token.VOID) {
-      returnType = parseVoidType();
-    } else if (!isFunctionTypeAliasName()) {
-      returnType = parseTypeAnnotation();
-    }
-    
-    DartIdentifier name = parseIdentifier();
-    if (PSEUDO_KEYWORDS_SET.contains(name.getName())) {
-      reportError(name, ParserErrorCode.BUILT_IN_IDENTIFIER_AS_TYPEDEF_NAME);
-    }
-    
-    List<DartTypeParameter> typeParameters = parseTypeParametersOpt();
-    FormalParameters params = parseFormalParameterList();
-    expect(Token.SEMICOLON);
-    validateNoDefaultParameterValues(
-        params.val,
-        ParserErrorCode.DEFAULT_VALUE_CAN_NOT_BE_SPECIFIED_IN_TYPEDEF);
-    
-    return done(new DartFunctionTypeAlias(name, returnType, params.val, typeParameters));
-  }
-
-  /**
-   * Parse a field or method, which may be inside a class or at the top level.
-   *
-   * <pre>
-   * // This rule is organized in a way that may not be most readable, but
-   * // gives the best error messages.
-   * classMemberDefinition
-   *     : declaration ';'
-   *     | methodDeclaration bodyOrNative
-   *     ;
-   *
-   * // Note: this syntax is not official, but used in dart_interpreter. It
-   * // is unlikely that Dart will support numbered natives.
-   * bodyOrNative
-   *     : error=NATIVE (':' (STRING | RATIONAL_NUMBER))? ';'
-   *       { legacy($error, "native not supported (yet)"); }
-   *     | functionStatementBody
-   *     ;
-   *
-   * // A method, operator, or constructor (which all should be followed by
-   * // a function body).
-   * methodDeclaration
-   *     : factoryConstructorDeclaration
-   *     | STATIC methodOrConstructorDeclaration
-   *     | specialSignatureDefinition
-   *     | methodOrConstructorDeclaration initializers?
-   *     | namedConstructorDeclaration initializers?
-   *     ;
-   *
-   *
-   * // An abstract method/operator, a field, or const constructor (which
-   * // all should be followed by a semicolon).
-   * declaration
-   *     : constantConstructorDeclaration initializers?
-   *     | ABSTRACT specialSignatureDefinition
-   *     | ABSTRACT methodOrConstructorDeclaration
-   *     | STATIC CONST type? staticConstDeclarationList
-   *     | STATIC? variableDeclaration
-   *     ;
-   *
-   * interfaceMemberDefinition
-   *     : STATIC CONST type? initializedIdentifierList ';'
-   *     | methodOrConstructorDeclaration ';'
-   *     | constantConstructorDeclaration ';'
-   *     | namedConstructorDeclaration ';'
-   *     | specialSignatureDefinition ';'
-   *     | variableDeclaration ';'
-   *     ;
-   *
-   * variableDeclaration
-   *     : constVarOrType identifierList
-   *     ;
-   *
-   * methodOrConstructorDeclaration
-   *     : typeOrFunction? identifier formalParameterList
-   *     ;
-   *
-   * factoryConstructorDeclaration
-   *     : FACTORY qualified ('.' identifier)? formalParameterList
-   *     ;
-   *
-   * namedConstructorDeclaration
-   *     : identifier typeArguments? '.' identifier formalParameterList
-   *     ;
-   *
-   * constructorDeclaration
-   *     : identifier typeArguments? formalParameterList
-   *     | namedConstructorDeclaration
-   *     ;
-   *
-   * constantConstructorDeclaration
-   *     : CONST qualified formalParameterList
-   *     ;
-   *
-   * specialSignatureDefinition
-   *     : STATIC? type? getOrSet identifier formalParameterList
-   *     | type? OPERATOR operator formalParameterList
-   *     ;
-   *
-   * getOrSet
-   *     : GET
-   *     | SET
-   *     ;
-   *
-   * operator
-   *     : unaryOperator
-   *     | binaryOperator
-   *     | '[' ']' { "[]".equals($text) }?
-   *     | '[' ']' '=' { "[]=".equals($text) }?
-   *     | NEGATE
-   *     | CALL
-   *     ;
-   * </pre>
-   *
-   * @param allowStatic true if the static modifier is allowed
-   * @return a {@link DartNode} representing the grammar fragment above
-   */
-  @Terminals(tokens={Token.SEMICOLON})
-  private DartNodeWithMetadata parseFieldOrMethod(boolean allowStatic) {
-    beginClassMember();
-    Modifiers modifiers = Modifiers.NONE;
-    if (isBuiltInSpecial() && optionalPseudoKeyword(EXTERNAL_KEYWORD)) {
-      modifiers = modifiers.makeExternal();
-    }
-    if (isBuiltInSpecial() && optionalPseudoKeyword(STATIC_KEYWORD)) {
-      if (!allowStatic) {
-        reportError(position(), ParserErrorCode.TOP_LEVEL_CANNOT_BE_STATIC);
-      } else {
-        if (isParsingInterface
-            && peek(0) != Token.FINAL && peek(0) != Token.CONST) {
-          reportError(position(), ParserErrorCode.NON_FINAL_STATIC_MEMBER_IN_INTERFACE);
-        }
-        modifiers = modifiers.makeStatic();
-      }
-    }
-    if (isBuiltInSpecial() && optionalPseudoKeyword(ABSTRACT_KEYWORD)) {
-      if (modifiers.isStatic()) {
-        reportError(position(), ParserErrorCode.STATIC_MEMBERS_CANNOT_BE_ABSTRACT);
-      }
-      if (modifiers.isExternal()) {
-        reportError(position(), ParserErrorCode.EXTERNAL_ABSTRACT);
-      }
-      modifiers = modifiers.makeAbstract();
-    }
-    if (isBuiltInSpecial() && optionalPseudoKeyword(FACTORY_KEYWORD)) {
-      if (isParsingInterface) {
-        reportError(position(), ParserErrorCode.FACTORY_MEMBER_IN_INTERFACE);
-      }
-      if (modifiers.isStatic()) {
-        reportError(position(), ParserErrorCode.FACTORY_CANNOT_BE_STATIC);
-      }
-      if (modifiers.isAbstract()) {
-        reportError(position(), ParserErrorCode.FACTORY_CANNOT_BE_ABSTRACT);
-      }
-
-      modifiers = modifiers.makeFactory();
-    }
-
-    if (match(Token.VAR) || match(Token.FINAL)) {
-      if (modifiers.isAbstract()) {
-        reportError(position(), ParserErrorCode.DISALLOWED_ABSTRACT_KEYWORD);
-      }
-      if (modifiers.isFactory()) {
-        reportError(position(), ParserErrorCode.DISALLOWED_FACTORY_KEYWORD);
-      }
-    }
-    
-    // report "abstract" warning after all other checks to don't hide error with warning
-    // we ignore problems if there was already reported problem after given position
-    if (modifiers.isAbstract()) {
-      reportError(position(), ParserErrorCode.DEPRECATED_ABSTRACT_METHOD);
-    }
-
-    if (modifiers.isFactory()) {
-      if (!isParsingClass) {
-        reportError(position(), ParserErrorCode.FACTORY_CANNOT_BE_TOP_LEVEL);
-      }
-      // Do parse factory.
-      DartMethodDefinition factoryNode = parseFactory(modifiers);
-      // If factory is not allowed, ensure that it is valid as method.
-      DartExpression actualName = factoryNode.getName();
-      if (!allowStatic && !(actualName instanceof DartIdentifier)) {
-        DartExpression replacementName = new DartIdentifier(actualName.toString());
-        factoryNode.setName(replacementName);
-      }
-      // Done.
-      return done(factoryNode);
-    }
-
-    final DartNodeWithMetadata member;
-
-    switch (peek(0)) {
-      case VAR: {
-        consume(Token.VAR);
-        // Check for malformed method starting with 'var' : var ^ foo() { }
-        if (peek(0).equals(Token.IDENTIFIER) && looksLikeMethodOrAccessorDefinition()) {
-          reportError(position(), ParserErrorCode.VAR_IS_NOT_ALLOWED_ON_A_METHOD_DEFINITION);
-          member = parseMethodOrAccessor(modifiers, null);
-          break;
-        }
-
-        member = parseFieldDeclaration(modifiers, null);
-        expectStatmentTerminator();
-        break;
-      }
-
-      case CONST: {
-        consume(Token.CONST);
-        modifiers = modifiers.makeConstant();
-        // Allow "const factory ... native" constructors for core libraries only
-        if (optionalPseudoKeyword(FACTORY_KEYWORD)) {
-          modifiers = modifiers.makeFactory();
-        }
-        if (peek(0).equals(Token.IDENTIFIER) && looksLikeMethodOrAccessorDefinition()) {
-          return done(parseMethod(modifiers, null));
-        }
-        // Try to find type, may be "const ^ Type field".
-        DartTypeNode type = null;
-        if (peek(1) != Token.COMMA
-            && peek(1) != Token.ASSIGN
-            && peek(1) != Token.SEMICOLON) {
-          type = parseTypeAnnotation();
-        }
-        // Parse field.
-        modifiers = modifiers.makeFinal();
-        member = parseFieldDeclaration(modifiers, type);
-        expectStatmentTerminator();
-        break;
-      }
-
-      case FINAL: {
-        consume(Token.FINAL);
-        modifiers = modifiers.makeFinal();
-
-        // Check for malformed method starting with 'final':   final ^ foo() { }
-        if (peek(0).equals(Token.IDENTIFIER) && looksLikeMethodOrAccessorDefinition()) {
-          reportError(position(), ParserErrorCode.FINAL_IS_NOT_ALLOWED_ON_A_METHOD_DEFINITION);
-          member = parseMethodOrAccessor(modifiers, null);
-          break;
-        }
-        DartTypeNode type = null;
-        if (peek(1) != Token.COMMA
-            && peek(1) != Token.ASSIGN
-            && peek(1) != Token.SEMICOLON) {
-          type = parseTypeAnnotation();
-
-          // Check again for malformed method starting with 'final':   final String ^ foo() { }
-          if (peek(0).equals(Token.IDENTIFIER) && looksLikeMethodOrAccessorDefinition()) {
-            reportError(position(), ParserErrorCode.FINAL_IS_NOT_ALLOWED_ON_A_METHOD_DEFINITION);
-            member = parseMethodOrAccessor(modifiers, null);
-            break;
-          }
-        }
-        member = parseFieldDeclaration(modifiers, type);
-        expectStatmentTerminator();
-        break;
-      }
-
-      case IDENTIFIER: {
-
-        // Check to see if it looks like the start of a method definition (sans type).
-        if (looksLikeMethodOrAccessorDefinition()) {
-          member = parseMethodOrAccessor(modifiers, null);
-          break;
-        }
-      }
-      //$FALL-THROUGH$
-
-      case VOID: {
-
-        // The next token may be a type specification or parameterized constructor: either a method or field.
-        boolean isVoidType = peek(0) == Token.VOID;
-        DartTypeNode type;
-        if (isVoidType) {
-          type = parseVoidType();
-        } else {
-          int nameIndex = skipTypeName(0);
-          if (nameIndex < 0 || peek(nameIndex) != Token.IDENTIFIER) {
-            // There was no type name.
-            type = null;
-          } else {
-            type = parseTypeAnnotation();
-          }
-        }
-        if (peek(1) == Token.SEMICOLON
-            || peek(1) == Token.COMMA
-            || peek(1) == Token.ASSIGN) {
-          if (modifiers.isAbstract()) {
-            reportError(position(), ParserErrorCode.INVALID_FIELD_DECLARATION);
-          }
-          member = parseFieldDeclaration(modifiers, type);
-          if (isVoidType) {
-            reportError(type, ParserErrorCode.VOID_FIELD);
-          } else if (!modifiers.isFinal() && type == null) {
-            reportError(position(), ParserErrorCode.INVALID_FIELD_DECLARATION);
-          }
-          expectStatmentTerminator();
-        } else {
-          member = parseMethodOrAccessor(modifiers, type);
-        }
-        break;
-      }
-
-      case SEMICOLON:
-      default: {
-        done(null);
-        reportUnexpectedToken(position(), null, next());
-        member = null;
-        break;
-      }
-    }
-    return member;
-  }
-
-  /**
-   * Returns true if the beginning of a method definition follows.
-   *
-   * This test is needed to disambiguate between a method that returns a type
-   * and a plain method.
-   *
-   * Assumes the next token has already been determined to be an identifier.
-   *
-   * The following constructs will match:
-   *
-   *      : get (
-   *      | get identifier (
-   *      | set (
-   *      | set identifier (
-   *      | operator (
-   *      | operator <op> (
-   *      | identifier (
-   *      | identifier DOT identifier  (
-   *      | identifier DOT identifier DOT identifier (
-   *
-   * @return <code>true</code> if the signature of a method has been found.  No tokens are consumed.
-   */
-  private boolean looksLikeMethodOrAccessorDefinition() {
-    assert (peek(0) == Token.IDENTIFIER );
-    beginMethodName(); // begin() equivalent
-    try {
-      if (isBuiltInSpecial() && peekPseudoKeyword(0, OPERATOR_KEYWORD)) {
-        next();
-        // Using 'operator' as a field name is valid
-        if (peek(0).equals(Token.SEMICOLON) || peek(0).equals(Token.ASSIGN)) {
-          return false;
-        }
-        // Using 'operator' as a method name is valid (but discouraged)
-        if (peek(0).equals(Token.LPAREN)) {
-          return true;
-        }
-        // operator call (
-        if (peekPseudoKeyword(0, CALL_KEYWORD) && peek(1).equals(Token.LPAREN)) {
-          return true;
-        }
-        // TODO(zundel): Look for valid operator overload tokens.  For now just assuming
-        // non-idents are good enough
-        // operator ??? (
-        if (!(peek(0).equals(Token.IDENTIFIER) &&  peek(1).equals(Token.LPAREN))) {
-          return true;
-        }
-        if (peek(0).equals(Token.LBRACK) && peek(1).equals(Token.RBRACK)) {
-          // operator [] (
-          if (peek(2).equals(Token.LPAREN)) {
-            return true;
-          }
-          // operator []= (
-          if (peek(2).equals(Token.ASSIGN) && peek(3).equals(Token.LPAREN)) {
-            return true;
-          }
-        }
-        return false;
-      }
-
-      if (peekPseudoKeyword(0, GETTER_KEYWORD)
-          || peekPseudoKeyword(0, SETTER_KEYWORD)) {
-        boolean isGetter = peekPseudoKeyword(0, GETTER_KEYWORD);
-        next();
-        // Using 'get' or 'set' as a field name is valid
-        if (peek(0).equals(Token.SEMICOLON) || peek(0).equals(Token.ASSIGN)) {
-          return false;
-        }
-        // Using 'get' or 'set' as a method name is valid (but discouraged)
-        if (peek(0).equals(Token.LPAREN)) {
-          return true;
-        }
-        // normal case:  get foo (
-        if (peek(0).equals(Token.IDENTIFIER) && (isGetter || peek(1).equals(Token.LPAREN))) {
-          return true;
-        }
-        return false;
-      }
-
-      consume(Token.IDENTIFIER);
-
-      if (peek(0).equals(Token.PERIOD) && peek(1).equals(Token.IDENTIFIER)) {
-        consume(Token.PERIOD);
-        consume(Token.IDENTIFIER);
-
-        if (peek(0).equals(Token.PERIOD) && peek(1).equals(Token.IDENTIFIER)) {
-          consume(Token.PERIOD);
-          consume(Token.IDENTIFIER);
-        }
-      }
-
-      // next token should be LPAREN
-      return (peek(0).equals(Token.LPAREN));
-    } finally {
-      rollback();
-    }
-  }
-
-  /**
-   * <pre>
-   * factoryConstructorDeclaration
-   *     : FACTORY qualified ('.' identifier)? formalParameterList
-   *     ;
-   * </pre>
-   */
-  private DartMethodDefinition parseFactory(Modifiers modifiers) {
-    beginMethodName();
-    DartExpression name = parseQualified(true);
-    if (optional(Token.PERIOD)) {
-      name = doneWithoutConsuming(new DartPropertyAccess(name, parseIdentifier()));
-    }
-    done(name);
-    FormalParameters formals = parseFormalParameterList();
-    int parametersCloseParen = ctx.getTokenLocation().getBegin();
-
-    // Parse redirecting factory
-    if (match(Token.ASSIGN)) {
-      next();
-      if (!modifiers.isFactory()) {
-        reportError(position(), ParserErrorCode.ONLY_FACTORIES_CAN_REDIRECT);
-      }
-      modifiers = modifiers.makeRedirectedConstructor();
-      DartTypeNode redirectedTypeName = parseTypeAnnotationPossiblyFollowedByName();
-      DartIdentifier redirectedConstructorName = null;
-      if (optional(Token.PERIOD)) {
-        redirectedConstructorName = parseIdentifier();
-      }
-      expect(Token.SEMICOLON);
-      DartFunction function = doneWithoutConsuming(new DartFunction(formals.val, formals.openParen,
-          formals.optionalOpenOffset, formals.optionalCloseOffset, parametersCloseParen, null, null));
-      return DartMethodDefinition.create(name, function, modifiers, redirectedTypeName, 
-                                         redirectedConstructorName);
-    }
-
-    DartFunction function;
-    if (peekPseudoKeyword(0, NATIVE_KEYWORD)) {
-      modifiers = modifiers.makeNative();
-      function = new DartFunction(formals.val, formals.optionalOpenOffset,
-          formals.optionalOpenOffset, formals.optionalCloseOffset, parametersCloseParen,
-          parseNativeBlock(modifiers), null);
-    } else {
-      function = new DartFunction(formals.val, formals.optionalOpenOffset,
-          formals.optionalOpenOffset, formals.optionalCloseOffset, parametersCloseParen,
-          parseFunctionStatementBody(!modifiers.isExternal(), true), null);
-    }
-    doneWithoutConsuming(function);
-    return DartMethodDefinition.create(name, function, modifiers, null);
-  }
-
-  private DartIdentifier parseVoidIdentifier() {
-    beginIdentifier();
-    expect(Token.VOID);
-    return done(new DartIdentifier(Token.VOID.getSyntax()));
-  }
-
-  private DartTypeNode parseVoidType() {
-    beginTypeAnnotation();
-    return done(new DartTypeNode(parseVoidIdentifier()));
-  }
-
-  private DartMethodDefinition parseMethod(Modifiers modifiers, DartTypeNode returnType) {
-    DartExpression name = new DartIdentifier("");
-
-    if (modifiers.isFactory()) {
-      if (modifiers.isAbstract()) {
-        reportError(position(), ParserErrorCode.FACTORY_CANNOT_BE_ABSTRACT);
-      }
-      if (modifiers.isStatic()) {
-        reportError(position(), ParserErrorCode.FACTORY_CANNOT_BE_STATIC);
-      }
-    }
-
-    int arity = -1;
-    Token operation = null;
-    if (isBuiltInSpecial() && optionalPseudoKeyword(OPERATOR_KEYWORD)) {
-      // Overloaded operator.
-      if (modifiers.isStatic()) {
-        reportError(position(), ParserErrorCode.OPERATOR_CANNOT_BE_STATIC);
-      }
-      modifiers = modifiers.makeOperator();
-
-      beginOperatorName();
-      operation = next();
-      if (operation.isUserDefinableOperator()) {
-        name = done(new DartIdentifier(operation.getSyntax()));
-        if (operation == Token.ASSIGN_INDEX) {
-          arity = 2;
-        } else if (operation == Token.SUB) {
-          arity = -1;
-        } else if (operation.isBinaryOperator()) {
-          arity = 1;
-        } else if (operation == Token.INDEX) {
-          arity = 1;
-        } else {
-          assert operation.isUnaryOperator();
-          arity = 0;
-        }
-      } else if (operation == Token.IDENTIFIER
-                 && ctx.getTokenString().equals(CALL_KEYWORD)) {
-        name = done(new DartIdentifier(CALL_KEYWORD));
-        arity = -1;
-      } else if (operation == Token.IDENTIFIER
-          && ctx.getTokenString().equals(CALL_KEYWORD)) {
-        name = done(new DartIdentifier(CALL_KEYWORD));
-      } else {
-        // Not a valid operator.  Try to recover.
-        boolean found = false;
-        for (int i = 0; i < 4; ++i) {
-          if (peek(i).equals(Token.LPAREN)) {
-            found = true;
-            break;
-          }
-        }
-        StringBuilder buf = new StringBuilder();
-        buf.append(operation.getSyntax());
-        if (found) {
-          reportError(position(), ParserErrorCode.OPERATOR_IS_NOT_USER_DEFINABLE);
-          while(true) {
-            Token token = peek(0);
-            if (token.equals(Token.LPAREN)) {
-              break;
-            }
-            buf.append(next().getSyntax());
-          }
-          name = done(new DartIdentifier(buf.toString()));
-        } else {
-          reportUnexpectedToken(position(), Token.COMMENT, operation);
-          done(null);
-        }
-      }
-    } else {
-      beginMethodName();
-      // Check for getters and setters.
-      if (peek(1) != Token.LPAREN && optionalPseudoKeyword(GETTER_KEYWORD)) {
-        name = parseIdentifier();
-        modifiers = modifiers.makeGetter();
-        arity = 0;
-      } else if (peek(1) != Token.LPAREN && optionalPseudoKeyword(SETTER_KEYWORD)) {
-        name = parseIdentifier();
-        modifiers = modifiers.makeSetter();
-        arity = 1;
-      } else {
-        // Normal method or property.
-        name = parseIdentifier();
-      }
-
-      // Check for named constructor.
-      if (optional(Token.PERIOD)) {
-        name = doneWithoutConsuming(new DartPropertyAccess(name, parseIdentifier()));
-        if(currentlyParsingToplevel()) {
-          // TODO: Error recovery could find a missing brace and treat this as an expression
-          reportError(name,  ParserErrorCode.FUNCTION_NAME_EXPECTED_IDENTIFIER);
-        }
-        if (optional(Token.PERIOD)) {
-          name = doneWithoutConsuming(new DartPropertyAccess(name, parseIdentifier()));
-        }
-      }
-      done(null);
-    }
-
-    // Parse the parameters definitions.
-    FormalParameters parametersInfo;
-    if (modifiers.isGetter()) {
-      parametersInfo = new FormalParameters(new ArrayList<DartParameter>(), -1, -1, -1);
-      if (peek(0) == Token.LPAREN) {
-        reportError(position(), ParserErrorCode.DEPRECATED_GETTER);
-        parametersInfo = parseFormalParameterList();
-      }
-    } else {
-      parametersInfo = parseFormalParameterList();
-    }
-    List<DartParameter> parameters = parametersInfo.val;
-    int parametersCloseParen = ctx.getTokenLocation().getBegin();
-
-    if (arity != -1) {
-      if (parameters.size() != arity) {
-        reportError(position(), ParserErrorCode.ILLEGAL_NUMBER_OF_PARAMETERS);
-      }
-      // In methods with required arity each parameter is required.
-      for (int i = 0, size = parameters.size(); i < size; i++) {
-        DartParameter parameter = parameters.get(i);
-        if (parameter.getModifiers().isOptional()) {
-          reportError(parameter, ParserErrorCode.OPTIONAL_POSITIONAL_PARAMETER_NOT_ALLOWED);
-        }
-        if (parameter.getModifiers().isNamed()) {
-          reportError(parameter, ParserErrorCode.NAMED_PARAMETER_NOT_ALLOWED);
-        }
-      }
-    } else if (operation == Token.SUB) {
-      if (parameters.size() != 0 && parameters.size() != 1) {
-        reportError(position(), ParserErrorCode.ILLEGAL_NUMBER_OF_PARAMETERS);
-      }
-      // In methods with required arity each parameter is required.
-      for (int i = 0, size = parameters.size(); i < size; i++) {
-        DartParameter parameter = parameters.get(i);
-        if (parameter.getModifiers().isNamed()) {
-          reportError(parameter, ParserErrorCode.NAMED_PARAMETER_NOT_ALLOWED);
-        }
-      }
-    }
-
-    // Parse redirecting factory
-    DartTypeNode redirectedTypeName = null;
-    DartIdentifier redirectedConstructorName = null;
-    if (match(Token.ASSIGN)) {
-      next();
-      if (!modifiers.isFactory()) {
-        reportError(position(), ParserErrorCode.ONLY_FACTORIES_CAN_REDIRECT);
-      }
-      modifiers = modifiers.makeRedirectedConstructor();
-      redirectedTypeName = parseTypeAnnotationPossiblyFollowedByName();
-      if (optional(Token.PERIOD)) {
-        redirectedConstructorName = parseIdentifier();
-      }
-      expect(Token.SEMICOLON);
-      DartFunction function = doneWithoutConsuming(new DartFunction(parameters,
-          parametersInfo.openParen, parametersInfo.optionalOpenOffset,
-          parametersInfo.optionalCloseOffset, parametersCloseParen, null, returnType));
-      return DartMethodDefinition.create(name, function, modifiers, redirectedTypeName, 
-                                         redirectedConstructorName);
-    }
-
-    // Parse initializer expressions for constructors.
-    List<DartInitializer> initializers = new ArrayList<DartInitializer>();
-    if (match(Token.COLON) && !(isParsingInterface || modifiers.isFactory())) {
-      parseInitializers(initializers);
-      boolean isRedirectedConstructor = validateInitializers(parameters, initializers);
-      if (isRedirectedConstructor) {
-        modifiers = modifiers.makeRedirectedConstructor();
-      }
-    }
-
-    // Parse the body.
-    DartBlock body = null;
-    if (!optional(Token.SEMICOLON)) {
-      if (peekPseudoKeyword(0, NATIVE_KEYWORD)) {
-        modifiers = modifiers.makeNative();
-        body = parseNativeBlock(modifiers);
-      } else {
-        body = parseFunctionStatementBody(!modifiers.isExternal(), true);
-      }
-      if (body != null && modifiers.isRedirectedConstructor()) {
-        reportError(position(), ParserErrorCode.REDIRECTING_CONSTRUCTOR_CANNOT_HAVE_A_BODY);
-      }
-    }
-
-    DartFunction function = doneWithoutConsuming(new DartFunction(parameters,
-        parametersInfo.openParen, parametersInfo.optionalOpenOffset,
-        parametersInfo.optionalCloseOffset, parametersCloseParen, body, returnType));
-    return DartMethodDefinition.create(name, function, modifiers, initializers);
-  }
-
-  private DartBlock parseNativeBlock(Modifiers modifiers) {
-    beginNativeBody();
-    if (!optionalPseudoKeyword(NATIVE_KEYWORD)) {
-      throw new AssertionError();
-    }
-    if (!allowNativeKeyword) {
-      reportError(position(), ParserErrorCode.NATIVE_ONLY_CORE_LIB);
-    }
-    DartExpression body = null;
-    if (match(Token.STRING)) {
-      body = parseStringWithPasting();
-    }
-    if (match(Token.LBRACE) || match(Token.ARROW)) {
-      return done(parseFunctionStatementBody(!modifiers.isExternal(), true));
-    } else {
-      expect(Token.SEMICOLON);
-      return done(new DartNativeBlock(body));
-    }
-  }
-
-  private DartNodeWithMetadata parseMethodOrAccessor(Modifiers modifiers, DartTypeNode returnType) {
-    DartMethodDefinition method = done(parseMethod(modifiers, returnType));
-    // Abstract method can not have a body.
-    if (method.getFunction().getBody() != null) {
-      if (isParsingInterface) {
-        reportError(method.getName(), ParserErrorCode.INTERFACE_METHOD_WITH_BODY);
-      }
-      if (method.getModifiers().isAbstract()) {
-        reportError(method.getName(), ParserErrorCode.ABSTRACT_METHOD_WITH_BODY);
-      }
-    }
-    // If getter or setter, generate DartFieldDefinition instead.
-    if (method.getModifiers().isGetter() || method.getModifiers().isSetter()) {
-      DartField field = new DartField((DartIdentifier) method.getName(),
-                                      method.getModifiers().makeAbstractField(), method, null);
-      field.setSourceInfo(method.getSourceInfo());
-      DartFieldDefinition fieldDefinition =
-        new DartFieldDefinition(null, Lists.<DartField>create(field));
-      fieldDefinition.setSourceInfo(field.getSourceInfo());
-      return fieldDefinition;
-    }
-    // OK, use method as method.
-    return method;
-  }
-
-  /**
-   * <pre>
-   * initializers
-   *            : ':' superCallOrFirstFieldInitializer (',' fieldInitializer)*
-   *            | THIS ('.' identifier) formalParameterList
-   *            ;
-   *
-   * fieldInitializer
-   *            : (THIS '.')? identifier '=' conditionalExpression
-   *            ;
-   *
-   * superCallOrFirstFieldInitializer
-   *            : SUPER arguments | SUPER '.' identifier arguments
-   *            | fieldInitializer
-   *            ;
-   *
-   * fieldInitializer
-   *            : (THIS '.')? identifier '=' conditionalExpression
-   *            | THIS ('.' identifier)? arguments
-   *            ;
-   * </pre>
-   */
-  private void parseInitializers(List<DartInitializer> initializers) {
-    expect(Token.COLON);
-    do {
-      beginInitializer();
-      if (match(Token.SUPER)) {
-        beginSuperInitializer();
-        expect(Token.SUPER);
-        DartIdentifier constructor = null;
-        if (optional(Token.PERIOD)) {
-          constructor = parseIdentifier();
-        }
-        DartSuperConstructorInvocation superInvocation =
-          new DartSuperConstructorInvocation(constructor, parseArguments());
-        initializers.add(done(new DartInitializer(null, done(superInvocation))));
-      } else {
-        boolean hasThisPrefix = optional(Token.THIS);
-        if (hasThisPrefix) {
-          if (match(Token.LPAREN)) {
-            parseRedirectedConstructorInvocation(null, initializers);
-            continue;
-          }
-          expect(Token.PERIOD);
-        }
-        DartIdentifier name = parseIdentifier();
-        if (hasThisPrefix && match(Token.LPAREN)) {
-          parseRedirectedConstructorInvocation(name, initializers);
-          continue;
-        } else {
-          expect(Token.ASSIGN);
-          boolean save = setAllowFunctionExpression(false);
-          DartExpression initExpr = parseExpression();
-          setAllowFunctionExpression(save);
-          initializers.add(done(new DartInitializer(name, initExpr)));
-        }
-      }
-    } while (optional(Token.COMMA));
-  }
-
-  private void parseRedirectedConstructorInvocation(DartIdentifier name,
-      List<DartInitializer> initializers) {
-    DartRedirectConstructorInvocation redirConstructor =
-        new DartRedirectConstructorInvocation(name, parseArguments());
-    initializers.add(done(new DartInitializer(null, doneWithoutConsuming(redirConstructor))));
-  }
-
-  private boolean validateInitializers(List<DartParameter> parameters,
-      List<DartInitializer> initializers) {
-    // Try to find DartRedirectConstructorInvocation, check for multiple invocations.
-    // Check for DartSuperConstructorInvocation multiple invocations.
-    DartInitializer redirectInitializer = null;
-    boolean firstMultipleRedirectReported = false;
-    {
-      DartInitializer superInitializer = null;
-      boolean firstMultipleSuperReported = false;
-      for (DartInitializer initializer : initializers) {
-        if (initializer.isInvocation()) {
-          // DartSuperConstructorInvocation
-          DartExpression initializerInvocation = initializer.getValue();
-          if (initializerInvocation instanceof DartSuperConstructorInvocation) {
-            if (superInitializer != null) {
-              if (!firstMultipleSuperReported) {
-                reportError(superInitializer, ParserErrorCode.SUPER_CONSTRUCTOR_MULTIPLE);
-                firstMultipleSuperReported = true;
-              }
-              reportError(initializer, ParserErrorCode.SUPER_CONSTRUCTOR_MULTIPLE);
-            } else {
-              superInitializer = initializer;
-            }
-          }
-          // DartRedirectConstructorInvocation
-          if (initializerInvocation instanceof DartRedirectConstructorInvocation) {
-            if (redirectInitializer != null) {
-              if (!firstMultipleRedirectReported) {
-                reportError(redirectInitializer, ParserErrorCode.REDIRECTING_CONSTRUCTOR_MULTIPLE);
-                firstMultipleRedirectReported = true;
-              }
-              reportError(initializer, ParserErrorCode.REDIRECTING_CONSTRUCTOR_MULTIPLE);
-            } else {
-              redirectInitializer = initializer;
-            }
-          }
-        }
-      }
-    }
-    // If there is redirecting constructor, then there should be no other initializers.
-    if (redirectInitializer != null) {
-      boolean shouldRedirectInvocationReported = false;
-      // Implicit initializer in form of "this.id" parameter.
-      for (DartParameter parameter : parameters) {
-        if (parameter.getName() instanceof DartPropertyAccess) {
-          DartPropertyAccess propertyAccess = (DartPropertyAccess) parameter.getName();
-          if (propertyAccess.getQualifier() instanceof DartThisExpression) {
-            shouldRedirectInvocationReported = true;
-            reportError(
-                parameter,
-                ParserErrorCode.REDIRECTING_CONSTRUCTOR_PARAM);
-          }
-        }
-      }
-      // Iterate all initializers and mark all except of DartRedirectConstructorInvocation
-      for (DartInitializer initializer : initializers) {
-        if (!(initializer.getValue() instanceof DartRedirectConstructorInvocation)) {
-          shouldRedirectInvocationReported = true;
-          reportError(
-              initializer,
-              ParserErrorCode.REDIRECTING_CONSTRUCTOR_OTHER);
-        }
-      }
-      // Mark DartRedirectConstructorInvocation if needed.
-      if (shouldRedirectInvocationReported) {
-        reportError(
-            redirectInitializer,
-            ParserErrorCode.REDIRECTING_CONSTRUCTOR_ITSELF);
-      }
-    }
-    // Done.
-    return redirectInitializer != null;
-  }
-
-  /**
-   * <pre>
-   * variableDeclaration
-   *    : constVarOrType identifierList
-   *    ;
-   * identifierList
-   *    : identifier (',' identifier)*
-   *    ;
-   *
-   * staticConstDeclarationList
-   *    : staticConstDeclaration (',' staticConstDeclaration)*
-   *    ;
-   *
-   * staticConstDeclaration
-   *    : identifier '=' constantExpression
-   *    ;
-   *
-   * // The compile-time expression production is used to mark certain expressions
-   * // as only being allowed to hold a compile-time constant. The grammar cannot
-   * // express these restrictions, so this will have to be enforced by a separate
-   * // analysis phase.
-   * constantExpression
-   *    : expression
-   *    ;
-   * </pre>
-   */
-  private DartFieldDefinition parseFieldDeclaration(Modifiers modifiers, DartTypeNode type) {
-    List<DartField> fields = new ArrayList<DartField>();
-    List<DartAnnotation> metadata = parseMetadata();
-    do {
-      beginVariableDeclaration();
-      DartIdentifier name = parseIdentifier();
-      DartExpression value = null;
-      if (optional(Token.ASSIGN)) {
-        value = parseExpression();
-        if (value != null) {
-          modifiers = modifiers.makeInitialized();
-        }
-      }
-      if (modifiers.isExternal()) {
-        reportError(name, ParserErrorCode.EXTERNAL_ONLY_METHOD);
-      }
-      DartField field = done(new DartField(name, modifiers, null, value));
-      setMetadata(field, metadata);
-      fields.add(field);
-    } while (optional(Token.COMMA));
-    DartFieldDefinition definition = new DartFieldDefinition(type, fields);
-    setMetadata(definition, metadata);
-    return done(definition);
-  }
-  
-  private static class FormalParameters {
-    private final List<DartParameter> val;
-    private final int openParen;
-    private final int optionalOpenOffset;
-    private final int optionalCloseOffset;
-    public FormalParameters(List<DartParameter> parameters, int openParen, int optionalOpenOffset,
-        int optionalCloseOffset) {
-      this.val = parameters;
-      this.openParen = openParen;
-      this.optionalOpenOffset = optionalOpenOffset;
-      this.optionalCloseOffset = optionalCloseOffset;
-    }
-  }
-
-  /**
-   * <pre>
-   * formalParameterList
-   *     : '(' ')'
-   *     | '(' normalFormalParameters (',' optionalFormalParameters)? ')'
-   *     | '(' optionalFormalParameters ')'
-   *     ;
-   *
-   * normalFormalParameters
-   *     : normalFormalParameter (',' normalFormalParameter)*
-   *     ;
-   *
-   * optionalFormalParameters
-   *     : optionalPositionalFormalParameters
-   *     | namedFormalParameters
-   *     ;
-   *
-   * optionalPositionalFormalParameters
-   *     : '[' defaultFormalParameter (',' defaultFormalParameter)* ']'
-   *     ;
-   *
-   * namedFormalParameters
-   *     : '{' defaultNamedParameter (',' defaultNamedParameter)* '}'
-   *     ;
-   * </pre>
-   */
-  @Terminals(tokens = {Token.COMMA, Token.RPAREN})
-  private FormalParameters parseFormalParameterList() {
-    beginFormalParameterList();
-    List<DartParameter> params = new ArrayList<DartParameter>();
-    int optionalOpenOffset = -1;
-    int optionalCloseOffset = -1;
-    expect(Token.LPAREN);
-    boolean done = optional(Token.RPAREN);
-    int openParen = ctx.getTokenLocation().getBegin();
-    boolean isOptional = false;
-    boolean isNamed = false;
-    while (!done) {
-      if (!isOptional && optional(Token.LBRACK)) {
-        if (isNamed) {
-          reportErrorWithoutAdvancing(ParserErrorCode.CANNOT_MIX_OPTIONAL_AND_NAMED_PARAMETERS);
-        }
-        isOptional = true;
-        optionalOpenOffset = ctx.getTokenLocation().getBegin();
-      }
-      if (!isNamed && optional(Token.LBRACE)) {
-        if (isOptional) {
-          reportErrorWithoutAdvancing(ParserErrorCode.CANNOT_MIX_OPTIONAL_AND_NAMED_PARAMETERS);
-        }
-        isNamed = true;
-        optionalOpenOffset = ctx.getTokenLocation().getBegin();
-      }
-
-      DartParameter param = parseFormalParameter(isOptional, isNamed);
-      params.add(param);
-
-      if (isOptional && optional(Token.RBRACK)) {
-        optionalCloseOffset = ctx.getTokenLocation().getBegin();
-        expectCloseParen();
-        break;
-      }
-      if (isNamed && optional(Token.RBRACE)) {
-        optionalCloseOffset = ctx.getTokenLocation().getBegin();
-        expectCloseParen();
-        break;
-      }
-
-      // Ensure termination if token is anything other than COMMA.
-      // Must keep Token.COMMA in sync with @Terminals above
-      if (!optional(Token.COMMA)) {
-        if (isOptional && !optional(Token.RBRACE)) {
-          reportErrorWithoutAdvancing(ParserErrorCode.MISSING_OPTIONAL_PARAMETER_END);
-        }
-        if (isNamed && !optional(Token.RBRACK)) {
-          reportErrorWithoutAdvancing(ParserErrorCode.MISSING_NAMED_PARAMETER_END);
-        }
-        // Must keep Token.RPAREN in sync with @Terminals above
-        expectCloseParen();
-        done = true;
-      }
-    }
-
-    return new FormalParameters(done(params), openParen, optionalOpenOffset, optionalCloseOffset);
-  }
-
-  /**
-   * <pre>
-   * normalFormalParameter
-   *     : functionDeclaration
-   *     | fieldFormalParameter
-   *     | simpleFormalParameter
-   *     ;
-   *
-   * defaultFormalParameter
-   *     : normalFormalParameter ('=' constantExpression)?
-   *     ;
-   * 
-   * defaultNamedParameter
-   *     : normalFormalParameter (':' constantExpression)?
-   *     ;
-   * </pre>
-   */
-  private DartParameter parseFormalParameter(boolean isOptional, boolean isNamed) {
-    beginFormalParameter();
-    List<DartAnnotation> metadata = parseMetadata();
-    DartExpression paramName = null;
-    DartTypeNode type = null;
-    DartExpression defaultExpr = null;
-    List<DartParameter> functionParams = null;
-    boolean hasVar = false;
-    Modifiers modifiers = Modifiers.NONE;
-
-    if (isOptional) {
-      modifiers = modifiers.makeOptional();
-    }
-    if (isNamed) {
-      modifiers = modifiers.makeNamed();
-    }
-
-    if (optional(Token.FINAL)) {
-      modifiers = modifiers.makeFinal();
-    } else if (optional(Token.CONST)) {
-      reportError(position(), ParserErrorCode.FORMAL_PARAMETER_IS_CONST);
-    } else if (optional(Token.VAR)) {
-      hasVar = true;
-    }
-
-    boolean isVoidType = false;
-    if (!hasVar) {
-      isVoidType = (peek(0) == Token.VOID);
-      if (isVoidType) {
-        type = parseVoidType();
-      } else if ((peek(0) != Token.ELLIPSIS)
-                 && (peek(1) != Token.COMMA)
-                 && (peek(1) != Token.RPAREN)
-                 && (peek(1) != Token.RBRACE)
-                 && (peek(1) != Token.RBRACK)
-                 && (peek(1) != Token.ASSIGN)
-                 && (peek(1) != Token.COLON)
-                 && (peek(1) != Token.LPAREN)
-                 && (peek(0) != Token.THIS)) {
-        // Must be a type specification.
-        type = parseTypeAnnotation();
-      }
-    }
-
-    paramName = parseParameterName();
-
-    if (peek(0) == Token.LPAREN) {
-      // Function parameter.
-      if (modifiers.isFinal()) {
-        reportError(position(), ParserErrorCode.FUNCTION_TYPED_PARAMETER_IS_FINAL);
-      }
-      if (hasVar) {
-        reportError(position(), ParserErrorCode.FUNCTION_TYPED_PARAMETER_IS_VAR);
-      }
-      functionParams = parseFormalParameterList().val;
-      validateNoDefaultParameterValues(
-          functionParams,
-          ParserErrorCode.DEFAULT_VALUE_CAN_NOT_BE_SPECIFIED_IN_CLOSURE);
-    } else {
-      // Not a function parameter.
-      if (isVoidType) {
-        reportError(type, ParserErrorCode.VOID_PARAMETER);
-      }
-    }
-
-    // Look for an initialization expression
-    switch (peek(0)) {
-      case COMMA:
-      case RPAREN:
-      case RBRACE:
-      case RBRACK:
-        // It is a simple parameter.
-        break;
-
-      case ASSIGN:
-        // Default parameter -- only allowed for optional parameters.
-        if (isOptional) {
-          consume(Token.ASSIGN);
-          defaultExpr = parseExpression();
-        } else if (isNamed) {
-          reportError(position(), ParserErrorCode.INVALID_SEPARATOR_FOR_NAMED);
-          consume(Token.ASSIGN);
-          defaultExpr = parseExpression();
-        } else {
-          reportError(position(), ParserErrorCode.DEFAULT_POSITIONAL_PARAMETER);
-        }
-        break;
-
-      case COLON:
-        // Default parameter -- only allowed for named parameters.
-        if (isNamed) {
-          consume(Token.COLON);
-          defaultExpr = parseExpression();
-        } else if (isOptional) {
-          reportError(position(), ParserErrorCode.INVALID_SEPARATOR_FOR_OPTIONAL);
-          consume(Token.COLON);
-          defaultExpr = parseExpression();
-        } else {
-          reportError(position(), ParserErrorCode.DEFAULT_POSITIONAL_PARAMETER);
-        }
-        break;
-
-      default:
-        reportUnexpectedToken(position(), null, peek(0));
-        break;
-    }
-
-    DartParameter parameter = new DartParameter(paramName, type, functionParams, defaultExpr,
-        modifiers);
-    setMetadata(parameter, metadata);
-    return done(parameter);
-  }
-
-  /**
-   * <pre>
-   * simpleFormalParameter
-   *     : declaredIdentifier
-   *     | identifier
-   *     ;
-   *
-   * fieldFormalParameter
-   *    : finalVarOrType? THIS '.' identifier
-   *    ;
-   * </pre>
-   */
-  private DartExpression parseParameterName() {
-    beginParameterName();
-    if (match(Token.THIS)) {
-      beginThisExpression();
-      expect(Token.THIS);
-      DartThisExpression thisExpression = done(DartThisExpression.get());
-      expect(Token.PERIOD);
-      return done(new DartPropertyAccess(thisExpression, parseIdentifier()));
-    }
-    return done(parseIdentifier());
-  }
-
-  /**
-   * Validates that given {@link DartParameter}s have no default values, or marks existing default
-   * values with given {@link ErrorCode}.
-   */
-  private void validateNoDefaultParameterValues(List<DartParameter> parameters,
-      ErrorCode errorCode) {
-    for (int i = 0, size = parameters.size(); i < size; i++) {
-      DartParameter parameter = parameters.get(i);
-      DartExpression defaultExpr = parameter.getDefaultExpr();
-      if (defaultExpr != null) {
-        reportError(defaultExpr,  errorCode);
-      }
-    }
-  }
-
-  /**
-   * Parse an expression.
-   *
-   * <pre>
-   * expression
-   *     : assignableExpression assignmentOperator expression
-   *     | conditionalExpression cascadeSection*
-   *     | throwExpression
-   *     ;
-   *
-   * assignableExpression
-   *     : primary (arguments* assignableSelector)+
-   *     | SUPER assignableSelector
-   *     | identifier
-   *     ;
-   * </pre>
-   *
-   * @return an expression matching the {@code expression} production above
-   */
-  @VisibleForTesting
-  public DartExpression parseExpression() {
-    if (peek(0) == Token.THROW) {
-      return parseThrowExpression(true);
-    }
-    beginExpression();
-    if (looksLikeTopLevelKeyword() || peek(0).equals(Token.RBRACE)) {
-      // Allow recovery back to the top level.
-      reportErrorWithoutAdvancing(ParserErrorCode.UNEXPECTED_TOKEN);
-      return done(null);
-    }
-    DartExpression result = parseConditionalExpression();
-    Token token = peek(0);
-    if (token == Token.CASCADE) {
-      List<DartExpression> cascadeSections = new ArrayList<DartExpression>();
-      while (token == Token.CASCADE) {
-        beginExpression();
-        DartExpression section = parseCascadeSection();
-        done(section);
-        if (section != null) {
-          cascadeSections.add(section);
-        }
-        token = peek(0);
-      }
-      result = done(new DartCascadeExpression(result, cascadeSections));
-    } else if (token.isAssignmentOperator()) {
-      ensureAssignable(result);
-      consume(token);
-      int tokenOffset = ctx.getTokenLocation().getBegin();
-      result = done(new DartBinaryExpression(token, tokenOffset, result, parseExpression()));
-    } else {
-      done(null);
-    }
-    return result;
-  }
-
-  /**
-   * Parse an expression without a cascade.
-   *
-   * <pre>
-   * expressionWithoutCascade
-   *     : assignableExpression assignmentOperator expressionWithoutCascade
-   *     | conditionalExpression
-   *     ;
-   * </pre>
-   *
-   * @return an expression matching the {@code expression} production above
-   */
-  private DartExpression parseExpressionWithoutCascade() {
-    if (peek(0) == Token.THROW) {
-      return parseThrowExpression(false);
-    }
-    beginExpression();
-    if (looksLikeTopLevelKeyword() || peek(0).equals(Token.RBRACE)) {
-      // Allow recovery back to the top level.
-      reportErrorWithoutAdvancing(ParserErrorCode.UNEXPECTED_TOKEN);
-      return done(null);
-    }
-    DartExpression result = parseConditionalExpression();
-    Token token = peek(0);
-   if (token.isAssignmentOperator()) {
-      ensureAssignable(result);
-      consume(token);
-      int tokenOffset = ctx.getTokenLocation().getBegin();
-      result = done(new DartBinaryExpression(token, tokenOffset, result, parseExpressionWithoutCascade()));
-    } else {
-      done(null);
-    }
-    return result;
-  }
-
-  /**
-   * Parse a cascade section.
-   * <pre>
-   * cascadeSection
-   *     : CASCADE (cascadeSelector arguments*) (assignableSelector arguments*)* (assignmentOperator
-   * expressionWithoutCascade)?
-   *     ;
-   *
-   * cascadeSelector
-   *     : LBRACK expression RBRACK
-   *     | identifier
-   *     ;
-   * </pre>
-   *
-   * @return the expression representing the cascaded method invocation
-   */
-  private DartExpression parseCascadeSection() {
-    expect(Token.CASCADE);
-    DartExpression result = null;
-    DartIdentifier functionName = null;
-    if (peek(0) == Token.IDENTIFIER) {
-      functionName = parseIdentifier();
-    } else if (peek(0) == Token.LBRACK) {
-      consume(Token.LBRACK);
-      result = doneWithoutConsuming(new DartArrayAccess(result, true, parseExpression()));
-      expect(Token.RBRACK);
-    } else {
-      reportUnexpectedToken(position(), null, next());
-      return result;
-    }
-    if (peek(0) == Token.LPAREN) {
-      while (peek(0) == Token.LPAREN) {
-        if (functionName != null) {
-          result = doneWithoutConsuming(new DartMethodInvocation(result, result == null, functionName, parseArguments()));
-          functionName = null;
-        } else if (result == null) {
-          return null;
-        } else {
-          result = doneWithoutConsuming(new DartFunctionObjectInvocation(result, parseArguments()));
-        }
-      }
-    } else if (functionName != null) {
-      result = doneWithoutConsuming(new DartPropertyAccess(result, result == null, functionName));
-    }
-    boolean progress = true;
-    while (progress) {
-      progress = false;
-      DartExpression selector = tryParseAssignableSelector(result);
-      if (selector != null) {
-        result = selector;
-        progress = true;
-        while (peek(0) == Token.LPAREN) {
-          result = doneWithoutConsuming(new DartFunctionObjectInvocation(result, parseArguments()));
-        }
-      }
-    }
-    Token token = peek(0);
-    if (token.isAssignmentOperator()) {
-      ensureAssignable(result);
-      consume(token);
-      int tokenOffset = ctx.getTokenLocation().getBegin();
-      result = doneWithoutConsuming(new DartBinaryExpression(token, tokenOffset, result, parseExpressionWithoutCascade()));
-    }
-    return result;
-  }
-
-  /**
-   * expressionList
-   *     : expression (',' expression)*
-   *     ;
-   */
-  @Terminals(tokens={Token.COMMA})
-  private DartExpression parseExpressionList() {
-    beginExpressionList();
-    DartExpression result = parseExpression();
-    // Must keep in sync with @Terminals above
-    while (optional(Token.COMMA)) {
-      int tokenOffset = ctx.getTokenLocation().getBegin();
-      result = new DartBinaryExpression(Token.COMMA, tokenOffset, result, parseExpression());
-      if (match(Token.COMMA)) {
-        result = doneWithoutConsuming(result);
-      }
-    }
-    return done(result);
-  }
-
-
-  /**
-   * Parse a binary expression.
-   *
-   * <pre>
-   * logicalOrExpression
-   *     : logicalAndExpression ('||' logicalAndExpression)*
-   *     ;
-   *
-   * logicalAndExpression
-   *     : bitwiseOrExpression ('&&' bitwiseOrExpression)*
-   *     ;
-   *
-   * bitwiseOrExpression
-   *     : bitwiseXorExpression ('|' bitwiseXorExpression)*
-   *     ;
-   *
-   * bitwiseXorExpression
-   *     : bitwiseAndExpression ('^' bitwiseAndExpression)*
-   *     ;
-   *
-   * bitwiseAndExpression
-   *     : equalityExpression ('&' equalityExpression)*
-   *     ;
-   *
-   * equalityExpression
-   *     : relationalExpression (equalityOperator relationalExpression)?
-   *     ;
-   *
-   * relationalExpression
-   *     : shiftExpression (isOperator type | relationalOperator shiftExpression)?
-   *     ;
-   *
-   * shiftExpression
-   *     : additiveExpression (shiftOperator additiveExpression)*
-   *     ;
-   *
-   * additiveExpression
-   *     : multiplicativeExpression (additiveOperator multiplicativeExpression)*
-   *     ;
-   *
-   * multiplicativeExpression
-   *     : unaryExpression (multiplicativeOperator unaryExpression)*
-   *     ;
-   * </pre>
-   *
-   * @return an expression matching one of the productions above
-   */
-  private DartExpression parseBinaryExpression(int precedence) {
-    assert (precedence >= 4);
-    beginBinaryExpression();
-    DartExpression lastResult = parseUnaryExpression();
-    DartExpression result = lastResult;
-    for (int level = peekMaybeAS(0).getPrecedence(); level >= precedence; level--) {
-      while (peekMaybeAS(0).getPrecedence() == level) {
-        int prevPositionStart = ctx.getTokenLocation().getBegin();
-        int prevPositionEnd = ctx.getTokenLocation().getEnd();
-        Token token = nextMaybeAS();
-        int tokenOffset = ctx.getTokenLocation().getBegin();
-        if (lastResult instanceof DartSuperExpression
-            && (token == Token.AND || token == Token.OR)) {
-          reportErrorAtPosition(prevPositionStart, prevPositionEnd,
-                                ParserErrorCode.SUPER_IS_NOT_VALID_AS_A_BOOLEAN_OPERAND);
-        }
-        if (token == Token.EQ_STRICT) {
-          reportError(tokenOffset, ParserErrorCode.DEPRECATED_STRICT_EQ);
-        }
-        if (token == Token.NE_STRICT) {
-          reportError(tokenOffset, ParserErrorCode.DEPRECATED_STRICT_NE);
-        }
-        DartExpression right;
-        if (token == Token.IS) {
-          beginTypeExpression();
-          if (optional(Token.NOT)) {
-            int notOffset = ctx.getTokenLocation().getBegin();
-            beginTypeExpression();
-            DartTypeExpression typeExpression = done(new DartTypeExpression(parseTypeAnnotation()));
-            right = done(new DartUnaryExpression(Token.NOT, notOffset, typeExpression, true));
-          } else {
-            right = done(new DartTypeExpression(parseTypeAnnotation()));
-          }
-        } else if (token == Token.AS) {
-          beginTypeExpression();
-          right = done(new DartTypeExpression(parseTypeAnnotation()));
-        } else {
-          right = parseBinaryExpression(level + 1);
-        }
-        if (right instanceof DartSuperExpression) {
-          reportError(position(), ParserErrorCode.SUPER_CANNOT_BE_USED_AS_THE_SECOND_OPERAND);
-        }
-
-        lastResult = right;
-        result = doneWithoutConsuming(new DartBinaryExpression(token, tokenOffset, result, right));
-        if (token == Token.IS
-            || token == Token.AS
-            || token.isRelationalOperator()
-            || token.isEqualityOperator()) {
-          // The operations cannot be chained.
-          if (peekMaybeAS(0) == token) {
-            reportError(position(), ParserErrorCode.INVALID_OPERATOR_CHAINING,
-              token.toString().toLowerCase());
-          }
-          break;
-        }
-      }
-    }
-    done(null);
-    return result;
-  }
-
-  /**
-   * Use this method where token "as" is expected to be used as built-in identifier.
-   * 
-   * @return the {@link Token} at given position or {@link Token#AS}.
-   */
-  private Token peekMaybeAS(int n) {
-    Token token = ctx.peek(n);
-    String tokenString = ctx.peekTokenString(n);
-    if (token == Token.IDENTIFIER && "as".equals(tokenString)) {
-      return Token.AS;
-    }
-    return token;
-  }
-
-  /**
-   * Use this method where token "as" is expected to be used as built-in identifier.
-   * 
-   * @return the current {@link Token} or {@link Token#AS}.
-   */
-  private Token nextMaybeAS() {
-    ctx.advance();
-    Token token = ctx.getCurrentToken();
-    String tokenString = ctx.getTokenString();
-    if (token == Token.IDENTIFIER && "as".equals(tokenString)) {
-      return Token.AS;
-    }
-    return token;
-  }
-
-  /**
-   * Parse the arguments passed to a function or method invocation.
-   *
-   * <pre>
-   * arguments
-   *    : '(' argumentList? ')'
-   *    ;
-   *
-   * argumentList
-   *    : expression (',' expression)* (',' spreadArgument)?
-   *    | spreadArgument
-   *    ;
-   *
-   * spreadArgument
-   *    : '...' expression
-   *    ;
-   * </pre>
-   *
-   * @return a list of expressions containing the arguments to be passed
-   */
-  @Terminals(tokens={Token.RPAREN, Token.COMMA})
-  public List<DartExpression> parseArguments() {
-    List<DartExpression> arguments = new ArrayList<DartExpression>();
-    expect(Token.LPAREN);
-    // SEMICOLON is for error recovery
-    boolean namedArgumentParsed = false;
-    outer: while (!match(Token.RPAREN) && !match(Token.EOS) && !match(Token.SEMICOLON)) {
-      beginParameter();
-      // parse argument, may be named
-      DartExpression expression;
-      if (peek(1) == Token.COLON) {
-        DartIdentifier name = parseIdentifier();
-        expect(Token.COLON);
-        expression = new DartNamedExpression(name, parseExpression());
-        namedArgumentParsed = true;
-      } else {
-        expression = parseExpression();
-        if (namedArgumentParsed) {
-          reportError(expression, ParserErrorCode.POSITIONAL_AFTER_NAMED_ARGUMENT);
-        }
-      }
-      done(expression);
-      // add argument, if parsed successfully
-      if (expression != null) {
-        arguments.add(expression);
-      }
-      // do we have more arguments?
-      switch(peek(0)) {
-        // Must keep in sync with @Terminals above
-        case COMMA:
-          if (peek(-1) == Token.COMMA) {
-            reportErrorWithoutAdvancing(ParserErrorCode.EXPECTED_EXPRESSION_AFTER_COMMA);
-          }
-          consume(Token.COMMA);
-          break;
-          // Must keep in sync with @Terminals above
-        case RPAREN:
-          break;
-        default:
-          Token actual = peek(0);
-          Set<Token> terminals = collectTerminalAnnotations();
-          if (terminals.contains(actual) || looksLikeTopLevelKeyword()) {
-            // Looks like a method already on the stack could use this token.
-            reportErrorWithoutAdvancing(ParserErrorCode.EXPECTED_COMMA_OR_RIGHT_PAREN);
-            break outer;
-          } else {
-            // Advance the parser state if no other method on the stack can use this token.
-            ctx.advance();
-          }
-          reportError(ctx.getTokenLocation().getEnd(),
-              ParserErrorCode.EXPECTED_COMMA_OR_RIGHT_PAREN, actual);
-          break;
-      }
-    }
-    if (peek(-1) == Token.COMMA) {
-      reportErrorWithoutAdvancing(ParserErrorCode.EXPECTED_EXPRESSION_AFTER_COMMA);
-    }
-    expectCloseParen();
-    return arguments;
-  }
-
-  /**
-   * Parse a conditional expression.
-   *
-   * <pre>
-   * conditionalExpression
-   *     : logicalOrExpression ('?' expression ':' expression)?
-   *     ;
-   * </pre>
-   *
-   * @return an expression matching the {@code conditionalExpression} production
-   */
-  private DartExpression parseConditionalExpression() {
-    beginConditionalExpression();
-    DartExpression result = parseBinaryExpression(4);
-    if (result instanceof DartSuperExpression) {
-      reportError(position(), ParserErrorCode.SUPER_IS_NOT_VALID_ALONE_OR_AS_A_BOOLEAN_OPERAND);
-    }
-    if (peek(0) != Token.CONDITIONAL) {
-      return done(result);
-    }
-    consume(Token.CONDITIONAL);
-    DartExpression yes = parseExpressionWithoutCascade();
-    expect(Token.COLON);
-    DartExpression no = parseExpressionWithoutCascade();
-    return done(new DartConditional(result, yes, no));
-  }
-
-  private boolean looksLikeStringInterpolation() {
-    int peekAhead = 0;
-    while (true) {
-      switch (peek(peekAhead++)) {
-        case STRING:
-          break;
-        case STRING_SEGMENT:
-        case STRING_LAST_SEGMENT:
-        case STRING_EMBED_EXP_START:
-        case STRING_EMBED_EXP_END:
-          return true;
-        default:
-          return false;
-      }
-    }
-  }
-  /**
-   * Pastes together adjacent strings.  Re-uses the StringInterpolation
-   * node if there is more than one adjacent string.
-   */
-  private DartExpression parseStringWithPasting() {
-    List<DartExpression> expressions = new ArrayList<DartExpression>();
-    if (looksLikeStringInterpolation()) {
-      beginStringInterpolation();
-    } else {
-      beginLiteral();
-    }
-    DartExpression result = null;
-    boolean foundStringInterpolation = false;
-    do {
-      result = null;
-      switch(peek(0)) {
-        case STRING:
-        case STRING_SEGMENT:
-        case STRING_EMBED_EXP_START:
-          // another string is coming, glue it together.
-          result = parseString();
-          if (result != null) {
-            expressions.add(result);
-          }
-          if (result instanceof DartStringInterpolation) {
-            foundStringInterpolation = true;
-          }
-          break;
-      }
-    } while (result != null);
-
-    if (expressions.size() == 0) {
-      return doneWithoutConsuming(null);
-    } else if (expressions.size() == 1) {
-      return done(expressions.get(0));
-    }
-
-    if (foundStringInterpolation) {
-      DartStringInterpolationBuilder builder = new DartStringInterpolationBuilder();
-      // Create a new DartStringInterpolation object from the expressions.
-      boolean first = true;
-      for (DartExpression expr : expressions) {
-        if (!first) {
-          // pad between interpolations with a dummy expression
-          builder.addExpression(DartStringLiteral.get(""));
-        }
-        if (expr instanceof DartStringInterpolation) {
-          builder.addInterpolation((DartStringInterpolation)expr);
-        } else if (expr instanceof DartStringLiteral) {
-          builder.addString((DartStringLiteral)expr);
-        } else {
-          throw new InternalCompilerException("Expected String or StringInterpolation");
-        }
-        first = false;
-      }
-      return done(builder.buildInterpolation());
-    }
-
-    // Synthesize a single String literal
-    List<DartStringLiteral> stringParts = new ArrayList<DartStringLiteral>();
-    StringBuilder builder = new StringBuilder();
-    for (DartExpression expr : expressions) {
-      DartStringLiteral stringPart = (DartStringLiteral)expr;
-      stringParts.add(stringPart);
-      builder.append(stringPart.getValue());
-    }
-    return done(DartStringLiteral.get(builder.toString(), stringParts));
-  }
-
-  private DartExpression parseString() {
-    switch(peek(0)) {
-      case STRING: {
-        beginLiteral();
-        consume(Token.STRING);
-        return done(DartStringLiteral.get(ctx.getTokenString()));
-      }
-
-      case STRING_SEGMENT:
-      case STRING_EMBED_EXP_START:
-        return parseStringInterpolation();
-
-      default:
-        DartExpression expression = parseExpression();
-        reportError(position(), ParserErrorCode.EXPECTED_STRING_LITERAL);
-        return expression;
-    }
-  }
-
-  private int skipStringLiteral(int offset) {
-    Token token = peek(offset);
-    while (token == Token.STRING || token == Token.STRING_SEGMENT || token == Token.STRING_EMBED_EXP_START) {
-      switch(token) {
-        case STRING:
-          offset = offset + 1;
-  
-        case STRING_SEGMENT:
-        case STRING_EMBED_EXP_START:
-          offset = skipStringInterpolation(offset);
-      }
-      token = peek(offset);
-    }
-    return offset;
-  }
-
-  private int skipStringInterpolation(int offset) {
-    Token token = peek(offset);
-    if (token == Token.STRING_LAST_SEGMENT) {
-      return -1;
-    }
-    boolean inString = true;
-    while (inString) { // Iterate until we find the last string segment.
-      switch (token) {
-        case STRING_SEGMENT:
-          offset = offset + 1;
-          token = peek(offset);
-          break;
-        case STRING_LAST_SEGMENT:
-          offset = offset + 1;
-          token = peek(offset);
-          inString = false;
-          break;
-        case STRING_EMBED_EXP_START: {
-          offset = offset + 1;
-          token = peek(offset);
-          while (token != Token.EOS && token != Token.STRING_EMBED_EXP_END && token != Token.STRING_LAST_SEGMENT) {
-            if (token == Token.STRING || token == Token.STRING_SEGMENT || token == Token.STRING_EMBED_EXP_START) {
-              offset = skipStringLiteral(offset);
-            } else {
-              offset = offset + 1;
-            }
-            token = peek(offset);
-          }
-          if (token != Token.STRING_EMBED_EXP_END) {
-            inString = Token.STRING_LAST_SEGMENT != token;
-          }
-          break;
-        }
-        default:
-          inString = false;
-          break;
-      }
-    }
-    return offset;
-  }
-
-  private DartStringLiteral parseUri() {
-    DartExpression str = parseStringWithPasting();
-    if (str instanceof DartStringLiteral) {
-      return (DartStringLiteral) str;
-    } else if (str != null) {
-      reportError(str, ParserErrorCode.URI_CANNOT_USE_INTERPOLATION);
-      DartStringLiteral result = DartStringLiteral.get("<invalid-uri>");
-      result.setSourceInfo(str.getSourceInfo());
-      return result;
-    } else {
-      expect(Token.STRING);
-      return DartStringLiteral.get(null);
-    }
-  }
-
-  /**
-   * Instances of the class {@code DepthCounter} represent the number of less than tokens that have
-   * not yet been matched.
-   */
-  private static class DepthCounter {
-    /**
-     * The number of less than tokens that have not yet been matched.
-     */
-    private int count = 0;
-
-    /**
-     * Increment the number of less than tokens that have not yet been matched by the given amount
-     * (or decrement the count if the argument is negative).
-     * 
-     * @param value the amount by which the count should be changed
-     * @return the count after it has been modified
-     */
-    public int add(int value) {
-      count += value;
-      return count;
-    }
-
-    /**
-     * Return the number of less than tokens that have not yet been matched.
-     * 
-     * @return the number of less than tokens that have not yet been matched
-     */
-    public int getCount() {
-      return count;
-    }
-  }
-
-  /**
-   * Return the offset of the first token after a type name, or {@code -1} if the token at the given
-   * offset is not the start of a type name.
-   * 
-   * @param offset the offset of the first token of the type name
-   * @return the offset of the first token after a type name
-   */
-  private int skipTypeName(int offset) {
-    return skipTypeName(offset, new DepthCounter());
-  }
-
-  /**
-   * Return the offset of the first token after a type name, or {@code -1} if the token at the given
-   * offset is not the start of a type name.
-   * 
-   * @param offset the offset of the first token of the type name
-   * @param depth the number of less-thans that have been encountered since the outer-most type name
-   * @return the offset of the first token after a type name
-   */
-  private int skipTypeArguments(int offset, DepthCounter depth) {
-    if (peek(offset) != Token.LT) {
-      return -1;
-    }
-    int oldDepth = depth.add(1);
-    offset = skipTypeName(offset + 1, depth);
-    if (offset < 0) {
-      return offset;
-    }
-    while (peek(offset) == Token.COMMA) {
-      offset = skipTypeName(offset + 1, depth);
-      if (offset < 0) {
-        return offset;
-      }
-    }
-    if (depth.getCount() < oldDepth) {
-      // We already passed the closing '>' for this list of type arguments
-      return offset;
-    }
-    if (peek(offset) == Token.GT) {
-      depth.add(-1);
-      return offset + 1;
-    } else if (peek(offset) == Token.SAR) {
-      depth.add(-2);
-      return offset + 1;
-    }
-    return -1;
-  }
-
-  /**
-   * Return the offset of the first token after a type name, or {@code -1} if the token at the given
-   * offset is not the start of a type name.
-   * 
-   * @param offset the offset of the first token of the type name
-   * @param depth the number of less-thans that have been encountered since the outer-most type name
-   * @return the offset of the first token after a type name
-   */
-  private int skipTypeName(int offset, DepthCounter depth) {
-    if (peek(offset) != Token.IDENTIFIER) {
-      return -1;
-    }
-    offset++;
-    if (peek(offset) == Token.PERIOD) {
-      offset++;
-      if (peek(offset) == Token.IDENTIFIER) {
-        // We tolerate a missing identifier in order to recover better
-        offset++;
-      }
-    }
-    if (peek(offset) == Token.LT) {
-      offset = skipTypeArguments(offset, depth);
-    }
-    return offset;
-  }
-
-  /**
-   * Parse any literal that is not a function literal (those have already been
-   * handled before this method is called, so we don't need to handle them
-   * here).
-   *
-   * <pre>
-   * nonFunctionLiteral
-   *   : NULL
-   *   | TRUE
-   *   | FALSE
-   *   | HEX_NUMBER
-   *   | RATIONAL_NUMBER
-   *   | DOUBLE_NUMBER
-   *   | STRING
-   *   | mapLiteral
-   *   | arrayLiteral
-   *   ;
-   * </pre>
-   *
-   * @return an expression matching the {@code literal} production above
-   */
-  private DartExpression parseLiteral() {
-    beginLiteral();
-    if (PSEUDO_KEYWORDS_SET.contains(peek(0).getSyntax())) {
-      return done(parseIdentifier());
-    }
-    switch (peek(0)) {
-      case NULL_LITERAL: {
-        consume(Token.NULL_LITERAL);
-        return done(DartNullLiteral.get());
-      }
-
-      case TRUE_LITERAL: {
-        consume(Token.TRUE_LITERAL);
-        return done(DartBooleanLiteral.get(true));
-      }
-
-      case FALSE_LITERAL: {
-        consume(Token.FALSE_LITERAL);
-        return done(DartBooleanLiteral.get(false));
-      }
-
-      case INTEGER_LITERAL: {
-        consume(Token.INTEGER_LITERAL);
-        String number = ctx.getTokenString();
-        return done(DartIntegerLiteral.get(new BigInteger(number)));
-      }
-
-      case DOUBLE_LITERAL: {
-        consume(Token.DOUBLE_LITERAL);
-        String number = ctx.getTokenString();
-        return done(DartDoubleLiteral.get(Double.parseDouble(number)));
-      }
-
-      case HEX_LITERAL: {
-        consume(Token.HEX_LITERAL);
-        String number = ctx.getTokenString();
-        return done(DartIntegerLiteral.get(new BigInteger(number, 16)));
-      }
-
-      case LBRACE: {
-        return done(parseMapLiteral(false, null));
-      }
-
-      case INDEX: {
-        expect(peek(0));
-        return done(new DartArrayLiteral(false, null, new ArrayList<DartExpression>()));
-      }
-
-      case LBRACK: {
-        return done(parseArrayLiteral(false, null));
-      }
-
-      case VOID:
-        // For better error recovery / code completion in the IDE, treat "void" as an identifier
-        // here and let it get reported as a resolution error.
-      case IDENTIFIER: {
-        return done(parseIdentifier());
-      }
-
-      case SEMICOLON: {
-        // this is separate from the default case for better error recovery,
-        // leaving the semicolon for the caller to use for a statement boundary
-
-        // we have to advance to get the proper position, but we want to leave
-        // the semicolon
-        startLookahead();
-        next();
-        reportUnexpectedToken(position(), null, Token.SEMICOLON);
-        rollback();
-        return done(new DartSyntheticErrorExpression(""));
-      }
-
-      default: {
-        Token unexpected = peek(0);
-        String unexpectedString = ctx.getTokenString();
-        if (unexpectedString == null && unexpected != Token.EOS) {
-          unexpectedString = unexpected.getSyntax();
-        }
-
-        // Don't eat tokens that could be used to successfully terminate a non-terminal
-        // further up the stack.
-        Set<Token> terminals = collectTerminalAnnotations();
-        if (!looksLikeTopLevelKeyword() && !terminals.contains(unexpected)) {
-          next();
-        }
-        reportUnexpectedToken(position(), null, unexpected);
-        StringBuilder tokenStr = new StringBuilder();
-        if (unexpectedString != null) {
-          tokenStr.append(unexpectedString);
-        }
-        // TODO(jat): should we eat additional tokens here for error recovery?
-        return done(new DartSyntheticErrorExpression(tokenStr.toString()));
-      }
-    }
-  }
-
-  /**
-   * mapLiteralEntry
-   *     : STRING ':' expression
-   *     ;
-   */
-  private DartMapLiteralEntry parseMapLiteralEntry() {
-    beginMapLiteralEntry();
-    // Parse the key.
-    DartExpression keyExpr = parseStringWithPasting();
-    if (keyExpr == null) {
-      return done(null);
-    }
-    // Parse the value.
-    DartExpression value;
-    if (expect(Token.COLON)) {
-      value = parseExpression();
-    } else {
-      value = doneWithoutConsuming(new DartSyntheticErrorExpression());
-    }
-    return done(new DartMapLiteralEntry(keyExpr, value));
-  }
-  private boolean looksLikeString() {
-    switch(peek(0)) {
-      case STRING:
-      case STRING_SEGMENT:
-      case STRING_EMBED_EXP_START:
-        return true;
-    }
-    return false;
-  }
-
-  /**
-   * <pre> mapLiteral : '{' (mapLiteralEntry (',' mapLiteralEntry)* ','?)? '}' ;
-   * </pre>
-   */
-  @Terminals(tokens={Token.RBRACE, Token.COMMA})
-  private DartExpression parseMapLiteral(boolean isConst, List<DartTypeNode> typeArguments) {
-    beginMapLiteral();
-    boolean foundOpenBrace = expect(Token.LBRACE);
-    boolean save = setAllowFunctionExpression(true);
-    List<DartMapLiteralEntry> entries = new ArrayList<DartMapLiteralEntry>();
-
-    while (!match(Token.RBRACE) && !match(Token.EOS)) {
-      if (!looksLikeString()) {
-        ctx.advance();
-        reportError(position(), ParserErrorCode.EXPECTED_STRING_LITERAL_MAP_ENTRY_KEY);
-        if (peek(0) == Token.COMMA) {
-          // a common error is to put an empty entry in the list, allow it to
-          // recover.
-          continue;
-        } else {
-          break;
-        }
-      }
-      DartMapLiteralEntry entry = parseMapLiteralEntry();
-      if (entry != null) {
-        entries.add(entry);
-      }
-      Token nextToken = peek(0);
-      switch (nextToken) {
-        // Must keep in sync with @Terminals above
-        case COMMA:
-          consume(Token.COMMA);
-          break;
-        // Must keep in sync with @Terminals above
-        case RBRACE:
-          break;
-        default:
-          if (entry == null) {
-            Set<Token> terminals = collectTerminalAnnotations();
-            if (!terminals.contains(nextToken) && !looksLikeTopLevelKeyword()) {
-              if (entry == null) {
-                // Ensure the parser makes progress.
-                ctx.advance();
-              }
-            }
-          }
-          reportError(position(), ParserErrorCode.EXPECTED_COMMA_OR_RIGHT_BRACE);
-          break;
-      }
-    }
-
-    expectCloseBrace(foundOpenBrace);
-    setAllowFunctionExpression(save);
-    return done(new DartMapLiteral(isConst, typeArguments, entries));
-  }
-
-  /**
-   * // The array literal syntax doesn't allow elided elements, unlike
-   * // in ECMAScript.
-   *
-   * <pre>
-   * arrayLiteral
-   *     : '[' expressionList? ']'
-   *     ;
-   * </pre>
-   */
-  @Terminals(tokens={Token.RBRACK, Token.COMMA})
-  private DartExpression parseArrayLiteral(boolean isConst, List<DartTypeNode> typeArguments) {
-    beginArrayLiteral();
-    expect(Token.LBRACK);
-    boolean save = setAllowFunctionExpression(true);
-    List<DartExpression> exprs = new ArrayList<DartExpression>();
-    while (!match(Token.RBRACK) && !EOS()) {
-      exprs.add(parseExpression());
-      // Must keep in sync with @Terminals above
-      if (!optional(Token.COMMA)) {
-        break;
-      }
-    }
-    // Must keep in sync with @Terminals above
-    expect(Token.RBRACK);
-    setAllowFunctionExpression(save);
-    return done(new DartArrayLiteral(isConst, typeArguments, exprs));
-  }
-
-  /**
-   * Parse a postfix expression.
-   *
-   * <pre>
-   * postfixExpression
-   *     | assignableExpression postfixOperator
-   *     : primary selector*
-   *     ;
-   * </pre>
-   *
-   * @return an expression matching the {@code postfixExpression} production above
-   */
-  private DartExpression parsePostfixExpression() {
-    beginPostfixExpression();
-    DartExpression receiver = doneWithoutConsuming(parsePrimaryExpression());
-    DartExpression result = receiver;
-    do {
-      receiver = result;
-      result = doneWithoutConsuming(parseSelectorExpression(receiver));
-    } while (receiver != result);
-
-    Token token = peek(0);
-    if (token.isCountOperator()) {
-      ensureAssignable(result);
-      consume(token);
-      int tokenOffset = ctx.getTokenLocation().getBegin();
-      result = doneWithoutConsuming(new DartUnaryExpression(token, tokenOffset, result, false));
-    }
-
-    return done(result);
-  }
-
-  /**
-   * <pre>
-   * typeParameters? (arrayLiteral | mapLiteral)
-   * </pre>
-   *
-   * @param isConst <code>true</code> if a CONST expression
-   *
-   */
-  private DartExpression tryParseTypedCompoundLiteral(boolean isConst) {
-    beginLiteral();
-    List<DartTypeNode> typeArguments = parseTypeArgumentsOpt();
-    switch (peek(0)) {
-      case INDEX:
-        beginArrayLiteral();
-        consume(Token.INDEX);
-        return done(done(new DartArrayLiteral(isConst, typeArguments, new ArrayList<DartExpression>())));
-      case LBRACK:
-        return done(parseArrayLiteral(isConst, typeArguments));
-      case LBRACE:
-        return done(parseMapLiteral(isConst, typeArguments));
-      default:
-        if (typeArguments != null) {
-          rollback();
-          return null;
-        }
-
-    }
-    // Doesn't look like a typed compound literal and no tokens consumed.
-    return done(null);
-  }
-
-  private enum LastSeenNode {
-    NONE,
-    STRING,
-    EXPRESSION;
-  }
-
-  private class DartStringInterpolationBuilder {
-
-    private final List<DartStringLiteral> strings = new ArrayList<DartStringLiteral>();
-    private final List<DartExpression> expressions = new ArrayList<DartExpression>();
-    private LastSeenNode lastSeen = LastSeenNode.NONE;
-
-    DartStringInterpolationBuilder() {
-    }
-
-    void addString(DartStringLiteral string) {
-      if (lastSeen == LastSeenNode.STRING) {
-        expressions.add(new DartSyntheticErrorExpression());
-      }
-      strings.add(string);
-      lastSeen = LastSeenNode.STRING;
-    }
-
-    void addExpression(DartExpression expression) {
-      switch (lastSeen) {
-        case EXPRESSION:
-        case NONE:
-          strings.add(DartStringLiteral.get(""));
-          break;
-        default:
-          break;
-      }
-      expressions.add(expression);
-      lastSeen = LastSeenNode.EXPRESSION;
-    }
-
-    void addInterpolation(DartStringInterpolation interpolation) {
-      strings.addAll(interpolation.getStrings());
-      expressions.addAll(interpolation.getExpressions());
-      lastSeen = LastSeenNode.STRING;
-    }
-
-    DartStringInterpolation buildInterpolation() {
-      if (strings.size() == expressions.size()) {
-        strings.add(DartStringLiteral.get(""));
-      }
-      return new DartStringInterpolation(strings, expressions);
-    }
-  }
-
-  /**
-   * Instances of the class {@code StringInterpolationParseError} represent the detection of an
-   * error that needs to be handled in an enclosing context.
-   */
-  private static class StringInterpolationParseError extends RuntimeException {
-    private static final long serialVersionUID = 1L;
-
-    public StringInterpolationParseError() {
-      super();
-    }
-  }
-
-  /**
-   * <pre>
-   * string-interpolation
-   *   : (STRING_SEGMENT? embedded-exp?)* STRING_LAST_SEGMENT
-   *
-   * embedded-exp
-   *   : STRING_EMBED_EXP_START expression STRING_EMBED_EXP_END
-   * </pre>
-   */
-  private DartExpression parseStringInterpolation() {
-    // TODO(sigmund): generalize to parse string templates as well.
-    if (peek(0) == Token.STRING_LAST_SEGMENT) {
-      throw new InternalCompilerException("Invariant broken");
-    }
-    beginStringInterpolation();
-    DartStringInterpolationBuilder builder = new DartStringInterpolationBuilder();
-    boolean inString = true;
-    while (inString) { // Iterate until we find the last string segment.
-      switch (peek(0)) {
-        case STRING_SEGMENT: {
-          beginStringSegment();
-          consume(Token.STRING_SEGMENT);
-          builder.addString(done(DartStringLiteral.get(ctx.getTokenString())));
-          break;
-        }
-        case STRING_LAST_SEGMENT: {
-          beginStringSegment();
-          consume(Token.STRING_LAST_SEGMENT);
-          builder.addString(done(DartStringLiteral.get(ctx.getTokenString())));
-          inString = false;
-          break;
-        }
-        case STRING_EMBED_EXP_START: {
-          consume(Token.STRING_EMBED_EXP_START);
-          /*
-           * We check for ILLEGAL specifically here to give nicer error
-           * messages, and because the scanner doesn't generate a
-           * STRING_EMBED_EXP_END to match the START in the case of an ILLEGAL
-           * token.
-           */
-          if (peek(0) == Token.ILLEGAL) {
-            reportError(position(), ParserErrorCode.UNEXPECTED_TOKEN_IN_STRING_INTERPOLATION,
-                next());
-            builder.addExpression(new DartSyntheticErrorExpression(""));
-            break;
-          } else {
-            try {
-              builder.addExpression(parseExpression());
-            } catch (StringInterpolationParseError exception) {
-              if (peek(0) == Token.STRING_LAST_SEGMENT) {
-                break;
-              }
-              throw new InternalCompilerException("Invalid expression found in string interpolation");
-            }
-          }
-          Token lookAhead = peek(0);
-          String lookAheadString = getPeekTokenValue(0);
-          if (!expect(Token.STRING_EMBED_EXP_END)) {
-            String errorText = null;
-            if (lookAheadString != null && lookAheadString.length() > 0) {
-              errorText = lookAheadString;
-            } else if (lookAhead.getSyntax() != null && lookAhead.getSyntax().length() > 0) {
-              errorText = lookAhead.getSyntax();
-            }
-            if (errorText != null) {
-              builder.addExpression(new DartSyntheticErrorExpression(errorText));
-            }
-            inString = !(Token.STRING_LAST_SEGMENT == lookAhead);
-          }
-          break;
-        }
-        case EOS: {
-          reportError(position(), ParserErrorCode.INCOMPLETE_STRING_LITERAL);
-          inString = false;
-          break;
-        }
-        default: {
-          String errorText = getPeekTokenValue(0) != null && getPeekTokenValue(0).length() > 0
-              ? getPeekTokenValue(0) : null;
-          if(errorText != null) {
-            builder.addExpression(new DartSyntheticErrorExpression(getPeekTokenValue(0)));
-          }
-          reportError(position(), ParserErrorCode.UNEXPECTED_TOKEN_IN_STRING_INTERPOLATION,
-              next());
-          break;
-        }
-      }
-    }
-    return done(builder.buildInterpolation());
-  }
-
-  /**
-   * Parse a return type, giving an error if the .
-   *
-   * @return a return type or null if the current text is not a return type
-   */
-  private DartTypeNode parseReturnType() {
-    if (peek(0) == Token.VOID) {
-      return parseVoidType();
-    } else {
-      return parseTypeAnnotation();
-    }
-  }
-
-  /**
-   * Check if the current text could be a return type, and advance past it if so.  The current
-   * position is unchanged if it is not a return type.
-   *
-   * NOTE: if the grammar is changed for what constitutes an acceptable return type, this method
-   * must be updated to match {@link #parseReturnType()}/etc.
-   *
-   * @return true if current text could be a return type, false otherwise
-   */
-  private boolean isReturnType() {
-    beginReturnType();
-    if (optional(Token.VOID)) {
-      done(null);
-      return true;
-    }
-    if (!optional(Token.IDENTIFIER)) {
-      rollback();
-      return false;
-    }
-    // handle prefixed identifiers
-    if (optional(Token.PERIOD)) {
-      if (!optional(Token.IDENTIFIER)) {
-        rollback();
-        return false;
-      }
-    }
-    // skip over type arguments if they are present
-    if (optional(Token.LT)) {
-      int count = 1;
-      while (count > 0) {
-        switch (next()) {
-          case EOS:
-            rollback();
-            return false;
-          case LT:
-            count++;
-            break;
-          case GT:
-            count--;
-            break;
-          case SHL:
-            count += 2;
-            break;
-          case SAR:  // >>
-            count -= 2;
-            break;
-          case COMMA:
-          case IDENTIFIER:
-            // extends is a pseudokeyword, so shows up as IDENTIFIER
-            break;
-          default:
-            rollback();
-            return false;
-        }
-      }
-      if (count < 0) {
-        // if we had too many > (which can only be >> or >>>), can't be a return type
-        rollback();
-        return false;
-      }
-    }
-    done(null);
-    return true;
-  }
-
-  /**
-   * Checks to see if the current text looks like a function expression:
-   *
-   * <pre>
-   *   FUNCTION name? ( args ) < => | { >
-   *   returnType name? ( args ) < => | { >
-   *   name? ( args ) < => | { >
-   * </pre>
-   *
-   * The current position is unchanged on return.
-   *
-   * NOTE: if the grammar for function expressions changes, this method must be
-   * adapted to match the actual parsing code. It is acceptable for this method
-   * to return true when the source text does not actually represent a function
-   * expression (which would result in error messages assuming it was a function
-   * expression, but it must not do so when the source text would be correct if
-   * parsed as a non-function expression.
-   *
-   * @return true if the current text looks like a function expression, false
-   *         otherwise
-   */
-  @VisibleForTesting
-  boolean looksLikeFunctionExpression() {
-    if (!allowFunctionExpression) {
-      return false;
-    }
-    return looksLikeFunctionDeclarationOrExpression();
-  }
-
-  /**
-   * Check to see if the following tokens could be a function expression, and if so try and parse
-   * it as one.
-   *
-   * @return a function expression if found, or null (with no tokens consumed) if not
-   */
-  private DartExpression parseFunctionExpressionWithReturnType() {
-    beginFunctionLiteral();
-    DartIdentifier[] namePtr = new DartIdentifier[1];
-    DartFunction function = parseFunctionDeclarationOrExpression(namePtr, false);
-    if (function == null) {
-      rollback();
-      return null;
-    }
-    if (function != null && function.getReturnTypeNode() != null) {
-      reportError(function.getReturnTypeNode(), ParserErrorCode.DEPRECATED_FUNCTION_LITERAL);
-    } else if (namePtr[0] != null) {
-      reportError(namePtr[0], ParserErrorCode.DEPRECATED_FUNCTION_LITERAL);
-    }
-    return done(new DartFunctionExpression(namePtr[0], doneWithoutConsuming(function), false));
-  }
-
-  /**
-   * Parse a function declaration or expression, including the body.
-   * <pre>
-   *     ... | functionDeclaration functionBody
-   *
-   * functionDeclaration
-   *    : returnType? identifier formalParameterList
-   *    ;
-   *
-   * functionExpression
-   *    : (returnType? identifier)? formalParameterList functionExpressionBody
-   *    ;
-   *
-   * functionBody
-   *    : '=>' expression ';'
-   *    | block
-   *    ;
-   *
-   * functionExpressionBody
-   *    : '=>' expression
-   *    | block
-   *    ;
-   * </pre>
-   *
-   * @param namePtr out parameter - parsed function name stored in namePtr[0]
-   * @param isDeclaration true if this is a declaration (i.e. a name is required and a trailing
-   *     semicolon is needed for arrow syntax
-   * @return a {@link DartFunction} containing the body of the function, or null
-   *     if the next tokens cannot be parsed as a function declaration or expression
-   */
-  private DartFunction parseFunctionDeclarationOrExpression(DartIdentifier[] namePtr,
-      boolean isDeclaration) {
-    DartTypeNode returnType = null;
-    namePtr[0] = null;
-    if (optionalPseudoKeyword(STATIC_KEYWORD)) {
-      reportError(position(), ParserErrorCode.LOCAL_CANNOT_BE_STATIC);
-    }
-    switch (peek(0)) {
-      case LPAREN:
-        // no type or name, just the formal parameter list
-        break;
-      case IDENTIFIER:
-        if (peek(1) == Token.LPAREN) {
-          // if there is only one identifier, it must be the name
-          namePtr[0] = parseIdentifier();
-          break;
-        }
-        //$FALL-THROUGH$
-      case VOID:
-        returnType = parseReturnType();
-        if (peek(0) == Token.IDENTIFIER) {
-          namePtr[0] = parseIdentifier();
-        }
-        break;
-      default:
-        return null;
-    }
-    FormalParameters params = parseFormalParameterList();
-    int parametersCloseParen = ctx.getTokenLocation().getBegin();
-    DartBlock body = parseFunctionStatementBody(true, isDeclaration);
-    DartFunction function = new DartFunction(params.val, params.openParen,
-        params.optionalOpenOffset, params.optionalCloseOffset, parametersCloseParen, body,
-        returnType);
-    doneWithoutConsuming(function);
-    return function;
-  }
-
-  /**
-   * Parse a primary expression.
-   *
-   * <pre>
-   * primary
-   *   : THIS
-   *   | SUPER assignableSelector
-   *   | literal
-   *   | identifier
-   *   | NEW type ('.' identifier)? arguments
-   *   | typeArguments? (arrayLiteral | mapLiteral)
-   *   | CONST typeArguments? (arrayLiteral | mapLiteral)
-   *   | CONST typeArguments? (arrayLiteral | mapLiteral)
-   *   | CONST type ('.' identifier)? arguments
-   *   | '(' expression ')'
-   *   | string-interpolation
-   *   | functionExpression
-   *   ;
-   * </pre>
-   *
-   * @return an expression matching the {@code primary} production above
-   */
-  private DartExpression parsePrimaryExpression() {
-    if (looksLikeFunctionExpression()) {
-      return parseFunctionExpressionWithReturnType();
-    }
-    switch (peek(0)) {
-      case THIS: {
-        beginThisExpression();
-        consume(Token.THIS);
-        return done(DartThisExpression.get());
-      }
-
-      case SUPER: {
-        beginSuperExpression();
-        consume(Token.SUPER);
-        return done(DartSuperExpression.get());
-      }
-
-      case NEW: {
-        beginNewExpression(); // DartNewExpression
-        consume(Token.NEW);
-        return done(parseConstructorInvocation(false));
-      }
-
-      case CONST: {
-        beginConstExpression();
-        consume(Token.CONST);
-
-        DartExpression literal = tryParseTypedCompoundLiteral(true);
-        if (literal != null) {
-          return done(literal);
-        }
-        return done(parseConstructorInvocation(true));
-      }
-
-      case LPAREN: {
-        beginParenthesizedExpression();
-        consume(Token.LPAREN);
-        beginExpression();
-        // inside parens, function blocks are allowed again
-        boolean save = setAllowFunctionExpression(true);
-        DartExpression expression = done(parseExpression());
-        setAllowFunctionExpression(save);
-        expectCloseParen();
-        return done(new DartParenthesizedExpression(expression));
-      }
-
-      case LT: {
-        beginLiteral();
-        DartExpression literal = tryParseTypedCompoundLiteral(false);
-        if (literal == null) {
-          reportError(position(), ParserErrorCode.EXPECTED_ARRAY_OR_MAP_LITERAL);
-        }
-        return done(literal);
-      }
-
-      case STRING:
-      case STRING_SEGMENT:
-      case STRING_EMBED_EXP_START: {
-        return parseStringWithPasting();
-      }
-
-      case STRING_LAST_SEGMENT:
-        throw new StringInterpolationParseError();
-
-      case CONDITIONAL:
-        return parseArgumentDefinitionTest();
-
-      default: {
-        return parseLiteral();
-      }
-    }
-  }
-
-  private DartExpression parseArgumentDefinitionTest() {
-    beginArgumentDefinitionTest();
-    int operatorOffset = position();
-    expect(Token.CONDITIONAL);
-    return done(new DartUnaryExpression(Token.CONDITIONAL, operatorOffset, parseIdentifier(), true));
-  }
-
-  private DartExpression parseConstructorInvocation(boolean isConst) {
-    List<DartTypeNode> parts = new ArrayList<DartTypeNode>();
-    beginConstructor();
-    do {
-      beginConstructorNamePart();
-      parts.add(done(new DartTypeNode(parseIdentifier(), parseTypeArgumentsOpt())));
-    } while (optional(Token.PERIOD));
-    assert parts.size() > 0;
-
-    DartNode constructor;
-    switch (parts.size()) {
-      case 1:
-        constructor = doneWithoutConsuming(parts.get(0));
-        break;
-
-      case 2: {
-        // This case is ambiguous. It can either be prefix.Type or
-        // Type.namedConstructor.
-        boolean hasPrefix = false;
-        DartTypeNode part1 = parts.get(0);
-        DartTypeNode part2 = parts.get(1);
-        if (prefixes.contains(((DartIdentifier) part1.getIdentifier()).getName())) {
-          hasPrefix = true;
-        }
-        if (!part2.getTypeArguments().isEmpty()) {
-          // If the second part has type arguments, the first part must be a prefix.
-          // If it isn't a prefix, the resolver will complain.
-          hasPrefix = true;
-        }
-        if (hasPrefix) {
-          constructor = doneWithoutConsuming(toPrefixedType(parts));
-        } else {
-          // Named constructor.
-          DartIdentifier identifier = (DartIdentifier) part2.getIdentifier();
-          constructor = doneWithoutConsuming(new DartPropertyAccess(part1, identifier));
-        }
-        break;
-      }
-      default: {
-        // This case is unambiguous. It must be prefix.Type.namedConstructor.
-        if (parts.size() > 3) {
-          reportError(parts.get(3), ParserErrorCode.EXPECTED_LEFT_PAREN);
-        }
-        DartTypeNode typeNode = doneWithoutConsuming(toPrefixedType(parts));
-        DartIdentifier identifier = (DartIdentifier)parts.get(2).getIdentifier();
-        constructor = doneWithoutConsuming(new DartPropertyAccess(typeNode, identifier));
-        break;
-      }
-    }
-
-    boolean save = setAllowFunctionExpression(true);
-    try {
-      List<DartExpression> args = parseArguments();
-      return done(new DartNewExpression(constructor, args, isConst));
-    } finally {
-      setAllowFunctionExpression(save);
-    }
-  }
-
-  private DartTypeNode toPrefixedType(List<DartTypeNode> parts) {
-    DartIdentifier part1 = (DartIdentifier)parts.get(0).getIdentifier();
-    DartTypeNode part2 = parts.get(1);
-    DartIdentifier identifier = (DartIdentifier) part2.getIdentifier();
-    DartPropertyAccess access = doneWithoutConsuming(new DartPropertyAccess(part1, identifier));
-    return new DartTypeNode(access, part2.getTypeArguments());
-  }
-
-  /**
-   * Parse a selector expression.
-   *
-   * <pre>
-   * selector
-   *    : assignableSelector
-   *    | arguments
-   *    ;
-   * </pre>
-   *
-   * @return an expression matching the {@code selector} production above
-   */
-  private DartExpression parseSelectorExpression(DartExpression receiver) {
-    DartExpression expression = tryParseAssignableSelector(receiver);
-    if (expression != null) {
-      return expression;
-    }
-
-    if (peek(0) == Token.LPAREN) {
-      beginSelectorExpression();
-      boolean save = setAllowFunctionExpression(true);
-      List<DartExpression> args = parseArguments();
-      setAllowFunctionExpression(save);
-      if (receiver instanceof DartIdentifier) {
-        return(done(new DartUnqualifiedInvocation((DartIdentifier) receiver, args)));
-      } else {
-        return(done(new DartFunctionObjectInvocation(receiver, args)));
-      }
-    }
-
-    return receiver;
-  }
-
-  /**
-   * <pre>
-   * assignableSelector
-   *    : '[' expression ']'
-   *    | '.' identifier
-   *    ;
-   * </pre>
-   */
-  private DartExpression tryParseAssignableSelector(DartExpression receiver) {
-    switch (peek(0)) {
-      case PERIOD:
-        consume(Token.PERIOD);
-        switch (peek(0)) {
-          case SEMICOLON:
-          case RBRACE:
-            reportError(position(), ParserErrorCode.EXPECTED_IDENTIFIER);
-            DartIdentifier error = doneWithoutConsuming(new DartIdentifier(""));
-            return doneWithoutConsuming(new DartPropertyAccess(receiver, error));
-        }
-        // receiver.() = missing name
-        if (peek(0) == Token.LPAREN) {
-          reportUnexpectedToken(position(), Token.IDENTIFIER, peek(0));
-          DartIdentifier name;
-          {
-            beginIdentifier();
-            name = done(new DartSyntheticErrorIdentifier());
-          }
-          boolean save = setAllowFunctionExpression(true);
-          DartMethodInvocation expr = doneWithoutConsuming(new DartMethodInvocation(receiver,
-              false, name, parseArguments()));
-          setAllowFunctionExpression(save);
-          return expr;
-        }
-        // expect name
-        DartIdentifier name = parseIdentifier();
-        if (peek(0) == Token.LPAREN) {
-          boolean save = setAllowFunctionExpression(true);
-          DartMethodInvocation expr = doneWithoutConsuming(new DartMethodInvocation(receiver, false,
-              name, parseArguments()));
-          setAllowFunctionExpression(save);
-          return expr;
-        } else {
-          return doneWithoutConsuming(new DartPropertyAccess(receiver, name));
-        }
-
-      case LBRACK:
-        consume(Token.LBRACK);
-        DartExpression key = parseExpression();
-        expect(Token.RBRACK);
-        return doneWithoutConsuming(new DartArrayAccess(receiver, key));
-
-      default:
-        return null;
-    }
-  }
-
-  /**
-   * <pre>
-   * block
-   *     : '{' statements deadCode* '}'
-   *     ;
-   *
-   * statements
-   *     : statement*
-   *     ;
-   *
-   * deadCode
-   *     : (normalCompletingStatement | abruptCompletingStatement)
-   *     ;
-   * </pre>
-   */
-  @Terminals(tokens={Token.RBRACE})
-  private DartBlock parseBlock() {
-    if (isDietParse) {
-      expect(Token.LBRACE);
-      DartBlock emptyBlock = new DartBlock(new ArrayList<DartStatement>());
-      int nesting = 1;
-      while (nesting > 0) {
-        Token token = next();
-        switch (token) {
-          case LBRACE:
-            ++nesting;
-            break;
-          case RBRACE:
-            --nesting;
-            break;
-          case EOS:
-            return emptyBlock;
-        }
-      }
-      // Return an empty block so we don't generate unparseable code.
-      return emptyBlock;
-    } else {
-      Token nextToken = peek(0);
-      if (!nextToken.equals(Token.LBRACE)
-          && (looksLikeTopLevelKeyword() || nextToken.equals(Token.RBRACE))) {
-        beginBlock();
-        // Allow recovery back to the top level.
-        reportErrorWithoutAdvancing(ParserErrorCode.UNEXPECTED_TOKEN);
-        return done(new DartBlock(new ArrayList<DartStatement>()));
-      }
-      beginBlock();
-      List<DartStatement> statements = new ArrayList<DartStatement>();
-      boolean foundOpenBrace = expect(Token.LBRACE);
-
-      while (!match(Token.RBRACE) && !EOS()) {
-        if (looksLikeTopLevelKeyword()) {
-          reportErrorWithoutAdvancing(ParserErrorCode.UNEXPECTED_TOKEN);
-          break;
-        }
-        int startPosition = position();
-        DartStatement newStatement = parseStatement();
-        if (newStatement == null) {
-          break;
-        }
-        if (startPosition == position()) {
-          // The parser is not making progress.
-          Set<Token> terminals = this.collectTerminalAnnotations();
-          if (terminals.contains(peek(0))) {
-            // bail out of the block
-            break;
-          }
-          reportUnexpectedToken(position(), null, next());
-        }
-        statements.add(newStatement);
-      }
-      expectCloseBrace(foundOpenBrace);
-      return done(new DartBlock(statements));
-    }
-  }
-
-  /**
-   * Parse a function statement body.
-   *
-   * <pre>
-   * functionStatementBody
-   *    : '=>' expression ';'
-   *    | block
-   * </pre>
-   *
-   * @param requireSemicolonForArrow true if a semicolon is required after an arrow expression
-   * @return {@link DartBlock} instance containing function body
-   */
-  private DartBlock parseFunctionStatementBody(boolean allowBody, boolean requireSemicolonForArrow) {
-    // A break inside a function body should have nothing to do with a loop in
-    // the code surrounding the definition.
-    boolean oldInLoopStatement = inLoopStatement;
-    boolean oldInCaseStatement = inCaseStatement;
-    inLoopStatement = inCaseStatement = false;
-    try {
-      DartBlock result;
-      if (isDietParse) {
-        result = dietParseFunctionStatementBody();
-      } else {
-        beginFunctionStatementBody();
-        if (optional(Token.SEMICOLON)) {
-          if (allowBody) {
-            reportError(position(), ParserErrorCode.EXPECTED_FUNCTION_STATEMENT_BODY);
-          }
-          result = done(null);
-        } else if (optional(Token.ARROW)) {
-          DartExpression expr = parseExpression();
-          if (expr == null) {
-            expr = new DartSyntheticErrorExpression();
-          }
-          if (requireSemicolonForArrow) {
-            expect(Token.SEMICOLON);
-          }
-          result = done(makeReturnBlock(expr));
-        } else {
-          result = done(parseBlock());
-        }
-      }
-      if (!allowBody && result != null) {
-        reportError(result, ParserErrorCode.EXTERNAL_METHOD_BODY);
-      }
-      return result;
-    } finally {
-      inLoopStatement = oldInLoopStatement;
-      inCaseStatement = oldInCaseStatement;
-    }
-  }
-
-  private DartBlock dietParseFunctionStatementBody() {
-    DartBlock emptyBlock = new DartBlock(new ArrayList<DartStatement>());
-    if (optional(Token.ARROW)) {
-      while (true) {
-        Token token = next();
-        if (token == Token.SEMICOLON) {
-          break;
-        }
-      }
-    } else {
-      if (!peek(0).equals(Token.LBRACE) && looksLikeTopLevelKeyword()) {
-        // Allow recovery back to the top level.
-        reportErrorWithoutAdvancing(ParserErrorCode.UNEXPECTED_TOKEN);
-        return done(emptyBlock);
-      }
-      expect(Token.LBRACE);
-      int nesting = 1;
-      while (nesting > 0) {
-        Token token = next();
-        switch (token) {
-          case LBRACE:
-            ++nesting;
-            break;
-          case RBRACE:
-            --nesting;
-            break;
-          case EOS:
-            return emptyBlock;
-        }
-      }
-    }
-    // Return an empty block so we don't generate unparseable code.
-    return emptyBlock;
-  }
-
-  /**
-   * Create a block containing a single return statement.
-   *
-   * @param returnVal return value expression
-   * @return block containing a single return statement
-   */
-  private DartBlock makeReturnBlock(DartExpression returnVal) {
-    return new DartReturnBlock(returnVal);
-  }
-
-  /**
-   * <pre>
-   * initializedVariableDeclaration
-   *     : constVarOrType initializedIdentifierList
-   *     ;
-   *
-   * initializedIdentifierList
-   *     : initializedIdentifier (',' initializedIdentifier)*
-   *     ;
-   *
-   * initializedIdentifier
-   *     : IDENTIFIER ('=' assignmentExpression)?
-   *     ;
-   *  </pre>
-   */
-  private List<DartVariable> parseInitializedVariableList() {
-    List<DartVariable> idents = new ArrayList<DartVariable>();
-    do {
-      beginVariableDeclaration();
-      List<DartAnnotation> metadata = parseMetadata();
-      DartIdentifier name = parseIdentifier();
-      DartExpression value = null;
-      if (isParsingInterface) {
-        expect(Token.ASSIGN);
-        value = parseExpression();
-      } else if (optional(Token.ASSIGN)) {
-        value = parseExpression();
-      }
-      DartVariable variable = done(new DartVariable(name, value));
-      setMetadata(variable, metadata);
-      idents.add(variable);
-    } while (optional(Token.COMMA));
-
-    return idents;
-  }
-
-  private DartAssertStatement parseAssertStatement() {
-    beginAssertStatement();
-    expect(Token.ASSERT);
-    expect(Token.LPAREN);
-    DartExpression condition = parseExpression();
-    expectCloseParen();
-    expectStatmentTerminator();
-    return done(new DartAssertStatement(condition));
-  }
-
-  /**
-   * <pre>
-   * abruptCompletingStatement
-   *     : BREAK identifier? ';'
-   *     | CONTINUE identifier? ';'
-   *     | RETURN expression? ';'
-   *     | THROW expression? ';'
-   *     ;
-   *  </pre>
-   */
-  private DartBreakStatement parseBreakStatement() {
-    beginBreakStatement();
-    expect(Token.BREAK);
-    DartIdentifier label = null;
-    if (match(Token.IDENTIFIER)) {
-      label = parseIdentifier();
-    } else if (!inLoopStatement && !inCaseStatement) {
-      // The validation of matching of labels to break statements is done later.
-      reportErrorWithoutAdvancing(ParserErrorCode.BREAK_OUTSIDE_OF_LOOP);
-    }
-    expectStatmentTerminator();
-    return done(new DartBreakStatement(label));
-  }
-
-  private DartContinueStatement parseContinueStatement() {
-    beginContinueStatement();
-    expect(Token.CONTINUE);
-    DartIdentifier label = null;
-    if (!inLoopStatement && !inCaseStatement) {
-      reportErrorWithoutAdvancing(ParserErrorCode.CONTINUE_OUTSIDE_OF_LOOP);
-    }
-    if (peek(0) == Token.IDENTIFIER) {
-      label = parseIdentifier();
-    } else if (!inLoopStatement && inCaseStatement) {
-      reportErrorWithoutAdvancing(ParserErrorCode.CONTINUE_IN_CASE_MUST_HAVE_LABEL);
-    }
-    expectStatmentTerminator();
-    return done(new DartContinueStatement(label));
-  }
-
-  private DartReturnStatement parseReturnStatement() {
-    beginReturnStatement();
-    expect(Token.RETURN);
-    DartExpression value = null;
-    if (peek(0) != Token.SEMICOLON) {
-      value = parseExpression();
-    }
-    expectStatmentTerminator();
-    return done(new DartReturnStatement(value));
-  }
-
-  private DartThrowExpression parseThrowExpression(boolean allowCascade) {
-    beginThrowExpression();
-    expect(Token.THROW);
-    DartExpression exception = null;
-    if (peek(0) != Token.SEMICOLON && peek(0) != Token.RPAREN) {
-      if (allowCascade) {
-        exception = parseExpression();
-      } else {
-        exception = parseExpressionWithoutCascade();
-      }
-    }
-    return done(new DartThrowExpression(exception));
-  }
-
-  /**
-   * <pre>
-   * statement
-   *     : label* nonLabelledStatement
-   *     ;
-   *
-   * label
-   *     : identifier ':'
-   *     ;
-   * </pre>
-   *
-   * @return a {@link DartStatement}
-   */
-  @VisibleForTesting
-  public DartStatement parseStatement() {
-    List<DartIdentifier> labels = new ArrayList<DartIdentifier>();
-    while (peek(0) == Token.IDENTIFIER && peek(1) == Token.COLON) {
-      beginLabel();
-      labels.add(parseIdentifier());
-      expect(Token.COLON);
-    }
-    List<DartAnnotation> metadata = parseMetadata();
-    DartStatement statement = parseNonLabelledStatement();
-    if (!metadata.isEmpty() && statement instanceof DartVariableStatement) {
-      DartVariableStatement variableStatement = (DartVariableStatement) statement;
-      if (!variableStatement.getVariables().isEmpty()) {
-        setMetadata(variableStatement.getVariables().get(0), metadata);
-      }
-    }
-    for (int i = labels.size() - 1; i >= 0; i--) {
-      statement = done(new DartLabel(labels.get(i), statement));
-    }
-    return statement;
-  }
-
-  private boolean isFunctionExpression(DartStatement statement) {
-    if (!(statement instanceof DartExprStmt)) {
-      return false;
-    }
-    DartExpression expression = ((DartExprStmt) statement).getExpression();
-    if (!(expression instanceof DartFunctionExpression)) {
-      return false;
-    }
-    return ((DartFunctionExpression) expression).getName() == null;
-  }
-
-  /**
-   * <pre>
-   * normalCompletingStatement
-   *     : functionStatement
-   *     | initializedVariableDeclaration ';'
-   *     | simpleStatement
-   *     ;
-   *
-   * functionStatement
-   *     : typeOrFunction identifier formalParameterList block
-   *     ;
-   *     ;
-   *
-   * simpleStatement
-   *     : ('{')=> block // Guard to break tie with map literal.
-   *     | expression? ';'
-   *     | tryStatement
-   *     | ASSERT '(' conditionalExpression ')' ';'
-   *     | abruptCompletingStatement
-   *     ;
-   * </pre>
-   */
-  // TODO(zundel):  Possibly  we could use Token.IDENTIFIER too, but it is used
-  // in so many places, it might make recovery worse rather than better.
-  @Terminals(tokens={Token.IF, Token.SWITCH, Token.WHILE, Token.DO, Token.FOR,
-      Token.VAR, Token.FINAL, Token.CONTINUE, Token.BREAK, Token.RETHROW,
-      Token.RETURN, Token.THROW, Token.TRY, Token.SEMICOLON })
-  private DartStatement parseNonLabelledStatement() {
-    // Try to parse as function declaration.
-    if (looksLikeFunctionDeclarationOrExpression()) {
-      ctx.begin();
-      DartStatement functionDeclaration = parseFunctionDeclaration();
-      // If "null", then we tried to parse, but found that this is not function declaration.
-      // So, parsing was rolled back and we can try to parse it as expression.
-      if (functionDeclaration != null) {
-        if (!isFunctionExpression(functionDeclaration)) {
-          ctx.done(null);
-          return functionDeclaration;
-        }
-        ctx.rollback();
-      } else {
-        ctx.done(null);
-      }
-    }
-    // Check possible statement kind.
-    switch (peek(0)) {
-      case ASSERT:
-        return parseAssertStatement();
-
-      case IF:
-        return parseIfStatement();
-        
-      case SWITCH:
-        return parseSwitchStatement();
-
-      case WHILE:
-        return parseWhileStatement();
-
-      case DO:
-        return parseDoWhileStatement();
-
-      case FOR:
-        return parseForStatement();
-
-      case VAR: {
-        beginVarDeclaration();
-        consume(Token.VAR);
-        List<DartVariable> vars = parseInitializedVariableList();
-        expectStatmentTerminator();
-        return done(new DartVariableStatement(vars, null));
-      }
-
-      case FINAL: {
-        beginFinalDeclaration();
-        consume(peek(0));
-        DartTypeNode type = null;
-        if (peek(1) == Token.IDENTIFIER || peek(1) == Token.LT || peek(1) == Token.PERIOD) {
-          // We know we have a type.
-          type = parseTypeAnnotation();
-        }
-        List<DartVariable> vars = parseInitializedVariableList();
-        expectStatmentTerminator();
-        return done(new DartVariableStatement(vars, type, Modifiers.NONE.makeFinal()));
-      }
-
-      case LBRACE:
-        Token token = peek(1);
-        if (token == Token.STRING || token == Token.STRING_SEGMENT || token == Token.STRING_EMBED_EXP_START) {
-          int offset = skipStringLiteral(1);
-          if (peek(offset) == Token.COLON) {
-            DartStatement statement = parseExpressionStatement();
-            if (statement instanceof DartExprStmt
-                && ((DartExprStmt) statement).getExpression() instanceof DartMapLiteral) {
-              reportError(
-                  ((DartExprStmt) statement).getExpression(),
-                  ParserErrorCode.NON_CONST_MAP_LITERAL_STATEMENT);
-            }
-            return statement;
-          }
-        }
-        return parseBlock();
-
-      case CONTINUE:
-        return parseContinueStatement();
-
-      case BREAK:
-        return parseBreakStatement();
-
-      case RETURN:
-        return parseReturnStatement();
-
-      case THROW:
-       return parseExpressionStatement();
-
-      case RETHROW:
-        consume(Token.RETHROW);
-        beginExpressionStatement();
-        return done(new DartExprStmt(new DartThrowExpression(null)));
-
-      case TRY:
-        return parseTryStatement();
-
-      case SEMICOLON:
-        beginEmptyStatement();
-        consume(Token.SEMICOLON);
-        return done(new DartEmptyStatement());
-
-      case CONST:
-        // Check to see whether this is a variable declaration. If not, then default to parsing an
-        // expression statement.
-        int offset = skipTypeName(1);
-        if (offset > 1 && (peek(offset) == Token.IDENTIFIER || (offset == 2
-            && (peek(offset) == Token.ASSIGN || peek(offset) == Token.COMMA || peek(offset) == Token.SEMICOLON)))) {
-          boolean hasType = peek(offset) == Token.IDENTIFIER;
-          beginVariableDeclaration();
-          next();
-          DartTypeNode type = null;
-          if (hasType) {
-            type = parseTypeAnnotation();
-          }
-          List<DartVariable> vars = parseInitializedVariableList();
-          expect(Token.SEMICOLON);
-          return done(new DartVariableStatement(vars, type, Modifiers.NONE.makeConstant().makeFinal()));
-        }
-        break;
-
-      case IDENTIFIER:
-        // We have already eliminated function declarations earlier, so check for:
-        // a) variable declarations;
-        // b) beginning of function literal invocation.
-        if (peek(1) == Token.LT || peekMaybeAS(1) == Token.IDENTIFIER
-            || (peek(1) == Token.PERIOD && peek(2) == Token.IDENTIFIER)) {
-          beginTypeFunctionOrVariable();
-          DartTypeNode type = tryTypeAnnotation();
-          if (type != null && peekMaybeAS(0) == Token.IDENTIFIER) {
-            List<DartVariable> vars = parseInitializedVariableList();
-            if (optional(Token.SEMICOLON)) {
-              return done(new DartVariableStatement(vars, type));
-            } else if (peek(0) == Token.LPAREN) {
-              // Probably a function object invocation.
-              rollback();
-            } else {
-              //reportError(position(), ParserErrorCode.EXPECTED_SEMICOLON);
-              expectStatmentTerminator();
-              return done(new DartVariableStatement(vars, type));
-            }
-          } else {
-            rollback();
-          }
-        }
-        break;
-    }
-    return parseExpressionStatement();
-  }
-
-  /**
-   * Check if succeeding tokens look like a function declaration - the parser state is unchanged
-   * upon return.
-   *
-   * See {@link #parseFunctionDeclaration()}.
-   *
-   * @return true if the following tokens should be parsed as a function definition
-   */
-  private boolean looksLikeFunctionDeclarationOrExpression() {
-    beginMethodName();
-    try {
-      optionalPseudoKeyword(STATIC_KEYWORD);
-      if (peek(0) == Token.IDENTIFIER && peek(1) == Token.LPAREN) {
-        // just a name, no return type
-        consume(Token.IDENTIFIER);
-      } else if (isReturnType()) {
-        if (!optional(Token.IDENTIFIER)) {
-          // return types must be followed by a function name
-          return false;
-        }
-      }
-      // start of parameter list
-      if (!optional(Token.LPAREN)) {
-        return false;
-      }
-      // if it looks as "(Type name, ....)" then it may be function expression
-      boolean hasTwoIdentifiersComma;
-      {
-        int nameOffset = skipTypeName(0);
-        hasTwoIdentifiersComma = nameOffset != -1 && peek(nameOffset + 0) == Token.IDENTIFIER
-            && peek(nameOffset + 1) == Token.COMMA;
-      }
-      // find matching parenthesis
-      int count = 1;
-      while (count != 0) {
-        switch (next()) {
-          case EOS:
-            return false;
-          case LPAREN:
-            count++;
-            break;
-          case RPAREN:
-            count--;
-            break;
-        }
-      }
-      return (peek(0) == Token.ARROW || peek(0) == Token.LBRACE) || hasTwoIdentifiersComma;
-    } finally {
-      rollback();
-    }
-  }
-
-  /**
-   * Parse a function declaration.
-   *
-   * <pre>
-   * nonLabelledStatement : ...
-   *     | functionDeclaration functionBody
-   *
-   * functionDeclaration
-   *    : FUNCTION identifier formalParameterList
-   *      { legacy($start, "deprecated 'function' keyword"); }
-   *    | returnType error=FUNCTION identifier? formalParameterList
-   *      { legacy($error, "deprecated 'function' keyword"); }
-   *    | returnType? identifier formalParameterList
-   *    ;
-   * </pre>
-   *
-   * @return a {@link DartStatement} representing the function declaration or <code>null</code> if
-   *         code ends with function invocation, so this is not function declaration.
-   */
-  private DartStatement parseFunctionDeclaration() {
-    beginFunctionDeclaration();
-    DartIdentifier[] namePtr = new DartIdentifier[1];
-    DartFunction function = parseFunctionDeclarationOrExpression(namePtr, true);
-    if (function.getBody() instanceof DartReturnBlock || peek(0) != Token.LPAREN) {
-      return done(new DartExprStmt(doneWithoutConsuming(new DartFunctionExpression(namePtr[0],
-          doneWithoutConsuming(function),
-          true))));
-    } else {
-      rollback();
-      return null;
-    }
-  }
-
-  private DartStatement parseExpressionStatement() {
-    beginExpressionStatement();
-    DartExpression expression = parseExpression();
-    expectStatmentTerminator();
-
-    return done(new DartExprStmt(expression));
-  }
-
-  /**
-   * Expect a close paren, reporting an error and consuming tokens until a
-   * plausible continuation is found if it isn't present.
-   */
-  private void expectCloseParen() {
-    int parenCount = 1;
-    Token nextToken = peek(0);
-    switch (nextToken) {
-      case RPAREN:
-        expect(Token.RPAREN);
-        return;
-
-      case EOS:
-      case LBRACE:
-      case SEMICOLON:
-        reportError(position(), ParserErrorCode.EXPECTED_TOKEN, Token.RPAREN.getSyntax(),
-            nextToken.getSyntax());
-        return;
-
-      case LPAREN:
-        ++parenCount;
-        //$FALL-THROUGH$
-      default:
-        reportError(position(), ParserErrorCode.EXPECTED_TOKEN, Token.RPAREN.getSyntax(),
-            nextToken.getSyntax());
-        Set<Token> terminals = this.collectTerminalAnnotations();
-        if (terminals.contains(nextToken) || looksLikeTopLevelKeyword()) {
-          return;
-        }
-        break;
-    }
-
-    // eat tokens until we get a close paren or a plausible terminator (which
-    // is not consumed)
-    while (parenCount > 0) {
-      switch (peek(0)) {
-        case RPAREN:
-          expect(Token.RPAREN);
-          --parenCount;
-          break;
-
-        case LPAREN:
-          expect(Token.LPAREN);
-          ++parenCount;
-          break;
-
-        case EOS:
-          reportErrorWithoutAdvancing(ParserErrorCode.UNEXPECTED_TOKEN);
-          return;
-
-        case LBRACE:
-        case SEMICOLON:
-          return;
-
-        default:
-          next();
-          break;
-      }
-    }
-  }
-
-  /**
-   * Expect a close brace, reporting an error and consuming tokens until a
-   * plausible continuation is found if it isn't present.
-   */
-  private void expectCloseBrace(boolean foundOpenBrace) {
-    // If a top level keyword is seen, bail out to recover.
-    if (looksLikeTopLevelKeyword()) {
-      reportUnexpectedToken(position(), Token.RBRACE, peek(0));
-      return;
-    }
-
-    int braceCount = 0;
-    if (foundOpenBrace) {
-      braceCount++;
-    }
-    Token nextToken = peek(0);
-    if (expect(Token.RBRACE)) {
-      return;
-    }
-    if (nextToken == Token.LBRACE) {
-      braceCount++;
-    }
-
-    // eat tokens until we get a matching close brace or end of stream
-    while (braceCount > 0) {
-      if (looksLikeTopLevelKeyword()) {
-        return;
-      }
-      switch (next()) {
-        case RBRACE:
-          braceCount--;
-          break;
-
-        case LBRACE:
-          braceCount++;
-          break;
-
-        case EOS:
-          return;
-      }
-    }
-  }
-
-  /**
-   * Collect plausible statement tokens and return a synthetic error statement
-   * containing them.
-   * <p>
-   * Note that this is a crude heuristic that needs to be improved for better
-   * error recovery.
-   *
-   * @return a {@link DartSyntheticErrorStatement}
-   */
-  private DartStatement parseErrorStatement() {
-    StringBuilder buf = new StringBuilder();
-    boolean done = false;
-    int braceCount = 1;
-    while (!done) {
-      buf.append(getPeekTokenValue(0));
-      next();
-      switch (peek(0)) {
-        case RBRACE:
-          if (--braceCount == 0) {
-            done = true;
-          }
-          break;
-        case LBRACE:
-          braceCount++;
-          break;
-        case EOS:
-        case SEMICOLON:
-          done = true;
-          break;
-      }
-    }
-    return new DartSyntheticErrorStatement(buf.toString());
-  }
-
-
-  /**
-   * Look for a statement terminator, giving error messages and consuming tokens
-   * for error recovery.
-   */
-  protected void expectStatmentTerminator() {
-    Token token = peek(0);
-    if (expect(Token.SEMICOLON)) {
-      return;
-    }
-    Set<Token> terminals = collectTerminalAnnotations();
-    assert(terminals.contains(Token.SEMICOLON));
-
-    if (peek(0) == token) {
-      reportErrorWithoutAdvancing(ParserErrorCode.EXPECTED_SEMICOLON);
-    } else {
-      reportError(position(), ParserErrorCode.EXPECTED_SEMICOLON);
-      token = peek(0);
-    }
-
-    // Consume tokens until we see something that could terminate or start a new statement
-    while (token != Token.SEMICOLON) {
-      if (looksLikeTopLevelKeyword() || terminals.contains(token)) {
-        return;
-      }
-      token = next();
-    }
-  }
-
-  /**
-   * Report an error without advancing past the next token.
-   *
-   * @param errCode the error code to report, which may take a string parameter
-   *     containing the actual token found
-   */
-  private void reportErrorWithoutAdvancing(ErrorCode errCode) {
-    startLookahead();
-    Token actual = peek(0);
-    next();
-    reportError(position(), errCode, actual);
-    rollback();
-  }
-
-  /**
-   * <pre>
-   * iterationStatement
-   *     : WHILE '(' expression ')' statement
-   *     | DO statement WHILE '(' expression ')' ';'
-   *     | FOR '(' forLoopParts ')' statement
-   *     ;
-   *  </pre>
-   */
-  private DartWhileStatement parseWhileStatement() {
-    beginWhileStatement();
-    expect(Token.WHILE);
-    expect(Token.LPAREN);
-    DartExpression condition = parseExpression();
-    expectCloseParen();
-    int closeParenOffset = ctx.getTokenLocation().getBegin();
-    DartStatement body = parseLoopStatement();
-    return done(new DartWhileStatement(condition, closeParenOffset, body));
-  }
-
-  /**
-   * <pre>
-   * iterationStatement
-   *     : WHILE '(' expression ')' statement
-   *     | DO statement WHILE '(' expression ')' ';'
-   *     | FOR '(' forLoopParts ')' statement
-   *     ;
-   *  </pre>
-   */
-  private DartDoWhileStatement parseDoWhileStatement() {
-    beginDoStatement();
-    expect(Token.DO);
-    DartStatement body = parseLoopStatement();
-    expect(Token.WHILE);
-    expect(Token.LPAREN);
-    DartExpression condition = parseExpression();
-    expectCloseParen();
-    expectStatmentTerminator();
-    return done(new DartDoWhileStatement(condition, body));
-  }
-
-  /**
-   * Use this wrapper to parse the body of a loop
-   *
-   * Sets up flag variables to make sure continue and break are properly
-   * marked as errors when in wrong context.
-   */
-  private DartStatement parseLoopStatement() {
-    boolean oldInLoop = inLoopStatement;
-    inLoopStatement = true;
-    try {
-      return parseStatement();
-    } finally {
-      inLoopStatement = oldInLoop;
-    }
-  }
-
-  /**
-   * <pre>
-   * iterationStatement
-   *     : WHILE '(' expression ')' statement
-   *     | DO statement WHILE '(' expression ')' ';'
-   *     | FOR '(' forLoopParts ')' statement
-   *     ;
-   *
-   * forLoopParts
-   *     : forInitializerStatement expression? ';' expressionList?
-   *     | constVarOrType? identifier IN expression
-   *     ;
-   *
-   * forInitializerStatement
-   *     : initializedVariableDeclaration ';'
-   *     | expression? ';'
-   *     ;
-   * </pre>
-   */
-  private DartStatement parseForStatement() {
-    beginForStatement();
-    expect(Token.FOR);
-    expect(Token.LPAREN);
-
-    // Setup
-    DartStatement setup = null;
-    if (peek(0) != Token.SEMICOLON) {
-      // Found a setup expression/statement
-      beginForInitialization();
-      Modifiers modifiers = Modifiers.NONE;
-      if (optional(Token.VAR)) {
-        setup = done(new DartVariableStatement(parseInitializedVariableList(), null, modifiers));
-      } else {
-        if (optional(Token.CONST)) {
-          modifiers = modifiers.makeConstant();
-        }
-        if (optional(Token.FINAL)) {
-          modifiers = modifiers.makeFinal();
-        }
-        DartTypeNode type = (peek(1) == Token.IDENTIFIER || peek(1) == Token.LT || peek(1) == Token.PERIOD)
-            ? tryTypeAnnotation() : null;
-        if (modifiers.isFinal() || type != null) {
-          setup = done(new DartVariableStatement(parseInitializedVariableList(), type, modifiers));
-        } else {
-          setup = done(new DartExprStmt(parseExpression()));
-        }
-      }
-    }
-
-    if (optional(Token.IN)) {
-      if (setup instanceof DartVariableStatement) {
-        DartVariableStatement variableStatement = (DartVariableStatement) setup;
-        List<DartVariable> variables = variableStatement.getVariables();
-        if (variables.size() != 1) {
-          reportError(variables.get(1), ParserErrorCode.FOR_IN_WITH_MULTIPLE_VARIABLES);
-        }
-        DartExpression initializer = variables.get(0).getValue();
-        if (initializer != null) {
-          reportError(initializer, ParserErrorCode.FOR_IN_WITH_VARIABLE_INITIALIZER);
-        }
-      } else {
-        DartExpression expression = ((DartExprStmt) setup).getExpression();
-        if (!(expression instanceof DartIdentifier)) {
-          reportError(setup, ParserErrorCode.FOR_IN_WITH_COMPLEX_VARIABLE);
-        }
-      }
-
-      DartExpression iterable = parseExpression();
-      expectCloseParen();
-      int closeParenOffset = ctx.getTokenLocation().getBegin();
-
-      DartStatement body = parseLoopStatement();
-      return done(new DartForInStatement(setup, iterable, closeParenOffset, body));
-
-    } else if (optional(Token.SEMICOLON)) {
-
-      // Condition
-      DartExpression condition = null;
-      if (peek(0) != Token.SEMICOLON) {
-        condition = parseExpression();
-      }
-      expect(Token.SEMICOLON);
-
-      // Next
-      DartExpression next = null;
-      if (peek(0) != Token.RPAREN) {
-        next = parseExpressionList();
-      }
-      expectCloseParen();
-      int closeParenOffset = ctx.getTokenLocation().getBegin();
-
-      DartStatement body = parseLoopStatement();
-      return done(new DartForStatement(setup, condition, next, closeParenOffset, body));
-    } else {
-      reportUnexpectedToken(position(), null, peek(0));
-      return done(parseErrorStatement());
-    }
-  }
-
-  /**
-   * <pre>
-   * selectionStatement
-   *    : IF '(' expression ')' statement ((ELSE)=> ELSE statement)?
-   *    | SWITCH '(' expression ')' '{' switchCase* defaultCase? '}'
-   *    ;
-   * </pre>
-   */
-  private DartIfStatement parseIfStatement() {
-    beginIfStatement();
-    expect(Token.IF);
-    expect(Token.LPAREN);
-    DartExpression condition = parseExpression();
-    expectCloseParen();
-    int closeParenOffset = ctx.getTokenLocation().getBegin();
-    DartStatement yes = parseStatement();
-    DartStatement no = null;
-    int elseTokenOffset = 0;
-    if (optional(Token.ELSE)) {
-      elseTokenOffset = ctx.getTokenLocation().getBegin();
-      no = parseStatement();
-    }
-    return done(new DartIfStatement(condition, closeParenOffset, yes, elseTokenOffset, no));
-  }
-
-  /**
-   * <pre>
-   * caseStatements
-   *    : normalCompletingStatement* abruptCompletingStatement
-   *    ;
-   * </pre>
-   */
-  private List<DartStatement> parseCaseStatements() {
-    List<DartStatement> statements = new ArrayList<DartStatement>();
-    DartStatement statement = null;
-    boolean endOfCaseFound = false;
-    boolean warnedUnreachable = false;
-    while (true) {
-      switch (peek(0)) {
-        case CLASS:
-          // exit loop to report error condition
-        case CASE:
-        case DEFAULT:
-        case RBRACE:
-        case EOS:
-          return statements;
-        case IDENTIFIER:
-          // Handle consecutively labeled case statements
-          if (isCaseOrDefault()) {
-            return statements;
-          }
-        default:
-          boolean oldInCaseStatement = inCaseStatement;
-          inCaseStatement = true;
-          try {
-            if (endOfCaseFound && !warnedUnreachable) {
-              reportErrorWithoutAdvancing(ParserErrorCode.UNREACHABLE_CODE_IN_CASE);
-              warnedUnreachable = true;
-            }
-            statement = parseStatement();
-          } finally {
-            inCaseStatement = oldInCaseStatement;
-          }
-          if (statement == null) {
-            return statements;
-          }
-
-          // Don't add unreachable code to the list of statements.
-          if (!endOfCaseFound) {
-            statements.add(statement);
-            if (statement.isAbruptCompletingStatement()) {
-              endOfCaseFound = true;
-            }
-          }
-      }
-    }
-  }
-
-  private boolean isCaseOrDefault() {
-    int index = 0;
-    while (peek(index) == Token.IDENTIFIER && peek(index + 1) == Token.COLON) {
-      index += 2;
-    }
-    Token next = peek(index);
-    return next == Token.CASE || next == Token.DEFAULT;
-  }
-
-  /**
-   * <pre>
-   * switchCase
-   *    : label? (CASE expression ':')+ caseStatements
-   *    ;
-   * </pre>
-   */
-  private DartSwitchMember parseCaseMember(List<DartLabel> labels) {
-    // The begin() associated with the done() in this method is in the method
-    // parseSwitchStatement(), called by beginSwitchMember().
-    expect(Token.CASE);
-    DartExpression caseExpr = parseExpression();
-    expect(Token.COLON);
-    return done(new DartCase(caseExpr, labels, parseCaseStatements()));
-  }
-
-  /**
-   * <pre>
-   * defaultCase
-   *    : label? (CASE expression ':')* DEFAULT ':' caseStatements
-   *    ;
-   * </pre>
-   */
-  private DartSwitchMember parseDefaultMember(List<DartLabel> labels) {
-    // The begin() associated with the done() in this method is in the method
-    // parseSwitchStatement(), called by beginSwitchMember().
-    expect(Token.DEFAULT);
-    expect(Token.COLON);
-    return done(new DartDefault(labels, parseCaseStatements()));
-  }
-
-
-  /**
-   * <pre>
-   * selectionStatement
-   *    : IF '(' expression ')' statement ((ELSE)=> ELSE statement)?
-   *    | SWITCH '(' expression ')' '{' switchCase* defaultCase? '}'
-   *    ;
-   * </pre>
-   */
-  private DartStatement parseSwitchStatement() {
-    beginSwitchStatement();
-    expect(Token.SWITCH);
-
-    expect(Token.LPAREN);
-    DartExpression expr = parseExpression();
-    expectCloseParen();
-
-    List<DartSwitchMember> members = new ArrayList<DartSwitchMember>();
-    if (peek(0) != Token.LBRACE) {
-      reportUnexpectedToken(position(), Token.LBRACE, peek(0));
-      return done(new DartSwitchStatement(expr, members));
-    }
-    boolean foundOpenBrace = expect(Token.LBRACE);
-
-    boolean done = optional(Token.RBRACE);
-    while (!done) {
-      List<DartLabel> labels = new ArrayList<DartLabel>();
-      beginSwitchMember(); // switch member
-      while (peek(0) == Token.IDENTIFIER && peek(1) == Token.COLON) {
-        beginLabel();
-        DartIdentifier identifier = parseIdentifier();
-        expect(Token.COLON);
-        labels.add(done(new DartLabel(identifier, null)));
-        if (peek(0) == Token.RBRACE) {
-          reportError(position(), ParserErrorCode.LABEL_NOT_FOLLOWED_BY_CASE_OR_DEFAULT);
-          expectCloseBrace(foundOpenBrace);
-          return done(new DartSwitchStatement(expr, members));
-        }
-      }
-      if (peek(0) == Token.CASE) {
-        members.add(parseCaseMember(labels));
-      } else if (optional(Token.RBRACE)) {
-        if (!labels.isEmpty()) {
-          reportError(position(), ParserErrorCode.EXPECTED_CASE_OR_DEFAULT);
-        }
-        done = true;
-        done(null);
-      } else {
-        if (peek(0) == Token.DEFAULT) {
-          members.add(parseDefaultMember(labels));
-        }
-        expectCloseBrace(foundOpenBrace);
-        done = true; // Ensure termination.
-      }
-    }
-    return done(new DartSwitchStatement(expr, members));
-  }
-
-  /**
-   * <pre>
-   * catchParameter
-   *    : FINAL type? identifier
-   *    | VAR identifier
-   *    | type identifier
-   *    ;
-   *  </pre>
-   */
-  private DartParameter parseCatchParameter() {
-    beginCatchParameter();
-    List<DartAnnotation> metadata = parseMetadata();
-    DartTypeNode type = null;
-    Modifiers modifiers = Modifiers.NONE;
-    boolean isDeclared = false;
-    if (optional(Token.VAR)) {
-      isDeclared = true;
-    } else {
-      if (optional(Token.FINAL)) {
-        modifiers = modifiers.makeFinal();
-        isDeclared = true;
-      }
-      if (peek(1) != Token.COMMA && peek(1) != Token.RPAREN) {
-        type = parseTypeAnnotation();
-        isDeclared = true;
-      }
-    }
-    DartIdentifier name = parseIdentifier();
-    if (!isDeclared) {
-      reportError(name, ParserErrorCode.EXPECTED_VAR_FINAL_OR_TYPE);
-    }
-    DartParameter parameter = done(new DartParameter(name, type, null, null, modifiers));
-    setMetadata(parameter, metadata);
-    return parameter;
-  }
-
-  /**
-   * Parse either the old try statement syntax:
-   * <pre>
-   * tryStatement
-   *     : TRY block (catchPart+ finallyPart? | finallyPart)
-   *     ;
-   *
-   * catchPart
-   *     : CATCH '(' declaredIdentifier (',' declaredIdentifier)? ')' block
-   *     ;
-   *
-   * finallyPart
-   *     : FINALLY block
-   *     ;
-   * </pre>
-   * or the new syntax:
-   * <pre>
-   * tryStatement
-   *     : TRY block (onPart+ finallyPart? | finallyPart)
-   *     ;
-   *
-   * onPart
-   *     : catchPart block
-   *     | ON qualified catchPart? block
-   *
-   * catchPart
-   *     : CATCH '(' identifier (',' identifier)? ')'
-   *     ;
-   *
-   * finallyPart
-   *     : FINALLY block
-   *     ;
-   * </pre>
-   */
-  private DartTryStatement parseTryStatement() {
-    beginTryStatement();
-    // Try.
-    expect(Token.TRY);
-    // TODO(zundel): It would be nice here to setup 'ON', 'CATCH' and 'FINALLY' as tokens for recovery
-    DartBlock tryBlock = parseBlock();
-
-    List<DartCatchBlock> catches = new ArrayList<DartCatchBlock>();
-    while (peekPseudoKeyword(0, ON_KEYWORD) || match(Token.CATCH)) {
-      // TODO(zundel): It would be nice here to setup 'FINALLY' as token for recovery
-      if (peekPseudoKeyword(0, ON_KEYWORD)) {
-        beginCatchClause();
-        next();
-        int onTokenOffset = position();
-        DartTypeNode exceptionType = parseTypeAnnotation();
-        DartParameter exception = null;
-        DartParameter stackTrace = null;
-        if (optional(Token.CATCH)) {
-          expect(Token.LPAREN);
-          beginCatchParameter();
-          List<DartAnnotation> metadata = parseMetadata();
-          DartIdentifier exceptionName = parseIdentifier();
-          exception = done(new DartParameter(exceptionName, exceptionType, null, null, Modifiers.NONE));
-          setMetadata(exception, metadata);
-          if (optional(Token.COMMA)) {
-            beginCatchParameter();
-            DartIdentifier stackName = parseIdentifier();
-            stackTrace = done(new DartParameter(stackName, null, null, null, Modifiers.NONE));
-          }
-          expectCloseParen();
-        } else {
-          // Create a dummy identifier that the user cannot reliably reference.
-          beginCatchParameter();
-          List<DartAnnotation> metadata = parseMetadata();
-          beginIdentifier();
-          DartIdentifier exceptionName = done(new DartIdentifier("e" + Long.toHexString(System.currentTimeMillis())));
-          exception = done(new DartParameter(exceptionName, exceptionType, null, null, Modifiers.NONE));
-          setMetadata(exception, metadata);
-        }
-        DartBlock block = parseBlock();
-        catches.add(done(new DartCatchBlock(block, onTokenOffset, exception, stackTrace)));
-      } else {
-        beginCatchClause();
-        next();
-        expect(Token.LPAREN);
-        DartParameter exception;
-        if (match(Token.IDENTIFIER) && (peek(1) == Token.COMMA || peek(1) == Token.RPAREN)) {
-          beginCatchParameter();
-          List<DartAnnotation> metadata = parseMetadata();
-          DartIdentifier exceptionName = parseIdentifier();
-          exception = done(new DartParameter(exceptionName, null , null, null, Modifiers.NONE));
-          setMetadata(exception, metadata);
-        } else {
-          // Old-style parameter
-          reportError(position(), ParserErrorCode.DEPRECATED_CATCH);
-          exception = parseCatchParameter();
-        }
-        DartParameter stackTrace = null;
-        if (optional(Token.COMMA)) {
-          if (match(Token.IDENTIFIER) && peek(1) == Token.RPAREN) {
-            beginCatchParameter();
-            List<DartAnnotation> metadata = parseMetadata();
-            DartIdentifier stackName = parseIdentifier();
-            stackTrace = done(new DartParameter(stackName, null, null, null, Modifiers.NONE));
-            setMetadata(stackTrace, metadata);
-          } else {
-            // Old-style parameter
-            reportError(position(), ParserErrorCode.DEPRECATED_CATCH);
-            stackTrace = parseCatchParameter();
-          }
-        }
-        expectCloseParen();
-        DartBlock block = parseBlock();
-        catches.add(done(new DartCatchBlock(block, -1, exception, stackTrace)));
-      }
-    }
-
-    // Finally.
-    DartBlock finallyBlock = null;
-    if (optional(Token.FINALLY)) {
-      finallyBlock = parseBlock();
-    }
-
-    if ( catches.size() == 0 && finallyBlock == null) {
-      reportError(new DartCompilationError(tryBlock.getSourceInfo().getSource(), new Location(position()),
-        ParserErrorCode.CATCH_OR_FINALLY_EXPECTED));
-    }
-
-    return done(new DartTryStatement(tryBlock, catches, finallyBlock));
-  }
-
-  /**
-   * <pre>
-   * unaryExpression
-   *     : postfixExpression
-   *     | prefixOperator unaryExpression
-   *     | incrementOperator assignableExpression
-   *     ;
-   *
-   *  @return an expression or null if noFail is true and the next tokens could not be parsed as an
-   *      expression, leaving the state unchanged.
-   *  </pre>
-   */
-  private DartExpression parseUnaryExpression() {
-    // There is no unary plus operator in Dart.
-    // However, we allow a leading plus in decimal numeric literals.
-    if (optional(Token.ADD)) {
-      if (peek(0) != Token.INTEGER_LITERAL && peek(0) != Token.DOUBLE_LITERAL) {
-        reportError(position(), ParserErrorCode.NO_UNARY_PLUS_OPERATOR);
-      } else if (position() + 1 != peekTokenLocation(0).getBegin()) {
-        reportError(position(), ParserErrorCode.NO_SPACE_AFTER_PLUS);
-      }
-    }
-    // Check for unary minus operator.
-    Token token = peek(0);
-    if (token.isUnaryOperator() || token == Token.SUB) {
-      if (token == Token.DEC && peek(1) == Token.SUPER) {
-        beginUnaryExpression();
-        beginUnaryExpression();
-        consume(token);
-        int tokenOffset = ctx.getTokenLocation().getBegin();
-        DartExpression unary = parseUnaryExpression();
-        DartUnaryExpression unary2 = new DartUnaryExpression(Token.SUB, tokenOffset, unary, true);
-        return done(new DartUnaryExpression(Token.SUB, tokenOffset, done(unary2), true));
-      } else {
-        beginUnaryExpression();
-        consume(token);
-        int tokenOffset = ctx.getTokenLocation().getBegin();
-        DartExpression unary = parseUnaryExpression();
-        if (token.isCountOperator()) {
-          ensureAssignable(unary);
-        }
-        return done(new DartUnaryExpression(token, tokenOffset, unary, true));
-      }
-    } else {
-      return parsePostfixExpression();
-    }
-  }
-
-  /**
-   * <pre>
-   * type
-   *     : qualified typeArguments?
-   *     ;
-   * </pre>
-   */
-  private DartTypeNode parseTypeAnnotation() {
-    beginTypeAnnotation();
-    return done(new DartTypeNode(parseQualified(false), parseTypeArgumentsOpt()));
-  }
-
-  /**
-   * <pre>
-   * type
-   *     : qualified typeArguments? ('.' identifier)?
-   *     ;
-   * </pre>
-   */
-  private DartTypeNode parseTypeAnnotationPossiblyFollowedByName() {
-    beginTypeAnnotation();
-    boolean canBeFollowedByPeriod = true;
-    if (peek(Token.IDENTIFIER, Token.LT) || peek(Token.IDENTIFIER, Token.PERIOD, Token.IDENTIFIER, Token.LT)) {
-      canBeFollowedByPeriod = false;
-    }
-    return done(new DartTypeNode(parseQualified(canBeFollowedByPeriod), parseTypeArgumentsOpt()));
-  }
-
-  private boolean peek(Token... tokens) {
-    int index = 0;
-    for (Token token : tokens) {
-      if (peek(index++) != token) {
-        return false;
-      }
-    }
-    return true;
-  }
-
-  /**
-   * <pre>
-   * typeArguments
-   *     : '<' typeList '>'
-   *     ;
-   *
-   * typeList
-   *     : type (',' type)*
-   *     ;
-   * </pre>
-   */
-  @Terminals(tokens={Token.GT, Token.COMMA})
-  private List<DartTypeNode> parseTypeArguments() {
-    consume(Token.LT);
-    List<DartTypeNode> arguments = new ArrayList<DartTypeNode>();
-    do {
-      arguments.add(parseTypeAnnotation());
-    } while (optional(Token.COMMA));
-    if (!tryParameterizedTypeEnd()) {
-      expect(Token.GT);
-    }
-    return arguments;
-  }
-
-  /**
-   * <pre>
-   * typeArguments?
-   * </pre>
-   */
-  private List<DartTypeNode> parseTypeArgumentsOpt() {
-    return (peek(0) == Token.LT)
-        ? parseTypeArguments()
-        : Collections.<DartTypeNode>emptyList();
-  }
-
-  /**
-   * <pre>
-   * qualified
-   *     : identifier ('.' identifier)?
-   *     ;
-   * </pre>
-   */
-  private DartExpression parseQualified(boolean canBeFollowedByPeriod) {
-    beginQualifiedIdentifier();
-    DartIdentifier identifier = parseIdentifier();
-    if (!prefixes.contains(identifier.getName())) {
-      if (canBeFollowedByPeriod && !(peek(0) == Token.PERIOD && peek(1) == Token.IDENTIFIER && peek(2) == Token.PERIOD)) {
-        return done(identifier);
-      }
-    }
-    DartExpression qualified = identifier;
-    if (optional(Token.PERIOD)) {
-      // The previous identifier was a prefix.
-      qualified = new DartPropertyAccess(qualified, parseIdentifier());
-    }
-    return done(qualified);
-  }
-
-  private boolean tryParameterizedTypeEnd() {
-    switch (peek(0)) {
-      case GT:
-        consume(Token.GT);
-        return true;
-      case SAR:
-        setPeek(0, Token.GT);
-        return true;
-      default:
-        return false;
-    }
-  }
-
-  private DartTypeNode tryTypeAnnotation() {
-    if (peek(0) != Token.IDENTIFIER) {
-      return null;
-    }
-    List<DartTypeNode> typeArguments = new ArrayList<DartTypeNode>();
-    beginTypeAnnotation(); // to allow roll-back in case we're not at a type
-
-    DartNode qualified = parseQualified(false);
-
-    if (optional(Token.LT)) {
-      if (peek(0) != Token.IDENTIFIER) {
-        rollback();
-        return null;
-      }
-      beginTypeArguments();
-      DartNode qualified2 = parseQualified(false);
-      DartTypeNode argument;
-      switch (peek(0)) {
-        case LT:
-          // qualified < qualified2 <
-          argument = done(new DartTypeNode(qualified2, parseTypeArguments()));
-          break;
-
-        case GT:
-        case SAR:
-          // qualified < qualified2 >
-        case COMMA:
-          // qualified < qualified2 ,
-          argument = done(new DartTypeNode(qualified2, Collections.<DartTypeNode>emptyList()));
-          break;
-
-        default:
-          done(null);
-          rollback();
-          return null;
-      }
-      typeArguments.add(argument);
-
-      while (optional(Token.COMMA)) {
-        typeArguments.add(parseTypeAnnotation());
-      }
-      if (!tryParameterizedTypeEnd()) {
-        expect(Token.GT);
-      }
-    }
-
-    return done(new DartTypeNode(qualified, typeArguments));
-  }
-
-  private DartIdentifier parseIdentifier() {
-    beginIdentifier();
-    if (looksLikeTopLevelKeyword()) {
-      reportErrorWithoutAdvancing(ParserErrorCode.EXPECTED_IDENTIFIER);
-      return done(new DartSyntheticErrorIdentifier());
-    }
-    DartIdentifier identifier;
-    if (expect(Token.IDENTIFIER) && ctx.getTokenString() != null) {
-      identifier = new DartIdentifier(new String(ctx.getTokenString()));
-    } else {
-      identifier = new DartSyntheticErrorIdentifier();
-    }
-    return done(identifier);
-  }
-
-  public DartExpression parseEntryPoint() {
-    beginEntryPoint();
-    DartExpression entry = parseIdentifier();
-    while (!EOS()) {
-      expect(Token.PERIOD);
-      entry = doneWithoutConsuming(new DartPropertyAccess(entry, parseIdentifier()));
-    }
-    return done(entry);
-  }
-
-  private void ensureAssignable(DartExpression expression) {
-    if (expression != null && !expression.isAssignable()) {
-      reportError(position(), ParserErrorCode.ILLEGAL_ASSIGNMENT_TO_NON_ASSIGNABLE);
-    }
-  }
-
-  /**
-   * Increment the number of errors encountered while parsing this compilation unit. Returns whether
-   * the current error should be reported.
-   * 
-   * @return whether the current error should be reported
-   */
-  private boolean incErrorCount(ErrorCode errorCode) {
-    // count only errors, but not warnings (such as "abstract")
-    if (errorCode.getErrorSeverity() == ErrorSeverity.ERROR) {
-      errorCount++;
-    }
-    
-    if (errorCount >= MAX_DEFAULT_ERRORS) {
-      if (errorCount == MAX_DEFAULT_ERRORS) {
-        // Create a 'too many errors' error.
-        DartCompilationError dartError = new DartCompilationError(ctx.getSource(),
-            ctx.getTokenLocation(), ParserErrorCode.NO_SOUP_FOR_YOU);
-        ctx.error(dartError);
-      }
-      
-      // Consume the rest of the input stream. Throwing an exception - as suggested elsewhere in
-      // this file - is not ideal.
-      Token next = next();
-      
-      while (next != null && next != Token.EOS) {
-        next = next();
-      }
-    }
-    
-    return errorCount < MAX_DEFAULT_ERRORS;
-  }
-  
-  private void reportDeprecatedError(int position, ErrorCode errorCode) {
-    // TODO(scheglov) remove after http://code.google.com/p/dart/issues/detail?id=6508
-    if (
-        true
-        && !Elements.isCoreLibrarySource(source)
-        && !Elements.isLibrarySource(source, "/isolate/isolate.dart")
-        && !Elements.isLibrarySource(source, "/json/json.dart")
-        && !Elements.isLibrarySource(source, "/math/math.dart")
-        && !Elements.isLibrarySource(source, "/io/io.dart")
-        && !Elements.isLibrarySource(source, "/crypto/crypto.dart")
-        && !Elements.isLibrarySource(source, "/uri/uri.dart")
-        && !Elements.isLibrarySource(source, "/utf/utf.dart")
-        && !Elements.isLibrarySource(source, "/typed_data/typed_data.dart")
-        ) {
-      super.reportError(position, errorCode);
-    }
-  }
-  
-  @Override
-  protected void reportError(int position, ErrorCode errorCode, Object... arguments) {
-    // TODO(devoncarew): we're not correctly identifying dart:html as a core library
-    if (incErrorCount(errorCode)) {
-      super.reportError(position, errorCode, arguments);
-    }
-  }
-
-  @Override
-  protected void reportErrorAtPosition(int startPosition, int endPosition,
-      ErrorCode errorCode, Object... arguments) {
-    if (incErrorCount(errorCode)) {
-      super.reportErrorAtPosition(startPosition, endPosition, errorCode, arguments);
-    }
-  }
-
-  private void reportError(DartCompilationError dartError) {
-    if (incErrorCount(dartError.getErrorCode())) {
-      ctx.error(dartError);
-      errorHistory.add(dartError.hashCode());
-    }
-  }
-
-  private void reportError(DartNode node, ErrorCode errorCode, Object... arguments) {
-    if (node != null) {
-      reportError(new DartCompilationError(node, errorCode, arguments));
-    }
-  }
-
-  private boolean currentlyParsingToplevel() {
-    return   !(isParsingInterface || isTopLevelAbstract || isParsingClass);
-  }
-  
-  /**
-   * @return <code>true</code> if current token is built-in identifier which can have special
-   * meaning. For example if it is used as import prefix, this is not special meaning, this is just
-   * normal identifier.
-   */
-  private boolean isBuiltInSpecial() {
-    Token nextToken = peek(1);
-    if (nextToken == Token.LT) {
-      return peek(2) != Token.IDENTIFIER;
-    }
-    return nextToken != Token.PERIOD && nextToken != Token.LPAREN;
-  }
-}
diff --git a/compiler/java/com/google/dart/compiler/parser/DartParserCommentsHelper.java b/compiler/java/com/google/dart/compiler/parser/DartParserCommentsHelper.java
deleted file mode 100644
index 46654c3..0000000
--- a/compiler/java/com/google/dart/compiler/parser/DartParserCommentsHelper.java
+++ /dev/null
@@ -1,289 +0,0 @@
-// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.parser;
-
-import com.google.common.collect.Lists;
-import com.google.dart.compiler.DartCompilerListener;
-import com.google.dart.compiler.Source;
-import com.google.dart.compiler.ast.ASTVisitor;
-import com.google.dart.compiler.ast.DartComment;
-import com.google.dart.compiler.ast.DartCommentNewName;
-import com.google.dart.compiler.ast.DartCommentRefName;
-import com.google.dart.compiler.ast.DartDeclaration;
-import com.google.dart.compiler.ast.DartField;
-import com.google.dart.compiler.ast.DartMethodDefinition;
-import com.google.dart.compiler.ast.DartNode;
-import com.google.dart.compiler.ast.DartUnit;
-import com.google.dart.compiler.common.SourceInfo;
-import com.google.dart.compiler.metrics.CompilerMetrics;
-import com.google.dart.compiler.util.apache.StringUtils;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.List;
-
-/**
- * A parser for Dart that records comment positions.
- */
-public class DartParserCommentsHelper {
-
-  static class CommentParserContext extends DartScannerParserContext {
-
-    private List<int[]> commentLocs;
-
-    CommentParserContext(Source source, String code, DartCompilerListener listener,
-        CompilerMetrics metrics) {
-      super(source, code, listener, metrics);
-    }
-
-    List<int[]> getCommentLocs() {
-      return commentLocs;
-    }
-
-    @Override
-    protected DartScanner createScanner(String sourceCode, Source source,
-        DartCompilerListener listener) {
-      commentLocs = Lists.newArrayList();
-      return new CommentScanner(sourceCode, 0, source, listener);
-    }
-
-    private class CommentScanner extends DartScanner {
-
-      CommentScanner(String sourceCode, int start, Source sourceReference,
-          DartCompilerListener listener) {
-        super(sourceCode, start, sourceReference, listener);
-      }
-
-      @Override
-      protected void recordCommentLocation(int start, int stop) {
-        int size = commentLocs.size();
-        if (size > 0) {
-          // the parser may re-scan lookahead tokens
-          // fortunately, comments are always scanned as comments
-          int[] loc = commentLocs.get(size - 1);
-          if (start <= loc[0] && stop <= loc[1]) {
-            return;
-          }
-        }
-        commentLocs.add(new int[] {start, stop});
-      }
-    }
-  }
-
-  static void addComments(DartUnit unit, Source source, String sourceCode, List<int[]> commentLocs) {
-    for (int[] loc : commentLocs) {
-      int start = loc[0];
-      int length = loc[1] - start;
-      DartComment.Style style = getCommentStyle(sourceCode, start);
-      unit.getComments().add(new DartComment(source, start, length, style));
-    }
-    List<DartComment> comments = unit.getComments();
-    if (comments != null) {
-      assignDartComments(unit, sourceCode, comments);
-    }
-  }
-
-  private static void assignDartComments(DartUnit unit, String sourceCode,
-      List<DartComment> comments) {
-    // Collect the AST nodes in a list.
-    final List<DartNode> astNodes = new ArrayList<DartNode>();
-    unit.accept(new ASTVisitor<DartNode>() {
-      @Override
-      public DartNode visitDeclaration(DartDeclaration<?> node) {
-        astNodes.add(node);
-        // Avoid NPE in visitors because of missing part. 
-        try {
-          super.visitDeclaration(node);
-        } catch (NullPointerException e) {
-        }
-        // No result.
-        return null;
-      }
-    });
-
-    // Collect all the nodes in one list.
-    List<DartNode> nodes = new ArrayList<DartNode>();
-
-    nodes.addAll(comments);
-    nodes.addAll(astNodes);
-
-    // Sort the nodes by their position in the source file.
-    Collections.sort(nodes, new Comparator<DartNode>() {
-      @Override
-      public int compare(DartNode node1, DartNode node2) {
-        return node1.getSourceInfo().getOffset() - node2.getSourceInfo().getOffset();
-      }
-    });
-
-    // Assign dart docs to their associated DartDeclarations.
-    for (int i = 0; i < nodes.size(); i++) {
-      DartNode node = nodes.get(i);
-      if (node instanceof DartComment) {
-        DartComment comment = (DartComment) node;
-        // prepare next declaration
-        DartDeclaration<?> decl = null;
-        {
-          int delta = 1;
-          while (i + delta < nodes.size()) {
-            DartNode next = nodes.get(i + delta);
-            // skip all comments
-            if (next instanceof DartComment) {
-              delta++;
-              continue;
-            }
-            // declaration found
-            if (next instanceof DartDeclaration) {
-              decl = (DartDeclaration<?>) next;
-              if (!commentContainedBySibling(comment, decl)) {
-                if (i + 2 < nodes.size()) {
-                  decl = adjustDartdocTarget(next, nodes.get(i + 2));
-                }
-              }
-              break;
-            }
-            // something other than declaration
-            break;
-          }
-        }
-        // apply comment to declaration
-        if (decl != null) {
-          String commentStr = sourceCode.substring(comment.getSourceInfo().getOffset(),
-              comment.getSourceInfo().getEnd());
-          tokenizeComment(comment, commentStr);
-          // DartDoc
-          if (comment.isDartDoc()) {
-            decl.setDartDoc(comment);
-          }
-        }
-      }
-    }
-  }
-
-  private static void tokenizeComment(DartComment comment, String src) {
-    int lastIndex = 0;
-    while (true) {
-      int openIndex = src.indexOf('[', lastIndex);
-      if (openIndex == -1) {
-        break;
-      }
-      int closeIndex = src.indexOf(']', openIndex);
-      if (closeIndex == -1) {
-        break;
-      }
-      lastIndex = closeIndex;
-      String tokenSrc = src.substring(openIndex + 1, closeIndex);
-      if (tokenSrc.startsWith(":") && tokenSrc.endsWith(":")) {
-        // TODO(scheglov) [:code:] and 'code'
-      } else if (tokenSrc.startsWith("new ")) {
-        SourceInfo sourceInfo = comment.getSourceInfo();
-        int offset = sourceInfo.getOffset() + openIndex;
-        int classOffset = offset + "[".length();
-        // remove leading "new "
-        String name = StringUtils.remove(tokenSrc, "new ");
-        classOffset += "new ".length();
-        // remove spaces
-        {
-          String stripName = StringUtils.stripStart(name, null);
-          classOffset += name.length() - stripName.length();
-          name = stripName;
-        }
-        name = name.trim();
-        //
-        String className = StringUtils.substringBefore(name, ".");
-        String constructorName = StringUtils.substringAfter(name, ".");
-        int constructorOffset = classOffset + className.length() + ".".length();
-        DartCommentNewName newNode = new DartCommentNewName(className, classOffset,
-            constructorName, constructorOffset);
-        {
-          Source source = sourceInfo.getSource();
-          int length = tokenSrc.length() + "[]".length();
-          newNode.setSourceInfo(new SourceInfo(source, offset, length));
-        }
-        // add node
-        comment.addNewName(newNode);
-      } else {
-        String name = tokenSrc.trim();
-        DartCommentRefName refNode = new DartCommentRefName(name);
-        {
-          SourceInfo sourceInfo = comment.getSourceInfo();
-          Source source = sourceInfo.getSource();
-          int offset = sourceInfo.getOffset() + openIndex;
-          int length = name.length() + "[]".length();
-          refNode.setSourceInfo(new SourceInfo(source, offset, length));
-        }
-        comment.addRefName(refNode);
-      }
-    }
-  }
-
-  private static DartDeclaration<?> adjustDartdocTarget(DartNode currentNode, DartNode nextNode) {
-    if (currentNode instanceof DartField && nextNode instanceof DartMethodDefinition) {
-      if (currentNode.getSourceInfo().equals(nextNode.getSourceInfo())) {
-        return (DartDeclaration<?>) nextNode;
-      }
-    }
-
-    return (DartDeclaration<?>) currentNode;
-  }
-
-  /**
-   * DartC creates both a {@link DartField} and a {@link DartMethodDefinition} for getters and
-   * setters. They have the same source location; we want to assign the DartDoc to the method
-   * definition and not the field.
-   */
-  private static boolean commentContainedBySibling(DartComment comment, DartDeclaration<?> node) {
-    if (node instanceof DartField) {
-      for (DartNode child : getChildren(node.getParent())) {
-        if (child != node && !(child instanceof DartComment)) {
-          if (isContainedBy(comment, child)) {
-            return true;
-          }
-        }
-      }
-    }
-    return false;
-  }
-
-  private static List<DartNode> getChildren(DartNode parent) {
-    final List<DartNode> children = new ArrayList<DartNode>();
-
-    parent.visitChildren(new ASTVisitor<DartNode>() {
-      @Override
-      public DartNode visitNode(DartNode node) {
-        children.add(node);
-        return null;
-      }
-    });
-
-    return children;
-  }
-
-  private static boolean isContainedBy(DartNode node, DartNode containedByNode) {
-    SourceInfo nodeSource = node.getSourceInfo();
-    SourceInfo containedBySource = containedByNode.getSourceInfo();
-    int nodeEnd = nodeSource.getOffset() + nodeSource.getLength();
-    int containedByEnd = containedBySource.getOffset() + containedBySource.getLength();
-    return nodeSource.getOffset() >= containedBySource.getOffset() && nodeEnd <= containedByEnd;
-  }
-
-  /**
-   * Return the style of the comment in the given string.
-   * 
-   * @param sourceString the source containing the comment
-   * @param commentStart the location of the comment in the source
-   * @return the style of the comment in the given string
-   */
-  private static DartComment.Style getCommentStyle(String sourceString, int commentStart) {
-    boolean hasMore1 = commentStart + 1 < sourceString.length();
-    boolean hasMore2 = commentStart + 2 < sourceString.length();
-    if (hasMore1 && sourceString.charAt(commentStart + 1) == '/') {
-      return DartComment.Style.END_OF_LINE;
-    } else if (hasMore2 && sourceString.charAt(commentStart + 2) == '*') {
-      return DartComment.Style.DART_DOC;
-    }
-    return DartComment.Style.BLOCK;
-  }
-}
diff --git a/compiler/java/com/google/dart/compiler/parser/DartPrefixParser.java b/compiler/java/com/google/dart/compiler/parser/DartPrefixParser.java
deleted file mode 100644
index 50686f9..0000000
--- a/compiler/java/com/google/dart/compiler/parser/DartPrefixParser.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Copyright 2012 Dart project authors.
- * 
- * Licensed under the Eclipse Public License v1.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.eclipse.org/legal/epl-v10.html
- * 
- * 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.dart.compiler.parser;
-
-import com.google.dart.compiler.DartCompilerListener;
-import com.google.dart.compiler.Source;
-import com.google.dart.compiler.ast.DartIdentifier;
-import com.google.dart.compiler.ast.DartImportDirective;
-import com.google.dart.compiler.ast.DartStringLiteral;
-import com.google.dart.compiler.metrics.CompilerMetrics;
-
-import java.util.Set;
-
-/**
- * An extension of {@link DartParser} that updates the prefixes collection
- */
-public class DartPrefixParser extends DartParser {
-
-  private final Set<String> prefixes;
-
-  public DartPrefixParser(
-      Source source,
-      String sourceCode,
-      boolean isDietParse,
-      Set<String> prefixes,
-      DartCompilerListener listener,
-      CompilerMetrics compilerMetrics) {
-    super(source, sourceCode, isDietParse, prefixes, listener, compilerMetrics);
-    this.prefixes = prefixes;
-  }
-
-  @Override
-  protected DartImportDirective parseImportDirective() {
-    DartImportDirective directive = super.parseImportDirective();
-    DartIdentifier prefix = directive.getPrefix();
-    if (prefix != null) {
-      prefixes.add(prefix.getName());
-    }
-    return directive;
-  }
-
-  @SuppressWarnings("deprecation")
-  @Override
-  protected DartImportDirective parseObsoleteImportDirective() {
-    DartImportDirective directive = super.parseObsoleteImportDirective();
-    DartStringLiteral oldPrefix = directive.getOldPrefix();
-    if (oldPrefix != null) {
-      prefixes.add(oldPrefix.getValue());
-    }
-    return directive;
-  }
-}
- 
\ No newline at end of file
diff --git a/compiler/java/com/google/dart/compiler/parser/DartScanner.java b/compiler/java/com/google/dart/compiler/parser/DartScanner.java
deleted file mode 100644
index a019d93..0000000
--- a/compiler/java/com/google/dart/compiler/parser/DartScanner.java
+++ /dev/null
@@ -1,1361 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.parser;
-
-import com.google.dart.compiler.DartCompilationError;
-import com.google.dart.compiler.DartCompilerListener;
-import com.google.dart.compiler.Source;
-import com.google.dart.compiler.common.SourceInfo;
-import com.google.dart.compiler.metrics.DartEventType;
-import com.google.dart.compiler.metrics.Tracer;
-import com.google.dart.compiler.metrics.Tracer.TraceEvent;
-import com.google.dart.compiler.parser.DartScanner.InternalState.Mode;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Stack;
-
-/**
- * The Dart scanner. Should normally be used only by {@link DartParser}.
- */
-public class DartScanner {
-
-  /**
-   * Represents a span of characters in a source file.
-   */
-  public static class Location {
-    public static final Location NONE = null;
-    private int begin;
-    private int end;
-
-    public Location(int begin, int end) {
-      this.begin = begin;
-      this.end = end;
-    }
-
-    public Location(int begin) {
-      this.begin = this.end = begin;
-    }
-
-    public int getBegin() {
-      return begin;
-    }
-
-    public int getEnd() {
-      return end;
-    }
-
-    @Override
-    public String toString() {
-      return begin + "::" + end;
-    }
-  }
-
-  public static class State {
-    State(int baseOffset) {
-      this.baseOffset = baseOffset;
-    }
-
-    static class RollbackToken {
-      public final int absoluteOffset;
-      final Token replacedToken;
-
-      public RollbackToken(int tokenOffset, Token token) {
-        absoluteOffset = tokenOffset;
-        replacedToken = token;
-      }
-    }
-
-    /* Stack of tokens present before setPeek() */
-    Stack<RollbackToken> rollbackTokens = null;
-    final int baseOffset;
-
-    @Override
-    public String toString() {
-      return "ofs=" + baseOffset;
-    }
-  }
-
-  /**
-   * Stores the entire state for the scanner.
-   */
-  protected static class InternalState {
-    enum Mode {
-      DEFAULT,
-
-      IN_STRING,
-
-      /**
-       * Inside a string, scanning a string-interpolation expression.
-       * Ex: "${foo}".
-       */
-      IN_STRING_EMBEDDED_EXPRESSION,
-
-      /**
-       * Inside a string, scanning a string-interpolation identifier.
-       * <pre>
-       * Ex: "$foo bc".
-       *        ^
-       * </pre>
-       */
-      IN_STRING_EMBEDDED_EXPRESSION_IDENTIFIER,
-
-      /**
-       * Inside a string, just after having scanned a string-interpolation identifier.
-       * <pre>
-       * Ex: "$foo bc".
-       *          ^
-       * </pre>
-       */
-      IN_STRING_EMBEDDED_EXPRESSION_END
-    }
-
-    /**
-     * Maintains the state of scanning strings, including interpolated
-     * expressions/identifiers, nested braces for terminating an interpolated
-     * expression, the quote character used to start/end the string, and whether
-     * it is a multiline string.
-     */
-    public static class StringState {
-      private int bracesCount;
-      private Mode mode;
-      private final boolean multiLine;
-      private final int quote;
-
-      /**
-       * Push a new mode on state stack.  If the new mode is
-       * {@link Mode#IN_STRING_EMBEDDED_EXPRESSION}, mark that we have seen an
-       * opening brace.
-       *
-       * @param mode
-       * @param quote
-       * @param multiLine
-       */
-      public StringState(Mode mode, int quote, boolean multiLine) {
-        this.bracesCount = mode == Mode.IN_STRING_EMBEDDED_EXPRESSION ? 1 : 0;
-        this.mode = mode;
-        this.quote = quote;
-        this.multiLine = multiLine;
-      }
-
-      /**
-       * Mark that we have seen an opening brace.
-       */
-      public void openBrace() {
-        if (mode == Mode.IN_STRING_EMBEDDED_EXPRESSION) {
-          bracesCount++;
-        }
-      }
-
-      /**
-       * Mark that we have seen a closing brace.
-       *
-       * @return true if the current mode is now complete and should be popped
-       * off the stack
-       */
-      public boolean closeBrace() {
-        if (mode == Mode.IN_STRING_EMBEDDED_EXPRESSION) {
-          return --bracesCount == 0;
-        }
-        return false;
-      }
-
-      /**
-       * @return the string scanning mode.
-       */
-      public Mode getMode() {
-        return mode;
-      }
-
-      /**
-       * @return the codepoint of the quote character used to bound the current
-       * string.
-       */
-      public int getQuote() {
-        return quote;
-      }
-
-      /**
-       * @return true if the current string is a multi-line string.
-       */
-      public boolean isMultiLine() {
-        return multiLine;
-      }
-
-      /**
-       * @param mode the string scanning mode.
-       */
-      public void setMode(Mode mode) {
-        this.mode = mode;
-      }
-
-      @Override
-      public String toString() {
-        StringBuilder buf = new StringBuilder();
-        buf.append(mode).append("/quote=").appendCodePoint(quote);
-        if (multiLine) {
-          buf.append("/multiline");
-        }
-        return buf.toString();
-      }
-    }
-
-    private int lookahead[] = new int[NUM_LOOKAHEAD];
-    private int lookaheadPos[] = new int[NUM_LOOKAHEAD];
-    private int nextLookaheadPos;
-    private ArrayList<TokenData> tokens;
-    private TokenData lastToken;
-
-    // Current offset in the token list
-    int currentOffset;
-
-    // The following fields store data used for parsing string interpolation.
-    // The scanner splits the interpolated string in segments, alternating
-    // strings and expressions so that the parser can construct the embedded
-    // expressions as it goes. The following information is used to ensure that
-    // the string is closed with matching quotes, and to deal with parsing
-    // ambiguity of "}" (which closes both embedded expressions and braces
-    // within embedded expressions).
-
-    /** The string scanning state stack. */
-    private List<StringState> stringStateStack = new ArrayList<StringState>();
-
-    public InternalState() {
-      currentOffset = 0;
-    }
-
-    @Override
-    public String toString() {
-      StringBuilder ret = new StringBuilder();
-
-      ret.append("currentOffset(");
-      ret.append(currentOffset);
-      ret.append(")");
-      if ( currentOffset > -1 ) {
-        TokenData tok = tokens.get(currentOffset);
-        ret.append(" = [");
-        ret.append(tok.token);
-        if (tok.value != null) {
-          ret.append(" (" + tok.value + ")");
-        }
-        ret.append("], ");
-      }
-
-      ret.append("[");
-      for (int i = 0; i < tokens.size(); i++) {
-        TokenData tok = tokens.get(i);
-        ret.append(tok.token);
-        if (tok.value != null) {
-          ret.append(" (" + tok.value + ")");
-        }
-        if (i < tokens.size() - 1) {
-          ret.append(", ");
-        }
-      }
-      ret.append("]");
-      if (getMode() != InternalState.Mode.DEFAULT) {
-        ret.append("(within string starting with ");
-        ret.appendCodePoint(getQuote());
-        if (isMultiLine()) {
-          ret.appendCodePoint(getQuote());
-          ret.appendCodePoint(getQuote());
-        }
-        ret.append(')');
-      }
-      return ret.toString();
-    }
-
-    /**
-     * @return the current scanning mode
-     */
-    protected Mode getMode() {
-      return stringStateStack.isEmpty() ? Mode.DEFAULT : getCurrentState().getMode();
-    }
-
-    /**
-     * Mark that we have seen an open brace.
-     */
-    protected void openBrace() {
-      if (!stringStateStack.isEmpty()) {
-        getCurrentState().openBrace();
-      }
-    }
-
-    /**
-     * Mark that we have seen a close brace.
-     *
-     * @return true if the current mode is now complete and should be popped
-     */
-    protected boolean closeBrace() {
-      if (!stringStateStack.isEmpty()) {
-        return getCurrentState().closeBrace();
-      }
-      return false;
-    }
-
-    /**
-     * Pop the current mode.
-     */
-    protected void popMode() {
-      if (!stringStateStack.isEmpty()) {
-        stringStateStack.remove(stringStateStack.size() - 1);
-      }
-    }
-
-    /**
-     * @param mode the mode to push
-     */
-    protected void pushMode(Mode mode, int quote, boolean multiLine) {
-      stringStateStack.add(new StringState(mode, quote, multiLine));
-    }
-
-    /**
-     * @param mode the mode to push
-     */
-    protected void replaceMode(Mode mode) {
-      getCurrentState().setMode(mode);
-    }
-
-    /**
-     * Remove all modes, returning to the default state.
-     */
-    public void resetModes() {
-      stringStateStack.clear();
-    }
-
-    /**
-     * @return the quote
-     */
-    private int getQuote() {
-      return getCurrentState().getQuote();
-    }
-
-    /**
-     * @return the current string scanning state
-     */
-    private StringState getCurrentState() {
-      assert !stringStateStack.isEmpty() : "called with empty state stack";
-      return stringStateStack.get(stringStateStack.size() - 1);
-    }
-
-    /**
-     * @return the multiLine
-     */
-    private boolean isMultiLine() {
-      return getCurrentState().isMultiLine();
-    }
-  }
-
-  private static class TokenData {
-    Token token;
-    Location location;
-    String value;
-
-    @Override
-    public String toString() {
-      String str = token.toString();
-      return (value != null) ? str + "(" + value + ")" : str;
-    }
-  }
-
-  private static final int NUM_LOOKAHEAD = 2;
-
-  private static boolean isDecimalDigit(int c) {
-    return c >= '0' && c <= '9';
-  }
-
-  private static boolean isHexDigit(int c) {
-    return isDecimalDigit(c) || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F');
-  }
-
-  private static boolean isIdentifierPart(int c) {
-    return isIdentifierStart(c) || isDecimalDigit(c);
-  }
-
-  private static boolean isIdentifierStart(int c) {
-    return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c == '_') || (c == '$');
-  }
-
-  private static boolean isLineTerminator(int c) {
-    return c == '\r' || c == '\n';
-  }
-
-  private static boolean isWhiteSpace(int c) {
-    return c == ' ' || c == '\t';
-  }
-
-  private int commentCharCount;
-  private int lastCommentStart;
-  private int lastCommentStop;
-  private String source;
-  private InternalState internalState;
-  private Source sourceReference;
-  private DartCompilerListener listener;
-
-  public DartScanner(String source) {
-    this(source, 0, null, null);
-  }
-
-  public DartScanner(String source, int start) {
-    this(source, 0, null, null);
-  }
-
-  public DartScanner(String source, int start, Source sourceReference, DartCompilerListener listener) {
-    final TraceEvent logEvent = Tracer.canTrace() ? Tracer.start(DartEventType.SCANNER) : null;
-    try {
-      this.source = source;
-      this.sourceReference = sourceReference;
-      this.listener = listener;
-      internalState = new InternalState();
-      internalState.tokens = new ArrayList<TokenData>(source.length()/2);
-
-      // Initialize lookahead positions.
-      // TODO Determine if line & column should be relative to 0 or 'start'
-      internalState.nextLookaheadPos = start;
-      for (int i = 0; i < internalState.lookaheadPos.length; ++i) {
-        internalState.lookaheadPos[i] = start;
-      }
-
-      // Fill all the characters in the look-ahead and all the peek
-      // elements in the tokens buffer.
-      for (int i = 0; i < NUM_LOOKAHEAD; i++) {
-        advance();
-      }
-
-      // Scan all the tokens up front
-      scanFile();
-    } finally {
-      Tracer.end(logEvent);
-    }
-  }
-
-  /**
-   * Returns the number of characters of source code that were scanned.
-   */
-  public int getCharCount() {
-    return internalState.nextLookaheadPos;
-  }
-
-  /**
-   * Returns the number of characters of source code that were scanned excluding the number of
-   * characters consumed by comments.
-   */
-  public int getNonCommentCharCount() {
-    return getCharCount() - commentCharCount;
-  }
-
-  /**
-   * Get the token value for one of the look-ahead tokens.
-   */
-  public String getPeekTokenValue(int n) {
-    assert (0 <= n && (internalState.currentOffset + n + 1) < internalState.tokens.size());
-    return internalState.tokens.get(internalState.currentOffset + n + 1).value;
-  }
-
-  /**
-   * Gets a copy of the current scanner state. This state can be passed to {@link
-   * #restoreState(State)}.
-   */
-  public State getState() {
-//    System.out.println("get state: " + internalState.currentOffset + " hash: 0x" + Integer.toHexString(this.hashCode()));
-    return new State(internalState.currentOffset);
-  }
-
-  /**
-   * Gets the current offset of the scanner.
-   */
-  public int getOffset() {
-    return internalState.currentOffset;
-  }
-
-  /**
-   * Gets the current token.
-   */
-  public Token getToken() {
-    return internalState.tokens.get(internalState.currentOffset).token;
-  }
-
-  /**
-   * Gets the location of the current token.
-   */
-  public Location getTokenLocation() {
-    return internalState.tokens.get(internalState.currentOffset).location;
-  }
-
-  public Location peekTokenLocation(int n) {
-    if ((internalState.currentOffset + n + 1) < internalState.tokens.size()) {
-      return internalState.tokens.get(internalState.currentOffset + n + 1).location;
-    } else {
-      // It is not valid to read beyond the end of the token stream, so we
-      // return the Location of the EOS token.
-      return internalState.tokens.get(internalState.tokens.size() - 1).location;
-    }
-
-  }
-
-  /**
-   * Get the token value or location for the current token previously returned
-   * by a call to next().
-   */
-  public String getTokenValue() {
-    return internalState.tokens.get(internalState.currentOffset).value;
-  }
-
-  public String peekTokenValue(int n) {
-    if ((internalState.currentOffset + n + 1) < internalState.tokens.size()) {
-      return internalState.tokens.get(internalState.currentOffset + n + 1).value;
-    } else {
-      // It is not valid to read beyond the end of the token stream, so we
-      // return the null, the default value of an EOS token.
-      return null;
-    }
-  }
-
-  /**
-   * Returns the next token.
-   */
-  public Token next() {
-    // Do not advance the current offset beyond the end of the stoken stream
-    if (internalState.currentOffset + 1 < internalState.tokens.size()) {
-      internalState.currentOffset++;
-    }
-    return getToken();
-  }
-
-  /**
-   * Token look-ahead - past the token returned by next().
-   */
-  public Token peek(int n) {
-    if ((internalState.currentOffset + n + 1) < internalState.tokens.size()) {
-      return internalState.tokens.get(internalState.currentOffset + n + 1).token;
-    } else {
-      // It is not valid to read beyond the end of the token stream, so we
-      // return the EOS token
-      return Token.EOS;
-    }
-  }
-
-  /**
-   * Sets the scanner's state, using a state object returned from {@link #getState()}.
-   */
-  public void restoreState(State oldState) {
-//    System.out.println("restore state " + oldState.baseOffset + " hash: 0x" + Integer.toHexString(this.hashCode()));
-    // reset offset
-    internalState.currentOffset = oldState.baseOffset;
-  }
-
-  /**
-   * Sets the token at the specified slot in the lookahead buffer.
-   */
-  public void setPeek(int n, Token token) {
-    assert (0 <= n && (internalState.currentOffset + n + 1) < internalState.tokens.size());
-    internalState.tokens.get(internalState.currentOffset + n + 1).token = token;
-  }
-
-  /**
-   * Sets the token at the specified slot in the lookahead buffer.
-   */
-  public void setAbsolutePeek(int n, Token token) {
-    assert (0 <= n && n < internalState.tokens.size());
-    internalState.tokens.get(n).token = token;
-  }
-
-  @Override
-  public String toString() {
-    if (internalState == null) {
-      return super.toString();
-    }
-    return internalState.toString();
-  }
-
-  /**
-   * A hook into low-level scanning machinery. Use with care and only as directed.<p>
-   * Record the location of a comment. Given a source string <code>source,</code>
-   * the actual comment string is <code>source.substring(start - 1, stop)</code>
-   * because the comment cannot be recognized until its second character is
-   * scanned.<p>
-   * Note: A single comment may be scanned multiple times. If the scanner has
-   * to backtrack it will re-scan comments until it no longer has to backtrack.
-   * Clients are responsible for filtering duplicate comment locations.<p>
-   * Warning: This method may be called during initialization of the scanner in
-   * the <code>DartScanner</code> constructor. Fields defined in the subclass
-   * that implements this method may not have been initialized before the first
-   * invocation.
-   * @param start the character position of the second character in the comment
-   * @param stop the character position of the final character in the comment
-   */
-  protected void recordCommentLocation(int start, int stop) {
-  }
-
-  private void advance() {
-    for (int i = 0; i < NUM_LOOKAHEAD - 1; ++i) {
-      internalState.lookahead[i] = internalState.lookahead[i + 1];
-      internalState.lookaheadPos[i] = internalState.lookaheadPos[i + 1];
-    }
-    if (internalState.nextLookaheadPos < source.length()) {
-      int ch = source.codePointAt(internalState.nextLookaheadPos);
-      internalState.lookahead[NUM_LOOKAHEAD - 1] = ch;
-      internalState.lookaheadPos[NUM_LOOKAHEAD - 1] = internalState.nextLookaheadPos;
-      internalState.nextLookaheadPos = source.offsetByCodePoints(internalState.nextLookaheadPos, 1);
-    } else {
-      // Let the last look-ahead position be past the source. This makes
-      // the position information for the last token correct.
-      internalState.lookahead[NUM_LOOKAHEAD - 1] = -1;
-      internalState.lookaheadPos[NUM_LOOKAHEAD - 1] = source.length();
-
-      // Leave the nextLookahead position pointing to the line after the last line
-      internalState.nextLookaheadPos = source.length();
-    }
-  }
-
-  /**
-   * Called when comments are identified to aggregate the total number of comment lines and comment
-   * characters then delegate to {@link #recordCommentLocation(int, int)}.  This provides
-   * a light weight way to track how much of the code is made up of comments without having to keep
-   * all comments.
-   *
-   * @param start the character position of the second character in the comment
-   * @param stop the character position of the final character in the comment
-   */
-  private void commentLocation(int start, int stop) {
-    if (start <= lastCommentStart && stop <= lastCommentStop) {
-      return;
-    }
-
-    lastCommentStart = start;
-    lastCommentStop = stop;
-    commentCharCount += stop - start + 1;
-
-    recordCommentLocation(start, stop);
-  }
-
-  private boolean is(int c) {
-    return internalState.lookahead[0] == c;
-  }
-
-  private boolean isEos() {
-    return internalState.lookahead[0] < 0;
-  }
-
-  private int lookahead(int n) {
-    assert (0 <= n && n < NUM_LOOKAHEAD);
-    return internalState.lookahead[n];
-  }
-
-  // Get the current source code position.
-  private int position() {
-    return internalState.lookaheadPos[0];
-  }
-
-  private void scanFile() {
-    // First node inserted as a dummy.
-    internalState.lastToken = new TokenData();
-    internalState.tokens.add(internalState.lastToken);
-
-    while (true) {
-      internalState.lastToken = new TokenData();
-      Token token;
-      int begin, end;
-      do {
-        skipWhiteSpace();
-        begin = position();
-        token = scanToken();
-      } while (token == Token.COMMENT);
-      end = position();
-
-      internalState.lastToken.token = token;
-      internalState.lastToken.location = new Location(begin, end);
-      internalState.tokens.add(internalState.lastToken);
-      if (token == Token.EOS) {
-//        System.out.print("tokens: ");
-//        for(TokenData t : internalState.tokens) {
-//          if (t != null) {
-//            if (t.token != null) {
-//              System.out.print(t + ", ");
-//            } else {
-//              System.out.print("Null, ");
-//            }
-//          }
-//        }
-//        System.out.println();
-        return;
-      }
-    }
-  }
-
-  private Token scanIdentifier(boolean allowDollars) {
-    assert (isIdentifierStart(lookahead(0)));
-    int begin = position();
-    while (true) {
-      int nextChar = lookahead(0);
-      if (!isIdentifierPart(nextChar) || (!allowDollars && nextChar == '$')) {
-        break;
-      }
-      advance();
-    }
-    int size = position() - begin;
-
-    // Use a substring of the source string instead of copying all the
-    // characters to the token value buffer.
-    String result = source.substring(begin, begin + size);
-    internalState.lastToken.value = result;
-    return Token.lookup(result);
-  }
-
-  private Token scanNumber() {
-    boolean isDouble = false;
-    assert (isDecimalDigit(lookahead(0)) || is('.'));
-    int begin = position();
-    while (isDecimalDigit(lookahead(0)))
-      advance();
-    if (is('.') && isDecimalDigit(lookahead(1))) {
-      isDouble = true;
-      advance();  // Consume .
-      while (isDecimalDigit(lookahead(0)))
-        advance();
-    }
-    if (isE()) {
-      isDouble = true;
-      advance();
-      if (is('+') || is('-')) {
-        advance();
-      }
-      if (!isDecimalDigit(lookahead(0))) {
-        return Token.ILLEGAL;
-      }
-      while (isDecimalDigit(lookahead(0)))
-        advance();
-    } else if (isIdentifierStart(lookahead(0))) {
-      // Number literals must not be followed directly by an identifier.
-      return Token.ILLEGAL;
-    }
-    int size = position() - begin;
-    internalState.lastToken.value = source.substring(begin, begin + size);
-    return isDouble ? Token.DOUBLE_LITERAL : Token.INTEGER_LITERAL;
-  }
-
-  private boolean isE() {
-    return is('e') || is('E');
-  }
-
-  private Token scanHexNumber() {
-    assert (isDecimalDigit(lookahead(0)) && (lookahead(1) == 'x' || lookahead(1) == 'X'));
-    // Skip 0x/0X.
-    advance();
-    advance();
-
-    int begin = position();
-    if (!isHexDigit(lookahead(0))) {
-      return Token.ILLEGAL;
-    }
-    advance();
-    while (isHexDigit(lookahead(0))) {
-      advance();
-    }
-    if (isIdentifierStart(lookahead(0))) {
-      return Token.ILLEGAL;
-    }
-    internalState.lastToken.value = source.substring(begin, position());
-    return Token.HEX_LITERAL;
-  }
-
-  private Token scanString(boolean isRaw) {
-    int quote = lookahead(0);
-    assert (is('\'') || is('"'));
-    boolean multiLine = false;
-    advance();
-
-    // detect whether this is a multi-line string:
-    if (lookahead(0) == quote && lookahead(1) == quote) {
-      multiLine = true;
-      advance();
-      advance();
-      // according to the dart guide, when multi-line strings start immediately
-      // with a \n, the \n is not part of the string:
-      if (is('\n')) {
-        advance();
-      }
-    }
-    internalState.pushMode(InternalState.Mode.IN_STRING, quote, multiLine);
-    if (isRaw) {
-      return scanRawString();
-    } else {
-      return scanWithinString(true);
-    }
-  }
-
-  private Token scanRawString() {
-    assert (internalState.getMode() == InternalState.Mode.IN_STRING);
-    int quote = internalState.getQuote();
-    boolean multiLine = internalState.isMultiLine();
-    // TODO(floitsch): Do we really need a StringBuffer to accumulate the characters?
-    StringBuilder tokenValueBuffer = new StringBuilder();
-    while (true) {
-      if (isEos()) {
-        // Unterminated string (either multi-line or not).
-        internalState.popMode();
-        return Token.ILLEGAL;
-      }
-      int c = lookahead(0);
-      advance();
-      if (c == quote) {
-        if (!multiLine) {
-          // Done parsing the string literal.
-          break;
-        } else if (lookahead(0) == quote && lookahead(1) == quote) {
-          // Done parsing the multi-line string literal.
-          advance();
-          advance();
-          break;
-        }
-      } else if (c == '\n' && !multiLine) {
-        advance();
-        internalState.popMode();
-        // unterminated (non multi-line) string
-        return Token.ILLEGAL;
-      }
-      tokenValueBuffer.appendCodePoint(c);
-    }
-    internalState.lastToken.value = tokenValueBuffer.toString();
-    internalState.popMode();
-    return Token.STRING;
-  }
-
-  /**
-   * Scan within a string watching for embedded expressions (string
-   * interpolation). This function returns 4 kinds of tokens:
-   * <ul>
-   *   <li> {@link Token#STRING} when {@code start} is true and no embedded
-   *   expressions are found (default to string literals when no interpolation
-   *   was used).
-   *   <li> {@link Token#STRING_SEGMENT} when the string is interrupted with an
-   *   embedded expression.
-   *   <li> {@link Token#STRING_EMBED_EXP_START} when an embedded expression is
-   *   found right away (the lookahead is "${").
-   *   <li> {@link Token#STRING_LAST_SEGMENT} when {@code start} is false and no
-   *   more embedded expressions are found.
-   * </ul>
-   */
-  private Token scanWithinString(boolean start) {
-    assert (internalState.getMode() == InternalState.Mode.IN_STRING);
-    int quote = internalState.getQuote();
-    boolean multiLine = internalState.isMultiLine();
-    StringBuffer tokenValueBuffer = new StringBuffer();
-    while (true) {
-      if (isEos()) {
-        // Unterminated string (either multi-line or not).
-        internalState.resetModes();
-        return Token.EOS;
-      }
-      int c = lookahead(0);
-      if (c == quote) {
-        advance();
-        if (!multiLine) {
-          // Done parsing string constant.
-          break;
-        } else if (lookahead(0) == quote && lookahead(1) == quote) {
-          // Done parsing multi-line string constant.
-          advance();
-          advance();
-          break;
-        }
-      } else if (c == '\n' && !multiLine) {
-        advance();
-        internalState.popMode();
-        // unterminated (non multi-line) string
-        return Token.ILLEGAL;
-      } else if (c == '\\') {
-        advance();
-        if (isEos()) {
-          // Unterminated string (either multi-line or not).
-          internalState.resetModes();
-          return Token.EOS;
-        }
-        c = lookahead(0);
-        advance();
-        switch (c) {
-          case '\n':
-            reportError(position() - 1, ParserErrorCode.ESCAPED_NEWLINE);
-            c = '\n';
-            break;
-          case 'b':
-            c = 0x08;
-            break;
-          case 'f':
-            c = 0x0C;
-            break;
-          case 'n':
-            c = '\n';
-            break;
-          case 'r':
-            c = '\r';
-            break;
-          case 't':
-            c = '\t';
-            break;
-          case 'v':
-            c = 0x0B;
-            break;
-          case 'x':
-          case 'u':
-            // Parse Unicode escape sequences, which are of the form (backslash) xXX, (backslash)
-            // uXXXX or (backslash) u{X*} where X is a hexadecimal digit - the delimited form must
-            // be between 1 and 6 digits.
-            int len = (c == 'u') ? 4 : 2;
-            if (isEos()) {
-              // Unterminated string (either multi-line or not).
-              internalState.resetModes();
-              return Token.EOS;
-            }
-            c = lookahead(0);
-            int unicodeCodePoint = 0;
-            // count of characters remaining or negative if delimited
-            if (c == '{') {
-              len = -1;
-              advance();
-              if (isEos()) {
-                // Unterminated string (either multi-line or not).
-                internalState.resetModes();
-                return Token.EOS;
-              }
-              c = lookahead(0);
-            }
-            while (len != 0) {
-              advance();
-              int digit = Character.getNumericValue(c);
-              if (digit < 0 || digit > 15) {
-                // TODO(jat): how to handle an error?  We would prefer to give a better error
-                // message about an invalid Unicode escape sequence
-                return Token.ILLEGAL;
-              }
-              unicodeCodePoint = unicodeCodePoint * 16 + digit;
-              c = lookahead(0);
-              if (len-- < 0 && c == '}') {
-                advance();
-                break;
-              }
-              if (isEos()) {
-                // Unterminated string (either multi-line or not).
-                internalState.resetModes();
-                return Token.EOS;
-              }
-              if (len < -6) {
-                // TODO(jat): better way to indicate error
-                // too many characters for a delimited character
-                return Token.ILLEGAL;
-              }
-            }
-            c = unicodeCodePoint;
-            // Unicode escapes must specify a valid Unicode scalar value, and may not specify
-            // UTF16 surrogates.
-            if (!Character.isValidCodePoint(c) || (c < 0x10000
-                && (Character.isHighSurrogate((char) c) || Character.isLowSurrogate((char) c)))) {
-              // TODO(jat): better way to indicate error
-              return Token.ILLEGAL;
-            }
-            // TODO(jat): any other checks?  We could use Character.isDefined, but then we risk
-            // version skew with the JRE's Unicode data.  For now, assume anything in the Unicode
-            // range besides surrogates are fine.
-            break;
-
-          default:
-            // any other character following a backslash is just itself
-            // see Dart guide 3.3
-            break;
-        }
-      } else if (c == '$') {
-        // TODO(sigmund): add support for named embedded expressions and
-        // function embedded expressions for string templates.
-        if (tokenValueBuffer.length() == 0) {
-          advance();
-          int nextChar = lookahead(0);
-          if (nextChar == '{') {
-            advance();
-            internalState.pushMode(InternalState.Mode.IN_STRING_EMBEDDED_EXPRESSION, quote,
-                multiLine);
-          } else {
-            internalState.pushMode(InternalState.Mode.IN_STRING_EMBEDDED_EXPRESSION_IDENTIFIER,
-                quote, multiLine);
-          }
-          return Token.STRING_EMBED_EXP_START;
-        } else {
-          // Encountered the beginning of an embedded expression (string
-          // interpolation), return the current segment, and keep the "$" for
-          // the next token.
-          internalState.lastToken.value = tokenValueBuffer.toString();
-          return Token.STRING_SEGMENT;
-        }
-      } else {
-        advance();
-      }
-      tokenValueBuffer.appendCodePoint(c);
-    }
-
-    internalState.lastToken.value = tokenValueBuffer.toString();
-    internalState.popMode();
-    if (start) {
-      return Token.STRING;
-    } else {
-      return Token.STRING_LAST_SEGMENT;
-    }
-  }
-
-  private Token scanToken() {
-    switch (internalState.getMode()) {
-      case IN_STRING:
-        return scanWithinString(false);
-      case IN_STRING_EMBEDDED_EXPRESSION_IDENTIFIER:
-        // We are inside a string looking for an identifier. Ex: "$foo".
-        internalState.replaceMode(InternalState.Mode.IN_STRING_EMBEDDED_EXPRESSION_END);
-        int c = lookahead(0);
-        if (isIdentifierStart(c) && c != '$') {
-          boolean allowDollars = false;
-          return scanIdentifier(allowDollars);
-        } else {
-          internalState.popMode();
-          if (!isEos()) {
-            internalState.lastToken.value = String.valueOf(c);
-          }
-          return Token.ILLEGAL;
-        }
-      case IN_STRING_EMBEDDED_EXPRESSION_END:
-        // We scanned the identifier of a string-interpolation. New we return the
-        // end-of-embedded-expression token.
-        internalState.popMode();
-        return Token.STRING_EMBED_EXP_END;
-      default:
-        // fall through
-    }
-
-    switch (lookahead(0)) {
-      case '"':
-      case '\'': {
-        boolean isRaw = false;
-        return scanString(isRaw);
-      }
-
-      case '<':
-        // < <= << <<=
-        advance();
-        if (is('='))
-          return select(Token.LTE);
-        if (is('<'))
-          return select('=', Token.ASSIGN_SHL, Token.SHL);
-        return Token.LT;
-
-      case '>':
-        // > >= >> >>=
-        advance();
-        if (is('='))
-          return select(Token.GTE);
-        if (is('>')) {
-          // >> >>=
-          advance();
-          if (is('='))
-            return select(Token.ASSIGN_SAR);
-          return Token.SAR;
-        }
-        return Token.GT;
-
-      case '=':
-        // = == === =>
-        advance();
-        if (is('>')) {
-          return select(Token.ARROW);
-        }
-        if (is('='))
-          return select('=', Token.EQ_STRICT, Token.EQ);
-        return Token.ASSIGN;
-
-      case '!':
-        // ! != !==
-        advance();
-        if (is('='))
-          return select('=', Token.NE_STRICT, Token.NE);
-        return Token.NOT;
-
-      case '+':
-        // + ++ +=
-        advance();
-        if (is('+'))
-          return select(Token.INC);
-        if (is('='))
-          return select(Token.ASSIGN_ADD);
-        return Token.ADD;
-
-      case '-':
-        // - -- -=
-        advance();
-        if (is('-'))
-          return select(Token.DEC);
-        if (is('='))
-          return select(Token.ASSIGN_SUB);
-        return Token.SUB;
-
-      case '*':
-        // * *=
-        return select('=', Token.ASSIGN_MUL, Token.MUL);
-
-      case '%':
-        // % %=
-        return select('=', Token.ASSIGN_MOD, Token.MOD);
-
-      case '/':
-        // / // /* /=
-        advance();
-        if (is('/'))
-          return skipSingleLineComment();
-        if (is('*'))
-          return skipMultiLineComment();
-        if (is('='))
-          return select(Token.ASSIGN_DIV);
-        return Token.DIV;
-
-      case '&':
-        // & && &=
-        advance();
-        if (is('&'))
-          return select(Token.AND);
-        if (is('='))
-          return select(Token.ASSIGN_BIT_AND);
-        return Token.BIT_AND;
-
-      case '|':
-        // | || |=
-        advance();
-        if (is('|'))
-          return select(Token.OR);
-        if (is('='))
-          return select(Token.ASSIGN_BIT_OR);
-        return Token.BIT_OR;
-
-      case '^':
-        // ^ ^=
-        return select('=', Token.ASSIGN_BIT_XOR, Token.BIT_XOR);
-
-      case '.':
-        // . <number>
-        if (isDecimalDigit(lookahead(1))) {
-          return scanNumber();
-        } else {
-          advance();
-          if (lookahead(0) == '.') {
-            if (lookahead(1) == '.') {
-              advance();
-              advance();
-              return Token.ELLIPSIS;
-            }
-            advance();
-            return Token.CASCADE;
-          }
-          return Token.PERIOD;
-        }
-
-      case ':':
-        return select(Token.COLON);
-
-      case ';':
-        return select(Token.SEMICOLON);
-
-      case ',':
-        return select(Token.COMMA);
-
-      case '(':
-        return select(Token.LPAREN);
-
-      case ')':
-        return select(Token.RPAREN);
-
-      case '[':
-        advance();
-        if (is(']')) {
-          return select('=', Token.ASSIGN_INDEX, Token.INDEX);
-        }
-        return Token.LBRACK;
-
-      case ']':
-        return select(Token.RBRACK);
-
-      case '{':
-        internalState.openBrace();
-        return select(Token.LBRACE);
-
-      case '}':
-        if (internalState.closeBrace()) {
-          internalState.popMode();
-          return select(Token.STRING_EMBED_EXP_END);
-        }
-        return select(Token.RBRACE);
-
-      case '?':
-        return select(Token.CONDITIONAL);
-
-      case '~':
-        // ~ ~/ ~/=
-        advance();
-        if (is('/')) {
-          if (lookahead(1) == '=') {
-            advance();
-            return select(Token.ASSIGN_TRUNC);
-          } else {
-            return select(Token.TRUNC);
-          }
-        } else {
-          return Token.BIT_NOT;
-        }
-
-      case '@':
-        // Raw strings.
-        advance();
-        if (is('\'') || is('"')) {
-          reportError(position() - 1, ParserErrorCode.DEPRECATED_RAW_STRING);
-          Token token = scanString(true);
-          return token;
-        } else {
-          return Token.AT;
-        }
-
-      case '#':
-        return scanDirective();
-
-      case 'r':
-        if (lookahead(1) == '\'' || lookahead(1) == '"') {
-          advance();
-          return scanString(true);
-        }
-        return scanIdentifier(true);
-
-      default:
-        if (isIdentifierStart(lookahead(0))) {
-          boolean allowDollars = true;
-          return scanIdentifier(allowDollars);
-        }
-        if (isDecimalDigit(lookahead(0))) {
-          if (lookahead(0) == '0' && (lookahead(1) == 'x' || lookahead(1) == 'X')) {
-            return scanHexNumber();
-          } else {
-            return scanNumber();
-          }
-        }
-        if (isEos())
-          return Token.EOS;
-        return select(Token.ILLEGAL);
-    }
-  }
-
-  private void reportError(int offset, ParserErrorCode errorCode) {
-    if (listener != null) {
-      listener.onError(new DartCompilationError(
-        new SourceInfo(sourceReference, offset, position() - offset),
-        errorCode));
-    }
-  }
-
-  /**
-   * Scan for #library, #import, #source, and #resource directives
-   */
-  private Token scanDirective() {
-    assert (is('#'));
-    int currPos = position();
-    int start = currPos;
-
-    // Skip over the #! if it exists and consider it a comment
-    if (start == 0) {
-      if (lookahead(1) == '!') {
-        while (!isEos() && !isLineTerminator(lookahead(0)))
-          advance();
-        int stop = internalState.lookaheadPos[0];
-        commentLocation(start, stop);
-        return Token.COMMENT;
-      }
-    }
-
-    // Directives must start at the beginning of a line
-    if (start > 0 && !isLineTerminator(source.codePointBefore(start)))
-      return select(Token.ILLEGAL);
-
-    // Determine which directive is being specified
-    advance();
-    while (true) {
-      int ch = lookahead(0);
-      if (ch < 'a' || ch > 'z') {
-        break;
-      }
-      advance();
-    }
-    String syntax = source.substring(start, position());
-    Token token = Token.lookup(syntax);
-    return token == Token.IDENTIFIER ? Token.ILLEGAL : token;
-  }
-
-  private Token select(int next, Token yes, Token no) {
-    advance();
-    if (lookahead(0) != next)
-      return no;
-    advance();
-    return yes;
-  }
-
-  private Token select(Token token) {
-    advance();
-    return token;
-  }
-
-  private Token skipMultiLineComment() {
-    assert (is('*'));
-    int currPos = internalState.lookaheadPos[0];
-    int start = currPos - 1;
-    int commentDepth = 1;
-    advance();
-    while (!isEos()) {
-      int first = lookahead(0);
-      advance();
-      if (first == '*' && is('/')) {
-        if(--commentDepth == 0) {
-          Token result = select(Token.COMMENT);
-          int stop = internalState.lookaheadPos[0];
-          commentLocation(start, stop);
-          return result;
-        }
-        advance();
-      } else if (first == '/' && is('*')) {
-        commentDepth++;
-        advance();
-      }
-    }
-    int stop = internalState.lookaheadPos[0];
-    commentLocation(start, stop);
-    // Unterminated multi-line comment.
-    return Token.ILLEGAL;
-  }
-
-  private Token skipSingleLineComment() {
-    assert (is('/'));
-    int currPos = internalState.lookaheadPos[0];
-    int start = currPos - 1;
-    advance();
-    while (!isEos() && !isLineTerminator(lookahead(0)))
-      advance();
-    int stop = internalState.lookaheadPos[0];
-    commentLocation(start, stop);
-    return Token.COMMENT;
-  }
-
-  private void skipWhiteSpace() {
-    Mode mode = internalState.getMode();
-    if ((mode != InternalState.Mode.DEFAULT)
-        && (mode != InternalState.Mode.IN_STRING_EMBEDDED_EXPRESSION)) {
-      return;
-    }
-    while (true) {
-      int c = lookahead(0);
-      if (isLineTerminator(c)) {
-      } else if (!isWhiteSpace(c)) {
-        break;
-      }
-      advance();
-    }
-  }
-}
diff --git a/compiler/java/com/google/dart/compiler/parser/DartScannerParserContext.java b/compiler/java/com/google/dart/compiler/parser/DartScannerParserContext.java
deleted file mode 100644
index e40bb4c..0000000
--- a/compiler/java/com/google/dart/compiler/parser/DartScannerParserContext.java
+++ /dev/null
@@ -1,201 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.parser;
-
-import com.google.dart.compiler.DartCompilationError;
-import com.google.dart.compiler.DartCompilerListener;
-import com.google.dart.compiler.DartSource;
-import com.google.dart.compiler.Source;
-import com.google.dart.compiler.ast.DartUnit;
-import com.google.dart.compiler.common.HasSourceInfo;
-import com.google.dart.compiler.common.HasSourceInfoSetter;
-import com.google.dart.compiler.common.SourceInfo;
-import com.google.dart.compiler.metrics.CompilerMetrics;
-import com.google.dart.compiler.parser.DartScanner.Location;
-import com.google.dart.compiler.parser.DartScanner.State;
-
-import java.util.ArrayDeque;
-import java.util.Deque;
-import java.util.Stack;
-
-/**
- * A ParserContext backed by a DartScanner.
- */
-class DartScannerParserContext implements ParserContext {
-  private DartScanner scanner;
-  private Deque<DartScanner.State> stateStack = new ArrayDeque<DartScanner.State>();
-  private Deque<Integer> positionStack = new ArrayDeque<Integer>();
-  private Source source;
-  private DartCompilerListener listener;
-  private final CompilerMetrics compilerMetrics;
-
-  public DartScannerParserContext(Source source, String sourceCode,
-      DartCompilerListener listener) {
-    this(source, sourceCode, listener, null);
-  }
-
-  public DartScannerParserContext(Source source, String sourceCode,
-      DartCompilerListener listener, CompilerMetrics compilerMetrics) {
-    this.source = source;
-    this.scanner = createScanner(sourceCode, source, listener);
-    this.listener = listener;
-    this.compilerMetrics = compilerMetrics;
-  }
-
-  @Override
-  public void begin() {
-    stateStack.push(scanner.getState());
-    positionStack.push(getBeginLocation(0));
-  }
-
-  private int getBeginLocation(int n) {
-    DartScanner.Location tokenLocation = scanner.peekTokenLocation(n);
-    return tokenLocation != null ? tokenLocation.getBegin() : 0;
-  }
-
-  private int getEndLocation() {
-    DartScanner.Location tokenLocation = scanner.getTokenLocation();
-    return tokenLocation != null ? tokenLocation.getEnd() : 0;
-  }
-
-  @Override
-  public <T> T done(T result) {
-    DartScanner.State oldState = stateStack.pop();
-    DartScanner.State newState = stateStack.peek();
-
-    // If there is more state left, push the newer token changes to them.
-    if (newState != null) {
-      if (oldState.rollbackTokens != null) {
-        if (newState.rollbackTokens != null) {
-          oldState.rollbackTokens.addAll(newState.rollbackTokens);
-        }
-        newState.rollbackTokens = oldState.rollbackTokens;
-      }
-    }
-
-    setSourcePosition(result, positionStack.pop());
-
-    if (result instanceof DartUnit) {
-      if (compilerMetrics != null) {
-        compilerMetrics.unitParsed(scanner.getCharCount(), scanner.getNonCommentCharCount(),
-            0, 0);
-      }
-    }
-
-    // want next begin() call to seek to the next token and skip whitespace after previous done()
-    return result;
-  }
-
-  /**
-   * Set the source position on a result, if it is a {@link HasSourceInfo}.
-   *
-   * @param <T> result type
-   * @param result
-   * @param startPos
-   */
-  private <T> void setSourcePosition(T result, int startPos) {
-    if (result instanceof HasSourceInfoSetter) {
-      HasSourceInfoSetter hasSourceInfoSetter = (HasSourceInfoSetter) result;
-      int start = startPos;
-      int end = getEndLocation();
-      if (start != -1 && end < start) {
-        // handle 0-length tokens, including where there is trailing whitespace
-        end = start;
-      }
-      hasSourceInfoSetter.setSourceInfo(new SourceInfo(source, start, end - start));
-    }
-  }
-
-  @Override
-  public <T> T doneWithoutConsuming(T result) {
-    // do not throw away state
-    setSourcePosition(result, positionStack.peek());
-
-    // want next begin() call to seek to the next token and skip whitespace after previous done()
-    return result;
-  }
-
-  @Override
-  public void error(DartCompilationError dartError) {
-    listener.onError(dartError);
-  }
-  
-  @Override
-  public void unitAboutToCompile(DartSource source, boolean diet) {
-    listener.unitAboutToCompile(source, diet);
-  }
-
-  @Override
-  public void advance() {
-    scanner.next();
-  }
-
-  @Override
-  public Token getCurrentToken() {
-    return scanner.getToken();
-  }
-
-  @Override
-  public Token peek(int steps) {
-    return scanner.peek(steps);
-  }
-
-  @Override
-  public void rollback() {
-    // undo changes made to scanner tokens
-    DartScanner.State oldState = stateStack.pop();
-    scanner.restoreState(oldState);
-
-    // Restore the replaced tokens to their state.
-    if (oldState.rollbackTokens != null) {
-      while (!oldState.rollbackTokens.isEmpty()) {
-        State.RollbackToken token = oldState.rollbackTokens.pop();
-        scanner.setAbsolutePeek(token.absoluteOffset, token.replacedToken);
-      }
-    }
-    positionStack.pop();
-  }
-
-  @Override
-  public String getTokenString() {
-    return scanner.getTokenValue();
-  }
-
-  @Override
-  public Location peekTokenLocation(int n) {
-    return scanner.peekTokenLocation(n);
-  }
-
-  @Override
-  public String peekTokenString(int steps) {
-    return scanner.peekTokenValue(steps);
-  }
-
-  @Override
-  public void replaceNextToken(Token token) {
-    DartScanner.State state = stateStack.peek();
-    DartScanner.State.RollbackToken oldToken
-      = new DartScanner.State.RollbackToken(scanner.getOffset() + 1, scanner.peek(0));
-    if (state.rollbackTokens == null) {
-      state.rollbackTokens = new Stack<State.RollbackToken>();
-    }
-    state.rollbackTokens.push(oldToken);
-    scanner.setPeek(0, token);
-  }
-
-  @Override
-  public DartScanner.Location getTokenLocation() {
-    return scanner.getTokenLocation();
-  }
-
-  protected DartScanner createScanner(String sourceCode, Source source, DartCompilerListener listener) {
-    return new DartScanner(sourceCode, 0, source, listener);
-  }
-
-  @Override
-  public Source getSource() {
-    return source;
-  }
-}
diff --git a/compiler/java/com/google/dart/compiler/parser/ParserContext.java b/compiler/java/com/google/dart/compiler/parser/ParserContext.java
deleted file mode 100644
index f56efde..0000000
--- a/compiler/java/com/google/dart/compiler/parser/ParserContext.java
+++ /dev/null
@@ -1,134 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.parser;
-
-import com.google.dart.compiler.DartCompilationError;
-import com.google.dart.compiler.DartSource;
-import com.google.dart.compiler.Source;
-import com.google.dart.compiler.parser.DartScanner.Location;
-
-/**
- * Abstracts parser and permits marking lexical ranges via event driven methods. Certain IDEs need
- * more location information than just the source line/column/position of an AST node, such as the
- * complete set of lexemes that encompass a given node, e.g. function foo() {}} =>
- * [FUNCTION, SPACE, IDENTIFIER, LPAREN, RPAREN, SPACE, LBRACE, RBRACE].This interface allows a
- * parser to mark the begin and end of each non-terminal AST node in a lexical stream.
- */
-public interface ParserContext {
-
-  /**
-   * Consume the current token, and advance to the next one, skipping whitespace and comment
-   * tokens.
-   */
-  void advance();
-
-  /**
-   * Called at the beginning of a non-terminal rule. The purpose for this method
-   * is to record any information that might be needed at the end of the rule
-   * (such as the current source position) as well as any state necessary to be
-   * able to roll back to the state just prior to the invocation of this method.
-   *
-   * @see #done(T)
-   * @see #doneWithoutConsuming(T)
-   * @see #rollback()
-   */
-  void begin();
-
-  /**
-   * Called at the end of a non-terminal rule to mark the end of the non-terminal
-   * node. This method consumes any information saved by the {@link #begin()}
-   * method, updating the node with any saved information (such as its position
-   * in the source) as appropriate.
-   *
-   * @param result the non-terminal node being ended
-   *
-   * @return the non-terminal node that should be included in the AST structure,
-   *         which is typically the same as the argument
-   *
-   * @see #begin()
-   * @see #doneWithoutConsuming(T)
-   * @see #rollback()
-   */
-  <T> T done(T result);
-
-  /**
-   * Called at the end of a non-terminal rule to mark the end of the non-terminal
-   * node. Unlike {@link #done()}, this method does not consume any information
-   * saved by the {@link #begin()} method, but does update the node with any
-   * saved information (such as its position in the source) as appropriate.
-   *
-   * @param result the non-terminal node being ended
-   *
-   * @return the non-terminal node that should be included in the AST structure,
-   *         which is typically the same as the argument
-   *
-   * @see #begin()
-   * @see #doneWithoutConsuming(T)
-   * @see #rollback()
-   */
-  <T> T doneWithoutConsuming(T result);
-
-  /**
-   * Log a parse error for the current lexical range.
-   * @param dartError helpful error messaging describing what the expected tokens were
-   */
-  void error(DartCompilationError dartError);
-
-  /**
-   * Called by the {@link DartParser} before parsing given {@link DartSource}.
-   */
-  void unitAboutToCompile(DartSource source, boolean diet);
-
-  /**
-   * Return the current token.
-   */
-  Token getCurrentToken();
-
-  /**
-   * Return Source if present.
-   */
-  Source getSource();
-
-  /**
-   * Return location information for the current token.
-   */
-  DartScanner.Location getTokenLocation();
-
-  /**
-   * Return the string value, if any, of the current token (e.g. IDENTIFIER)
-   */
-  String getTokenString();
-
-  /**
-   * Peek ahead without advancing the lexer.
-   */
-  Token peek(int steps);
-
-  /**
-   * Return location information for the token that is 'n' tokens ahead of the current token.
-   */
-  Location peekTokenLocation(int n);
-
-  /**
-   * Set the next token to be returned.
-   */
-  void replaceNextToken(Token token);
-
-  /**
-   * Rolls back the current token to the position when {@link begin()} was
-   * called.
-   *
-   * @see #begin()
-   * @see #done(T)
-   * @see #doneWithoutConsuming(T)
-   */
-  void rollback();
-
-  /**
-   * Peek ahead, for the value, without advancing the lexer.
-   */
-  String peekTokenString(int steps);
-
-}
diff --git a/compiler/java/com/google/dart/compiler/parser/ParserErrorCode.java b/compiler/java/com/google/dart/compiler/parser/ParserErrorCode.java
deleted file mode 100644
index 5fb33c9..0000000
--- a/compiler/java/com/google/dart/compiler/parser/ParserErrorCode.java
+++ /dev/null
@@ -1,197 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.parser;
-
-import com.google.dart.compiler.ErrorCode;
-import com.google.dart.compiler.ErrorSeverity;
-import com.google.dart.compiler.SubSystem;
-
-/**
- * {@link ErrorCode}s for parser.
- * <p>
- * The convention in this file (with some exceptions) is that the enumeration name matches at least
- * the beginning default English translation of the message.
- */
-public enum ParserErrorCode implements ErrorCode {
-  ABSTRACT_MEMBER_IN_INTERFACE("Abstract members are not allowed in interfaces"),
-  ABSTRACT_METHOD_WITH_BODY("Abstract method cannot have a body"),
-  ABSTRACT_TOP_LEVEL_ELEMENT("Only class can be abstract top-level element"),
-  BREAK_OUTSIDE_OF_LOOP("'break' used outside of loop, case statement"),
-  BUILT_IN_IDENTIFIER_AS_TYPE_NAME("Built-in identifier cannot be used as type name"),
-  BUILT_IN_IDENTIFIER_AS_TYPEDEF_NAME("Built-in identifier can not be used as type alias name"),
-  BUILT_IN_IDENTIFIER_AS_TYPE_VARIABLE_NAME("Built-in identifier can not be used as type variable name"),
-  CANNOT_MIX_OPTIONAL_AND_NAMED_PARAMETERS("Cannot mix both optional and named parameters in the same function"),
-  CATCH_OR_FINALLY_EXPECTED("catch or finally clause expected."),
-  CONTINUE_IN_CASE_MUST_HAVE_LABEL("'continue' in case statement must have a label as a target."),
-  CONTINUE_OUTSIDE_OF_LOOP("'continue' used outside of loop or case statement"),
-  DEFAULT_VALUE_CAN_NOT_BE_SPECIFIED_IN_CLOSURE(
-      "Default values cannot be specified in closure parameter"),
-  DEFAULT_VALUE_CAN_NOT_BE_SPECIFIED_IN_TYPEDEF(
-      "Default values cannot be specified in closure type definition"),
-  DEFAULT_POSITIONAL_PARAMETER("Positional parameters cannot have default values"),
-  DEPRECATED_CATCH("This style of catch clause has been deprecated. Please use the 'on' <type> " +
-      "'catch' '(' <identifier> (',' <identifier>)? ')' form."),
-  DEPRECATED_ABSTRACT_METHOD(ErrorSeverity.WARNING, "Modifier 'abstract' is deprecated for methods without body. Remove it."),
-  DEPRECATED_FUNCTION_LITERAL("Deprecated function literal syntax, remove return type and name"),
-  DEPRECATED_GETTER("The presence of parentheses after the name of the getter "
-      + "has been deprecated and will soon be disallowed. Please remove the parentheses."),
-  DEPRECATED_INTERFACE("Deprecated declaration of the 'interface', use abstract 'class' instead"),
-  DEPRECATED_USE_OF_FACTORY_KEYWORD("Deprecated use of the 'factory' keyword: use 'default' instead"),
-  DEPRECATED_RAW_STRING("The use of '@' to prefix a raw string has been deprecated; use 'r' instead"),
-  DEPRECATED_RESOURCE_DIRECTIVE("The #resource directive has been deprecated and will soon be disallowed"),
-  DEPRECATED_STRICT_EQ("Deprecated use of '===', use 'identical()' or '==' instead."),
-  DEPRECATED_STRICT_NE("Deprecated use of '!==', use '!identical()' or '!=' instead."),
-  DEPRECATED_LIBRARY_DIRECTIVE("The '#library(url)' directive has been deprecated, use 'library name' instead"),
-  DEPRECATED_IMPORT_DIRECTIVE("The '#import(url)' directive has been deprecated, use 'import url' instead"),
-  DEPRECATED_SOURCE_DIRECTIVE("The '#source(url)' directive has been deprecated, use 'part url' instead"),
-  DIRECTIVE_OUT_OF_ORDER("Directive out of order"),
-  DISALLOWED_ABSTRACT_KEYWORD("Abstract keyword not allowed here"),
-  // TODO(zundel): error message needs JUnit test (unreachable code?)
-  DISALLOWED_FACTORY_KEYWORD("Factory keyword not allowed here"),
-  DISALLOWED_STATIC_KEYWORD("Static keyword not allowed here"),
-  ESCAPED_NEWLINE("Escaped new-line characters are not allowed in string literals"),
-  EXPECTED_ARRAY_OR_MAP_LITERAL("Expected array or map literal"),
-  // TODO(zundel): error message needs JUnit test (unreachable code?)
-  EXPECTED_CASE_OR_DEFAULT("Expected 'case' or 'default'"),
-  EXPECTED_CLASS_DECLARATION_LBRACE("Expected '{' in class or interface declaration"),
-  // TODO(zundel): error message needs JUnit test
-  EXPECTED_COMMA_OR_RIGHT_BRACE("Expected ',' or '}'"),
-  EXPECTED_COMMA_OR_RIGHT_PAREN("Expected ',' or ')', but got '%s'"),
-  // TODO(zundel): error message needs JUnit test
-  EXPECTED_EOS("Unexpected token '%s' (expected end of file)"),
-  EXPECTED_EXPORT("Expected 'export'"),
-  // TODO(zundel): error message needs JUnit test
-  EXPECTED_EXPRESSION_AFTER_COMMA("Expected expression after comma"),
-  EXPECTED_EXTENDS("Expected 'extends'"),
-  EXPECTED_FUNCTION_STATEMENT_BODY("Expected function statement body"),
-  // TODO(zundel): error message needs JUnit test
-  EXPECTED_IDENTIFIER("Expected identifier"),
-  // TODO(zundel): error message needs JUnit test
-  EXPECTED_LEFT_PAREN("'(' expected"),
-  EXPECTED_PREFIX_KEYWORD("Expected 'prefix' after comma"),
-  EXPECTED_PREFIX_IDENTIFIER("Prefix string can only contain valid identifier characters"),
-  // TODO(zundel): error message needs JUnit test
-  EXPECTED_SEMICOLON("Expected ';'"),
-  // TODO(zundel): error message needs JUnit test
-  EXPECTED_STRING_LITERAL("Expected string literal"),
-  // TODO(zundel): error message needs JUnit test (unreachable code?)
-  EXPECTED_STRING_LITERAL_MAP_ENTRY_KEY("Expected string literal for map entry key"),
-  EXPECTED_TOKEN("Unexpected token '%s' (expected '%s')"),
-  // TODO(zundel): error message needs JUnit test
-  EXPECTED_VAR_FINAL_OR_TYPE("Expected 'var', 'final' or type"),
-  EXPORT_WITHOUT_LIBRARY_DIRECTIVE("Only library can use 'export' directive"),
-  EXTERNAL_ABSTRACT("External methods cannot be abstract"),
-  EXTERNAL_ONLY_METHOD("Only a top-level function, a method, a getter, a setter or an non-redirecting constructor can be specified as external"),
-  EXTERNAL_METHOD_BODY("External methods cannot have body"),
-  INVALID_SEPARATOR_FOR_NAMED("Use ':' between a named parameter and its value"),
-  INVALID_SEPARATOR_FOR_OPTIONAL("Use '=' between an optional parameter and its value"),
-  INVALID_UNICODE_NORMALIZATION("Source code should be normalized to Unicode Normalization Form C"),
-  // TODO(zundel): this error message is out of date
-  NATIVE_ONLY_CLASS("Native keyword can be specified only for classes"),
-  NATIVE_ONLY_CORE_LIB("Native keyword can be used only in corelib"),
-  FACTORY_CANNOT_BE_ABSTRACT("A factory cannot be abstract"),
-  FACTORY_CANNOT_BE_STATIC("A factory cannot be static"),
-  FACTORY_CANNOT_BE_TOP_LEVEL("A factory cannot be top level, it must be a member of a class"),
-  FACTORY_MEMBER_IN_INTERFACE("Factory members are not allowed in interfaces"),
-  FINAL_IS_NOT_ALLOWED_ON_A_METHOD_DEFINITION("'final' is not allowed on a method definition"),
-  FOR_IN_WITH_COMPLEX_VARIABLE("Only simple variables can be assigned to in a for-in construct"),
-  FOR_IN_WITH_MULTIPLE_VARIABLES("Too many variable declarations in a for-in construct"),
-  FOR_IN_WITH_VARIABLE_INITIALIZER("Cannot initialize for-in variables"),
-  FORMAL_PARAMETER_IS_CONST("Formal parameters cannot be declared 'const'"),
-  FUNCTION_TYPED_PARAMETER_IS_FINAL("Formal parameter with a function type cannot be const"),
-  FUNCTION_TYPED_PARAMETER_IS_VAR("Formal parameter with a function type cannot be var"),
-  FUNCTION_NAME_EXPECTED_IDENTIFIER("Function name expected to be an identifier"),
-  ILLEGAL_ASSIGNMENT_TO_NON_ASSIGNABLE("Illegal assignment to non-assignable expression"),
-  // TODO(zundel): error message needs JUnit test
-  ILLEGAL_NUMBER_OF_PARAMETERS("Illegal number of parameters"),
-  IMPLEMENTS_BEFORE_EXTENDS("The extends clause must be before the implements clause"),
-  IMPLEMENTS_BEFORE_WITH("The with clause must be before the implements clause"),
-  INCOMPLETE_STRING_LITERAL("Incomplete string literal"),
-  INTERFACE_METHOD_WITH_BODY("Interface method cannot have a body"),
-  // TODO(zundel): error message needs JUnit test
-  INVALID_FIELD_DECLARATION("Wrong syntax for field declaration"),
-  INVALID_IDENTIFIER("The token '%s' cannot be used as an identifier"),
-  INVALID_OPERATOR_CHAINING("Cannot chain '%s'"),
-  LABEL_NOT_FOLLOWED_BY_CASE_OR_DEFAULT("Label not followed by 'case', 'default', or statement"),
-  LOCAL_CANNOT_BE_STATIC("Local function cannot be static"),
-  MISSING_FUNCTION_NAME(ErrorSeverity.WARNING, "a function name is required for a declaration"),
-  MISSING_NAMED_PARAMETER_END("Expected '}' to close the list of named parameters"),
-  MISSING_OPTIONAL_PARAMETER_END("Expected ']' to close the list of optional parameters"),
-  MULTIPLE_EXTENDS_CLAUSES("Each class definition can have at most one extends clause"),
-  MULTIPLE_IMPLEMENTS_CLAUSES("Each class definition can have at most one implements clause"),
-  MULTIPLE_WITH_CLAUSES("Each class definition can have at most one with clause"),
-  NAMED_PARAMETER_NOT_ALLOWED("Named parameter is not allowed for operator or setter method"),
-  NO_SPACE_AFTER_PLUS("Cannot have space between plus and numeric literal"),
-  NO_SOUP_FOR_YOU("Too many errors"),
-  NO_UNARY_PLUS_OPERATOR("No unary plus operator in Dart"),
-  NON_CONST_MAP_LITERAL_STATEMENT("Map literals appearing as a statement must be 'const'"),
-  NON_FINAL_STATIC_MEMBER_IN_INTERFACE("Non-final/const static members are not allowed in interfaces"),
-  ONLY_FACTORIES_CAN_REDIRECT("Only factory constructors can redirect to another constructor"),
-  ONLY_ONE_LIBRARY_DIRECTIVE("Only one library directive may be declared in a file"),
-  OPERATOR_CANNOT_BE_STATIC("Operators cannot be static"),
-  OPERATOR_IS_NOT_USER_DEFINABLE("Operator is not user definable"),
-  OPTIONAL_POSITIONAL_PARAMETER_NOT_ALLOWED("Optional positional parameter is not allowed for operator or setter method"),
-  POSITIONAL_AFTER_NAMED_ARGUMENT("Positional argument after named argument"),
-  REDIRECTING_CONSTRUCTOR_CANNOT_HAVE_A_BODY("Redirecting constructor cannot have a body"),
-  REDIRECTING_CONSTRUCTOR_PARAM("Redirecting constructor cannot have initializers"),
-  REDIRECTING_CONSTRUCTOR_ITSELF("Redirecting constructor cannot have initializers"),
-  REDIRECTING_CONSTRUCTOR_MULTIPLE("Multiple redirecting constructor invocations"),
-  REDIRECTING_CONSTRUCTOR_OTHER("Redirecting constructor cannot have initializers"),
-  STATIC_MEMBERS_CANNOT_BE_ABSTRACT("Static members cannot be abstract"),
-  SUPER_CONSTRUCTOR_MULTIPLE("'super' must be called only once in the initialization list"),
-  SUPER_CANNOT_BE_USED_AS_THE_SECOND_OPERAND(
-      "'super' cannot be used as the second operand in a binary expression."),
-  SUPER_IS_NOT_VALID_AS_A_BOOLEAN_OPERAND("'super' is not valid as a boolean operand"),
-  SUPER_IS_NOT_VALID_ALONE_OR_AS_A_BOOLEAN_OPERAND(
-      "'super' is not valid alone or as a boolean operand"),
-  TOP_LEVEL_CANNOT_BE_STATIC("Top-level field or method cannot be static"),
-  UNREACHABLE_CODE_IN_CASE(ErrorSeverity.WARNING, "Unreachable code in case statement"),
-  UNEXPECTED_TOKEN("Unexpected token '%s'"),
-  UNEXPECTED_TOKEN_IN_STRING_INTERPOLATION("Unexpected token in string interpolation: %s"),
-  URI_CANNOT_USE_INTERPOLATION("URIs cannot use string interpolation"),
-  VAR_IS_NOT_ALLOWED_ON_A_METHOD_DEFINITION("'var' is not allowed on a method definition"),
-  VOID_FIELD("Field cannot be of type void"),
-  VOID_PARAMETER("Parameter cannot be of type void"),
-  WITH_BEFORE_EXTENDS("The extends clause must be before the with clause"),
-  WITH_WITHOUT_EXTENDS("The with clause cannot be used without an extends clause");
-
-  private final ErrorSeverity severity;
-  private final String message;
-
-  /**
-   * Initialize a newly created error code to have the given message and ERROR severity.
-   */
-  private ParserErrorCode(String message) {
-    this(ErrorSeverity.ERROR, message);
-  }
-
-  /**
-   * Initialize a newly created error code to have the given severity and message.
-   */
-  private ParserErrorCode(ErrorSeverity severity, String message) {
-    this.severity = severity;
-    this.message = message;
-  }
-
-  @Override
-  public String getMessage() {
-    return message;
-  }
-
-  @Override
-  public ErrorSeverity getErrorSeverity() {
-    return severity;
-  }
-
-  @Override
-  public SubSystem getSubSystem() {
-    return SubSystem.PARSER;
-  }
-
-  @Override
-  public boolean needsRecompilation() {
-    return true;
-  }
-}
\ No newline at end of file
diff --git a/compiler/java/com/google/dart/compiler/parser/Terminals.java b/compiler/java/com/google/dart/compiler/parser/Terminals.java
deleted file mode 100644
index 85c8e67..0000000
--- a/compiler/java/com/google/dart/compiler/parser/Terminals.java
+++ /dev/null
@@ -1,19 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-package com.google.dart.compiler.parser;
-
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-/**
- * Put this annotation on a method in {@link DartParser} so that code will not consume any tokens
- * that a method further up on the stack can use to properly terminate a statement.
- */
-@Retention(value=RetentionPolicy.RUNTIME)
-@Target(value=ElementType.METHOD)
-public @interface Terminals {
- public Token[] tokens() default {};
-}
diff --git a/compiler/java/com/google/dart/compiler/parser/Token.java b/compiler/java/com/google/dart/compiler/parser/Token.java
deleted file mode 100644
index 53b3dde..0000000
--- a/compiler/java/com/google/dart/compiler/parser/Token.java
+++ /dev/null
@@ -1,268 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.parser;
-
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * Dart tokens and associated data.
- *
- * Note: Token ordinals matter for some accessors, so don't change the order of these without
- * knowing what you're doing.
- */
-public enum Token {
-  /* End-of-stream. */
-  EOS(null, 0),
-
-  /* Punctuators. */
-  AT("@", 0),
-  LPAREN("(", 0),
-  RPAREN(")", 0),
-  LBRACK("[", 0),
-  RBRACK("]", 0),
-  LBRACE("{", 0),
-  RBRACE("}", 0),
-  COLON(":", 0),
-  SEMICOLON(";", 0),
-  PERIOD(".", 0),
-  CASCADE("..", 2),
-  ELLIPSIS("...", 0),
-  COMMA(",", 0),
-  CONDITIONAL("?", 3),
-  ARROW("=>", 0),
-
-  /* Assignment operators. */
-  ASSIGN("=", 1),
-  ASSIGN_BIT_OR("|=", 1),
-  ASSIGN_BIT_XOR("^=", 1),
-  ASSIGN_BIT_AND("&=", 1),
-  ASSIGN_SHL("<<=", 1),
-  ASSIGN_SAR(">>=", 1),
-  ASSIGN_ADD("+=", 1),
-  ASSIGN_SUB("-=", 1),
-  ASSIGN_MUL("*=", 1),
-  ASSIGN_DIV("/=", 1),
-  ASSIGN_MOD("%=", 1),
-  ASSIGN_TRUNC("~/=", 1),
-
-  /* Binary operators sorted by precedence. */
-  OR("||", 4),
-  AND("&&", 5),
-  BIT_OR("|", 6),
-  BIT_XOR("^", 7),
-  BIT_AND("&", 8),
-  SHL("<<", 11),
-  SAR(">>", 11),
-  ADD("+", 12),
-  SUB("-", 12),
-  MUL("*", 13),
-  DIV("/", 13),
-  TRUNC("~/", 13),
-  MOD("%", 13),
-
-  /* Compare operators sorted by precedence. */
-  EQ("==", 9),
-  NE("!=", 9),
-  EQ_STRICT("===", 9),
-  NE_STRICT("!==", 9),
-  LT("<", 10),
-  GT(">", 10),
-  LTE("<=", 10),
-  GTE(">=", 10),
-  AS("as", 10),
-  IS("is", 10),
-
-  /* Unary operators. */
-  NOT("!", 0),
-  BIT_NOT("~", 0),
-
-  /* Count operators (also unary). */
-  INC("++", 0),
-  DEC("--", 0),
-
-  /* [] operator overloading. */
-  INDEX("[]", 0),
-  ASSIGN_INDEX("[]=", 0),
-
-  /* Keywords. */
-  ASSERT("assert", 0),
-  BREAK("break", 0),
-  CASE("case", 0),
-  CATCH("catch", 0),
-  CLASS("class",0),
-  CONST("const", 0),
-  CONTINUE("continue", 0),
-  DEFAULT("default", 0),
-  DO("do", 0),
-  ELSE("else", 0),
-  EXTENDS("extends", 0),
-  FINAL("final", 0),
-  FINALLY("finally", 0),
-  FOR("for", 0),
-  IF("if", 0),
-  IN("in", 0),
-  NEW("new", 0),
-  RETHROW("rethrow", 0),
-  RETURN("return", 0),
-  SUPER("super", 0),
-  SWITCH("switch", 0),
-  THIS("this", 0),
-  THROW("throw", 0),
-  TRY("try", 0),
-  VAR("var", 0),
-  VOID("void", 0),
-  WHILE("while", 0),
-  WITH("with", 0),
-
-  /* Literals. */
-  NULL_LITERAL("null", 0),
-  TRUE_LITERAL("true", 0),
-  FALSE_LITERAL("false", 0),
-  HEX_LITERAL(null, 0),
-  INTEGER_LITERAL(null, 0),
-  DOUBLE_LITERAL(null, 0),
-  STRING(null, 0),
-
-  /** String interpolation and string templates. */
-  STRING_SEGMENT(null, 0),
-  STRING_LAST_SEGMENT(null, 0),
-  // STRING_EMBED_EXP_START does not have a unique string representation in the code:
-  //   "$id" yields the token STRING_EMBED_EXP_START after the '$', and similarly
-  //   "${id}" yield the same token for '${'.
-  STRING_EMBED_EXP_START(null, 0),
-  STRING_EMBED_EXP_END(null, 0),
-
-  // Note: STRING_EMBED_EXP_END uses the same symbol as RBRACE, but it is
-  // recognized by the scanner when closing embedded expressions in string
-  // interpolation and string templates.
-
-  /* Directives */
-  LIBRARY("#library", 0),
-  IMPORT("#import", 0),
-  SOURCE("#source", 0),
-  RESOURCE("#resource", 0),
-  NATIVE("#native", 0),
-
-  /* Identifiers (not keywords). */
-  IDENTIFIER(null, 0),
-  WHITESPACE(null, 0),
-
-  /* Pseudo tokens. */
-  // If you add another pseudo token, don't forget to update the predicate below.
-  ILLEGAL(null, 0),
-  COMMENT(null, 0),
-
-  /**
-   * Non-token to be used by tools where a value outside the range of anything
-   * returned by the scanner is needed. This is the equivalent of -1 in a C
-   * tokenizer.
-   *
-   * This token is never returned by the scanner. It must have an ordinal
-   * value outside the range of all tokens returned by the scanner.
-   */
-  NON_TOKEN(null, 0);
-
-  private static Map<String, Token> tokens = new HashMap<String, Token>();
-
-  static {
-    for (Token tok : Token.values()) {
-      if (tok.syntax_ != null) {
-        tokens.put(tok.syntax_, tok);
-      }
-    }
-  }
-
-  /**
-   * Given a string finds the corresponding token. Pseudo tokens (EOS, ILLEGAL and COMMENT) are
-   * ignored.
-   */
-  public static Token lookup(String syntax) {
-    Token token = tokens.get(syntax);
-    if ("as".equals(syntax)) {
-      return IDENTIFIER;
-    }
-    if (token == null) {
-      return IDENTIFIER;
-    }
-    return token;
-  }
-
-  private final String syntax_;
-  private final int precedence_;
-
-  /**
-   * The <CODE>syntax</CODE> parameter serves two purposes: 1. map tokens that
-   * look like identifiers ("null", "true", etc.) to their correct token.
-   * 2. Find the string-representation of operators.</BR>
-   * When it is <CODE>null</CODE> then the token either doesn't have a unique
-   * representation, or it is a pseudo token (which doesn't physically appear
-   * in the source).
-   */
-  Token(String syntax, int precedence) {
-    syntax_ = syntax;
-    precedence_ = precedence;
-  }
-
-  public Token asBinaryOperator() {
-    int ordinal = ordinal() - ASSIGN_BIT_OR.ordinal() + BIT_OR.ordinal();
-    return values()[ordinal];
-  }
-
-  public int getPrecedence() {
-    return precedence_;
-  }
-
-  public String getSyntax() {
-    return syntax_;
-  }
-
-  public boolean isEqualityOperator() {
-    int ordinal = ordinal();
-    return EQ.ordinal() <= ordinal && ordinal <= NE_STRICT.ordinal();
-  }
-
-  public boolean isRelationalOperator() {
-    int ordinal = ordinal();
-    return LT.ordinal() <= ordinal && ordinal <= GTE.ordinal();
-  }
-
-  public boolean isAssignmentOperator() {
-    int ordinal = ordinal();
-    return ASSIGN.ordinal() <= ordinal && ordinal <= ASSIGN_TRUNC.ordinal();
-  }
-
-  public boolean isBinaryOperator() {
-    int ordinal = ordinal();
-    return (ASSIGN.ordinal() <= ordinal && ordinal <= IS.ordinal())
-        || (ordinal == COMMA.ordinal());
-  }
-
-  public boolean isCountOperator() {
-    int ordinal = ordinal();
-    return INC.ordinal() <= ordinal && ordinal <= DEC.ordinal();
-  }
-
-  public boolean isUnaryOperator() {
-    int ordinal = ordinal();
-    return NOT.ordinal() <= ordinal && ordinal <= DEC.ordinal();
-  }
-
-  public boolean isUserDefinableOperator() {
-    int ordinal = ordinal();
-    return ((BIT_OR.ordinal() <= ordinal && ordinal <= GTE.ordinal())
-        || this == BIT_NOT || this == INDEX || this == ASSIGN_INDEX)
-        && this != NE && this != EQ_STRICT && this != NE_STRICT;
-  }
-
-  @Override
-  public String toString() {
-    String result = getSyntax();
-    if (result == null) {
-      return name();
-    }
-    return result;
-  }
-}
diff --git a/compiler/java/com/google/dart/compiler/resolver/AbstractNodeElement.java b/compiler/java/com/google/dart/compiler/resolver/AbstractNodeElement.java
deleted file mode 100644
index 2c5a703..0000000
--- a/compiler/java/com/google/dart/compiler/resolver/AbstractNodeElement.java
+++ /dev/null
@@ -1,88 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.resolver;
-
-import com.google.dart.compiler.ast.DartNode;
-import com.google.dart.compiler.ast.DartObsoleteMetadata;
-import com.google.dart.compiler.ast.Modifiers;
-import com.google.dart.compiler.common.SourceInfo;
-import com.google.dart.compiler.type.Type;
-import com.google.dart.compiler.type.Types;
-import com.google.dart.compiler.util.StringInterner;
-
-abstract class AbstractNodeElement implements Element, NodeElement {
-  private final DartNode node;
-  private final String name;
-  private SourceInfo sourceInfo;
-
-  AbstractNodeElement(DartNode node, String name) {
-    // TODO(scheglov) in the future we will not use ASTNode and remove null check
-    this.sourceInfo = node != null ? node.getSourceInfo() : SourceInfo.UNKNOWN;
-    this.node = node;
-    this.name = StringInterner.intern(name);
-  }
-
-  @Override
-  public DartNode getNode() {
-    return node;
-  }
-
-  @Override
-  public String getName() {
-    return name;
-  }
-
-  @Override
-  public String getOriginalName() {
-    return name;
-  }
-
-  @Override
-  public abstract ElementKind getKind();
-
-  @Override
-  public final String toString() {
-    return getKind() + " " + getName();
-  }
-
-  @Override
-  public Type getType() {
-    return Types.newDynamicType();
-  }
-
-  void setType(Type type) {
-    throw new UnsupportedOperationException();
-  }
-
-  @Override
-  public boolean isDynamic() {
-    return false;
-  }
-
-  @Override
-  public DartObsoleteMetadata getMetadata() {
-    return DartObsoleteMetadata.EMPTY;
-  }
-
-  @Override
-  public Modifiers getModifiers() {
-    return Modifiers.NONE;
-  }
-
-  @Override
-  public EnclosingElement getEnclosingElement() {
-    return null;
-  }
-
-  @Override
-  public SourceInfo getNameLocation() {
-    return sourceInfo;
-  }
-  
-  @Override
-  public final SourceInfo getSourceInfo() {
-    return sourceInfo;
-  }
-}
diff --git a/compiler/java/com/google/dart/compiler/resolver/ClassAliasElement.java b/compiler/java/com/google/dart/compiler/resolver/ClassAliasElement.java
deleted file mode 100644
index c392fbd..0000000
--- a/compiler/java/com/google/dart/compiler/resolver/ClassAliasElement.java
+++ /dev/null
@@ -1,11 +0,0 @@
-// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.resolver;
-
-/**
- * A class type alias.
- */
-public interface ClassAliasElement extends ClassElement {
-}
diff --git a/compiler/java/com/google/dart/compiler/resolver/ClassElement.java b/compiler/java/com/google/dart/compiler/resolver/ClassElement.java
deleted file mode 100644
index e219536..0000000
--- a/compiler/java/com/google/dart/compiler/resolver/ClassElement.java
+++ /dev/null
@@ -1,62 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.resolver;
-
-import com.google.dart.compiler.type.InterfaceType;
-import com.google.dart.compiler.type.Type;
-
-import java.util.List;
-
-public interface ClassElement extends EnclosingElement {
-  void setType(InterfaceType type);
-
-  @Override
-  InterfaceType getType();
-
-  List<Type> getTypeParameters();
-
-  InterfaceType getSupertype();
-
-  InterfaceType getDefaultClass();
-
-  void setSupertype(InterfaceType element);
-
-  List<? extends ConstructorElement> getConstructors();
-
-  LibraryElement getLibrary();
-
-  List<InterfaceType> getInterfaces();
-  
-  List<InterfaceType> getMixins();
-
-  List<InterfaceType> getAllSupertypes() throws CyclicDeclarationException;
-
-  String getNativeName();
-
-  /**
-   * FIXME(scheglov) We use this in {@link Resolver} to check that "factory" clause is exactly
-   * same as declaration of factory class.
-   */
-  String getDeclarationNameWithTypeParameters();
-
-  boolean isObject();
-
-  boolean isObjectChild();
-
-  ConstructorElement lookupConstructor(String name);
-
-  /**
-   * @return the {@link Element}s which are declared in superclass or interfaces, but not
-   *         implemented in this class. May be <code>null</code> if this {@link ClassElement} is
-   *         {@link ClassNodeElement} and was not analyzed yet.
-   */
-  List<Element> getUnimplementedMembers();
-  
-  int getOpenBraceOffset();
-  
-  int getCloseBraceOffset();
-  
-  boolean hasSuperInvocation();
-}
diff --git a/compiler/java/com/google/dart/compiler/resolver/ClassElementImplementation.java b/compiler/java/com/google/dart/compiler/resolver/ClassElementImplementation.java
deleted file mode 100644
index 83b6631..0000000
--- a/compiler/java/com/google/dart/compiler/resolver/ClassElementImplementation.java
+++ /dev/null
@@ -1,463 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.resolver;
-
-import com.google.common.collect.Lists;
-import com.google.dart.compiler.ast.ASTNodes;
-import com.google.dart.compiler.ast.DartClass;
-import com.google.dart.compiler.ast.DartClassTypeAlias;
-import com.google.dart.compiler.ast.DartDeclaration;
-import com.google.dart.compiler.ast.DartIdentifier;
-import com.google.dart.compiler.ast.DartObsoleteMetadata;
-import com.google.dart.compiler.ast.DartStringLiteral;
-import com.google.dart.compiler.ast.DartTypeParameter;
-import com.google.dart.compiler.ast.Modifiers;
-import com.google.dart.compiler.common.SourceInfo;
-import com.google.dart.compiler.type.InterfaceType;
-import com.google.dart.compiler.type.Type;
-
-import java.util.ArrayList;
-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.concurrent.atomic.AtomicReference;
-
-class ClassElementImplementation extends AbstractNodeElement implements ClassNodeElement {
-  private InterfaceType type;
-  private InterfaceType supertype;
-  private InterfaceType defaultClass;
-  private final List<InterfaceType> interfaces = Lists.newArrayList();
-  private final List<InterfaceType> mixins = Lists.newArrayList();
-  private final boolean isInterface;
-  private final String nativeName;
-  private final DartObsoleteMetadata metadata;
-  private final Modifiers modifiers;
-  private final AtomicReference<List<InterfaceType>> allSupertypes =
-      new AtomicReference<List<InterfaceType>>();
-  private final SourceInfo nameLocation;
-  private final String declarationNameWithTypeParameter;
-  private List<Element> unimplementedMembers;
-  private final int openBraceOffset;
-  private final int closeBraceOffset;
-  private final boolean hasSuperInvocation;
-
-  // declared volatile for thread-safety
-  @SuppressWarnings("unused")
-  private volatile Set<InterfaceType> subtypes;
-
-  private final List<ConstructorNodeElement> constructors = Lists.newArrayList();
-  private final ElementMap members = new ElementMap();
-
-  private final LibraryElement library;
-
-  private static ThreadLocal<Set<Element>> seenSupertypes = new ThreadLocal<Set<Element>>() {
-    @Override
-    protected Set<Element> initialValue() {
-      return new HashSet<Element>();
-    }
-  };
-
-  ClassElementImplementation(DartClass node, String name, String nativeName,
-                             LibraryElement library) {
-    super(node, name);
-    this.nativeName = nativeName;
-    this.library = library;
-    if (node != null) {
-      isInterface = node.isInterface();
-      metadata = node.getObsoleteMetadata();
-      modifiers = node.getModifiers();
-      nameLocation = node.getName().getSourceInfo();
-      declarationNameWithTypeParameter = createDeclarationName(node.getName(), node.getTypeParameters());
-      openBraceOffset = node.getOpenBraceOffset();
-      closeBraceOffset = node.getCloseBraceOffset();
-      hasSuperInvocation = ASTNodes.hasSuperInvocation(node);
-    } else {
-      isInterface = false;
-      metadata = DartObsoleteMetadata.EMPTY;
-      modifiers = Modifiers.NONE;
-      nameLocation = SourceInfo.UNKNOWN;
-      declarationNameWithTypeParameter = "";
-      openBraceOffset = -1;
-      closeBraceOffset = -1;
-      hasSuperInvocation = false;
-    }
-  }
-  
-  ClassElementImplementation(DartClassTypeAlias node, String name,
-      LibraryElement library) {
-    super(node, name);
-    this.nativeName = null;
-    this.library = library;
-    if (node != null) {
-      isInterface = false;
-      metadata = node.getObsoleteMetadata();
-      modifiers = node.getModifiers();
-      nameLocation = node.getName().getSourceInfo();
-      declarationNameWithTypeParameter = createDeclarationName(node.getName(), node.getTypeParameters());
-      openBraceOffset = -1;
-      closeBraceOffset = -1;
-      hasSuperInvocation = false;
-    } else {
-      isInterface = false;
-      metadata = DartObsoleteMetadata.EMPTY;
-      modifiers = Modifiers.NONE;
-      nameLocation = SourceInfo.UNKNOWN;
-      declarationNameWithTypeParameter = "";
-      openBraceOffset = -1;
-      closeBraceOffset = -1;
-      hasSuperInvocation = false;
-    }
-  }
-
-  @Override
-  public DartDeclaration<?> getNode() {
-    return (DartDeclaration<?>) super.getNode();
-  }
-
-  @Override
-  public SourceInfo getNameLocation() {
-    return nameLocation;
-  }
-
-  @Override
-  public void setType(InterfaceType type) {
-    this.type = type;
-  }
-
-  @Override
-  public InterfaceType getType() {
-    return type;
-  }
-
-  @Override
-  public List<Type> getTypeParameters() {
-    return getType().getArguments();
-  }
-
-  @Override
-  public InterfaceType getSupertype() {
-    return supertype;
-  }
-
-  @Override
-  public InterfaceType getDefaultClass() {
-    return defaultClass;
-  }
-
-  @Override
-  public void setSupertype(InterfaceType supertype) {
-    if (this.supertype != null) {
-      this.supertype.unregisterSubClass(this);
-    }
-    this.supertype = supertype;
-    if (this.supertype != null) {
-      this.supertype.registerSubClass(this);
-    }
-  }
-
-  void setDefaultClass(InterfaceType element) {
-    defaultClass = element;
-  }
-
-  @Override
-  public Iterable<NodeElement> getMembers() {
-    return new Iterable<NodeElement>() {
-      // The only use case for calling getMembers() is for iterating through the
-      // members. You should not be able to add or remove members through the
-      // object returned by this method. Returning members or members.value()
-      // would allow such direct manipulation which might be problematic for
-      // keeping the element model consistent.
-      //
-      // On the other hand, we don't want to make a defensive copy of the list
-      // because that makes this method expensive. This method should not be
-      // expensive because the IDE may be using it in interactive scenarios.
-      // Strictly speaking, we should also wrap the iterator as we don't want
-      // the method Iterator.remove to be used either.
-      @Override
-      public Iterator<NodeElement> iterator() {
-        return members.values().iterator();
-      }
-    };
-  }
-
-  @Override
-  public List<ConstructorNodeElement> getConstructors() {
-    return constructors;
-  }
-
-  @Override
-  public List<InterfaceType> getInterfaces() {
-    return interfaces;
-  }
-  
-  @Override
-  public List<InterfaceType> getMixins() {
-    return mixins;
-  }
-
-  @Override
-  public ElementKind getKind() {
-    return ElementKind.CLASS;
-  }
-
-  @Override
-  public boolean isInterface() {
-    return isInterface;
-  }
-
-  @Override
-  public DartObsoleteMetadata getMetadata() {
-    return metadata;
-  }
-
-  @Override
-  public Modifiers getModifiers() {
-    return modifiers;
-  }
-
-  @Override
-  public LibraryElement getLibrary() {
-    return library;
-  }
-
-  @Override
-  public String getNativeName() {
-    return nativeName;
-  }
-
-  @Override
-  public String getDeclarationNameWithTypeParameters() {
-    return declarationNameWithTypeParameter;
-  }
-
-  void addMethod(MethodNodeElement member) {
-    String name = member.getName();
-    if (member.getModifiers().isOperator()) {
-      name = "operator " + name;
-    }
-    members.add(name, member);
-  }
-
-  void addConstructor(ConstructorNodeElement member) {
-    constructors.add(member);
-  }
-
-  void addField(FieldNodeElement member) {
-    members.add(member.getName(), member);
-  }
-
-  void addInterface(InterfaceType type) {
-    interfaces.add(type);
-    type.registerSubClass(this);
-  }
-  
-  void addMixin(InterfaceType type) {
-    mixins.add(type);
-  }
-
-  Element findElement(String name) {
-    // Temporary find all strategy to get things working.
-    // Match resolve order in Resolver.visitMethodInvocation
-    Element element = lookupLocalMethod(name);
-    if (element != null) {
-      return element;
-    }
-    element = lookupLocalField(name);
-    if (element != null) {
-      return element;
-    }
-    if (type != null) {
-      for (Type arg : type.getArguments()) {
-        if (arg.getElement().getName().equals(name)) {
-          return arg.getElement();
-        }
-      }
-    }
-    // Don't look for constructors, they are in a different namespace.
-    return null;
-  }
-
-  /**
-   * Lookup a constructor declared in this class. Note that a class may define
-   * constructors for interfaces in case the class is a default implementation.
-   *
-   * @param type The type of the object this constructor is creating.
-   * @param name The constructor name ("" if unnamed).
-   *
-   * @return The constructor found in the class, or null if not found.
-   */
-  ConstructorElement lookupConstructor(ClassElement type, String name) {
-    for (ConstructorElement element : constructors) {
-      if (element.getConstructorType().equals(type) && element.getName().equals(name)) {
-        return element;
-      }
-    }
-    return null;
-  }
-
-  @Override
-  public ConstructorElement lookupConstructor(String name) {
-    // Lookup a constructor that creates instances of this class.
-    return lookupConstructor(this, name);
-  }
-
-  @Override
-  public Element lookupLocalElement(String name) {
-    return members.get(name);
-  }
-
-  FieldElement lookupLocalField(String name) {
-    return (FieldElement) members.get(name, ElementKind.FIELD);
-  }
-
-  MethodElement lookupLocalMethod(String name) {
-    return (MethodElement) members.get(name, ElementKind.METHOD);
-  }
-
-  public static ClassElementImplementation fromNode(DartClass node, LibraryElement library) {
-    DartStringLiteral nativeName = node.getNativeName();
-    String nativeNameString = (nativeName == null ? null : nativeName.getValue());
-    return new ClassElementImplementation(node, node.getClassName(), nativeNameString, library);
-  }
-  
-  static class ClassAliasElementImplementation extends ClassElementImplementation implements ClassAliasElement {
-    ClassAliasElementImplementation(DartClassTypeAlias node, String name, LibraryElement library) {
-      super(node, name, library);
-    }
-  }
-  public static ClassAliasElement fromNode(DartClassTypeAlias node, LibraryElement library) {
-    return new ClassAliasElementImplementation(node, node.getClassName(), library);
-  }
-
-  public static ClassElementImplementation named(String name) {
-    return new ClassElementImplementation(null, name, null, null);
-  }
-
-  @Override
-  public boolean isObject() {
-    return supertype == null;
-  }
-
-  @Override
-  public boolean isObjectChild() {
-    return supertype != null && supertype.getElement().isObject();
-  }
-
-  @Override
-  public EnclosingElement getEnclosingElement() {
-    return library;
-  }
-
-  @Override
-  public List<InterfaceType> getAllSupertypes()
-      throws CyclicDeclarationException {
-    List<InterfaceType> list = allSupertypes.get();
-    if (list == null) {
-      allSupertypes.compareAndSet(null, computeAllSupertypes());
-      list = allSupertypes.get();
-    }
-    return list;
-  }
-
-  private List<InterfaceType> computeAllSupertypes()
-      throws CyclicDeclarationException {
-    Map<ClassElement, InterfaceType> interfaces = new HashMap<ClassElement, InterfaceType>();
-    if (!seenSupertypes.get().add(this)) {
-      throw new CyclicDeclarationException(this);
-    }
-    ArrayList<InterfaceType> supertypes = new ArrayList<InterfaceType>();
-    try {
-      for (InterfaceType intf : getInterfaces()) {
-        addInterfaceToSupertypes(interfaces, supertypes, intf);
-      }
-      for (InterfaceType mix : getMixins()) {
-        addInterfaceToSupertypes(interfaces, supertypes, mix);
-      }
-      for (InterfaceType intf : getInterfaces()) {
-        for (InterfaceType t : intf.getElement().getAllSupertypes()) {
-          if (!t.getElement().isObject()) {
-            addInterfaceToSupertypes(interfaces, supertypes,
-                               t.subst(intf.getArguments(),
-                                       intf.getElement().getTypeParameters()));
-          }
-        }
-      }
-      if (supertype != null) {
-        for (InterfaceType t : supertype.getElement().getAllSupertypes()) {
-          if (t.getElement().isInterface()) {
-            addInterfaceToSupertypes(interfaces, supertypes,
-                               t.subst(supertype.getArguments(),
-                                       supertype.getElement().getTypeParameters()));
-          }
-        }
-        supertypes.add(supertype);
-        for (InterfaceType t : supertype.getElement().getAllSupertypes()) {
-          if (!t.getElement().isInterface()) {
-            supertypes.add(t.subst(supertype.getArguments(),
-                                   supertype.getElement().getTypeParameters()));
-          }
-        }
-      }
-    } finally {
-      seenSupertypes.get().remove(this);
-    }
-    return supertypes;
-  }
-
-  private String createDeclarationName(
-      DartIdentifier name, List<DartTypeParameter> typeParameters) {
-    StringBuilder builder = new StringBuilder();
-    builder.append(name.toSource());
-    int count = typeParameters.size();
-    if (count > 0) {
-      builder.append("<");
-      for (int i = 0; i < count; i++) {
-        if (i > 0) {
-          builder.append(", ");
-        }
-        builder.append(typeParameters.get(i).toSource());
-      }
-      builder.append(">");
-    }
-    return builder.toString();
-  }
-
-  private void addInterfaceToSupertypes(Map<ClassElement, InterfaceType> interfaces,
-                                  ArrayList<InterfaceType> supertypes,
-                                  InterfaceType intf) {
-    InterfaceType existing = interfaces.put(intf.getElement(), intf);
-    if (existing == null || !(existing.equals(intf))){
-      supertypes.add(intf);
-    }
-  }
-
-  @Override
-  public List<Element> getUnimplementedMembers() {
-    return unimplementedMembers;
-  }
-
-  @Override
-  public void setUnimplementedMembers(List<Element> members) {
-    this.unimplementedMembers = members;
-  }
-  
-  @Override
-  public int getOpenBraceOffset() {
-    return openBraceOffset;
-  }
-  
-  @Override
-  public int getCloseBraceOffset() {
-    return closeBraceOffset;
-  }
-  
-  @Override
-  public boolean hasSuperInvocation() {
-    return hasSuperInvocation;
-  }
-}
diff --git a/compiler/java/com/google/dart/compiler/resolver/ClassElementUnion.java b/compiler/java/com/google/dart/compiler/resolver/ClassElementUnion.java
deleted file mode 100644
index 59e5fad..0000000
--- a/compiler/java/com/google/dart/compiler/resolver/ClassElementUnion.java
+++ /dev/null
@@ -1,211 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.resolver;
-
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.Iterables;
-import com.google.common.collect.Lists;
-import com.google.dart.compiler.ast.DartObsoleteMetadata;
-import com.google.dart.compiler.ast.Modifiers;
-import com.google.dart.compiler.common.SourceInfo;
-import com.google.dart.compiler.type.InterfaceType;
-import com.google.dart.compiler.type.Type;
-
-import java.util.List;
-
-public class ClassElementUnion implements ClassElement {
-  
-  private final InterfaceType unionType;
-  private final List<InterfaceType> types;
-  private final InterfaceType lastType;
-  private final ClassElement lastElement;
-
-  public ClassElementUnion(InterfaceType unionType, List<InterfaceType> types) {
-    this.unionType = unionType;
-    this.types = types;
-    this.lastType = types.get(types.size() - 1);
-    this.lastElement = lastType.getElement();
-  }
-
-  @Override
-  public void setType(InterfaceType type) {
-    throw new UnsupportedOperationException();
-  }
-
-  @Override
-  public InterfaceType getType() {
-    return unionType;
-  }
-
-  @Override
-  public List<Type> getTypeParameters() {
-    return ImmutableList.<Type>of();
-  }
-
-  @Override
-  public InterfaceType getSupertype() {
-    return lastElement.getSupertype();
-  }
-
-  @Override
-  public InterfaceType getDefaultClass() {
-    throw new UnsupportedOperationException();
-  }
-
-  @Override
-  public void setSupertype(InterfaceType element) {
-    throw new UnsupportedOperationException();
-  }
-
-  @Override
-  public LibraryElement getLibrary() {
-    return null;
-  }
-
-  @Override
-  public List<InterfaceType> getInterfaces() {
-    List<InterfaceType> interfaces = Lists.newArrayList();
-    for (InterfaceType type : types) {
-      if (type.getElement().isInterface()) {
-        interfaces.add(type);
-      }
-    }
-    return interfaces;
-  }
-  
-  @Override
-  public List<InterfaceType> getMixins() {
-    return ImmutableList.of();
-  }
-
-  @Override
-  public List<InterfaceType> getAllSupertypes() throws CyclicDeclarationException {
-    List<InterfaceType> superTypes = Lists.newArrayList();
-    for (InterfaceType type : types) {
-      superTypes.addAll(type.getElement().getAllSupertypes());
-    }
-    return superTypes;
-  }
-
-  @Override
-  public String getNativeName() {
-    return lastElement.getNativeName();
-  }
-
-  @Override
-  public String getDeclarationNameWithTypeParameters() {
-    return lastElement.getDeclarationNameWithTypeParameters();
-  }
-
-  @Override
-  public boolean isObject() {
-    return lastElement.isObject();
-  }
-
-  @Override
-  public boolean isObjectChild() {
-    return lastElement.isObjectChild();
-  }
-
-  @Override
-  public ConstructorElement lookupConstructor(String name) {
-    throw new UnsupportedOperationException();
-  }
-
-  @Override
-  public List<Element> getUnimplementedMembers() {
-    throw new UnsupportedOperationException();
-  }
-
-  @Override
-  public Element lookupLocalElement(String name) {
-    for (InterfaceType type : types) {
-      Element localElement = type.getElement().lookupLocalElement(name);
-      if (localElement != null) {
-        return localElement;
-      }
-    }
-    return null;
-  }
-
-  @Override
-  public boolean isInterface() {
-    return lastElement.isInterface();
-  }
-
-  @Override
-  public String getOriginalName() {
-    return lastElement.getOriginalName();
-  }
-
-  @Override
-  public String getName() {
-    return lastElement.getName();
-  }
-
-  @Override
-  public ElementKind getKind() {
-    return ElementKind.CLASS;
-  }
-
-  @Override
-  public boolean isDynamic() {
-    return false;
-  }
-
-  @Override
-  public Modifiers getModifiers() {
-    return Modifiers.NONE;
-  }
-
-  @Override
-  public DartObsoleteMetadata getMetadata() {
-    return null;
-  }
-
-  @Override
-  public EnclosingElement getEnclosingElement() {
-    return lastElement.getEnclosingElement();
-  }
-
-  @Override
-  public SourceInfo getNameLocation() {
-    return lastElement.getNameLocation();
-  }
-
-  @Override
-  public SourceInfo getSourceInfo() {
-    return lastElement.getSourceInfo();
-  }
-
-  @Override
-  public Iterable<Element> getMembers() {
-    List<Iterable<? extends Element>> typeMembers = Lists.newArrayList();
-    for (InterfaceType type : types) {
-      typeMembers.add(type.getElement().getMembers());
-    }
-    return Iterables.concat(typeMembers);
-  }
-
-  @Override
-  public List<ConstructorNodeElement> getConstructors() {
-    throw new UnsupportedOperationException();
-  }
-
-  @Override
-  public int getOpenBraceOffset() {
-    return -1;
-  }
-  
-  @Override
-  public int getCloseBraceOffset() {
-    return -1;
-  }
-  
-  @Override
-  public boolean hasSuperInvocation() {
-    return false;
-  }
-}
diff --git a/compiler/java/com/google/dart/compiler/resolver/ClassNodeElement.java b/compiler/java/com/google/dart/compiler/resolver/ClassNodeElement.java
deleted file mode 100644
index ba10ff6..0000000
--- a/compiler/java/com/google/dart/compiler/resolver/ClassNodeElement.java
+++ /dev/null
@@ -1,22 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-package com.google.dart.compiler.resolver;
-
-import com.google.dart.compiler.ast.DartNode;
-
-import java.util.List;
-
-/**
- * Extension of {@link ClassElement} which is based on {@link DartNode}.
- */
-public interface ClassNodeElement extends ClassElement, NodeElement {
-  Iterable<NodeElement> getMembers();
-
-  List<ConstructorNodeElement> getConstructors();
-
-  /**
-   * Sets {@link Element}s which as not implemented in this {@link ClassElement}.
-   */
-  void setUnimplementedMembers(List<Element> members);
-}
diff --git a/compiler/java/com/google/dart/compiler/resolver/ClassScope.java b/compiler/java/com/google/dart/compiler/resolver/ClassScope.java
deleted file mode 100644
index e5c393f..0000000
--- a/compiler/java/com/google/dart/compiler/resolver/ClassScope.java
+++ /dev/null
@@ -1,93 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.resolver;
-
-import com.google.dart.compiler.type.InterfaceType;
-
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-
-/**
- * Lexical scope corresponding to a class body.
- */
-class ClassScope extends Scope {
-  private final ClassElement classElement;
-
-  ClassScope(ClassElement classElement, Scope parent) {
-    super(classElement.getName(), parent.getLibrary(), parent);
-    this.classElement = classElement;
-  }
-
-  @Override
-  public Element declareElement(String name, Element element) {
-    throw new AssertionError("not supported yet");
-  }
-
-  @Override
-  public Element findElement(LibraryElement inLibrary, String name) {
-    return findElement(inLibrary, name, new HashSet<ClassElement>());
-  }
-
-  protected Element findElement(LibraryElement inLibrary, String name, Set<ClassElement> examinedTypes) {
-    Element element = super.findElement(inLibrary, name);
-    if (element != null) {
-      return element;
-    }
-    examinedTypes.add(classElement);
-    InterfaceType superclass = classElement.getSupertype();
-    if (superclass != null) {
-      Element enclosing = superclass.getElement().getEnclosingElement();
-      ClassElement superclassElement = superclass.getElement();
-      if (!examinedTypes.contains(superclassElement)) {
-        ClassScope scope = new ClassScope(superclassElement,
-                                          new Scope("library", (LibraryElement) enclosing));
-        element = scope.findElement(inLibrary, name, examinedTypes);
-        switch (ElementKind.of(element)) {
-          case TYPE_VARIABLE:
-            return null;
-          case NONE:
-            break;
-          default:
-            return element;
-        }
-      }
-    }
-
-    List<InterfaceType> interfaces = classElement.getInterfaces();
-    for (int i = 0, size = interfaces.size(); i < size; i++) {
-      InterfaceType intf = interfaces.get(i);
-      ClassElement intfElement = intf.getElement();
-      if (!examinedTypes.contains(intfElement)) {
-        Element enclosing = intf.getElement().getEnclosingElement();
-        ClassScope scope = new ClassScope(intfElement,
-                                          new Scope("library", (LibraryElement) enclosing));
-        element = scope.findElement(inLibrary, name, examinedTypes);
-        if (element != null) {
-          return element;
-        }
-      }
-    }
-    
-    List<InterfaceType> mixins = classElement.getMixins();
-    for (int i = 0, size = mixins.size(); i < size; i++) {
-      InterfaceType mixin = mixins.get(i);
-      ClassElement mixinElement = mixin.getElement();
-      if (!examinedTypes.contains(mixinElement)) {
-        MixinScope scope = new MixinScope(mixinElement);
-        element = scope.findElement(inLibrary, name);
-        if (element != null) {
-          return element;
-        }
-      }
-    }
-    return null;
-  }
-
-  @Override
-  public Element findLocalElement(String name) {
-    return Elements.findElement(classElement, name);
-  }
-}
diff --git a/compiler/java/com/google/dart/compiler/resolver/CompileTimeConstantAnalyzer.java b/compiler/java/com/google/dart/compiler/resolver/CompileTimeConstantAnalyzer.java
deleted file mode 100644
index f0dc599..0000000
--- a/compiler/java/com/google/dart/compiler/resolver/CompileTimeConstantAnalyzer.java
+++ /dev/null
@@ -1,822 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.resolver;
-
-import com.google.common.collect.Maps;
-import com.google.common.collect.Sets;
-import com.google.dart.compiler.DartCompilationError;
-import com.google.dart.compiler.DartCompilationPhase;
-import com.google.dart.compiler.DartCompilerContext;
-import com.google.dart.compiler.ast.ASTVisitor;
-import com.google.dart.compiler.ast.DartArrayLiteral;
-import com.google.dart.compiler.ast.DartBinaryExpression;
-import com.google.dart.compiler.ast.DartBooleanLiteral;
-import com.google.dart.compiler.ast.DartCase;
-import com.google.dart.compiler.ast.DartClass;
-import com.google.dart.compiler.ast.DartConditional;
-import com.google.dart.compiler.ast.DartDeclaration;
-import com.google.dart.compiler.ast.DartDoubleLiteral;
-import com.google.dart.compiler.ast.DartExpression;
-import com.google.dart.compiler.ast.DartField;
-import com.google.dart.compiler.ast.DartFunction;
-import com.google.dart.compiler.ast.DartFunctionObjectInvocation;
-import com.google.dart.compiler.ast.DartIdentifier;
-import com.google.dart.compiler.ast.DartInitializer;
-import com.google.dart.compiler.ast.DartIntegerLiteral;
-import com.google.dart.compiler.ast.DartInvocation;
-import com.google.dart.compiler.ast.DartMapLiteral;
-import com.google.dart.compiler.ast.DartMapLiteralEntry;
-import com.google.dart.compiler.ast.DartMethodDefinition;
-import com.google.dart.compiler.ast.DartMethodInvocation;
-import com.google.dart.compiler.ast.DartNamedExpression;
-import com.google.dart.compiler.ast.DartNewExpression;
-import com.google.dart.compiler.ast.DartNode;
-import com.google.dart.compiler.ast.DartNullLiteral;
-import com.google.dart.compiler.ast.DartParameter;
-import com.google.dart.compiler.ast.DartParenthesizedExpression;
-import com.google.dart.compiler.ast.DartPropertyAccess;
-import com.google.dart.compiler.ast.DartRedirectConstructorInvocation;
-import com.google.dart.compiler.ast.DartStringInterpolation;
-import com.google.dart.compiler.ast.DartStringLiteral;
-import com.google.dart.compiler.ast.DartSuperConstructorInvocation;
-import com.google.dart.compiler.ast.DartSuperExpression;
-import com.google.dart.compiler.ast.DartThisExpression;
-import com.google.dart.compiler.ast.DartUnaryExpression;
-import com.google.dart.compiler.ast.DartUnit;
-import com.google.dart.compiler.ast.DartUnqualifiedInvocation;
-import com.google.dart.compiler.ast.DartVariable;
-import com.google.dart.compiler.ast.DartVariableStatement;
-import com.google.dart.compiler.ast.Modifiers;
-import com.google.dart.compiler.common.HasSourceInfo;
-import com.google.dart.compiler.type.Type;
-import com.google.dart.compiler.type.TypeKind;
-
-import java.math.BigInteger;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-/**
- * Given an tree, finds all compile-time constant expressions, and determines if
- * each expression matches all the rules for a compile-time constant. Emits a
- * resolution error if not.
- *
- * This script doesn't just resolve expressions, it also sets types to the
- * extent needed to validate compile-time constant expressions (boolean, int,
- * double, and string types might be set)
- */
-public class CompileTimeConstantAnalyzer {
-
-  private class ExpressionVisitor extends ASTVisitor<Void> {
-    private boolean checkBoolean(DartNode x, Type type) {
-      // Spec 0.11 allows using "null" literal in place of bool.
-      if (x instanceof DartNullLiteral) {
-        return true;
-      }
-      // check actual type
-      if (!type.equals(boolType)) {
-        context.onError(new DartCompilationError(x,
-            ResolverErrorCode.EXPECTED_CONSTANT_EXPRESSION_BOOLEAN, type
-                .toString()));
-        return false;
-      }
-      return true;
-    }
-
-    private boolean checkInt(DartNode x, Type type) {
-      // Spec 0.11 allows using "null" literal in place of num.
-      if (x instanceof DartNullLiteral) {
-        return true;
-      }
-      // check actual type
-      if (!type.equals(intType)) {
-        context
-            .onError(new DartCompilationError(x,
-                ResolverErrorCode.EXPECTED_CONSTANT_EXPRESSION_INT, type
-                    .toString()));
-        return false;
-      }
-      return true;
-    }
-
-    private boolean checkString(DartNode x, Type type) {
-      if (!type.equals(stringType)) {
-        context
-            .onError(new DartCompilationError(x,
-                ResolverErrorCode.EXPECTED_CONSTANT_EXPRESSION_STRING, type
-                    .toString()));
-        return false;
-      }
-      return true;
-    }
-
-    private boolean checkNumber(DartNode x, Type type) {
-      // for "const" constructor we check "potentially constant expression",
-      // so suppose that parameters have correct type
-      if (TypeKind.of(type) == TypeKind.DYNAMIC && x.getElement() != null
-          && x.getElement().getEnclosingElement() instanceof MethodElement) {
-        return true;
-      }
-      // Spec 0.11 allows using "null" literal in place of num.
-      if (x instanceof DartNullLiteral) {
-        return true;
-      }
-      // check actual type
-      if (!(type.equals(numType) || type.equals(intType) || type
-          .equals(doubleType))) {
-        context.onError(new DartCompilationError(x,
-            ResolverErrorCode.EXPECTED_CONSTANT_EXPRESSION_NUMBER, type
-                .toString()));
-
-        return false;
-      }
-      return true;
-    }
-
-    private boolean checkNumberBooleanOrStringType(DartNode x, Type type) {
-      if (type.equals(intType) || type.equals(boolType)
-          || type.equals(numType) || type.equals(doubleType)
-          || type.equals(stringType) || (x instanceof DartNullLiteral)) {
-        return true;
-      } else if (x instanceof DartStringInterpolation) {
-        DartStringInterpolation interpolation = (DartStringInterpolation) x;
-        for (DartExpression expression : interpolation.getExpressions()) {
-          Type expressionType = getMostSpecificType(expression);
-          if (!checkNumberBooleanOrStringType(expression, expressionType)) {
-            return false;
-          }
-        }
-        return true;
-      }
-      context.onError(new DartCompilationError(x,
-          ResolverErrorCode.EXPECTED_CONSTANT_EXPRESSION_STRING_NUMBER_BOOL,
-          type.toString()));
-      return false;
-    }
-
-    /**
-     * Logs a general message "expected a constant expression" error. Use a more
-     * specific error message when possible.
-     */
-    private void expectedConstant(HasSourceInfo x) {
-      context.onError(new DartCompilationError(x, ResolverErrorCode.EXPECTED_CONSTANT_EXPRESSION));
-    }
-
-    /**
-     * Determine the most specific type assigned to an expression node. Prefer
-     * the setting in the expression's element if present. Otherwise, use a type
-     * tagged in the expression node itself.
-     *
-     * @return a non <code>null</code> type value. Dynamic if none other can be
-     * determined.
-     */
-    private Type getMostSpecificType(DartNode node) {
-      if (node != null) {
-        Type type = inferredTypes.get(node);
-        if (type != null) {
-          return type;
-        }
-        Element element = node.getElement();
-        if (Elements.isFunctionIdentical(element)) {
-          return boolType;
-        }
-        if (element != null) {
-          type = element.getType();
-          if (type != null && TypeKind.of(type) != TypeKind.DYNAMIC) {
-            return type;
-          }
-          if (element instanceof VariableElement) {
-            VariableElement variable = (VariableElement) element;
-            if (variable.getModifiers().isConstant()) {
-              DartExpression value = variable.getDefaultValue();
-              if (value != null) {
-                type = getMostSpecificType(value);
-              }
-            }
-          } else if (element instanceof FieldElement) {
-            FieldElement field = (FieldElement) element;
-            if (field.getModifiers().isConstant()) {
-              type = field.getConstantType();
-            }
-          }
-          if (type != null) {
-            return type;
-          }
-        }
-      }
-      return dynamicType;
-    }
-
-    private void rememberInferredType(DartNode x, Type type) {
-      if (type != null && ! type.equals(dynamicType)) {
-        inferredTypes.put(x,  type);
-      }
-    }
-
-    @Override
-    public Void visitArrayLiteral(DartArrayLiteral x) {
-      if (!x.isConst()) {
-        expectedConstant(x);
-      } else {
-        for (DartExpression expr : x.getExpressions()) {
-          expr.accept(this);
-        }
-      }
-      return null;
-    }
-
-    @Override
-    public Void visitBinaryExpression(DartBinaryExpression x) {
-      x.visitChildren(this);
-
-      DartExpression lhs = x.getArg1();
-      DartExpression rhs = x.getArg2();
-      Type lhsType = getMostSpecificType(lhs);
-      Type rhsType = getMostSpecificType(rhs);
-
-      switch (x.getOperator()) {
-        case NE:
-        case EQ:
-        case NE_STRICT:
-        case EQ_STRICT:
-          if (checkNumberBooleanOrStringType(lhs, lhsType)
-              && checkNumberBooleanOrStringType(rhs, rhsType)) {
-            rememberInferredType(x, boolType);
-          }
-          break;
-
-        case AND:
-        case OR:
-          if (checkBoolean(lhs, lhsType) && checkBoolean(rhs, rhsType)) {
-            rememberInferredType(x, boolType);
-          }
-          break;
-
-        case BIT_XOR:
-        case BIT_AND:
-        case BIT_OR:
-        case SAR:
-        case SHL:
-          if (checkInt(lhs, lhsType) && checkInt(rhs, rhsType)) {
-            rememberInferredType(x, intType);
-          }
-          break;
-
-        case ADD:
-          if (lhsType.equals(stringType)) {
-            // TODO(zundel): remove this when + no longer acceptable as string concat operator
-            if (checkString(rhs, rhsType)) {
-              rememberInferredType(x, stringType);
-            }
-          } else {
-            checkMathExpression(x, lhs, rhs, lhsType, rhsType);
-          }
-          break;
-        case SUB:
-        case MUL:
-        case DIV:
-          checkMathExpression(x, lhs, rhs, lhsType, rhsType);
-          break;
-        case TRUNC:
-        case MOD:
-          reportExceptionIfZeroLiteral(x, rhs);
-          if (checkNumber(lhs, lhsType) && checkNumber(rhs, rhsType)) {
-            rememberInferredType(x, intType);
-          }
-          break;
-        case LT:
-        case GT:
-        case LTE:
-        case GTE:
-          if (checkNumber(lhs, lhsType) && checkNumber(rhs, rhsType)) {
-            rememberInferredType(x, boolType);
-          }
-          break;
-
-        default:
-          // all other operators...
-          expectedConstant(x);
-      }
-      return null;
-    }
-    
-    private void reportExceptionIfZeroLiteral(HasSourceInfo target, DartExpression e) {
-      if (e instanceof DartIntegerLiteral) {
-        DartIntegerLiteral literal = (DartIntegerLiteral) e;
-        if (literal.getValue().equals(BigInteger.ZERO)) {
-          context.onError(new DartCompilationError(target,
-              ResolverErrorCode.CONSTANTS_EVALUATION_EXCEPTION));
-        }
-      }
-    }
-
-    private void checkMathExpression(DartBinaryExpression x,
-                                     DartExpression lhs, DartExpression rhs,
-                                     Type lhsType, Type rhsType) {
-      if (checkNumber(lhs, lhsType) && checkNumber(rhs, rhsType)) {
-        if (lhsType.equals(intType) && rhsType.equals(intType)) {
-          rememberInferredType(x, intType);
-        } else if (lhsType.equals(doubleType) && rhsType.equals(doubleType)) {
-          rememberInferredType(x, doubleType);
-        } else  if (lhsType.equals(doubleType) && rhsType.equals(intType)
-            || lhsType.equals(intType) && rhsType.equals(doubleType)) {
-          rememberInferredType(x, doubleType);
-        } else {
-          rememberInferredType(x, numType);
-        }
-      }
-    }
-
-    @Override
-    public Void visitBooleanLiteral(DartBooleanLiteral x) {
-      rememberInferredType(x, boolType);
-      return null;
-    }
-
-    @Override
-    public Void visitDoubleLiteral(DartDoubleLiteral x) {
-      rememberInferredType(x, doubleType);
-      return null;
-    }
-    
-    @Override
-    public Void visitConditional(DartConditional node) {
-      expectedConstant(node);
-      return null;
-    }
-
-    @Override
-    public Void visitField(DartField x) {
-      x.visitChildren(this);
-      if (x.getType() == null || x.getType().equals(dynamicType)) {
-        Type type = getMostSpecificType(x.getValue());
-        rememberInferredType(x, type);
-      }
-      return null;
-    }
-
-    @Override
-    public Void visitFunction(DartFunction x) {
-      // No need to traverse, functions are always disallowed.
-      expectedConstant(x);
-      return null;
-    }
-
-    @Override
-    public Void visitFunctionObjectInvocation(DartFunctionObjectInvocation x) {
-      // No need to traverse, function object invocations are always disallowed.
-      expectedConstant(x);
-      return null;
-    }
-
-    @Override
-    public Void visitNamedExpression(DartNamedExpression node) {
-      return node.getExpression().accept(this);
-    }
-
-    @Override
-    public Void visitIdentifier(DartIdentifier x) {
-      x.visitChildren(this);
-
-      if (x.getParent() instanceof DartDeclaration<?>
-          && ((DartDeclaration<?>) x.getParent()).getName() == x) {
-        return null;
-      }
-
-      Element element = x.getElement();
-      boolean elementIsStatic = element != null
-          && (element.getModifiers().isStatic() || Elements.isTopLevel(element));
-      switch (ElementKind.of(element)) {
-        case CLASS:
-        case PARAMETER:
-        case LIBRARY_PREFIX:
-          break;
-
-        case FIELD:
-          FieldElement fieldElement = (FieldElement) element;
-
-          // Check for circular references.
-          if (element != null && visitedElements.contains(element)) {
-            context.onError(new DartCompilationError(x, ResolverErrorCode.CIRCULAR_REFERENCE));
-            rememberInferredType(x, getMostSpecificType(x));
-            return null;
-          }
-          visitedElements.add(element);
-
-          // Should be declared as constant.
-          if (!element.getModifiers().isConstant()) {
-            expectedConstant(x);
-          }
-
-          // Infer type by visiting node or cached from Element.
-          final Type inferredType;
-          if (element instanceof FieldNodeElement) {
-            FieldNodeElement fieldNodeElement = (FieldNodeElement) element;
-            DartNode fieldNode = fieldNodeElement.getNode();
-            fieldNode.accept(this);
-            inferredType = getMostSpecificType(fieldNode);
-            fieldNodeElement.setConstantType(inferredType);
-          } else if (fieldElement.getType() != null
-              && !fieldElement.getType().equals(dynamicType)) {
-            inferredType = fieldElement.getType();
-          } else {
-            inferredType = fieldElement.getConstantType();
-          }
-
-          // Done with this element.
-          visitedElements.remove(element);
-
-          rememberInferredType(x, inferredType);
-          break;
-          
-        case VARIABLE:
-          if (!element.getModifiers().isConstant()) {
-            expectedConstant(x);
-          }
-          return null;
-
-        case METHOD:
-          if (!elementIsStatic) {
-            expectedConstant(x);
-          }
-          return null;
-
-        case NONE:
-        default:
-          expectedConstant(x);
-          return null;
-      }
-      return null;
-    }
-
-
-    @Override
-    public Void visitIntegerLiteral(DartIntegerLiteral x) {
-      rememberInferredType(x, intType);
-      return null;
-    }
-
-    @Override
-    public Void visitInvocation(DartInvocation x) {
-      // No need to traverse, invocations are always disallowed.
-      expectedConstant(x);
-      return null;
-    }
-
-    @Override
-    public Void visitMapLiteral(DartMapLiteral x) {
-      if (!x.isConst()) {
-        expectedConstant(x);
-      } else {
-        for (DartMapLiteralEntry entry : x.getEntries()) {
-          entry.accept(this);
-        }
-      }
-      return null;
-    }
-
-    @Override
-    public Void visitMethodInvocation(DartMethodInvocation x) {
-      // No need to traverse, method invocations are always disallowed.
-      expectedConstant(x);
-      return null;
-    }
-
-    @Override
-    public Void visitNewExpression(DartNewExpression x) {
-      if (!x.isConst()) {
-        expectedConstant(x);
-      } else {
-        for (DartExpression arg : x.getArguments()) {
-          arg.accept(this);
-        }
-      }
-      rememberInferredType(x, x.getConstructor().getType());
-      return null;
-    }
-
-    @Override
-    public Void visitParenthesizedExpression(DartParenthesizedExpression x) {
-      x.visitChildren(this);
-      Type type = getMostSpecificType(x.getExpression());
-      rememberInferredType(x, type);
-      return null;
-    }
-
-    @Override
-    public Void visitPropertyAccess(DartPropertyAccess x) {
-      switch (ElementKind.of(x.getRealTarget().getElement())) {
-        case CLASS:
-        case LIBRARY_PREFIX:
-        case LIBRARY:
-        case NONE:
-          // OK.
-          break;
-        default:
-          expectedConstant(x);
-          return null;
-      }
-
-      Type type = getMostSpecificType(x.getName());
-      rememberInferredType(x, type);
-
-      Element element = x.getName().getElement();
-      if (element != null) {
-        // OK. Static method reference.
-        if (ElementKind.of(element) == ElementKind.METHOD && element.getModifiers().isStatic()) {
-          return null;
-        }
-        // OK. Constant field.
-        if (element.getModifiers().isConstant()) {
-          return null;
-        }
-        // Fail.
-        expectedConstant(x);
-      }
-      return null;
-    }
-
-    @Override
-    public Void visitRedirectConstructorInvocation(DartRedirectConstructorInvocation x) {
-      Element element = x.getElement();
-      if (element != null) {
-        if (!element.getModifiers().isConstant()) {
-          expectedConstant(x);
-        }
-      }
-      x.visitChildren(this);
-      return null;
-    }
-
-    @Override
-    public Void visitStringInterpolation(DartStringInterpolation x) {
-      x.visitChildren(this);
-      for (DartExpression expression : x.getExpressions()) {
-        Type expressionType = getMostSpecificType(expression);
-        checkNumberBooleanOrStringType(expression, expressionType);
-      }
-      return null;
-    }
-
-    @Override
-    public Void visitStringLiteral(DartStringLiteral x) {
-      rememberInferredType(x, stringType);
-      return null;
-    }
-
-    @Override
-    public Void visitSuperExpression(DartSuperExpression x) {
-      if (!x.getElement().getModifiers().isConstant()) {
-        expectedConstant(x);
-      }
-      return null;
-    }
-
-    @Override
-    public Void visitThisExpression(DartThisExpression x) {
-      // No need to traverse, this expressions are never constant
-      expectedConstant(x);
-      return null;
-    }
-
-    @Override
-    public Void visitUnaryExpression(DartUnaryExpression x) {
-      x.visitChildren(this);
-
-      Type type = getMostSpecificType(x.getArg());
-      switch (x.getOperator()) {
-        case NOT:
-          if (checkBoolean(x.getArg(), type)) {
-            rememberInferredType(x, boolType);
-          }
-          break;
-        case SUB:
-          if (intType.equals(type)) {
-            rememberInferredType(x, intType);
-          } else if (checkNumber(x.getArg(), type)) {
-            rememberInferredType(x, numType);
-          }
-          break;
-        case BIT_NOT:
-          if (checkInt(x.getArg(), type)) {
-            rememberInferredType(x, intType);
-          }
-          break;
-        default:
-          expectedConstant(x);
-      }
-      return null;
-    }
-
-    @Override
-    public Void visitSuperConstructorInvocation(DartSuperConstructorInvocation x) {
-      x.visitChildren(this);
-      return null;
-    }
-
-    @Override
-    public Void visitUnqualifiedInvocation(DartUnqualifiedInvocation x) {
-      Element element = x.getElement();
-      // "identical"
-      if (Elements.isFunctionIdentical(element)) {
-        x.visitChildren(this);
-        return null;
-      }
-      // No need to traverse, always disallowed.
-      expectedConstant(x);
-      return null;
-    }
-  }
-
-  private class FindCompileTimeConstantExpressionsVisitor extends ASTVisitor<Void> {
-    private ClassElement currentClass;
-    private boolean inConstConstructor;
-
-    @Override
-    public Void visitArrayLiteral(DartArrayLiteral node) {
-      if (node.isConst()) {
-        for (DartExpression expr : node.getExpressions()) {
-          checkConstantExpression(expr);
-        }
-        return null;
-      }
-      return super.visitArrayLiteral(node);
-    }
-
-    @Override
-    public Void visitField(DartField node) {
-      if (node.getParent() != null) {
-        if (node.getModifiers().isConstant()) {
-          Type type = checkConstantExpression(node.getValue());
-          if (node.getElement().getType().equals(dynamicType)) {
-            node.getElement().setConstantType(type);
-          }
-          return null;
-        }
-      }
-      return super.visitField(node);
-    }
-
-    @Override
-    public Void visitClass(DartClass node) {
-      ClassElement oldClassElement = currentClass;
-      currentClass = node.getElement();
-      try {
-        return super.visitClass(node);
-      } finally {
-        currentClass = oldClassElement;
-      }
-    }
-
-    @Override
-    public Void visitMethodDefinition(DartMethodDefinition node) {
-      inConstConstructor = node.getModifiers().isConstant();
-      return super.visitMethodDefinition(node);
-    }
-
-    @Override
-    public Void visitInitializer(DartInitializer node) {
-      if (inConstConstructor) {
-        String name = node.getInitializerName();
-        if (name != null) {
-          Element member = currentClass.lookupLocalElement(name);
-          if (member instanceof FieldElement) {
-            if (member.getModifiers().isFinal()) {
-              checkConstantExpression(node.getValue());
-            }
-          }
-        } else {
-          DartExpression value = node.getValue();
-          if (value instanceof DartSuperConstructorInvocation
-              || value instanceof DartRedirectConstructorInvocation) {
-            List<DartExpression> arguments = ((DartInvocation) value).getArguments();
-            for (DartExpression argument : arguments) {
-              checkConstantExpression(argument);
-            }
-          }
-        }
-      }
-      return super.visitInitializer(node);
-    }
-    
-    @Override
-    public Void visitCase(DartCase node) {
-      checkConstantExpression(node.getExpr());
-      return super.visitCase(node);
-    }
-
-    @Override
-    public Void visitMapLiteral(DartMapLiteral node) {
-      if (node.isConst()) {
-        for (DartMapLiteralEntry entry : node.getEntries()) {
-          checkConstantExpression(entry.getKey());
-          checkConstantExpression(entry.getValue());
-        }
-        return null;
-      }
-      return super.visitMapLiteral(node);
-    }
-
-    @Override
-    public Void visitNewExpression(DartNewExpression node) {
-      if (node.isConst()) {
-        for (DartExpression arg : node.getArguments()) {
-          checkConstantExpression(arg);
-        }
-        return null;
-      }
-      return super.visitNewExpression(node);
-    }
-
-    @Override
-    public Void visitParameter(DartParameter node) {
-      checkConstantExpression(node.getDefaultExpr());
-      List<DartParameter> parameters = node.getFunctionParameters();
-      if (parameters != null) {
-        for (DartParameter parameter : parameters) {
-          visitParameter(parameter);
-        }
-      }
-      return null;
-    }
-
-    @Override
-    public Void visitVariableStatement(DartVariableStatement node) {
-      Modifiers modifiers = node.getModifiers();
-      if (modifiers.isConstant()) {
-        for (DartVariable variable : node.getVariables()) {
-          if (variable.getValue() != null) {
-            checkConstantExpression(variable.getValue());
-          }
-        }
-        return null;
-      }
-      return super.visitVariableStatement(node);
-    }
-
-    @Override
-    public Void visitRedirectConstructorInvocation(DartRedirectConstructorInvocation node) {
-      // Don't evaluate now, wait until it is referenced and evaluate as part of the expression
-      return null;
-    }
-
-    @Override
-    public Void visitSuperConstructorInvocation(DartSuperConstructorInvocation node) {
-      // Don't evaluate now, wait until it is referenced and evaluate as part of the expression
-      return null;
-    }
-  }
-
-  public static class Phase implements DartCompilationPhase {
-    /**
-     * Executes element resolution on the given compilation unit.
-     *
-     * @param context The listener through which compilation errors are reported
-     *          (not <code>null</code>)
-     */
-    @Override
-    public DartUnit exec(DartUnit unit, DartCompilerContext context,
-                         CoreTypeProvider typeProvider) {
-      new CompileTimeConstantAnalyzer(typeProvider, context).exec(unit);
-      return unit;
-    }
-  }
-
-  public Set<Element> visitedElements = Sets.newHashSet();
-
-  public Map<DartNode, Type> inferredTypes = Maps.newHashMap();
-
-  private final DartCompilerContext context;
-  private final Type boolType;
-  private final Type doubleType;
-  private final Type intType;
-  private final Type numType;
-  private final Type stringType;
-  private final Type dynamicType;
-
-  public CompileTimeConstantAnalyzer(CoreTypeProvider typeProvider,
-      DartCompilerContext context) {
-    this.context = context;
-    this.boolType = typeProvider.getBoolType();
-    this.doubleType = typeProvider.getDoubleType();
-    this.intType = typeProvider.getIntType();
-    this.numType = typeProvider.getNumType();
-    this.stringType = typeProvider.getStringType();
-    this.dynamicType = typeProvider.getDynamicType();
-  }
-
-  private Type checkConstantExpression(DartExpression expression) {
-    if (expression != null) {
-      ExpressionVisitor visitor = new ExpressionVisitor();
-      expression.accept(visitor);
-      return visitor.getMostSpecificType(expression);
-    }
-    return null;
-  }
-
-  public void exec(DartUnit unit) {
-    unit.accept(new FindCompileTimeConstantExpressionsVisitor());
-  }
-}
diff --git a/compiler/java/com/google/dart/compiler/resolver/ConstructorElement.java b/compiler/java/com/google/dart/compiler/resolver/ConstructorElement.java
deleted file mode 100644
index 7db795d..0000000
--- a/compiler/java/com/google/dart/compiler/resolver/ConstructorElement.java
+++ /dev/null
@@ -1,28 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-package com.google.dart.compiler.resolver;
-
-public interface ConstructorElement extends MethodElement {
-  /**
-   * Returns the type of the instances created by this constructor. Note that a constructor in a
-   * class may be a default implementation of an interface's constructor.
-   */
-  ClassElement getConstructorType();
-
-  /**
-   * @return the {@link ConstructorElement} in default factory class, may be <code>null</code>.
-   */
-  ConstructorElement getDefaultConstructor();
-  
-  boolean isSynthetic();
-  
-  String getRawName();
-
-  /**
-   * Sets {@link ConstructorElement} in default factory class, may be <code>null</code>.
-   */
-  void setDefaultConstructor(ConstructorElement defaultConstructor);
-  
-  ConstructorElement getRedirectingFactoryConstructor();
-}
diff --git a/compiler/java/com/google/dart/compiler/resolver/ConstructorElementImplementation.java b/compiler/java/com/google/dart/compiler/resolver/ConstructorElementImplementation.java
deleted file mode 100644
index 227daae..0000000
--- a/compiler/java/com/google/dart/compiler/resolver/ConstructorElementImplementation.java
+++ /dev/null
@@ -1,94 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.resolver;
-
-import com.google.dart.compiler.ast.DartIdentifier;
-import com.google.dart.compiler.ast.DartMethodDefinition;
-import com.google.dart.compiler.ast.DartNode;
-import com.google.dart.compiler.ast.DartParameterizedTypeNode;
-import com.google.dart.compiler.ast.DartPropertyAccess;
-
-class ConstructorElementImplementation extends MethodElementImplementation
-    implements ConstructorNodeElement {
-  private final ClassElement constructorType;
-  private final String rawName;
-  private ConstructorElement defaultConstructor;
-  private ConstructorElement redirectingFactoryConstructor;
-
-  private ConstructorElementImplementation(DartMethodDefinition node,
-                             String name,
-                             ClassElement declaringClass,
-                             ClassElement constructorType) {
-    super(node, name, declaringClass);
-    this.constructorType = constructorType;
-    this.rawName = getRawName(node.getName());
-  }
-
-  private static String getRawName(DartNode name) {
-    if (name instanceof DartIdentifier) {
-      return ((DartIdentifier) name).getName();
-    } else if (name instanceof DartParameterizedTypeNode) {
-      return getRawName(((DartParameterizedTypeNode) name).getExpression());
-    } else {
-      DartPropertyAccess propertyAccess = (DartPropertyAccess) name;
-      DartNode qualifier = propertyAccess.getQualifier();
-      if (ElementKind.of(qualifier.getElement()) == ElementKind.CLASS) {
-        return getRawName(qualifier) + "." + getRawName(propertyAccess.getName());
-      } else {
-        return getRawName(propertyAccess.getName());
-      }
-    }
-  }
-
-  public ClassElement getConstructorType() {
-    return constructorType;
-  }
-  
-  @Override
-  public String getRawName() {
-    return rawName;
-  }
-
-  @Override
-  public ElementKind getKind() {
-    return ElementKind.CONSTRUCTOR;
-  }
-
-  @Override
-  public boolean isConstructor() {
-    return true;
-  }
-  
-  @Override
-  public boolean isSynthetic() {
-    return false;
-  }
-
-  @Override
-  public ConstructorElement getDefaultConstructor() {
-    return defaultConstructor;
-  }
-
-  @Override
-  public void setDefaultConstructor(ConstructorElement defaultConstructor) {
-    this.defaultConstructor = defaultConstructor;
-  }
-
-  @Override
-  public ConstructorElement getRedirectingFactoryConstructor() {
-    return redirectingFactoryConstructor;
-  }
-  
-  public void setRedirectingFactoryConstructor(ConstructorElement redirectingFactoryConstructor) {
-    this.redirectingFactoryConstructor = redirectingFactoryConstructor;
-  }
-
-  public static ConstructorElementImplementation fromMethodNode(DartMethodDefinition node,
-                                                  String name,
-                                                  ClassElement declaringClass,
-                                                  ClassElement constructorType) {
-    return new ConstructorElementImplementation(node, name, declaringClass, constructorType);
-  }
-}
diff --git a/compiler/java/com/google/dart/compiler/resolver/ConstructorNodeElement.java b/compiler/java/com/google/dart/compiler/resolver/ConstructorNodeElement.java
deleted file mode 100644
index 35b5c2f..0000000
--- a/compiler/java/com/google/dart/compiler/resolver/ConstructorNodeElement.java
+++ /dev/null
@@ -1,12 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-package com.google.dart.compiler.resolver;
-
-import com.google.dart.compiler.ast.DartNode;
-
-/**
- * Extension of {@link ConstructorElement} which is based on {@link DartNode}.
- */
-public interface ConstructorNodeElement extends ConstructorElement, MethodNodeElement {
-}
diff --git a/compiler/java/com/google/dart/compiler/resolver/CoreTypeProvider.java b/compiler/java/com/google/dart/compiler/resolver/CoreTypeProvider.java
deleted file mode 100644
index 5d319a6..0000000
--- a/compiler/java/com/google/dart/compiler/resolver/CoreTypeProvider.java
+++ /dev/null
@@ -1,40 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.resolver;
-
-import com.google.dart.compiler.type.DynamicType;
-import com.google.dart.compiler.type.InterfaceType;
-import com.google.dart.compiler.type.Type;
-
-public interface CoreTypeProvider {
-
-  InterfaceType getIntType();
-
-  InterfaceType getDoubleType();
-
-  InterfaceType getBoolType();
-
-  InterfaceType getStringType();
-
-  InterfaceType getFunctionType();
-
-  Type getNullType();
-
-  Type getVoidType();
-
-  DynamicType getDynamicType();
-
-  InterfaceType getArrayType(Type elementType);
-  
-  InterfaceType getIteratorType(Type elementType);
-  
-  InterfaceType getMapType(Type key, Type value);
-
-  InterfaceType getObjectType();
-
-  InterfaceType getNumType();
-
-  InterfaceType getTypeType();
-}
diff --git a/compiler/java/com/google/dart/compiler/resolver/CoreTypeProviderImplementation.java b/compiler/java/com/google/dart/compiler/resolver/CoreTypeProviderImplementation.java
deleted file mode 100644
index 337eb3a..0000000
--- a/compiler/java/com/google/dart/compiler/resolver/CoreTypeProviderImplementation.java
+++ /dev/null
@@ -1,133 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.resolver;
-
-import com.google.dart.compiler.DartCompilationError;
-import com.google.dart.compiler.DartCompilerListener;
-import com.google.dart.compiler.parser.DartScanner.Location;
-import com.google.dart.compiler.type.DynamicType;
-import com.google.dart.compiler.type.InterfaceType;
-import com.google.dart.compiler.type.Type;
-import com.google.dart.compiler.type.Types;
-
-import java.util.Arrays;
-
-public class CoreTypeProviderImplementation implements CoreTypeProvider {
-  private final InterfaceType intType;
-  private final InterfaceType doubleType;
-  private final InterfaceType numType;
-  private final InterfaceType boolType;
-  private final InterfaceType stringType;
-  private final InterfaceType functionType;
-  private final InterfaceType arrayType;
-  private final DynamicType dynamicType;
-  private final Type voidType;
-  private final Type nullType;
-  private final InterfaceType mapType;
-  private final InterfaceType objectType;
-  private final InterfaceType iteratorType;
-  private final InterfaceType typeType;
-
-  public CoreTypeProviderImplementation(Scope scope, DartCompilerListener listener) {
-    this.intType = getType("int", scope, listener);
-    this.doubleType = getType("double", scope, listener);
-    this.boolType = getType("bool", scope, listener);
-    this.numType = getType("num", scope, listener);
-    this.stringType = getType("String", scope, listener);
-    this.functionType = getType("Function", scope, listener);
-    this.arrayType = getType("List", scope, listener);
-    this.dynamicType = Types.newDynamicType();
-    this.voidType = Types.newVoidType();
-    // Currently, there is no need for a special null type.
-    this.nullType = dynamicType;
-    this.mapType = getType("Map", scope, listener);
-    this.objectType = getType("Object", scope, listener);
-    this.iteratorType = getType("Iterator", scope, listener);
-    this.typeType = getType("Type", scope, listener);
-  }
-
-  private static InterfaceType getType(String name, Scope scope, DartCompilerListener listener) {
-    ClassElement element = (ClassElement) scope.findElement(scope.getLibrary(), name);
-    if (element == null) {
-      DartCompilationError error =
-          new DartCompilationError(null, Location.NONE,
-              ResolverErrorCode.CANNOT_RESOLVE_SDK_TYPE, name);
-      listener.onError(error);
-      return Types.newDynamicType();
-    }
-    return element.getType();
-  }
-
-  @Override
-  public InterfaceType getIntType() {
-    return intType;
-  }
-
-  @Override
-  public InterfaceType getDoubleType() {
-    return doubleType;
-  }
-
-  @Override
-  public InterfaceType getBoolType() {
-    return boolType;
-  }
-
-  @Override
-  public InterfaceType getStringType() {
-    return stringType;
-  }
-
-  @Override
-  public InterfaceType getFunctionType() {
-    return functionType;
-  }
-
-  @Override
-  public InterfaceType getArrayType(Type elementType) {
-    return arrayType.subst(Arrays.asList(elementType), arrayType.getElement().getTypeParameters());
-  }
-
-  @Override
-  public DynamicType getDynamicType() {
-    return dynamicType;
-  }
-
-  @Override
-  public Type getVoidType() {
-    return voidType;
-  }
-
-  @Override
-  public Type getNullType() {
-    return nullType;
-  }
-
-  @Override
-  public InterfaceType getMapType(Type key, Type value) {
-    return mapType.subst(Arrays.asList(key, value), mapType.getElement().getTypeParameters());
-  }
-
-  @Override
-  public InterfaceType getObjectType() {
-    return objectType;
-  }
-
-  @Override
-  public InterfaceType getNumType() {
-    return numType;
-  }
-
-  @Override
-  public InterfaceType getIteratorType(Type elementType) {
-    return iteratorType.subst(Arrays.asList(elementType),
-        iteratorType.getElement().getTypeParameters());
-  }
-  
-  @Override
-  public InterfaceType getTypeType() {
-    return typeType;
-  }
-}
diff --git a/compiler/java/com/google/dart/compiler/resolver/CyclicDeclarationException.java b/compiler/java/com/google/dart/compiler/resolver/CyclicDeclarationException.java
deleted file mode 100644
index 90e673a..0000000
--- a/compiler/java/com/google/dart/compiler/resolver/CyclicDeclarationException.java
+++ /dev/null
@@ -1,23 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.resolver;
-
-/**
- * Exception thrown if a cycle is detected in the supertype graph of a class or interface.
- */
-public class CyclicDeclarationException extends Exception {
-  private static final long serialVersionUID = 1L;
-
-  private final ClassElement element;
-
-  public CyclicDeclarationException(ClassElement element) {
-    super(element.getName());
-    this.element = element;
-  }
-
-  public ClassElement getElement() {
-    return element;
-  }
-}
diff --git a/compiler/java/com/google/dart/compiler/resolver/DuplicateElement.java b/compiler/java/com/google/dart/compiler/resolver/DuplicateElement.java
deleted file mode 100644
index ed526db..0000000
--- a/compiler/java/com/google/dart/compiler/resolver/DuplicateElement.java
+++ /dev/null
@@ -1,14 +0,0 @@
-// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.resolver;
-
-import java.util.List;
-
-/**
- * {@link Element} for duplicate import.
- */
-public interface DuplicateElement extends Element {
-  List<String> getLocations();
-}
diff --git a/compiler/java/com/google/dart/compiler/resolver/DuplicateElementImplementation.java b/compiler/java/com/google/dart/compiler/resolver/DuplicateElementImplementation.java
deleted file mode 100644
index 3faaff3..0000000
--- a/compiler/java/com/google/dart/compiler/resolver/DuplicateElementImplementation.java
+++ /dev/null
@@ -1,88 +0,0 @@
-// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.resolver;
-
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.Lists;
-import com.google.dart.compiler.ast.DartObsoleteMetadata;
-import com.google.dart.compiler.ast.Modifiers;
-import com.google.dart.compiler.common.SourceInfo;
-import com.google.dart.compiler.type.Type;
-
-import java.util.List;
-
-class DuplicateElementImplementation implements DuplicateElement {
-  private final String name;
-  private final List<String> locations = Lists.newArrayList();
-
-  public DuplicateElementImplementation(Element oldElement, Element newElement) {
-    name = oldElement.getName();
-    locations.addAll(getLocations(oldElement));
-    locations.addAll(getLocations(newElement));
-  }
-
-  @Override
-  public String getOriginalName() {
-    return name;
-  }
-
-  @Override
-  public String getName() {
-    return name;
-  }
-
-  @Override
-  public ElementKind getKind() {
-    return ElementKind.DUPLICATE;
-  }
-
-  @Override
-  public Type getType() {
-    return null;
-  }
-
-  @Override
-  public boolean isDynamic() {
-    return false;
-  }
-
-  @Override
-  public Modifiers getModifiers() {
-    return Modifiers.NONE;
-  }
-
-  @Override
-  public DartObsoleteMetadata getMetadata() {
-    return null;
-  }
-
-  @Override
-  public EnclosingElement getEnclosingElement() {
-    return null;
-  }
-
-  @Override
-  public SourceInfo getNameLocation() {
-    return null;
-  }
-
-  @Override
-  public SourceInfo getSourceInfo() {
-    return null;
-  }
-
-  @Override
-  public List<String> getLocations() {
-    return locations;
-  }
-
-  private static List<String> getLocations(Element element) {
-    if (element instanceof DuplicateElement) {
-      return ((DuplicateElement) element).getLocations();
-    } else {
-      return ImmutableList.of(Elements.getLibraryUnitLocation(element));
-    }
-  }
-}
diff --git a/compiler/java/com/google/dart/compiler/resolver/DynamicElement.java b/compiler/java/com/google/dart/compiler/resolver/DynamicElement.java
deleted file mode 100644
index b971ce2..0000000
--- a/compiler/java/com/google/dart/compiler/resolver/DynamicElement.java
+++ /dev/null
@@ -1,17 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.resolver;
-
-import com.google.dart.compiler.type.DynamicType;
-
-/**
- * Dummy element corresponding to {@link DynamicType}.
- */
-public interface DynamicElement extends FunctionAliasElement, LibraryElement, FieldElement,
-                                        LabelElement, SuperElement, VariableElement,
-                                        TypeVariableElement, ConstructorElement {
-  @Override
-  DynamicType getType();
-}
diff --git a/compiler/java/com/google/dart/compiler/resolver/DynamicElementImplementation.java b/compiler/java/com/google/dart/compiler/resolver/DynamicElementImplementation.java
deleted file mode 100644
index 3950e85..0000000
--- a/compiler/java/com/google/dart/compiler/resolver/DynamicElementImplementation.java
+++ /dev/null
@@ -1,330 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.resolver;
-
-import com.google.common.collect.ImmutableSet;
-import com.google.dart.compiler.ast.DartExpression;
-import com.google.dart.compiler.ast.LibraryUnit;
-import com.google.dart.compiler.type.DynamicType;
-import com.google.dart.compiler.type.FunctionType;
-import com.google.dart.compiler.type.InterfaceType;
-import com.google.dart.compiler.type.Type;
-import com.google.dart.compiler.type.Types;
-
-import java.util.Collections;
-import java.util.List;
-import java.util.Set;
-
-/**
- * Dummy element corresponding to {@link DynamicType}.
- */
-class DynamicElementImplementation extends AbstractNodeElement implements DynamicElement, MethodNodeElement {
-
-  private DynamicElementImplementation() {
-    super(null, "dynamic");
-  }
-
-  @Override
-  public ElementKind getKind() {
-    return ElementKind.DYNAMIC;
-  }
-
-  public static DynamicElementImplementation getInstance() {
-    return new DynamicElementImplementation();
-  }
-
-  @Override
-  public void setType(InterfaceType type) {
-    throw new UnsupportedOperationException();
-  }
-
-  @Override
-  public List<Type> getTypeParameters() {
-    return Collections.<Type>emptyList();
-  }
-
-  @Override
-  public InterfaceType getSupertype() {
-    return null;
-  }
-
-  @Override
-  public InterfaceType getDefaultClass() {
-    return null;
-  }
-
-  @Override
-  public void setSupertype(InterfaceType element) {
-    throw new UnsupportedOperationException();
-  }
-
-  @Override
-  public List<Element> getMembers() {
-    return Collections.<Element>emptyList();
-  }
-
-  @Override
-  public List<ConstructorElement> getConstructors() {
-    return Collections.<ConstructorElement>emptyList();
-  }
-
-  @Override
-  public Scope getImportScope() {
-    return null;
-  }
-
-  @Override
-  public List<InterfaceType> getInterfaces() {
-    return Collections.<InterfaceType>emptyList();
-  }
-  
-  @Override
-  public List<InterfaceType> getMixins() {
-    return Collections.<InterfaceType>emptyList();
-  }
-
-  @Override
-  public DynamicType getType() {
-    return Types.newDynamicType();
-  }
-
-  @Override
-  public DynamicType getTypeVariable() {
-    return getType();
-  }
-
-  @Override
-  public ClassElement getEnclosingElement() {
-    return this;
-  }
-
-  @Override
-  public boolean isConstructor() {
-    return false;
-  }
-  
-  @Override
-  public boolean isSynthetic() {
-    return true;
-  }
-
-  @Override
-  public ConstructorElement getDefaultConstructor() {
-    throw new UnsupportedOperationException();
-  }
-
-  @Override
-  public ConstructorElement getRedirectingFactoryConstructor() {
-    throw new UnsupportedOperationException();
-  }
-
-  @Override
-  public void setDefaultConstructor(ConstructorElement defaultConstructor) {
-    throw new UnsupportedOperationException();
-  }
-
-  @Override
-  public boolean isStatic() {
-    return false;
-  }
-
-  @Override
-  public boolean hasBody() {
-    return false;
-  }
-
-  @Override
-  public boolean isInterface() {
-    return false;
-  }
-
-  @Override
-  public String getNativeName() {
-    return null;
-  }
-
-  @Override
-  public List<VariableElement> getParameters() {
-    return Collections.<VariableElement>emptyList();
-  }
-
-  @Override
-  public Type getReturnType() {
-    return getType();
-  }
-
-  @Override
-  public boolean isDynamic() {
-    return true;
-  }
-
-  @Override
-  public boolean isObject() {
-    return false;
-  }
-  
-  @Override
-  public String getDeclarationNameWithTypeParameters() {
-    return "dynamic";
-  }
-
-  @Override
-  public boolean isObjectChild() {
-    return false;
-  }
-
-  @Override
-  public Element lookupLocalElement(String name) {
-    return this;
-  }
-
-  @Override
-  public LibraryElement getLibrary() {
-    return null;
-  }
-
-  @Override
-  public Type getBound() {
-    return getType();
-  }
-
-  @Override
-  public Element getDeclaringElement() {
-    return this;
-  }
-
-  @Override
-  public ConstructorElement lookupConstructor(String name) {
-    return null;
-  }
-
-  @Override
-  public FunctionType getFunctionType() {
-    return null;
-  }
-
-  @Override
-  public void setFunctionType(FunctionType functionType) {
-  }
-
-  @Override
-  public List<InterfaceType> getAllSupertypes() {
-    return Collections.emptyList();
-  }
-
-  @Override
-  public Scope getScope() {
-    return null;
-  }
-
-  @Override
-  public List<Element> getExportedElements() {
-    return null;
-  }
-
-  @Override
-  public LibraryUnit getLibraryUnit() {
-    return null;
-  }
-
-  @Override
-  public void setEntryPoint(MethodElement element) {
-    throw new AssertionError();
-  }
-
-  @Override
-  public MethodElement getEntryPoint() {
-    return null;
-  }
-
-  @Override
-  public MethodElement getGetter() {
-    return null;
-  }
-
-  @Override
-  public MethodElement getSetter() {
-    return null;
-  }
-
-  @Override
-  public MethodElement getEnclosingFunction() {
-    return this;
-  }
-
-  @Override
-  public ClassElement getClassElement() {
-    return this;
-  }
-
-  @Override
-  public FieldElement getParameterInitializerElement() {
-    return this;
-  }
-
-  @Override
-  public boolean isOptional() {
-    return false;
-  }
-
-  @Override
-  public boolean isNamed() {
-    return false;
-  }
-
-  @Override
-  public DartExpression getDefaultValue() {
-    return null;
-  }
-
-  @Override
-  public ClassElement getConstructorType() {
-    return this;
-  }
-  
-  @Override
-  public String getRawName() {
-    return getName();
-  }
-
-  @Override
-  public void setType(Type type) {
-    super.setType(type);
-  }
-  
-  @Override
-  public Type getConstantType() {
-    return null;
-  }
-  @Override
-  public List<Element> getUnimplementedMembers() {
-    return null;
-  }
-
-  @Override
-  public Set<Element> getOverridden() {
-    return ImmutableSet.of();
-  }
-
-  @Override
-  public LabeledStatementType getStatementType() {
-    return LabeledStatementType.STATEMENT;
-  }
-
-  @Override
-  public int getOpenBraceOffset() {
-    return -1;
-  }
-  
-  @Override
-  public int getCloseBraceOffset() {
-    return -1;
-  }
-  
-  @Override
-  public boolean hasSuperInvocation() {
-    return false;
-  }
-}
diff --git a/compiler/java/com/google/dart/compiler/resolver/Element.java b/compiler/java/com/google/dart/compiler/resolver/Element.java
deleted file mode 100644
index 5dd5fb6..0000000
--- a/compiler/java/com/google/dart/compiler/resolver/Element.java
+++ /dev/null
@@ -1,37 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.resolver;
-
-import com.google.dart.compiler.ast.DartObsoleteMetadata;
-import com.google.dart.compiler.ast.Modifiers;
-import com.google.dart.compiler.common.HasSourceInfo;
-import com.google.dart.compiler.common.SourceInfo;
-import com.google.dart.compiler.type.Type;
-
-public interface Element extends HasSourceInfo {
-  String getOriginalName();
-
-  String getName();
-
-  ElementKind getKind();
-
-  Type getType();
-
-  boolean isDynamic();
-
-  Modifiers getModifiers();
-  
-  DartObsoleteMetadata getMetadata();
-
-  /**
-   * @return the innermost {@link EnclosingElement} which encloses this {@link Element}.
-   */
-  EnclosingElement getEnclosingElement();
-  
-  /**
-   * @return location of the name in the declaration of this {@link Element}.
-   */
-  SourceInfo getNameLocation();
-}
diff --git a/compiler/java/com/google/dart/compiler/resolver/ElementKind.java b/compiler/java/com/google/dart/compiler/resolver/ElementKind.java
deleted file mode 100644
index 65d1cfd..0000000
--- a/compiler/java/com/google/dart/compiler/resolver/ElementKind.java
+++ /dev/null
@@ -1,38 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.resolver;
-
-
-/**
- * Kinds of elements. Use kinds instead of instanceof for maximum flexibility
- * and sharing of similar implementation classes.
- */
-public enum ElementKind {
-  CLASS,
-  CONSTRUCTOR,
-  DUPLICATE,
-  FIELD,
-  FUNCTION_OBJECT,
-  LABEL,
-  METHOD,
-  PARAMETER,
-  TYPE_VARIABLE,
-  VARIABLE,
-  FUNCTION_TYPE_ALIAS,
-  DYNAMIC,
-  LIBRARY,
-  LIBRARY_PREFIX,
-  SUPER,
-  NONE,
-  VOID;
-
-  public static ElementKind of(Element element) {
-    if (element != null) {
-      return element.getKind();
-    } else {
-      return NONE;
-    }
-  }
-}
diff --git a/compiler/java/com/google/dart/compiler/resolver/ElementMap.java b/compiler/java/com/google/dart/compiler/resolver/ElementMap.java
deleted file mode 100644
index 5a186a6..0000000
--- a/compiler/java/com/google/dart/compiler/resolver/ElementMap.java
+++ /dev/null
@@ -1,268 +0,0 @@
-// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.resolver;
-
-import com.google.common.annotations.VisibleForTesting;
-import com.google.dart.compiler.ast.DartNode;
-import com.google.dart.compiler.ast.DartObsoleteMetadata;
-import com.google.dart.compiler.ast.Modifiers;
-import com.google.dart.compiler.common.SourceInfo;
-import com.google.dart.compiler.type.Type;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * A more efficient version of {@link com.google.common.collect.Multimap} specifically for
- * {@link NodeElement}
- */
-@VisibleForTesting
-public class ElementMap {
-
-  /**
-   * A synthetic place holder for an element where the name given to the element map does not match
-   * the value returned by {@link NodeElement#getName()} or where there are multiple elements associated
-   * with the same name.
-   */
-  static class ElementHolder implements NodeElement {
-    private static final String INTERNAL_ONLY_ERROR =
-        "ElementHolder should not be accessed outside this class";
-
-    final String name;
-    final NodeElement element;
-    ElementHolder nextHolder;
-
-    ElementHolder(String name, NodeElement element) {
-      this.name = name;
-      this.element = element;
-    }
-    
-    @Override
-    public SourceInfo getNameLocation() {
-      throw new AssertionError(INTERNAL_ONLY_ERROR);
-    }
-
-    @Override
-    public EnclosingElement getEnclosingElement() {
-      throw new AssertionError(INTERNAL_ONLY_ERROR);
-    }
-
-    @Override
-    public ElementKind getKind() {
-      throw new AssertionError(INTERNAL_ONLY_ERROR);
-    }
-
-    @Override
-    public DartObsoleteMetadata getMetadata() {
-      throw new AssertionError(INTERNAL_ONLY_ERROR);
-    }
-
-    @Override
-    public Modifiers getModifiers() {
-      throw new AssertionError(INTERNAL_ONLY_ERROR);
-    }
-
-    @Override
-    public String getName() {
-      return name;
-    }
-
-    @Override
-    public DartNode getNode() {
-      throw new AssertionError(INTERNAL_ONLY_ERROR);
-    }
-
-    @Override
-    public String getOriginalName() {
-      throw new AssertionError(INTERNAL_ONLY_ERROR);
-    }
-
-    @Override
-    public Type getType() {
-      throw new AssertionError(INTERNAL_ONLY_ERROR);
-    }
-
-    @Override
-    public boolean isDynamic() {
-      throw new AssertionError(INTERNAL_ONLY_ERROR);
-    }
-
-    @Override
-    public SourceInfo getSourceInfo() {
-      throw new AssertionError(INTERNAL_ONLY_ERROR);
-    }
-
-  }
-
-  // Array indexed by hashed name ... length is always power of 2
-  private NodeElement[] elements;
-  private List<NodeElement> ordered = new ArrayList<NodeElement>();
-
-  @VisibleForTesting
-  public ElementMap() {
-    clear();
-  }
-
-  /**
-   * Associate the specified element with the specified name. If the element is already associated
-   * with that name, do not associate it again.
-   */
-  @VisibleForTesting
-  public void add(String name, NodeElement element) {
-
-    // Most of the time name equals getName() thus holder == element
-    NodeElement newHolder;
-    if (name.equals(element.getName())) {
-      newHolder = element;
-    } else {
-      newHolder = new ElementHolder(name, element);
-    }
-
-    // 75% fill rate which anecdotal evidence claims is a good threshold for growing
-    if ((elements.length >> 2) * 3 <= size()) {
-      grow();
-    }
-    int index = internalAdd(newHolder);
-    if (index == -1) {
-      ordered.add(element);
-      return;
-    }
-
-    // Handle existing element with the same name
-    NodeElement existingHolder = elements[index];
-    if (existingHolder == element) {
-      return;
-    }
-    if (!(existingHolder instanceof ElementHolder)) {
-      existingHolder = new ElementHolder(name, existingHolder);
-      elements[index] = existingHolder;
-    }
-
-    // Check the list for a duplicate element entry, and append if none found
-    ElementHolder holder = (ElementHolder) existingHolder;
-    while (true) {
-      if (holder.element == element) {
-        return;
-      }
-      if (holder.nextHolder == null) {
-        holder.nextHolder = new ElementHolder(name, element);
-        ordered.add(element);
-        return;
-      }
-      holder = holder.nextHolder;
-    }
-  }
-
-  void clear() {
-    elements = new NodeElement[16];
-    ordered.clear();
-  }
-
-  /**
-   * Answer the element last associated with the specified name.
-   * 
-   * @return the element or <code>null</code> if none
-   */
-  @VisibleForTesting
-  public NodeElement get(String name) {
-    NodeElement element = internalGet(name);
-    if (element instanceof ElementHolder) {
-      return ((ElementHolder) element).element;
-    } else {
-      return element;
-    }
-  }
-
-  /**
-   * Answer the element associated with the specified name and kind
-   * 
-   * @return the element of that kind or <code>null</code> if none
-   */
-  @VisibleForTesting
-  public NodeElement get(String name, ElementKind kind) {
-    NodeElement element = internalGet(name);
-    if (element instanceof ElementHolder) {
-      ElementHolder holder = (ElementHolder) element;
-      while (true) {
-        element = holder.element;
-        if (ElementKind.of(element).equals(kind)) {
-          return element;
-        }
-        holder = holder.nextHolder;
-        if (holder == null) {
-          break;
-        }
-      }
-    } else {
-      if (ElementKind.of(element).equals(kind)) {
-        return element;
-      }
-    }
-    return null;
-  }
-
-  @VisibleForTesting
-  public boolean isEmpty() {
-    return ordered.isEmpty();
-  }
-
-  @VisibleForTesting
-  public int size() {
-    return ordered.size();
-  }
-
-  @VisibleForTesting
-  public List<NodeElement> values() {
-    return ordered;
-  }
-
-  private void grow() {
-    NodeElement[] old = elements;
-    elements = new NodeElement[elements.length << 2];
-    for (NodeElement element : old) {
-      if (element != null) {
-        if (internalAdd(element) != -1) {
-          // Every element in the array should have a unique name, so there should not be any collision
-          throw new RuntimeException("Failed to grow: " + element.getName());
-        }
-      }
-    }
-  }
-
-  /**
-   * If an element with the given name does not exist in the array, then add the element and return
-   * -1 otherwise nothing is added and the index of the existing element returned.
-   */
-  private int internalAdd(NodeElement element) {
-    String name = element.getName();
-    int mask = elements.length - 1;
-    int probe = name.hashCode() & mask;
-    for (int i = probe; i < probe + mask + 1; i++) {
-      int index = i & mask;
-      NodeElement current = elements[index];
-      if (current == null) {
-        elements[index] = element;
-        return -1;
-      }
-      if (current.getName().equals(name)) {
-        return index;
-      }
-    }
-    throw new AssertionError("overfilled array");
-  }
-
-  private NodeElement internalGet(String name) {
-    NodeElement element;
-    int mask = elements.length - 1;
-    int probe = name.hashCode() & mask;
-    for (int i = probe; i < probe + mask + 1; i++) {
-      element = elements[i & mask];
-      if (element == null || element.getName().equals(name)) {
-        return element;
-      }
-    }
-    throw new AssertionError("overfilled array");
-  }
-}
diff --git a/compiler/java/com/google/dart/compiler/resolver/Elements.java b/compiler/java/com/google/dart/compiler/resolver/Elements.java
deleted file mode 100644
index 36d41c6..0000000
--- a/compiler/java/com/google/dart/compiler/resolver/Elements.java
+++ /dev/null
@@ -1,989 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.resolver;
-
-import com.google.common.annotations.VisibleForTesting;
-import com.google.common.base.Objects;
-import com.google.common.collect.Iterables;
-import com.google.common.collect.Lists;
-import com.google.common.collect.Sets;
-import com.google.dart.compiler.DartSource;
-import com.google.dart.compiler.LibrarySource;
-import com.google.dart.compiler.Source;
-import com.google.dart.compiler.ast.DartClass;
-import com.google.dart.compiler.ast.DartClassMember;
-import com.google.dart.compiler.ast.DartClassTypeAlias;
-import com.google.dart.compiler.ast.DartField;
-import com.google.dart.compiler.ast.DartFunctionExpression;
-import com.google.dart.compiler.ast.DartFunctionTypeAlias;
-import com.google.dart.compiler.ast.DartIdentifier;
-import com.google.dart.compiler.ast.DartLabel;
-import com.google.dart.compiler.ast.DartMethodDefinition;
-import com.google.dart.compiler.ast.DartNativeBlock;
-import com.google.dart.compiler.ast.DartNode;
-import com.google.dart.compiler.ast.DartObsoleteMetadata;
-import com.google.dart.compiler.ast.DartParameter;
-import com.google.dart.compiler.ast.DartSuperExpression;
-import com.google.dart.compiler.ast.DartTypeNode;
-import com.google.dart.compiler.ast.DartTypeParameter;
-import com.google.dart.compiler.ast.DartVariable;
-import com.google.dart.compiler.ast.LibraryUnit;
-import com.google.dart.compiler.ast.Modifiers;
-import com.google.dart.compiler.common.SourceInfo;
-import com.google.dart.compiler.resolver.LabelElement.LabeledStatementType;
-import com.google.dart.compiler.type.InterfaceType;
-import com.google.dart.compiler.type.InterfaceType.Member;
-import com.google.dart.compiler.type.Type;
-import com.google.dart.compiler.type.TypeVariable;
-import com.google.dart.compiler.util.Paths;
-import com.google.dart.compiler.util.apache.StringUtils;
-
-import java.io.File;
-import java.net.URI;
-import java.text.MessageFormat;
-import java.util.Arrays;
-import java.util.List;
-import java.util.Set;
-
-/**
- * Utility and factory methods for elements.
- */
-public class Elements {
-
-  private Elements() {} // Prevent subclassing and instantiation.
-
-  static void setParameterInitializerElement(VariableElement varElement, FieldElement element) {
-    ((VariableElementImplementation) varElement).setParameterInitializerElement(element);
-  }
-
-  static void setDefaultClass(ClassElement classElement, InterfaceType defaultClass) {
-    ((ClassElementImplementation) classElement).setDefaultClass(defaultClass);
-  }
-
-  static void addInterface(ClassElement classElement, InterfaceType type) {
-    ((ClassElementImplementation) classElement).addInterface(type);
-  }
-  
-  static void addMixin(ClassElement classElement, InterfaceType type) {
-    ((ClassElementImplementation) classElement).addMixin(type);
-  }
-
-  static LabelElement statementLabelElement(DartLabel node, String name,
-      MethodElement enclosingFunction) {
-    return new LabelElementImplementation(node, name, enclosingFunction,
-        LabeledStatementType.STATEMENT);
-  }
-
-  static LabelElement switchMemberLabelElement(DartLabel node, String name,
-      MethodElement enclosingFunction) {
-    return new LabelElementImplementation(node, name, enclosingFunction,
-        LabeledStatementType.SWITCH_MEMBER_STATEMENT);
-  }
-
-  static LabelElement switchLabelElement(DartLabel node, String name,
-      MethodElement enclosingFunction) {
-    return new LabelElementImplementation(node, name, enclosingFunction,
-        LabeledStatementType.SWITCH_STATEMENT);
-  }
-
-  public static LibraryElement libraryElement(LibraryUnit libraryUnit) {
-    return new LibraryElementImplementation(libraryUnit);
-  }
-  
-  public static void setLibraryMetadata(LibraryElement element, DartObsoleteMetadata metadata) {
-    ((LibraryElementImplementation) element).setMetadata(metadata);
-  }
-  
-  public static Element addExportedElement(LibraryElement libraryElement, Element element) {
-    return ((LibraryElementImplementation) libraryElement).addExportedElements(element);
-  }
-
-  public static LibraryElement getLibraryElement(Element element) {
-    while (element != null) {
-      if (ElementKind.of(element) == ElementKind.LIBRARY) {
-        return (LibraryElement) element;
-      }
-      EnclosingElement enclosingElement = element.getEnclosingElement();
-      if (enclosingElement == element) {
-        return null;
-      }
-      element = enclosingElement;
-    };
-    return null;
-  }
-  
-  /**
-   * @return <code>true</code> if "a" and "b" are declared in the same {@link LibraryElement}.
-   */
-  public static boolean areSameLibrary(Element a, Element b) {
-    LibraryElement aLibrary = getLibraryElement(a);
-    LibraryElement bLibrary = getLibraryElement(b);
-    return Objects.equal(aLibrary, bLibrary);
-  }
-
-  @VisibleForTesting
-  public static MethodElement methodElement(DartFunctionExpression node, String name) {
-    return new MethodElementImplementation(node, name, Modifiers.NONE);
-  }
-
-  public static TypeVariableElement typeVariableElement(String name, Type bound) {
-    return new TypeVariableElementImplementation(name, bound);
-  }
-
-  public static VariableElement variableElement(EnclosingElement owner,
-      DartVariable node,
-      String name,
-      Modifiers modifiers) {
-    return new VariableElementImplementation(owner,
-        node,
-        node.getName().getSourceInfo(),
-        name,
-        ElementKind.VARIABLE,
-        modifiers,
-        false,
-        null);
-  }
-
-  public static VariableElement parameterElement(EnclosingElement owner,
-      DartParameter node,
-      String name,
-      Modifiers modifiers) {
-    return new VariableElementImplementation(owner,
-        node,
-        node.getName().getSourceInfo(),
-        name,
-        ElementKind.PARAMETER,
-        modifiers,
-        node.getModifiers().isNamed(),
-        node.getDefaultExpr());
-  }
-
-  public static SuperElement superElement(DartSuperExpression node, ClassElement cls) {
-    return new SuperElementImplementation(node, cls);
-  }
-
-  static void addConstructor(ClassElement cls, ConstructorNodeElement constructor) {
-    ((ClassElementImplementation) cls).addConstructor(constructor);
-  }
-
-  static void addField(EnclosingElement holder, FieldNodeElement field) {
-    if (ElementKind.of(holder).equals(ElementKind.CLASS)) {
-      ((ClassElementImplementation) holder).addField(field);
-    } else if (ElementKind.of(holder).equals(ElementKind.LIBRARY)) {
-      ((LibraryElementImplementation) holder).addField(field);
-    } else {
-      throw new IllegalArgumentException();
-    }
-  }
-
-  @VisibleForTesting
-  public static void addMethod(EnclosingElement holder, MethodNodeElement method) {
-    if (ElementKind.of(holder).equals(ElementKind.CLASS)) {
-      ((ClassElementImplementation) holder).addMethod(method);
-    } else if (ElementKind.of(holder).equals(ElementKind.LIBRARY)) {
-      ((LibraryElementImplementation) holder).addMethod(method);
-    } else {
-      throw new IllegalArgumentException();
-    }
-  }
-
-  public static void addParameter(MethodElement method, VariableElement parameter) {
-    ((MethodElementImplementation) method).addParameter(parameter);
-  }
-
-  static Element findElement(EnclosingElement cls, String name) {
-    if (cls instanceof  ClassElementImplementation) {
-      return ((ClassElementImplementation) cls).findElement(name);
-    }
-    return null;
-  }
-
-  public static MethodElement methodFromFunctionExpression(DartFunctionExpression node,
-                                                           Modifiers modifiers) {
-    return MethodElementImplementation.fromFunctionExpression(node, modifiers);
-  }
-
-  public static MethodNodeElement methodFromMethodNode(DartMethodDefinition node,
-      EnclosingElement holder) {
-    return MethodElementImplementation.fromMethodNode(node, holder);
-  }
-
-  static ConstructorNodeElement constructorFromMethodNode(DartMethodDefinition node,
-                                                      String name,
-                                                      ClassElement declaringClass,
-                                                      ClassElement constructorType) {
-    return ConstructorElementImplementation.fromMethodNode(node, name, declaringClass,
-                                                           constructorType);
-  }
-
-  public static void setType(Element element, Type type) {
-    ((AbstractNodeElement) element).setType(type);
-  }
-
-  public static void setOverridden(Element element, Set<Element> overridden) {
-    if (element instanceof MethodElementImplementation) {
-      ((MethodElementImplementation) element).setOverridden(overridden);
-    }
-    if (element instanceof FieldElementImplementation) {
-      ((FieldElementImplementation) element).setOverridden(overridden);
-    }
-  }
-
-static FieldElementImplementation fieldFromNode(DartField node,
-                                                  EnclosingElement holder,
-                                                  DartObsoleteMetadata metadata,
-                                                  Modifiers modifiers) {
-    return FieldElementImplementation.fromNode(node, holder, metadata, modifiers);
-  }
-
-  static ClassElement classFromNode(DartClass node, LibraryElement library) {
-    return ClassElementImplementation.fromNode(node, library);
-  }
-  
-  static ClassAliasElement classFromNode(DartClassTypeAlias node, LibraryElement library) {
-    return ClassElementImplementation.fromNode(node, library);
-  }
-
-  public static ClassElement classNamed(String name) {
-    return ClassElementImplementation.named(name);
-  }
-
-  static TypeVariableElement typeVariableFromNode(DartTypeParameter node, EnclosingElement element) {
-    return TypeVariableElementImplementation.fromNode(node, element);
-  }
-
-  public static DynamicElement dynamicElement() {
-    return DynamicElementImplementation.getInstance();
-  }
-
-  static ConstructorElement lookupConstructor(ClassElement cls, ClassElement type, String name) {
-    return ((ClassElementImplementation) cls).lookupConstructor(type, name);
-  }
-
-  static ConstructorElement lookupConstructor(ClassElement cls, String name) {
-    if (cls instanceof  ClassElementImplementation) {
-      return ((ClassElementImplementation) cls).lookupConstructor(name);
-    }
-    return null;
-  }
-
-  public static MethodElement lookupLocalMethod(ClassElement cls, String name) {
-    return ((ClassElementImplementation) cls).lookupLocalMethod(name);
-  }
-
-  public static FieldElement lookupLocalField(ClassElement cls, String name) {
-    return ((ClassElementImplementation) cls).lookupLocalField(name);
-  }
-
-  public static FunctionAliasElement functionTypeAliasFromNode(DartFunctionTypeAlias node,
-                                                               LibraryElement library) {
-    return FunctionAliasElementImplementation.fromNode(node, library);
-  }
-
-  /**
-   * @return <code>true</code> if given {@link Element} represents {@link VariableElement} for
-   *         parameter in {@link DartMethodDefinition}.
-   */
-  public static boolean isConstructorParameter(Element element) {
-    Element parent = element.getEnclosingElement();
-    if (parent instanceof MethodElement) {
-      return ((MethodElement) parent).isConstructor();
-    }
-    return false;
-  }
-
-  /**
-   * @return <code>true</code> if given {@link Element} represents {@link VariableElement} for
-   *         parameter in {@link DartMethodDefinition} without body, or with {@link DartNativeBlock}
-   *         as body.
-   */
-  public static boolean isParameterOfMethodWithoutBody(Element element) {
-    if (element instanceof VariableElement) {
-      Element parent = element.getEnclosingElement();
-      if (parent instanceof MethodElement) {
-        MethodElement parentMethod = (MethodElement) parent;
-        return !parentMethod.hasBody();
-      }
-    }
-    return false;
-  }
-
-  /**
-   * @return <code>not-null</code> {@link MethodElement} if "holder", or one of its interfaces, or
-   *         its superclass has {@link FieldElement} with getter.
-   */
-  public static MethodElement lookupFieldElementGetter(EnclosingElement holder, String name) {
-    MethodElement result = lookupFieldElementGetter0(holder, name);
-    if (result != null) {
-      return result;
-    }
-    if (holder instanceof ClassElement) {
-      ClassElement classHolder = (ClassElement) holder;
-      for (InterfaceType interfaceType : classHolder.getInterfaces()) {
-        result = lookupFieldElementGetter(interfaceType.getElement(), name);
-        if (result != null) {
-          return result;
-        }
-      }
-      for (InterfaceType mixinType : classHolder.getMixins()) {
-        result = lookupFieldElementGetter0(mixinType.getElement(), name);
-        if (result != null) {
-          return result;
-        }
-      }
-      if (classHolder.getSupertype() != null) {
-        result = lookupFieldElementGetter(classHolder.getSupertype().getElement(), name);
-        if (result != null) {
-          return result;
-        }
-      }
-    }
-
-    return null;
-  }
-
-  /**
-   * @return the {@link MethodElement} if "holder" has {@link FieldElement} with getter.
-   */
-  private static MethodElement lookupFieldElementGetter0(EnclosingElement holder, String name) {
-    Element element = holder.lookupLocalElement(name);
-    if (element instanceof FieldElement) {
-      FieldElement fieldElement = (FieldElement) element;
-      MethodElement result = fieldElement.getGetter();
-      if (result != null) {
-        return fieldElement.getGetter();
-      }
-    }
-    return null;
-  }
-
-  /**
-   * @return <code>non-null</code> {@link MethodElement} if "holder", or one of its interfaces, or
-   *         its superclass has {@link FieldElement} with setter.
-   */
-  public static MethodElement lookupFieldElementSetter(EnclosingElement holder, String name) {
-    MethodElement result = lookupFieldElementSetter0(holder, name);
-    if (result != null) {
-      return result;
-    }
-    if (holder instanceof ClassElement) {
-      ClassElement classHolder = (ClassElement) holder;
-      for (InterfaceType interfaceType : classHolder.getInterfaces()) {
-        result = lookupFieldElementSetter(interfaceType.getElement(), name);
-        if (result != null) {
-          return result;
-        }
-      }
-      for (InterfaceType mixinType : classHolder.getMixins()) {
-        result = lookupFieldElementSetter0(mixinType.getElement(), name);
-        if (result != null) {
-          return result;
-        }
-      }
-      if (classHolder.getSupertype() != null) {
-        result = lookupFieldElementSetter(classHolder.getSupertype().getElement(), name);
-        if (result != null) {
-          return result;
-        }
-      }
-    }
-    return null;
-  }
-
-  /**
-   * @return the {@link MethodElement} if "holder" has {@link FieldElement} with setter.
-   */
-  private static MethodElement lookupFieldElementSetter0(EnclosingElement holder, String name) {
-    Element element = holder.lookupLocalElement(name);
-    if (element instanceof FieldElement) {
-      FieldElement fieldElement = (FieldElement) element;
-      MethodElement result = fieldElement.getSetter();
-      if (result != null) {
-        return result;
-      }
-    }
-    return null;
-  }
-
-  /**
-   * @return <code>true</code> if {@link DartNode} of given {@link Element} if part of static
-   *         {@link DartClassMember} or part of top level declaration.
-   */
-  public static boolean isStaticContext(Element element) {
-    if (element instanceof ClassElement) {
-      return true;
-    }
-    while (element != null) {
-      if (element instanceof MethodElement) {
-        MethodElement methodElement = (MethodElement) element;
-        return methodElement.isStatic() || methodElement.getEnclosingElement()  instanceof LibraryElement;
-      }
-      if (element instanceof FieldElement) {
-        FieldElement fieldElement = (FieldElement) element;
-        return fieldElement.isStatic()
-            || fieldElement.getEnclosingElement() instanceof LibraryElement;
-      }
-      if (element instanceof ClassElement) {
-        return false;
-      }
-      element = element.getEnclosingElement();
-    }
-    return true;
-  }
-
-  public static boolean isNonFactoryConstructor(Element method) {
-    return !method.getModifiers().isFactory()
-        && ElementKind.of(method) == ElementKind.CONSTRUCTOR;
-  }
-
-  public static boolean isTopLevel(Element element) {
-    return ElementKind.of(element.getEnclosingElement()) == ElementKind.LIBRARY;
-  }
-
-  static List<TypeVariable> makeTypeVariables(List<DartTypeParameter> parameterNodes,
-                                              EnclosingElement enclosingElement) {
-    if (parameterNodes == null) {
-      return Arrays.<TypeVariable>asList();
-    }
-    TypeVariable[] typeVariables = new TypeVariable[parameterNodes.size()];
-    int i = 0;
-    for (DartTypeParameter parameterNode : parameterNodes) {
-      TypeVariable typeVariable =
-          Elements.typeVariableFromNode(parameterNode, enclosingElement).getTypeVariable();
-      typeVariables[i++] = typeVariable;
-      parameterNode.getName().setElement(typeVariable.getElement());
-    }
-    return Arrays.asList(typeVariables);
-  }
-
-  public static Element voidElement() {
-    return VoidElement.getInstance();
-  }
-
-  /**
-   * Returns true if the class needs an implicit default constructor.
-   */
-  public static boolean needsImplicitDefaultConstructor(ClassElement classElement) {
-    return classElement.getConstructors().isEmpty()
-        && (!classElement.isInterface() || classElement.getDefaultClass() != null);
-  }
-
-  /**
-   * @return <code>true</code> if {@link #classElement} implements {@link #interfaceElement}.
-   */
-  public static boolean implementsType(ClassElement classElement, ClassElement interfaceElement) {
-    try {
-      for (InterfaceType supertype : classElement.getAllSupertypes()) {
-        if (supertype.getElement().equals(interfaceElement)) {
-          return true;
-        }
-      }
-    } catch (Throwable e) {
-    }
-    return false;
-  }
-
-  /**
-   * @return the "name" or "qualifier.name" raw name of {@link DartMethodDefinition} which
-   *         corresponds the given {@link MethodElement}.
-   */
-  public static String getRawMethodName(MethodElement methodElement) {
-    if (methodElement instanceof ConstructorElement) {
-      ConstructorElement constructorElement = (ConstructorElement) methodElement;
-      return constructorElement.getRawName();
-    }
-    return methodElement.getName();
-  }
-
-  /**
-   * @return the number of required (not optional/named) parameters in given {@link MethodElement}.
-   */
-  public static int getNumberOfRequiredParameters(MethodElement method) {
-    int num = 0;
-    List<VariableElement> parameters = method.getParameters();
-    for (VariableElement parameter : parameters) {
-      if (!parameter.isOptional() && !parameter.isNamed()) {
-        num++;
-      }
-    }
-    return num;
-  }
-  
-  /**
-   * @return the number of optional positional parameters in given {@link MethodElement}.
-   */
-  public static int getNumberOfOptionalPositionalParameters(MethodElement method) {
-    int num = 0;
-    List<VariableElement> parameters = method.getParameters();
-    for (VariableElement parameter : parameters) {
-      if (parameter.isOptional()) {
-        num++;
-      }
-    }
-    return num;
-  }
-
-  /**
-   * @return the names for named parameters in given {@link MethodElement}.
-   */
-  public static List<String> getNamedParameters(MethodElement method) {
-    List<String> names = Lists.newArrayList();
-    List<VariableElement> parameters = method.getParameters();
-    for (VariableElement parameter : parameters) {
-      if (parameter.isNamed()) {
-        names.add(parameter.getName());
-      }
-    }
-    return names;
-  }
-
-  /**
-   * @return the names for parameters types in given {@link MethodElement}.
-   */
-  public static List<String> getParameterTypeNames(MethodElement method) {
-    List<String> names = Lists.newArrayList();
-    List<VariableElement> parameters = method.getParameters();
-    for (VariableElement parameter : parameters) {
-      String typeName = parameter.getType().getElement().getName();
-      names.add(typeName);
-    }
-    return names;
-  }
-  
-  /**
-   * Prepares title for {@link TypeErrorCode#DEPRECATED_ELEMENT}.
-   */
-  public static String getDeprecatedElementTitle(Element element) {
-    String title = getUserElementTitle(element);
-    return StringUtils.capitalize(title);
-  }
-
-  /**
-   * @return the user readable title of the given {@link Element}, a little different than
-   *         "technical" title returned from {@link Element#toString()}.
-   */
-  public static String getUserElementTitle(Element element) {
-    return MessageFormat.format("{0} ''{1}''", getUserElementKindTitle(element), element.getName());
-  }
-
-  /**
-   * @return the user readable title of the given {@link Element}'s {@link ElementKind}, a little
-   *         different than "technical" title returned from {@link Element#toString()}.
-   */
-  private static String getUserElementKindTitle(Element element) {
-    ElementKind kind = element.getKind();
-    switch (kind) {
-      case CLASS:
-        if (((ClassElement) element).isInterface()) {
-          return "interface";
-        }
-        break;
-      case METHOD:
-        if (isTopLevel(element)) {
-          return "top-level function";
-        }
-        break;
-      case FIELD:
-        if (isTopLevel(element)) {
-          return "top-level variable";
-        }
-        break;
-    }
-    String title = kind.toString();
-    title = StringUtils.replace(title, "_", " ");
-    title = title.toLowerCase();
-    return title;
-  }
-
-  /**
-   * @return the {@link String} which contains user-readable description of "target" {@link Element}
-   *         location relative to "source".
-   */
-  public static String getRelativeElementLocation(Element source, Element target) {
-    // Prepare "target" SourceInfo.
-    SourceInfo targetInfo;
-    {
-      targetInfo = target.getNameLocation();
-      if (targetInfo == null) {
-        return "unknown";
-      }
-    }
-    // Prepare path to the target unit from source unit.
-    String targetPath;
-    {
-      SourceInfo sourceInfo = source.getSourceInfo();
-      targetPath = getRelativeSourcePath(sourceInfo, targetInfo);
-    }
-    // Prepare (may be empty) target class name.
-    String targetClassName;
-    {
-      EnclosingElement targetEnclosing = target.getEnclosingElement();
-      ClassElement targetClass = getEnclosingClassElement(targetEnclosing);
-      targetClassName = targetClass != null ? targetClass.getName() : "";
-    }
-    // Format location string.
-    if (StringUtils.isEmpty(targetClassName)) {
-      return MessageFormat.format("{0} line:{1} col:{2}", targetPath, targetInfo.getLine(),
-          targetInfo.getColumn());
-    } else {
-      return MessageFormat.format("{0} class:{1} line:{2} col:{3}", targetPath, targetClassName,
-          targetInfo.getLine(), targetInfo.getColumn());
-    }
-  }
-
-  /**
-   * @return the relative or absolute path from "source" to "target".
-   */
-  private static String getRelativeSourcePath(SourceInfo source, SourceInfo target) {
-    Source sourceSource = source.getSource();
-    Source targetSource = target.getSource();
-    return getRelativeSourcePath(sourceSource, targetSource);
-  }
-
-  /**
-   * @return the relative or absolute path from "source" to "target".
-   */
-  public static String getRelativeSourcePath(Source sourceSource, Source targetSource) {
-    // If both source are from file, prepare relative path.
-    if (sourceSource != null && targetSource != null) {
-      URI sourceUri = sourceSource.getUri();
-      URI targetUri = targetSource.getUri();
-      if (Objects.equal(sourceUri.getScheme(), "file")
-          && Objects.equal(targetUri.getScheme(), "file")) {
-        return Paths.relativePathFor(new File(sourceUri.getPath()), new File(targetUri.getPath()));
-      }
-    }
-    // Else return absolute path (including dart:// protocol).
-    if (targetSource != null) {
-      URI targetUri = targetSource.getUri();
-      return targetUri.toString();
-    }
-    // No source for target.
-    return "<unknown>";
-  }
-
-  /**
-   * @return the full location of the given {@link Element} - library and unit.
-   */
-  public static String getLibraryUnitLocation(Element element) {
-    try {
-      StringBuilder sb = new StringBuilder();
-      // library URI
-      String libraryUri;
-      {
-        LibraryUnit libraryUnit = getDeclaringLibrary(element).getLibraryUnit();
-        libraryUri = libraryUnit.getSource().getUri().toString();
-        sb.append(libraryUri);
-      }
-      // unit URI
-      SourceInfo sourceInfo = element.getSourceInfo();
-      {
-        String unitUri = sourceInfo.getSource().getUri().toString();
-        if (!unitUri.equals(libraryUri)) {
-          sb.append(" ");
-          sb.append(unitUri);
-        }
-      }
-      // line
-      sb.append(":");
-      sb.append(sourceInfo.getLine());
-      // done
-      return sb.toString();
-    } catch (Throwable e) {
-      return "<exception>";
-    }
-  }
-
-  /**
-   * @return the enclosing {@link ClassElement} (may be same if already given {@link ClassElement}),
-   *         may be <code>null</code> if top level element.
-   */
-  public static ClassElement getEnclosingClassElement(Element element) {
-    while (element != null) {
-      if (element instanceof ClassElement) {
-        return (ClassElement) element;
-      }
-      element = element.getEnclosingElement();
-    }
-    return null;
-  }
-
-  /**
-   * @return <code>true</code> if the given {@link DartTypeNode} is type with one of the given
-   *         names.
-   */
-  public static boolean isTypeNode(DartTypeNode typeNode, Set<String> names) {
-    if (typeNode != null) {
-      DartNode identifier = typeNode.getIdentifier();
-      String typeName = getIdentifierName(identifier);
-      return names.contains(typeName);
-    }
-    return false;
-  }
-
-  /**
-   * @return <code>true</code> if the given {@link DartTypeNode} is type with given name.
-   */
-  public static boolean isTypeNode(DartTypeNode typeNode, String name) {
-    return typeNode != null && isIdentifierName(typeNode.getIdentifier(), name);
-  }
-
-  /**
-   * @return <code>true</code> if the given {@link DartNode} is type identifier with given name.
-   */
-  public static boolean isIdentifierName(DartNode identifier, String name) {
-    String identifierName = getIdentifierName(identifier);
-    return Objects.equal(identifierName, name);
-  }
-
-  /**
-   * @return <code>true</code> if the given {@link ConstructorElement} is a synthetic default
-   *         constructor.
-   */
-  public static boolean isSyntheticConstructor(ConstructorElement element) {
-    return element != null && element.isSynthetic();
-  }
-
-  /**
-   * @return <code>true</code> if the given {@link ConstructorElement} is a default constructor.
-   */
-  public static boolean isDefaultConstructor(ConstructorElement element) {
-    return element != null
-        && element.getParameters().isEmpty()
-        && getRawMethodName(element).equals(element.getEnclosingElement().getName());
-  }
-  
-  public static void setRedirectingFactoryConstructor(ConstructorElement source,
-      ConstructorElement target) {
-    ((ConstructorElementImplementation) source).setRedirectingFactoryConstructor(target);
-  }
-
-  /**
-   * @return the name of given {@link DartNode} if it is {@link DartIdentifier}, or
-   *         <code>null</code> otherwise.
-   */
-  private static String getIdentifierName(DartNode identifier) {
-    if (identifier != null && identifier instanceof DartIdentifier) {
-      return ((DartIdentifier) identifier).getName();
-    }
-    return null;
-  }
-
-  /**
-   * @return <code>true</code> if given {@link Source} represents library with given name.
-   */
-  public static boolean isLibrarySource(Source source, String name) {
-    LibrarySource library = null;
-    if (source instanceof LibrarySource) {
-      library = (LibrarySource) source;
-    }
-    if (source instanceof DartSource) {
-      DartSource dartSource = (DartSource) source;
-      library = dartSource.getLibrary();
-    }
-    if (library != null) {
-      String libraryName = library.getName();
-      return libraryName.endsWith(name);
-    }
-    return false;
-  }
-
-  /**
-   * @return <code>true</code> if given {@link Source} represents code library declaration or
-   *         implementation.
-   */
-  public static boolean isCoreLibrarySource(Source source) {
-    if (source != null && source.getUri() != null
-        && source.getUri().toString().equals("libraries.dart")) {
-      return true;
-    }
-    // TODO (danrubel) remove these when dartc libraries are removed
-    // Old core library file names
-    return Elements.isLibrarySource(source, "/core/corelib.dart")
-        || Elements.isLibrarySource(source, "/core/corelib_impl.dart")
-        // New core library file names
-        || Elements.isLibrarySource(source, "/core/core.dart");
-  }
-  
-  public static boolean isCollectionLibrarySource(Source source) {
-    return Elements.isLibrarySource(source, "/collection/collection.dart");
-  }
-  
-  public static boolean isHtmlLibrarySource(Source source) {
-    return Elements.isLibrarySource(source, "/html/dartium/html_dartium.dart");
-  }
-  
-  public static boolean isSourceName(Source source, String requiredName) {
-    return source.getName().equals(requiredName);
-  }
-
-  /**
-   * @return the {@link LibraryElement} which declares given {@link Element}.
-   */
-  public static LibraryElement getDeclaringLibrary(Element element) {
-    while (element != null) {
-      if (element instanceof LibraryElement) {
-        return (LibraryElement) element;
-      }
-      element = element.getEnclosingElement();
-    }
-    return null;
-  }
-
-  /**
-   * @return <code>true</code> if "element" is accessible in "scopeLibrary".
-   */
-  public static boolean isAccessible(LibraryElement scopeLibrary, Element element) {
-    if (element != null && StringUtils.startsWith(element.getName(), "_")) {
-      return Objects.equal(scopeLibrary, getDeclaringLibrary(element));
-    }
-    return true;
-  }
-
-  /**
-   * @return <code>true</code> if given {@link Element} if {@link MethodElement} for
-   *         function "identical".
-   */
-  public static boolean isFunctionIdentical(Element element) {
-    if (element instanceof MethodElement) {
-      MethodElement methodElement = (MethodElement) element;
-      return Objects.equal(methodElement.getName(), "identical")
-          && methodElement.getEnclosingElement() instanceof LibraryElement
-          && methodElement.getEnclosingElement().getName().equals("dart://core/core.dart");
-    }
-    return false;
-  }
-
-  /**
-   * @return <code>true</code> if normal field or abstract field with getter.
-   */
-  public static boolean isFieldWithGetter(FieldElement fieldElement) {
-    if (fieldElement.getModifiers().isAbstractField()) {
-      return fieldElement.getGetter() != null;
-    }
-    return true;
-  }
-  
-  public static boolean isAbstractFieldWithoutGetter(Element element) {
-    if (element instanceof FieldElement) {
-      FieldElement fieldElement = (FieldElement) element;
-      return fieldElement.getModifiers().isAbstractField() && fieldElement.getGetter() == null;
-    }
-    return false;
-  }
-
-  public static boolean hasClassMember(ClassElement clazz, String name) {
-    if (clazz.lookupLocalElement(name) != null) {
-      return true;
-    }
-    for (InterfaceType interfaceType : clazz.getInterfaces()) {
-      if (hasClassMember(interfaceType.getElement(), name)) {
-        return true;
-      }
-    }
-    for (InterfaceType mixinType : clazz.getMixins()) {
-      if (mixinType.getElement().lookupLocalElement(name) != null) {
-        return true;
-      }
-    }
-    if (clazz.getSupertype() != null) {
-      if (hasClassMember(clazz.getSupertype().getElement(), name)) {
-        return true;
-      }
-    }
-    return false;
-  }
-  
-  /**
-   * @return <code>true</code> if given {@link FieldElement} is explicitly declared static, or is
-   *         static implicitly.
-   */
-  public static boolean isStaticField(FieldElement field) {
-    Modifiers modifiers = field.getModifiers();
-    return modifiers.isStatic();
-  }
-
-  /**
-   * @return <code>true</code> if given {@link InterfaceType} overrides "noSuchMethod".
-   */
-  public static boolean handlesNoSuchMethod(InterfaceType type) {
-    Member member = type.lookupMember("noSuchMethod");
-    if (member == null) {
-      return false;
-    }
-    Source source = member.getElement().getSourceInfo().getSource();
-    return !isCoreLibrarySource(source);
-  }
-  
-  public static DuplicateElement createDuplicateElement(Element oldElement, Element newElement) {
-    return new DuplicateElementImplementation(oldElement, newElement);
-  }
-  
-  
-  public static List<Element> getAllMembers(ClassElement classElement) {
-    List<Element> allMembers = Lists.newArrayList();
-    Set<ClassElement> visited = Sets.newHashSet();
-    addAllMembers(visited, allMembers, classElement);
-    return allMembers;
-  }
-  
-  private static void addAllMembers(Set<ClassElement> visited, List<Element> allMembers, ClassElement classElement) {
-    if (classElement == null) {
-      return;
-    }
-    if (visited.contains(classElement)) {
-      return;
-    }
-    visited.add(classElement);
-    Iterables.addAll(allMembers, classElement.getMembers());
-    {
-      InterfaceType superType = classElement.getSupertype();
-      if (superType != null)
-        addAllMembers(visited, allMembers, superType.getElement());
-    }
-    for (InterfaceType intf : classElement.getInterfaces()) {
-      addAllMembers(visited, allMembers, intf.getElement());
-    }
-    for (InterfaceType mix : classElement.getMixins()) {
-      Iterables.addAll(allMembers, mix.getElement().getMembers());
-    }
-  }
-  
-  public static boolean isAbstractElement(Element element) {
-    if (element == null) {
-      return false;
-    }
-    if (element.getModifiers().isAbstract()) {
-      return true;
-    }
-    if (element.getModifiers().isExternal()) {
-      return false;
-    }
-    if (element.getModifiers().isNative()) {
-      return false;
-    }
-    if (element.getModifiers().isStatic()) {
-      return false;
-    }
-    if (ElementKind.of(element) == ElementKind.METHOD) {
-      MethodElement method = (MethodElement) element;
-      return !method.hasBody();
-    }
-    return false;
-  }
-  
-  public static boolean isFieldOfSameClassAsEnclosingConstructor(Element maybeField,
-      Element maybeConstructor) {
-    if (ElementKind.of(maybeField) == ElementKind.FIELD
-        && ElementKind.of(maybeConstructor) == ElementKind.CONSTRUCTOR) {
-      FieldElement field = (FieldElement) maybeField;
-      ConstructorElement constructor = (ConstructorElement) maybeConstructor;
-      if (field.getEnclosingElement() == constructor.getEnclosingElement()) {
-        return true;
-      }
-    }
-    return false;
-  }
-}
diff --git a/compiler/java/com/google/dart/compiler/resolver/EnclosingElement.java b/compiler/java/com/google/dart/compiler/resolver/EnclosingElement.java
deleted file mode 100644
index 0a96bea..0000000
--- a/compiler/java/com/google/dart/compiler/resolver/EnclosingElement.java
+++ /dev/null
@@ -1,13 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.resolver;
-
-public interface EnclosingElement extends Element {
-  Iterable<? extends Element> getMembers();
-
-  Element lookupLocalElement(String name);
-
-  boolean isInterface();
-}
diff --git a/compiler/java/com/google/dart/compiler/resolver/FieldElement.java b/compiler/java/com/google/dart/compiler/resolver/FieldElement.java
deleted file mode 100644
index a2fb975..0000000
--- a/compiler/java/com/google/dart/compiler/resolver/FieldElement.java
+++ /dev/null
@@ -1,29 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.resolver;
-
-import com.google.dart.compiler.type.Type;
-
-import java.util.Set;
-
-public interface FieldElement extends Element {
-  boolean isStatic();
-
-  void setType(Type type);
-
-  MethodElement getGetter();
-
-  MethodElement getSetter();
-
-  /**
-   * @return the inferred {@link Type} of this constant, may be <code>null</code> if not set yet.
-   */
-  Type getConstantType();
-
-  /**
-   * @return {@link Element}s overridden by this {@link MethodElement}.
-   */
-  Set<Element> getOverridden();
-}
diff --git a/compiler/java/com/google/dart/compiler/resolver/FieldElementImplementation.java b/compiler/java/com/google/dart/compiler/resolver/FieldElementImplementation.java
deleted file mode 100644
index d60a144..0000000
--- a/compiler/java/com/google/dart/compiler/resolver/FieldElementImplementation.java
+++ /dev/null
@@ -1,128 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.resolver;
-
-import com.google.common.collect.ImmutableSet;
-import com.google.dart.compiler.ast.DartField;
-import com.google.dart.compiler.ast.DartNode;
-import com.google.dart.compiler.ast.DartObsoleteMetadata;
-import com.google.dart.compiler.ast.Modifiers;
-import com.google.dart.compiler.common.SourceInfo;
-import com.google.dart.compiler.type.Type;
-
-import java.util.Set;
-
-class FieldElementImplementation extends AbstractNodeElement implements FieldElement, FieldNodeElement {
-  private final EnclosingElement holder;
-  private final SourceInfo nameLocation;
-  private DartObsoleteMetadata metadata;
-  private Modifiers modifiers;
-  private Type type;
-  private MethodNodeElement getter;
-  private MethodNodeElement setter;
-  private Type constantType;
-  private Set<Element> overridden = ImmutableSet.of();
-
-  FieldElementImplementation(DartNode node,
-      SourceInfo nameLocation,
-      String name,
-      EnclosingElement holder,
-      DartObsoleteMetadata metadata,
-      Modifiers modifiers) {
-    super(node, name);
-    this.holder = holder;
-    this.metadata = metadata;
-    this.modifiers = modifiers;
-    this.nameLocation = nameLocation;
-  }
-
-  @Override
-  public Type getType() {
-    return type;
-  }
-
-  @Override
-  public void setType(Type type) {
-    this.type = type;
-  }
-
-  @Override
-  public ElementKind getKind() {
-    return ElementKind.FIELD;
-  }
-
-  @Override
-  public SourceInfo getNameLocation() {
-    return nameLocation;
-  }
-
-  @Override
-  public EnclosingElement getEnclosingElement() {
-    return holder;
-  }
-
-  @Override
-  public DartObsoleteMetadata getMetadata() {
-    return metadata;
-  }
-
-  @Override
-  public Modifiers getModifiers() {
-    return modifiers;
-  }
-
-  @Override
-  public boolean isStatic() {
-    return modifiers.isStatic();
-  }
-
-  public static FieldElementImplementation fromNode(DartField node,
-      EnclosingElement holder,
-      DartObsoleteMetadata metadata,
-      Modifiers modifiers) {
-    return new FieldElementImplementation(node,
-        node.getName().getSourceInfo(),
-        (node.getAccessor() != null && node.getAccessor().getModifiers().isSetter() ? "setter " : "") + node.getName().getName(),
-        holder,
-        metadata,
-        modifiers);
-  }
-
-  @Override
-  public MethodNodeElement getGetter() {
-    return getter;
-  }
-
-  @Override
-  public MethodNodeElement getSetter() {
-    return setter;
-  }
-
-  void setGetter(MethodNodeElement getter) {
-    this.getter = getter;
-  }
-
-  void setSetter(MethodNodeElement setter) {
-    this.setter = setter;
-  }
-
-  @Override
-  public Type getConstantType() {
-    return constantType;
-  }
-
-  @Override
-  public void setConstantType(Type type) {
-    constantType = type;
-  }
-
-  public void setOverridden(Set<Element> overridden) {
-    this.overridden = overridden;
-  }
-  
-  public Set<Element> getOverridden() {
-    return overridden;
-  }
-}
diff --git a/compiler/java/com/google/dart/compiler/resolver/FieldNodeElement.java b/compiler/java/com/google/dart/compiler/resolver/FieldNodeElement.java
deleted file mode 100644
index 6b05965..0000000
--- a/compiler/java/com/google/dart/compiler/resolver/FieldNodeElement.java
+++ /dev/null
@@ -1,23 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-package com.google.dart.compiler.resolver;
-
-import com.google.dart.compiler.ast.DartNode;
-import com.google.dart.compiler.type.Type;
-
-/**
- * Extension of {@link FieldElement} which is based on {@link DartNode} and is modifiable.
- */
-public interface FieldNodeElement extends FieldElement, NodeElement {
-  /**
-   * Sets the inferred type of this constant.
-   * 
-   * @param type the {@link Type} to set, not <code>null</code>.
-   */
-  void setConstantType(Type type);
-  
-  MethodNodeElement getGetter();
-  
-  MethodNodeElement getSetter();
-}
diff --git a/compiler/java/com/google/dart/compiler/resolver/FunctionAliasElement.java b/compiler/java/com/google/dart/compiler/resolver/FunctionAliasElement.java
deleted file mode 100644
index 982677e..0000000
--- a/compiler/java/com/google/dart/compiler/resolver/FunctionAliasElement.java
+++ /dev/null
@@ -1,20 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.resolver;
-
-import com.google.dart.compiler.type.FunctionAliasType;
-import com.google.dart.compiler.type.FunctionType;
-
-/**
- * A function type alias.
- */
-public interface FunctionAliasElement extends ClassElement {
-  @Override
-  FunctionAliasType getType();
-
-  FunctionType getFunctionType();
-
-  void setFunctionType(FunctionType functionType);
-}
diff --git a/compiler/java/com/google/dart/compiler/resolver/FunctionAliasElementImplementation.java b/compiler/java/com/google/dart/compiler/resolver/FunctionAliasElementImplementation.java
deleted file mode 100644
index e6f2439..0000000
--- a/compiler/java/com/google/dart/compiler/resolver/FunctionAliasElementImplementation.java
+++ /dev/null
@@ -1,60 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.resolver;
-
-import com.google.dart.compiler.ast.DartFunctionTypeAlias;
-import com.google.dart.compiler.type.FunctionAliasType;
-import com.google.dart.compiler.type.FunctionType;
-import com.google.dart.compiler.type.InterfaceType;
-
-// Could be a direct subclass of AbstractElement.
-public class FunctionAliasElementImplementation extends ClassElementImplementation
-    implements FunctionAliasElement {
-
-  private FunctionType functionType;
-  private final DartFunctionTypeAlias node;
-
-  FunctionAliasElementImplementation(DartFunctionTypeAlias node, String name, LibraryElement library) {
-    super(null, name, null, library);
-    this.node = node;
-  }
-
-  @Override
-  public DartFunctionTypeAlias getNode() {
-    return node;
-  }
-
-  @Override
-  public ElementKind getKind() {
-    return ElementKind.FUNCTION_TYPE_ALIAS;
-  }
-
-  @Override
-  public FunctionAliasType getType() {
-    return (FunctionAliasType) super.getType();
-  }
-
-  @Override
-  public FunctionType getFunctionType() {
-    return functionType;
-  }
-
-  @Override
-  public void setType(InterfaceType type) {
-    FunctionAliasType ftype = (FunctionAliasType) type;
-    super.setType(ftype);
-  }
-
-  @Override
-  public void setFunctionType(FunctionType functionType) {
-    this.functionType = functionType;
-  }
-
-  public static FunctionAliasElement fromNode(DartFunctionTypeAlias node,
-                                              LibraryElement library) {
-    return new FunctionAliasElementImplementation(
-        node, node.getName().getName(), library);
-  }
-}
diff --git a/compiler/java/com/google/dart/compiler/resolver/LabelElement.java b/compiler/java/com/google/dart/compiler/resolver/LabelElement.java
deleted file mode 100644
index 8fb58d9..0000000
--- a/compiler/java/com/google/dart/compiler/resolver/LabelElement.java
+++ /dev/null
@@ -1,21 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.resolver;
-
-public interface LabelElement extends Element {
-  
-  public enum LabeledStatementType {
-    STATEMENT,
-    SWITCH_MEMBER_STATEMENT,
-    SWITCH_STATEMENT,
-  }
-  
-  /**
-   * Returns the innermost function where this label is defined.
-   */
-  public MethodElement getEnclosingFunction();
-  
-  public LabeledStatementType getStatementType();
-}
diff --git a/compiler/java/com/google/dart/compiler/resolver/LabelElementImplementation.java b/compiler/java/com/google/dart/compiler/resolver/LabelElementImplementation.java
deleted file mode 100644
index f61c03d..0000000
--- a/compiler/java/com/google/dart/compiler/resolver/LabelElementImplementation.java
+++ /dev/null
@@ -1,35 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.resolver;
-
-import com.google.dart.compiler.ast.DartLabel;
-
-class LabelElementImplementation extends AbstractNodeElement implements LabelElement {
-
-  private MethodElement enclosingFunction;
-  private final LabeledStatementType statementType;
-  
-  LabelElementImplementation(DartLabel node, String name, MethodElement enclosingFunction, 
-      LabeledStatementType statementType) {
-    super(node, name);
-    this.enclosingFunction = enclosingFunction;
-    this.statementType = statementType;
-  }
-
-  @Override
-  public ElementKind getKind() {
-    return ElementKind.LABEL;
-  }
-
-  @Override
-  public MethodElement getEnclosingFunction() {
-    return enclosingFunction;
-  }
-  
-  @Override
-  public LabeledStatementType getStatementType() {
-    return statementType;
-  }
-}
diff --git a/compiler/java/com/google/dart/compiler/resolver/LibraryElement.java b/compiler/java/com/google/dart/compiler/resolver/LibraryElement.java
deleted file mode 100644
index 529ad64..0000000
--- a/compiler/java/com/google/dart/compiler/resolver/LibraryElement.java
+++ /dev/null
@@ -1,23 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.resolver;
-
-import com.google.dart.compiler.ast.LibraryUnit;
-
-import java.util.Collection;
-
-public interface LibraryElement extends EnclosingElement {
-  Scope getImportScope();
-
-  Scope getScope();
-  
-  Collection<Element> getExportedElements();
-
-  LibraryUnit getLibraryUnit();
-
-  void setEntryPoint(MethodElement element);
-
-  MethodElement getEntryPoint();
-}
diff --git a/compiler/java/com/google/dart/compiler/resolver/LibraryElementImplementation.java b/compiler/java/com/google/dart/compiler/resolver/LibraryElementImplementation.java
deleted file mode 100644
index 3e2c49c..0000000
--- a/compiler/java/com/google/dart/compiler/resolver/LibraryElementImplementation.java
+++ /dev/null
@@ -1,100 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.resolver;
-
-import com.google.common.collect.Maps;
-import com.google.dart.compiler.ast.DartObsoleteMetadata;
-import com.google.dart.compiler.ast.LibraryUnit;
-
-import java.util.Collection;
-import java.util.Map;
-
-class LibraryElementImplementation extends AbstractNodeElement implements LibraryElement {
-
-  private final Scope importScope = new Scope("import", this);
-  private final Scope scope = new Scope("library", this, importScope);
-  private final Map<String, Element> exportedElements = Maps.newHashMap();
-  private LibraryUnit libraryUnit;
-  private MethodElement entryPoint;
-  private DartObsoleteMetadata metadata = DartObsoleteMetadata.EMPTY;
-
-  public LibraryElementImplementation(LibraryUnit libraryUnit) {
-    // TODO(ngeoffray): What should we pass the super? Should a LibraryUnit be a node?
-    super(null, libraryUnit.getSource().getName());
-    this.libraryUnit = libraryUnit;
-  }
-
-  @Override
-  public boolean isInterface() {
-    return false;
-  }
-
-  @Override
-  public Scope getImportScope() {
-    return importScope;
-  }
-
-  @Override
-  public Scope getScope() {
-    return scope;
-  }
-
-  public Element addExportedElements(Element element) {
-    String name = element.getName();
-    return exportedElements.put(name, element);
-  }
-  
-  public Collection<Element> getExportedElements() {
-    return exportedElements.values();
-  }
-
-  @Override
-  public ElementKind getKind() {
-    return ElementKind.LIBRARY;
-  }
-
-  @Override
-  public LibraryUnit getLibraryUnit() {
-    return libraryUnit;
-  }
-
-  @Override
-  public void setEntryPoint(MethodElement element) {
-    this.entryPoint = element;
-  }
-
-  @Override
-  public MethodElement getEntryPoint() {
-    return entryPoint;
-  }
-
-  @Override
-  public Collection<Element> getMembers() {
-    // TODO(ngeoffray): have a proper way to get all the declared top level elements.
-    return scope.getElements().values();
-  }
-
-  @Override
-  public Element lookupLocalElement(String name) {
-    return scope.findLocalElement(name);
-  }
-
-  void addField(FieldElement field) {
-    scope.declareElement(field.getName(), field);
-  }
-
-  void addMethod(MethodElement method) {
-    scope.declareElement(method.getName(), method);
-  }
-  
-  @Override
-  public DartObsoleteMetadata getMetadata() {
-    return metadata;
-  }
-
-  public void setMetadata(DartObsoleteMetadata metadata) {
-    this.metadata = metadata;
-  }
-}
diff --git a/compiler/java/com/google/dart/compiler/resolver/LibraryPrefixElement.java b/compiler/java/com/google/dart/compiler/resolver/LibraryPrefixElement.java
deleted file mode 100644
index 9648617..0000000
--- a/compiler/java/com/google/dart/compiler/resolver/LibraryPrefixElement.java
+++ /dev/null
@@ -1,13 +0,0 @@
-// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.resolver;
-
-import java.util.List;
-
-public interface LibraryPrefixElement extends EnclosingElement {
-  Scope getScope();
-  void addLibrary(LibraryElement library);
-  List<LibraryElement> getLibraries();
-}
diff --git a/compiler/java/com/google/dart/compiler/resolver/LibraryPrefixElementImplementation.java b/compiler/java/com/google/dart/compiler/resolver/LibraryPrefixElementImplementation.java
deleted file mode 100644
index e54c625..0000000
--- a/compiler/java/com/google/dart/compiler/resolver/LibraryPrefixElementImplementation.java
+++ /dev/null
@@ -1,56 +0,0 @@
-// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.resolver;
-
-import com.google.common.collect.Lists;
-
-import java.util.Collection;
-import java.util.List;
-
-class LibraryPrefixElementImplementation extends AbstractNodeElement implements
-    LibraryPrefixElement {
-
-  private final List<LibraryElement> libraries = Lists.newArrayList();
-  private final Scope scope;
-
-  public LibraryPrefixElementImplementation(String name, Scope parent) {
-    super(null, name);
-    scope = new Scope("prefix:" + name, parent.getLibrary());
-  }
-
-  @Override
-  public boolean isInterface() {
-    return false;
-  }
-
-  @Override
-  public Scope getScope() {
-    return scope;
-  }
-
-  @Override
-  public ElementKind getKind() {
-    return ElementKind.LIBRARY_PREFIX;
-  }
-
-  @Override
-  public Collection<Element> getMembers() {
-    return scope.getElements().values();
-  }
-
-  @Override
-  public Element lookupLocalElement(String name) {
-    return scope.findLocalElement(name);
-  }
-
-  public void addLibrary(LibraryElement library) {
-    libraries.add(library);
-  }
-
-  @Override
-  public List<LibraryElement> getLibraries() {
-    return libraries;
-  }
-}
diff --git a/compiler/java/com/google/dart/compiler/resolver/MemberBuilder.java b/compiler/java/com/google/dart/compiler/resolver/MemberBuilder.java
deleted file mode 100644
index a46aa61..0000000
--- a/compiler/java/com/google/dart/compiler/resolver/MemberBuilder.java
+++ /dev/null
@@ -1,736 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.resolver;
-
-import com.google.common.annotations.VisibleForTesting;
-import com.google.common.base.Objects;
-import com.google.dart.compiler.DartCompilerContext;
-import com.google.dart.compiler.ErrorCode;
-import com.google.dart.compiler.ast.ASTVisitor;
-import com.google.dart.compiler.ast.DartBlock;
-import com.google.dart.compiler.ast.DartClass;
-import com.google.dart.compiler.ast.DartExpression;
-import com.google.dart.compiler.ast.DartField;
-import com.google.dart.compiler.ast.DartFieldDefinition;
-import com.google.dart.compiler.ast.DartFunction;
-import com.google.dart.compiler.ast.DartFunctionTypeAlias;
-import com.google.dart.compiler.ast.DartIdentifier;
-import com.google.dart.compiler.ast.DartMethodDefinition;
-import com.google.dart.compiler.ast.DartNativeBlock;
-import com.google.dart.compiler.ast.DartNode;
-import com.google.dart.compiler.ast.DartParameter;
-import com.google.dart.compiler.ast.DartParameterizedTypeNode;
-import com.google.dart.compiler.ast.DartPropertyAccess;
-import com.google.dart.compiler.ast.DartThisExpression;
-import com.google.dart.compiler.ast.DartUnit;
-import com.google.dart.compiler.ast.Modifiers;
-import com.google.dart.compiler.common.HasSourceInfo;
-import com.google.dart.compiler.common.SourceInfo;
-import com.google.dart.compiler.type.Type;
-import com.google.dart.compiler.type.Types;
-import com.google.dart.compiler.util.apache.StringUtils;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Builds the method, field and constructor elements of classes and the library in a DartUnit.
- */
-public class MemberBuilder {
-  private ResolutionContext topLevelContext;
-  private LibraryElement libraryElement;
-
-  public void exec(DartUnit unit, DartCompilerContext context, CoreTypeProvider typeProvider) {
-    Scope scope = unit.getLibrary().getElement().getScope();
-    exec(unit, context, scope, typeProvider);
-  }
-
-  @VisibleForTesting
-  public void exec(DartUnit unit, DartCompilerContext compilerContext, Scope scope,
-                   CoreTypeProvider typeProvider) {
-    libraryElement = unit.getLibrary().getElement();
-    topLevelContext = new ResolutionContext(scope, compilerContext, typeProvider);
-    unit.accept(new MemberElementBuilder(typeProvider));
-  }
-
-  /**
-   * Creates elements for the fields, methods and constructors of a class. The
-   * elements are added to the ClassElement.
-   *
-   * TODO(ngeoffray): Errors reported:
-   *  - Duplicate member names in the same class.
-   *  - Unresolved types.
-   */
-  private class MemberElementBuilder extends ResolveVisitor {
-    EnclosingElement currentHolder;
-    private EnclosingElement enclosingElement;
-    private ResolutionContext context;
-    private boolean isStatic;
-    private boolean isFactory;
-
-    MemberElementBuilder(CoreTypeProvider typeProvider) {
-      super(typeProvider);
-      context = topLevelContext;
-      currentHolder = libraryElement;
-    }
-
-    @Override
-    ResolutionContext getContext() {
-      return context;
-    }
-
-    @Override
-    protected EnclosingElement getEnclosingElement() {
-      return enclosingElement;
-    }
-
-    @Override
-    public Element visitClass(DartClass node) {
-      assert !ElementKind.of(currentHolder).equals(ElementKind.CLASS) : "nested class?";
-      beginClassContext(node);
-      ClassElement classElement = node.getElement();
-      EnclosingElement previousEnclosingElement = enclosingElement;
-      enclosingElement = classElement;
-      // visit fields, to make their Elements ready for constructor parameters
-      for (DartNode member : node.getMembers()) {
-        if (member instanceof DartFieldDefinition) {
-          member.accept(this);
-        }
-      }
-      // visit all other members
-      for (DartNode member : node.getMembers()) {
-        if (!(member instanceof DartFieldDefinition)) {
-          member.accept(this);
-        }
-      }
-      // check constructor names
-      for (ConstructorElement constructor : classElement.getConstructors()) {
-        String name = constructor.getName();
-        SourceInfo nameLocation = constructor.getNameLocation();
-        // should be name of immediately enclosing class
-        if (constructor.getModifiers().isFactory()) {
-          String rawName = constructor.getRawName();
-          String consClassName = StringUtils.substringBefore(rawName, ".");
-          String consUserName = StringUtils.substringAfter(rawName, ".");
-          if (!StringUtils.equals(consClassName, classElement.getName())) {
-            // report error for for M part of M.id or pure M
-            SourceInfo consClassLocation = new SourceInfo(nameLocation.getSource(),
-                nameLocation.getOffset(), consClassName.length());
-            resolutionError(consClassLocation,
-                ResolverErrorCode.CONSTRUCTOR_NAME_NOT_ENCLOSING_CLASS);
-            // in addition also report warning for whole constructor name
-            if (!StringUtils.isEmpty(consUserName)) {
-              resolutionError(nameLocation,
-                  ResolverErrorCode.CONSTRUCTOR_NAME_NOT_ENCLOSING_CLASS_ID);
-            }
-          }
-        }
-        // should not conflict with member names
-        {
-          Element member = classElement.lookupLocalElement(name);
-          if (member != null) {
-            resolutionError(nameLocation,
-                ResolverErrorCode.CONSTRUCTOR_WITH_NAME_OF_MEMBER);
-          }
-        }
-      }
-      // done with this class
-      enclosingElement = previousEnclosingElement;
-      endClassContext();
-      return null;
-    }
-
-    private void checkParameterInitializer(DartMethodDefinition method, DartParameter parameter) {
-      if (Elements.isNonFactoryConstructor(method.getElement())) {
-        if (method.getModifiers().isRedirectedConstructor()) {
-          resolutionError(parameter.getName(),
-              ResolverErrorCode.PARAMETER_INIT_WITH_REDIR_CONSTRUCTOR);
-        }
-
-        FieldElement element =
-          Elements.lookupLocalField((ClassElement) currentHolder, parameter.getParameterName());
-        if (element == null) {
-          resolutionError(parameter, ResolverErrorCode.PARAMETER_NOT_MATCH_FIELD,
-                          parameter.getName());
-        } else if (element.isStatic()) {
-          resolutionError(parameter,
-                          ResolverErrorCode.PARAMETER_INIT_STATIC_FIELD,
-                          parameter.getName());
-        }
-
-        // Field parameters are not visible as parameters, so we do not declare them
-        // in the context. Instead we record the resolved field element.
-        Elements.setParameterInitializerElement(parameter.getElement(), element);
-
-        // The editor expects the referenced elements to be non-null
-        DartPropertyAccess prop = (DartPropertyAccess)parameter.getName();
-        prop.setElement(element);
-        prop.getName().setElement(element);
-
-        // If no type specified, use type of field.
-        if (parameter.getTypeNode() == null && element != null) {
-          Elements.setType(parameter.getElement(), element.getType());
-        }
-      } else {
-        resolutionError(parameter.getName(),
-            ResolverErrorCode.PARAMETER_INIT_OUTSIDE_CONSTRUCTOR);
-      }
-    }
-
-    @Override
-    public Element visitFunctionTypeAlias(DartFunctionTypeAlias node) {
-      isStatic = false;
-      isFactory = false;
-      assert !ElementKind.of(currentHolder).equals(ElementKind.CLASS) : "nested class?";
-      FunctionAliasElement element = node.getElement();
-      currentHolder = element;
-      context = context.extend((ClassElement) currentHolder); // Put type variables in scope.
-      visit(node.getTypeParameters());
-      List<VariableElement> parameters = new ArrayList<VariableElement>();
-      for (DartParameter parameter : node.getParameters()) {
-        parameters.add((VariableElement) parameter.accept(this));
-      }
-      Type returnType = resolveType(node.getReturnTypeNode(), false, false, true,
-          TypeErrorCode.NO_SUCH_TYPE, TypeErrorCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS);
-      ClassElement functionElement = getTypeProvider().getFunctionType().getElement();
-      element.setFunctionType(Types.makeFunctionType(getContext(), functionElement,
-                                                     parameters, returnType));
-      currentHolder = libraryElement;
-      context = topLevelContext;
-      return null;
-    }
-
-    @Override
-    public Element visitMethodDefinition(final DartMethodDefinition method) {
-      isFactory = method.getModifiers().isFactory();
-      isStatic = method.getModifiers().isStatic() || isFactory;
-      MethodNodeElement element = method.getElement();
-      if (element == null) {
-        switch (getMethodKind(method)) {
-          case NONE:
-          case CONSTRUCTOR:
-            element = buildConstructor(method);
-            checkConstructor(element, method);
-            addConstructor((ClassElement) currentHolder, (ConstructorNodeElement) element);
-            break;
-
-          case METHOD:
-            element = Elements.methodFromMethodNode(method, currentHolder);
-            addMethod(currentHolder, element);
-            break;
-        }
-      } else {
-        // This is a top-level element, and an element was already created in
-        // TopLevelElementBuilder.
-        Elements.addMethod(currentHolder, element);
-        assertTopLevel(method);
-      }
-      if (element != null) {
-        checkTopLevelMainFunction(method);
-        checkModifiers(element, method);
-        recordElement(method, element);
-        recordElement(method.getName(), element);
-        ResolutionContext previous = context;
-        context = context.extend(element.getName());
-        EnclosingElement previousEnclosingElement = enclosingElement;
-        enclosingElement = element;
-        resolveFunction(method.getFunction(), element);
-        enclosingElement = previousEnclosingElement;
-        context = previous;
-      }
-      return null;
-    }
-
-    @Override
-    protected void resolveFunctionWithParameters(DartFunction node, MethodElement element) {
-      super.resolveFunctionWithParameters(node, element);
-      // Bind "formal initializers" to fields.
-      if (node.getParent() instanceof DartMethodDefinition) {
-        DartMethodDefinition method = (DartMethodDefinition) node.getParent();
-        for (DartParameter parameter : node.getParameters()) {
-          if (parameter.getQualifier() instanceof DartThisExpression) {
-            checkParameterInitializer(method, parameter);
-          }
-        }
-      }
-    }
-
-    @Override
-    public Element visitFieldDefinition(DartFieldDefinition node) {
-      isStatic = false;
-      isFactory = false;
-      for (DartField fieldNode : node.getFields()) {
-        if (fieldNode.getModifiers().isStatic()) {
-          isStatic = true;
-        }
-      }
-      Type type = resolveType(node.getTypeNode(), isStatic, false, true, TypeErrorCode.NO_SUCH_TYPE,
-          TypeErrorCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS);
-      for (DartField fieldNode : node.getFields()) {
-        if (fieldNode.getModifiers().isAbstractField()) {
-          buildAbstractField(fieldNode);
-        } else {
-          buildField(fieldNode, type);
-        }
-      }
-      return null;
-    }
-
-    private void beginClassContext(final DartClass node) {
-      assert !ElementKind.of(currentHolder).equals(ElementKind.CLASS) : "nested class?";
-      currentHolder = node.getElement();
-      context = context.extend((ClassElement) currentHolder);
-    }
-
-    private void endClassContext() {
-      currentHolder = libraryElement;
-      context = topLevelContext;
-    }
-
-    private Element resolveConstructorName(final DartMethodDefinition method) {
-      return method.getName().accept(new ASTVisitor<Element>() {
-        @Override
-        public Element visitPropertyAccess(DartPropertyAccess node) {
-          Element element = context.resolveName(node);
-          if (ElementKind.of(element) == ElementKind.CLASS) {
-            return resolveType(node);
-          } else {
-            element = node.getQualifier().accept(this);
-            recordElement(node.getQualifier(), element);
-          }
-          if (ElementKind.of(element) == ElementKind.CLASS) {
-            return Elements.constructorFromMethodNode(
-                method, node.getPropertyName(), (ClassElement) currentHolder, (ClassElement) element);
-          } else {
-            // Nothing else is valid. Already warned in getMethodKind().
-            return getTypeProvider().getDynamicType().getElement();
-          }
-        }
-        @Override
-        public Element visitIdentifier(DartIdentifier node) {
-          return resolveType(node);
-        }
-        private Element resolveType(DartNode node) {
-          return context.resolveType(
-              node,
-              node,
-              null,
-              true,
-              false,
-              false,
-              ResolverErrorCode.NO_SUCH_TYPE_CONSTRUCTOR,
-              ResolverErrorCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS).getElement();
-        }
-        @Override
-        public Element visitParameterizedTypeNode(DartParameterizedTypeNode node) {
-          Element element = node.getExpression().accept(this);
-          if (ElementKind.of(element).equals(ElementKind.CONSTRUCTOR)) {
-            recordElement(node.getExpression(), currentHolder);
-          } else {
-            recordElement(node.getExpression(), element);
-          }
-          return element;
-        }
-        @Override
-        public Element visitNode(DartNode node) {
-          throw new RuntimeException("Unexpected node " + node);
-        }
-      });
-    }
-
-    private MethodNodeElement buildConstructor(final DartMethodDefinition method) {
-      // Resolve the constructor's name and class name.
-      Element e = resolveConstructorName(method);
-
-      switch (ElementKind.of(e)) {
-        default:
-          // Report an error and create a fake constructor element below.
-          resolutionError(method.getName(), ResolverErrorCode.INVALID_TYPE_NAME_IN_CONSTRUCTOR);
-          break;
-
-        case DYNAMIC:
-        case CLASS:
-          break;
-
-        case CONSTRUCTOR:
-          return (ConstructorNodeElement) e;
-      }
-
-      // If the constructor name resolves to a class or there was an error,
-      // create the unnamed constructor.
-      return Elements.constructorFromMethodNode(method, "", (ClassElement) currentHolder,
-                                                (ClassElement) e);
-    }
-
-    private FieldElement buildField(DartField fieldNode, Type type) {
-      assert !fieldNode.getModifiers().isAbstractField();
-      Modifiers modifiers = fieldNode.getModifiers();
-      // top-level fields are implicitly static.
-      if (context == topLevelContext) {
-        modifiers = modifiers.makeStatic();
-      }
-      if (fieldNode.getValue() != null) {
-        modifiers = modifiers.makeInitialized();
-      }
-      FieldNodeElement fieldElement = fieldNode.getElement();
-      if (fieldElement == null) {
-        fieldElement = Elements.fieldFromNode(fieldNode, currentHolder, fieldNode.getObsoleteMetadata(),
-            modifiers);
-        addField(currentHolder, fieldElement);
-      } else {
-        // This is a top-level element, and an element was already created in
-        // TopLevelElementBuilder.
-        Elements.addField(currentHolder, fieldElement);
-        assertTopLevel(fieldNode);
-      }
-      fieldElement.setType(type);
-      recordElement(fieldNode.getName(), fieldElement);
-      return recordElement(fieldNode, fieldElement);
-    }
-
-    private void assertTopLevel(DartNode node) throws AssertionError {
-      if (!currentHolder.getKind().equals(ElementKind.LIBRARY)) {
-        throw topLevelContext.internalError(node, "expected top-level node");
-      }
-    }
-
-    /**
-     * Creates FieldElement for AST getters and setters.
-     *
-     * class A {
-     *   int get foo() { ... }
-     *   set foo(x) { ... }
-     * }
-     *
-     * The AST will have the shape (simplified):
-     * DartClass
-     *   members
-     *     DartFieldDefinition
-     *       DartField
-     *       + name: foo
-     *       + modifiers: abstractfield
-     *       + accessor: int get foo() { ... }
-     *     DartFieldDefinition
-     *       DartField
-     *       + name: foo
-     *       + modifiers: abstractfield
-     *       + accessor: set foo(x) { ... }
-     *
-     * MemberBuilder will reduce to one class element as below (simplified):
-     * ClassElement
-     *   members:
-     *     FieldElement
-     *     + name: foo
-     *     + getter:
-     *       MethodElement
-     *       + name: foo
-     *       + function: int get foo() { ... }
-     *     + setter:
-     *       MethodElement
-     *       + name: foo
-     *       + function: set foo(x) { ... }
-     *
-     */
-    private FieldElement buildAbstractField(DartField fieldNode) {
-      assert fieldNode.getModifiers().isAbstractField();
-      boolean topLevelDefinition = fieldNode.getParent().getParent() instanceof DartUnit;
-      DartMethodDefinition accessorNode = fieldNode.getAccessor();
-      MethodNodeElement accessorElement = Elements.methodFromMethodNode(accessorNode, currentHolder);
-      EnclosingElement previousEnclosingElement = enclosingElement;
-      enclosingElement = accessorElement;
-      recordElement(accessorNode, accessorElement);
-      resolveFunction(accessorNode.getFunction(), accessorElement);
-      enclosingElement = previousEnclosingElement;
-
-      String name = fieldNode.getName().getName();
-      Element element = null;
-      if (currentHolder != null) {
-          element = currentHolder.lookupLocalElement(name);
-          if (element == null) {
-            element = currentHolder.lookupLocalElement("setter " + name);
-          }
-      } else {
-        // Top level nodes are not handled gracefully
-        Scope scope = topLevelContext.getScope();
-        LibraryElement library = context.getScope().getLibrary();
-        element = scope.findElement(library, name);
-        if (element == null) {
-          element = scope.findElement(library, "setter " + name);
-        }
-      }
-
-      FieldElementImplementation fieldElement = null;
-      if (element == null || element.getKind().equals(ElementKind.FIELD)
-          && element.getModifiers().isAbstractField()) {
-        fieldElement = (FieldElementImplementation) element;
-      }
-
-      if (accessorNode.getModifiers().isGetter() && fieldElement != null && fieldElement.getSetter() != null) {
-        MethodNodeElement oldSetter = fieldElement.getSetter();
-        fieldElement = Elements.fieldFromNode(fieldNode, currentHolder, fieldNode.getObsoleteMetadata(),
-            fieldNode.getModifiers());
-        fieldElement.setSetter(oldSetter);
-        addField(currentHolder, fieldElement);
-      }
-
-      if (fieldElement == null) {
-        fieldElement = Elements.fieldFromNode(fieldNode, currentHolder, fieldNode.getObsoleteMetadata(),
-            fieldNode.getModifiers());
-        addField(currentHolder, fieldElement);
-      }
-
-      if (accessorNode.getModifiers().isGetter()) {
-        if (fieldElement.getGetter() != null) {
-          if (!topLevelDefinition) {
-            reportDuplicateDeclaration(ResolverErrorCode.DUPLICATE_MEMBER, fieldElement.getGetter());
-            reportDuplicateDeclaration(ResolverErrorCode.DUPLICATE_MEMBER, accessorElement);
-          }
-        } else {
-          fieldElement.setGetter(accessorElement);
-          fieldElement.setType(accessorElement.getReturnType());
-        }
-      } else if (accessorNode.getModifiers().isSetter()) {
-        if (fieldElement.getSetter() != null) {
-          if (!topLevelDefinition) {
-            reportDuplicateDeclaration(ResolverErrorCode.DUPLICATE_MEMBER, fieldElement.getSetter());
-            reportDuplicateDeclaration(ResolverErrorCode.DUPLICATE_MEMBER, accessorElement);
-          }
-        } else {
-          fieldElement.setSetter(accessorElement);
-          List<VariableElement> parameters = accessorElement.getParameters();
-          Type type;
-          if (parameters.size() == 0) {
-            // Error flagged in parser
-            type = getTypeProvider().getDynamicType();
-          } else {
-            type = parameters.get(0).getType();
-          }
-          fieldElement.setType(type);
-        }
-      }
-      recordElement(fieldNode.getName(), accessorElement);
-      return recordElement(fieldNode, fieldElement);
-    }
-
-    private void addField(EnclosingElement holder, FieldNodeElement element) {
-      if (holder != null) {
-        checkUniqueName(holder, element);
-        checkMemberNameNotSameAsEnclosingClassName(holder, element);
-        Elements.addField(holder, element);
-      }
-    }
-
-    private void addMethod(EnclosingElement holder, MethodNodeElement element) {
-      checkUniqueName(holder, element);
-      checkMemberNameNotSameAsEnclosingClassName(holder, element);
-      Elements.addMethod(holder, element);
-    }
-
-    private void addConstructor(ClassElement cls, ConstructorNodeElement element) {
-      checkUniqueName(cls, element);
-      Elements.addConstructor(cls, element);
-    }
-
-    private ElementKind getMethodKind(DartMethodDefinition method) {
-      if (!ElementKind.of(currentHolder).equals(ElementKind.CLASS)) {
-        return ElementKind.METHOD;
-      }
-
-      if (method.getModifiers().isFactory()) {
-        return ElementKind.CONSTRUCTOR;
-      }
-
-      DartExpression name = method.getName();
-      if (name instanceof DartIdentifier) {
-        if (((DartIdentifier) name).getName().equals(currentHolder.getName())) {
-          return ElementKind.CONSTRUCTOR;
-        } else {
-          return ElementKind.METHOD;
-        }
-      } else {
-        DartPropertyAccess property = (DartPropertyAccess) name;
-        if (property.getQualifier() instanceof DartIdentifier) {
-          DartIdentifier qualifier = (DartIdentifier) property.getQualifier();
-          if (qualifier.getName().equals(currentHolder.getName())) {
-            return ElementKind.CONSTRUCTOR;
-          }
-          resolutionError(method.getName(),
-                          ResolverErrorCode.CANNOT_DECLARE_NON_FACTORY_CONSTRUCTOR);
-        } else if (property.getQualifier() instanceof DartParameterizedTypeNode) {
-          DartParameterizedTypeNode paramNode = (DartParameterizedTypeNode)property.getQualifier();
-          if (paramNode.getExpression() instanceof DartIdentifier) {
-            return ElementKind.CONSTRUCTOR;
-          }
-          resolutionError(method.getName(),
-                          ResolverErrorCode.TOO_MANY_QUALIFIERS_FOR_METHOD);
-        } else {
-          // Multiple qualifiers (Foo.bar.baz)
-          resolutionError(method.getName(),
-                          ResolverErrorCode.TOO_MANY_QUALIFIERS_FOR_METHOD);
-        }
-      }
-
-      return ElementKind.NONE;
-    }
-
-    /**
-     * Checks that top-level "main()" has no parameters.
-     */
-    private void checkTopLevelMainFunction(DartMethodDefinition method) {
-      if (!method.getFunction().getParameters().isEmpty()
-          && currentHolder instanceof LibraryElement
-          && Objects.equal(method.getName().toString(), "main")) {
-        resolutionError(method.getName(), ResolverErrorCode.MAIN_FUNCTION_PARAMETERS);
-      }
-    }
-
-    private void checkModifiers(MethodElement element, DartMethodDefinition method) {
-      Modifiers modifiers = method.getModifiers();
-      boolean isNonFactoryConstructor = Elements.isNonFactoryConstructor(element);
-      // TODO(ngeoffray): The errors should report the position of the modifier.
-      if (isNonFactoryConstructor) {
-        if (modifiers.isStatic()) {
-          resolutionError(method.getName(), ResolverErrorCode.CONSTRUCTOR_CANNOT_BE_STATIC);
-        }
-        if (modifiers.isAbstract()) {
-          resolutionError(method.getName(), ResolverErrorCode.CONSTRUCTOR_CANNOT_BE_ABSTRACT);
-        }
-        if (modifiers.isConstant()) {
-          // Allow const ... native ... ; type of constructors.  Used in core libraries.
-          DartBlock dartBlock = method.getFunction().getBody();
-          if (dartBlock != null && !(dartBlock instanceof DartNativeBlock)) {
-            resolutionError(method.getName(),
-                            ResolverErrorCode.CONST_CONSTRUCTOR_CANNOT_HAVE_BODY);
-          }
-        }
-      }
-
-      if (modifiers.isFactory()) {
-        if (modifiers.isConstant()) {
-          // Allow const factory ... native ... ; type of constructors, used in core libraries.
-          // Allow const factory redirecting.
-          DartBlock dartBlock = method.getFunction().getBody();
-          if (!(dartBlock instanceof DartNativeBlock || method.getRedirectedTypeName() != null)) {
-            resolutionError(method.getName(), ResolverErrorCode.FACTORY_CANNOT_BE_CONST);
-          }
-        }
-      }
-      // TODO(ngeoffray): Add more checks on the modifiers. For
-      // example const and missing body.
-    }
-
-    private void checkConstructor(MethodElement element, DartMethodDefinition method) {
-      if (Elements.isNonFactoryConstructor(element) && method.getFunction() != null
-          && method.getFunction().getReturnTypeNode() != null) {
-        resolutionError(method.getFunction().getReturnTypeNode(),
-            ResolverErrorCode.CONSTRUCTOR_CANNOT_HAVE_RETURN_TYPE);
-      }
-    }
-
-    private void checkMemberNameNotSameAsEnclosingClassName(EnclosingElement holder, Element e) {
-      if (ElementKind.of(holder) == ElementKind.CLASS) {
-        if (Objects.equal(holder.getName(), e.getName())) {
-          resolutionError(e.getNameLocation(), ResolverErrorCode.MEMBER_WITH_NAME_OF_CLASS);
-        }
-      }
-    }
-      
-    private void checkUniqueName(EnclosingElement holder, Element e) {
-      if (ElementKind.of(holder) == ElementKind.LIBRARY) {
-        return;
-      }
-      Element other = lookupElementByName(holder, e.getName(), e.getModifiers());
-      assert e != other : "forgot to call checkUniqueName() before adding to the class?";
-      
-      if (other == null && e instanceof FieldElement) {
-        FieldElement eField = (FieldElement) e;
-        if (!eField.getModifiers().isAbstractField()) {
-          other = lookupElementByName(holder, "setter " + e.getName(), e.getModifiers());
-        }
-        if (eField.getModifiers().isAbstractField()
-            && StringUtils.startsWith(e.getName(), "setter ")) {
-          Element other2 = lookupElementByName(holder,
-              StringUtils.removeStart(e.getName(), "setter "), e.getModifiers());
-          if (other2 instanceof FieldElement) {
-            FieldElement otherField = (FieldElement) other2;
-            if (!otherField.getModifiers().isAbstractField()) {
-              other = otherField;
-            }
-          }
-        }
-      }
-      
-      if (other != null) {
-        ElementKind eKind = ElementKind.of(e);
-        ElementKind oKind = ElementKind.of(other);
-
-        // Constructors have a separate namespace.
-        boolean oIsConstructor = oKind.equals(ElementKind.CONSTRUCTOR);
-        boolean eIsConstructor = eKind.equals(ElementKind.CONSTRUCTOR);
-        if (oIsConstructor != eIsConstructor) {
-          return;
-        }
-
-        // Both can be constructors, as long as they're for different classes.
-        if (oIsConstructor && eIsConstructor) {
-          if (((ConstructorElement) e).getConstructorType() !=
-              ((ConstructorElement) other).getConstructorType()) {
-            return;
-          }
-        }
-
-        boolean eIsOperator = e.getModifiers().isOperator();
-        boolean oIsOperator = other.getModifiers().isOperator();
-        if (oIsOperator != eIsOperator) {
-          return;
-        }
-
-        // Operators and methods can share the same name.
-        boolean oIsMethod = oKind.equals(ElementKind.METHOD);
-        boolean eIsMethod = eKind.equals(ElementKind.METHOD);
-        if ((oIsOperator && eIsMethod) || (oIsMethod && eIsOperator)) {
-          return;
-        }
-
-        // Report initial declaration and current declaration.
-        reportDuplicateDeclaration(ResolverErrorCode.DUPLICATE_MEMBER, other);
-        reportDuplicateDeclaration(ResolverErrorCode.DUPLICATE_MEMBER, e);
-      }
-    }
-
-    private Element lookupElementByName(EnclosingElement holder, String name, Modifiers modifiers) {
-      Element element = holder.lookupLocalElement(name);
-      if (element == null && ElementKind.of(holder).equals(ElementKind.CLASS)) {
-        ClassElement cls = (ClassElement) holder;
-        String ctorName = name.equals(holder.getName()) ? "" : name;
-        for (Element e : cls.getConstructors()) {
-          if (e.getName().equals(ctorName)) {
-            return e;
-          }
-        }
-      }
-      return element;
-    }
-
-    void resolutionError(HasSourceInfo node, ErrorCode errorCode, Object... arguments) {
-      resolutionError(node.getSourceInfo(), errorCode, arguments);
-    }
-
-    void resolutionError(SourceInfo sourceInfo, ErrorCode errorCode, Object... arguments) {
-      topLevelContext.onError(sourceInfo, errorCode, arguments);
-    }
-
-    /**
-     * Reports duplicate declaration for given named element.
-     */
-    private void reportDuplicateDeclaration(ErrorCode errorCode, Element element) {
-      String name =
-          element instanceof MethodElement
-              ? Elements.getRawMethodName((MethodElement) element)
-              : element.getName();
-      resolutionError(element.getNameLocation(), errorCode, name);
-    }
-  }
-}
diff --git a/compiler/java/com/google/dart/compiler/resolver/MethodElement.java b/compiler/java/com/google/dart/compiler/resolver/MethodElement.java
deleted file mode 100644
index 43e88ce..0000000
--- a/compiler/java/com/google/dart/compiler/resolver/MethodElement.java
+++ /dev/null
@@ -1,30 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.resolver;
-
-import com.google.dart.compiler.type.FunctionType;
-import com.google.dart.compiler.type.Type;
-
-import java.util.List;
-import java.util.Set;
-
-public interface MethodElement extends Element, EnclosingElement {
-  boolean isConstructor();
-
-  boolean isStatic();
-  
-  boolean hasBody();
-
-  List<VariableElement> getParameters();
-
-  Type getReturnType();
-
-  FunctionType getFunctionType();
-
-  /**
-   * @return {@link Element}s overridden by this {@link MethodElement}.
-   */
-  Set<Element> getOverridden();
-}
diff --git a/compiler/java/com/google/dart/compiler/resolver/MethodElementImplementation.java b/compiler/java/com/google/dart/compiler/resolver/MethodElementImplementation.java
deleted file mode 100644
index 74ca609..0000000
--- a/compiler/java/com/google/dart/compiler/resolver/MethodElementImplementation.java
+++ /dev/null
@@ -1,200 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.resolver;
-
-import com.google.common.annotations.VisibleForTesting;
-import com.google.common.collect.ImmutableSet;
-import com.google.dart.compiler.ast.DartBlock;
-import com.google.dart.compiler.ast.DartClass;
-import com.google.dart.compiler.ast.DartFunctionExpression;
-import com.google.dart.compiler.ast.DartIdentifier;
-import com.google.dart.compiler.ast.DartMethodDefinition;
-import com.google.dart.compiler.ast.DartNativeBlock;
-import com.google.dart.compiler.ast.DartNode;
-import com.google.dart.compiler.ast.DartObsoleteMetadata;
-import com.google.dart.compiler.ast.Modifiers;
-import com.google.dart.compiler.common.SourceInfo;
-import com.google.dart.compiler.type.FunctionType;
-import com.google.dart.compiler.type.Type;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.Set;
-
-class MethodElementImplementation extends AbstractNodeElement implements MethodNodeElement {
-  private final DartObsoleteMetadata metadata;
-  private final Modifiers modifiers;
-  private final EnclosingElement holder;
-  private final ElementKind kind;
-  private final List<VariableElement> parameters = new ArrayList<VariableElement>();
-  private FunctionType type;
-  private final SourceInfo nameLocation;
-  private final boolean hasBody;
-  private Set<Element> overridden = ImmutableSet.of();
-
-  // TODO(ngeoffray): name, return type, argument types.
-  @VisibleForTesting
-  MethodElementImplementation(DartFunctionExpression node, String name, Modifiers modifiers) {
-    super(node, name);
-    this.metadata = DartObsoleteMetadata.EMPTY;
-    this.modifiers = modifiers;
-    this.hasBody = true;
-    this.holder = findParentEnclosingElement(node);
-    this.kind = ElementKind.FUNCTION_OBJECT;
-    if (node != null && node.getName() != null) {
-      this.nameLocation = node.getName().getSourceInfo();
-    } else {
-      this.nameLocation = SourceInfo.UNKNOWN;
-    }
-  }
-
-  protected MethodElementImplementation(DartMethodDefinition node, String name,
-                                        EnclosingElement holder) {
-    super(node, name);
-    if (node != null) {
-      this.metadata = node.getObsoleteMetadata();
-      this.modifiers = node.getModifiers();
-      this.nameLocation = node.getName().getSourceInfo();
-      DartBlock body = node.getFunction().getBody();
-      this.hasBody = body != null && !(body instanceof DartNativeBlock);
-    } else {
-      this.metadata = DartObsoleteMetadata.EMPTY;
-      this.modifiers = Modifiers.NONE;
-      this.nameLocation = SourceInfo.UNKNOWN;
-      this.hasBody = false;
-    }
-    this.holder = holder;
-    this.kind = ElementKind.METHOD;
-  }
-
-  @Override
-  public DartObsoleteMetadata getMetadata() {
-    return metadata;
-  }
-
-  @Override
-  public Modifiers getModifiers() {
-    return modifiers;
-  }
-
-  @Override
-  public ElementKind getKind() {
-    return kind;
-  }
-
-  @Override
-  public EnclosingElement getEnclosingElement() {
-    return holder;
-  }
-
-  @Override
-  public boolean isConstructor() {
-    return false;
-  }
-
-  @Override
-  public boolean isStatic() {
-    return getModifiers().isStatic();
-  }
-
-  @Override
-  public List<VariableElement> getParameters() {
-    return parameters;
-  }
-  
-  @Override
-  public boolean hasBody() {
-    return hasBody;
-  }
-
-  void addParameter(VariableElement parameter) {
-    parameters.add(parameter);
-  }
-
-  @Override
-  public Type getReturnType() {
-    return getType().getReturnType();
-  }
-
-  @Override
-  void setType(Type type) {
-    this.type = (FunctionType) type;
-  }
-
-  @Override
-  public FunctionType getType() {
-    return type;
-  }
-
-  @Override
-  public FunctionType getFunctionType() {
-    return getType();
-  }
-
-  @Override
-  public boolean isInterface() {
-    return false;
-  }
-
-  @Override
-  public Iterable<Element> getMembers() {
-    return Collections.emptyList();
-  }
-
-  @Override
-  public Element lookupLocalElement(String name) {
-    return null;
-  }
-
-  public static MethodElementImplementation fromMethodNode(DartMethodDefinition node,
-                                                           EnclosingElement holder) {
-    String targetName;
-    if(node.getName() instanceof DartIdentifier) {
-      targetName = ((DartIdentifier) node.getName()).getName();
-      if (targetName.equals("-") && node.getFunction().getParameters().size() == 1) {
-        targetName += "binary";
-      }
-    } else {
-      // Visit the unknown node to generate a string for our use.
-      targetName = node.toSource();
-    }
-    return new MethodElementImplementation(node, targetName, holder);
-  }
-
-  public static MethodElementImplementation fromFunctionExpression(DartFunctionExpression node,
-                                                                   Modifiers modifiers) {
-    return new MethodElementImplementation(node, node.getFunctionName(), modifiers);
-  }
-
-  /**
-   * @return the innermost {@link EnclosingElement} for given {@link DartNode}, may be
-   *         <code>null</code>.
-   */
-  private static EnclosingElement findParentEnclosingElement(DartNode node) {
-    while (node != null && node.getParent() != null) {
-      node = node.getParent();
-      boolean isEnclosingNode = node instanceof DartClass || node instanceof DartMethodDefinition
-          || node instanceof DartFunctionExpression;
-      if (isEnclosingNode && node.getElement() instanceof EnclosingElement) {
-        return (EnclosingElement) node.getElement();
-      }
-    }
-    return null;
-  }
-  
-  @Override
-  public SourceInfo getNameLocation() {
-    return nameLocation;
-  }
-
-  public void setOverridden(Set<Element> overridden) {
-    this.overridden = overridden;
-  }
-  
-  public Set<Element> getOverridden() {
-    return overridden;
-  }
-}
diff --git a/compiler/java/com/google/dart/compiler/resolver/MethodNodeElement.java b/compiler/java/com/google/dart/compiler/resolver/MethodNodeElement.java
deleted file mode 100644
index 46db965..0000000
--- a/compiler/java/com/google/dart/compiler/resolver/MethodNodeElement.java
+++ /dev/null
@@ -1,12 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-package com.google.dart.compiler.resolver;
-
-import com.google.dart.compiler.ast.DartNode;
-
-/**
- * Extension of {@link MethodElement} which is based on {@link DartNode}.
- */
-public interface MethodNodeElement extends MethodElement, NodeElement {
-}
diff --git a/compiler/java/com/google/dart/compiler/resolver/MixinScope.java b/compiler/java/com/google/dart/compiler/resolver/MixinScope.java
deleted file mode 100644
index e40ff71..0000000
--- a/compiler/java/com/google/dart/compiler/resolver/MixinScope.java
+++ /dev/null
@@ -1,27 +0,0 @@
-// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.resolver;
-
-/**
- * Lexical scope corresponding to a mixin.
- */
-class MixinScope extends Scope {
-  private final ClassElement mixinElement;
-
-  MixinScope(ClassElement mixinElement) {
-    super(mixinElement.getName(), mixinElement.getLibrary(), null);
-    this.mixinElement = mixinElement;
-  }
-
-  @Override
-  public Element declareElement(String name, Element element) {
-    throw new AssertionError("not supported yet");
-  }
-
-  @Override
-  public Element findLocalElement(String name) {
-    return Elements.findElement(mixinElement, name);
-  }
-}
diff --git a/compiler/java/com/google/dart/compiler/resolver/NodeElement.java b/compiler/java/com/google/dart/compiler/resolver/NodeElement.java
deleted file mode 100644
index 215efb2..0000000
--- a/compiler/java/com/google/dart/compiler/resolver/NodeElement.java
+++ /dev/null
@@ -1,13 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-package com.google.dart.compiler.resolver;
-
-import com.google.dart.compiler.ast.DartNode;
-
-/**
- * {@link Element} which has {@link DartNode}.
- */
-public interface NodeElement extends Element {
-  DartNode getNode();
-}
diff --git a/compiler/java/com/google/dart/compiler/resolver/ResolutionContext.java b/compiler/java/com/google/dart/compiler/resolver/ResolutionContext.java
deleted file mode 100644
index c1522c3..0000000
--- a/compiler/java/com/google/dart/compiler/resolver/ResolutionContext.java
+++ /dev/null
@@ -1,408 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.resolver;
-import com.google.common.annotations.VisibleForTesting;
-import com.google.dart.compiler.DartCompilationError;
-import com.google.dart.compiler.DartCompilerContext;
-import com.google.dart.compiler.ErrorCode;
-import com.google.dart.compiler.ErrorSeverity;
-import com.google.dart.compiler.PackageLibraryManager;
-import com.google.dart.compiler.Source;
-import com.google.dart.compiler.SubSystem;
-import com.google.dart.compiler.ast.ASTVisitor;
-import com.google.dart.compiler.ast.DartClassTypeAlias;
-import com.google.dart.compiler.ast.DartFunctionExpression;
-import com.google.dart.compiler.ast.DartFunctionTypeAlias;
-import com.google.dart.compiler.ast.DartIdentifier;
-import com.google.dart.compiler.ast.DartNode;
-import com.google.dart.compiler.ast.DartPropertyAccess;
-import com.google.dart.compiler.ast.DartSyntheticErrorIdentifier;
-import com.google.dart.compiler.ast.DartTypeNode;
-import com.google.dart.compiler.ast.LibraryUnit;
-import com.google.dart.compiler.ast.Modifiers;
-import com.google.dart.compiler.common.HasSourceInfo;
-import com.google.dart.compiler.common.SourceInfo;
-import com.google.dart.compiler.parser.DartParser;
-import com.google.dart.compiler.type.InterfaceType;
-import com.google.dart.compiler.type.Type;
-import com.google.dart.compiler.type.TypeKind;
-import com.google.dart.compiler.type.TypeVariable;
-import com.google.dart.compiler.type.Types;
-
-import java.util.Arrays;
-import java.util.List;
-
-
-/**
- * Resolution context for resolution of Dart programs. The initial context is
- * derived from the library scope, which is then extended with class scope,
- * method scope, and block scope as the program is traversed.
- */
-@VisibleForTesting
-public class ResolutionContext implements ResolutionErrorListener {
-  private Scope scope;
-  private final DartCompilerContext context;
-  private final CoreTypeProvider typeProvider;
-  private final boolean suppressSdkWarnings;
-
-  ResolutionContext(String name, LibraryElement library, DartCompilerContext context,
-                    CoreTypeProvider typeProvider) {
-    this(new Scope(name, library), context, typeProvider);
-  }
-
-  @VisibleForTesting
-  public ResolutionContext(Scope scope, DartCompilerContext context,
-                           CoreTypeProvider typeProvider) {
-    this.scope = scope;
-    this.context = context;
-    this.typeProvider = typeProvider;
-    this.suppressSdkWarnings = context.getCompilerConfiguration().getCompilerOptions()
-        .suppressSdkWarnings();
-  }
-
-  ResolutionContext(LibraryUnit unit, DartCompilerContext context, CoreTypeProvider typeProvider) {
-    this(unit.getElement().getScope(), context, typeProvider);
-  }
-
-  @VisibleForTesting
-  public ResolutionContext extend(ClassElement element) {
-    return new ResolutionContext(new ClassScope(element, scope), context, typeProvider);
-  }
-
-  ResolutionContext extend(String name) {
-    return new ResolutionContext(new Scope(name, scope.getLibrary(), scope), context, typeProvider);
-  }
-
-  Scope getScope() {
-    return scope;
-  }
-
-  void declare(Element element, ErrorCode errorCode) {
-    String name = element.getName();
-    Element existingLocalElement = scope.findLocalElement(name);
-    // Check for duplicate declaration in the same scope.
-    if (existingLocalElement != null && errorCode != null) {
-      SourceInfo nameSourceInfo = element.getNameLocation();
-      String existingLocation = Elements.getRelativeElementLocation(element, existingLocalElement);
-      onError(nameSourceInfo, errorCode, name, existingLocation);
-    }
-    // Declare, may be hide existing element.
-    scope.declareElement(name, element);
-  }
-
-  void pushScope(String name) {
-    scope = new Scope(name, scope.getLibrary(), scope);
-  }
-
-  void popScope() {
-    scope = scope.getParent();
-  }
-
-  /**
-   * Returns <code>true</code> if the type is dynamic or an interface type where
-   * {@link ClassElement#isInterface()} equals <code>isInterface</code>.
-   */
-  private boolean isInterfaceEquals(Type type, boolean isInterface) {
-    switch (type.getKind()) {
-      case DYNAMIC:
-        // Considered to be a match.
-        return true;
-
-      case INTERFACE:
-        InterfaceType interfaceType = (InterfaceType) type;
-        ClassElement element = interfaceType.getElement();
-        return (element != null && element.isInterface() == isInterface);
-
-      default:
-        break;
-    }
-
-    return false;
-  }
-
-  /**
-   * Returns <code>true</code> if the type is dynamic or is a class type.
-   */
-  private boolean isClassType(Type type) {
-    return isInterfaceEquals(type, false);
-  }
-
-  /**
-   * Returns <code>true</code> if the type is a class or interface type.
-   */
-  private boolean isClassOrInterfaceType(Type type) {
-    return type.getKind() == TypeKind.INTERFACE
-        && ((InterfaceType) type).getElement() != null;
-  }
-
-  /**
-   * To resolve the  class<typeparameters?> specified for extends on a class definition.
-   */
-  InterfaceType resolveClass(DartTypeNode node, boolean isStatic, boolean isFactory) {
-    if (node == null) {
-      return null;
-    }
-
-    Type type = resolveType(node, isStatic, isFactory, false, ResolverErrorCode.NO_SUCH_TYPE,
-        ResolverErrorCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS);
-    if (!isClassType(type)) {
-      onError(node.getIdentifier(), ResolverErrorCode.NOT_A_CLASS, type);
-      type = typeProvider.getDynamicType();
-    }
-
-    node.setType(type);
-    return (InterfaceType) type;
-  }
-
-  InterfaceType resolveInterface(DartTypeNode node, boolean isStatic, boolean isFactory) {
-    Type type = resolveType(node, isStatic, isFactory, false,
-        ResolverErrorCode.NO_SUCH_TYPE, ResolverErrorCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS);
-    if (type.getKind() != TypeKind.DYNAMIC && !isClassOrInterfaceType(type)) {
-      onError(node.getIdentifier(), ResolverErrorCode.NOT_A_CLASS_OR_INTERFACE, type);
-      type = typeProvider.getDynamicType();
-    }
-
-    node.setType(type);
-    return (InterfaceType) type;
-  }
-
-  Type resolveType(DartTypeNode node, boolean isStatic, boolean isFactory, boolean isAnnotation,
-      ErrorCode errorCode, ErrorCode wrongNumberErrorCode) {
-    if (node == null) {
-      return null;
-    } else {
-      Type type = resolveType(node, node.getIdentifier(), node.getTypeArguments(), isStatic,
-          isFactory, isAnnotation, errorCode, wrongNumberErrorCode);
-      recordTypeIdentifier(node.getIdentifier(), type.getElement());
-      return type;
-    }
-  }
-
-  protected <E extends Element> E recordTypeIdentifier(DartNode node, E element) {
-    node.getClass();
-    if (node instanceof DartPropertyAccess) {
-      recordTypeIdentifier(((DartPropertyAccess)node).getQualifier(),
-                           element.getEnclosingElement());
-      return recordTypeIdentifier(((DartPropertyAccess)node).getName(), element);
-    } else if (node instanceof DartIdentifier) {
-      if (element == null) {
-        // TypeAnalyzer will diagnose unresolved identifiers.
-        return null;
-      }
-      node.setElement(element);
-    } else {
-      throw internalError(node, "Unexpected node: %s", node);
-    }
-    return element;
-  }
-
-  Type resolveType(DartNode diagnosticNode, DartNode identifier, List<DartTypeNode> typeArguments,
-                   boolean isStatic, boolean isFactory, boolean isAnnotation, ErrorCode errorCode,
-                   ErrorCode wrongNumberErrorCode) {
-    // Built-in identifier can not be used as a type annotation.
-    if (identifier instanceof DartIdentifier) {
-      String name = ((DartIdentifier) identifier).getName();
-      if (DartParser.PSEUDO_KEYWORDS_SET.contains(name) && !"dynamic".equals(name)
-          && typeArguments.isEmpty()) {
-        onError(identifier, ResolverErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE, name);
-        return Types.newDynamicType();
-      }
-    }
-    // OK, valid name for type.
-    Element element = resolveName(identifier);
-    ElementKind elementKind = ElementKind.of(element);
-    switch (elementKind) {
-      case TYPE_VARIABLE: {
-        TypeVariableElement typeVariableElement = (TypeVariableElement) element;
-        if (!isFactory && isStatic &&
-          typeVariableElement.getDeclaringElement().getKind().equals(ElementKind.CLASS)) {
-          onError(identifier, ResolverErrorCode.TYPE_VARIABLE_IN_STATIC_CONTEXT, identifier);
-          return typeProvider.getDynamicType();
-        }
-        return makeTypeVariable(typeVariableElement, typeArguments);
-      }
-      case CLASS:
-      case FUNCTION_TYPE_ALIAS:
-      case DYNAMIC:
-        return instantiateParameterizedType(
-            (ClassElement) element,
-            diagnosticNode,
-            typeArguments,
-            isStatic,
-            isFactory,
-            errorCode,
-            wrongNumberErrorCode);
-      case DUPLICATE: {
-        DuplicateElement duplicateElement = (DuplicateElement) element;
-        List<String> locations = duplicateElement.getLocations();
-        ResolverErrorCode duplicateErrorCode;
-        if (isAnnotation) {
-          duplicateErrorCode = ResolverErrorCode.DUPLICATE_IMPORTED_NAME_TYPE;
-        } else {
-          duplicateErrorCode = ResolverErrorCode.DUPLICATE_IMPORTED_NAME;
-        }
-        onError(identifier, duplicateErrorCode, element.getName(), locations.size(), locations);
-        return typeProvider.getDynamicType();
-      }
-      case VOID:
-        return typeProvider.getVoidType();
-      case NONE:
-        onError(identifier, errorCode, identifier);
-        return typeProvider.getDynamicType();
-      default:
-        if (!(identifier instanceof DartSyntheticErrorIdentifier)) {
-          if (errorCode.getSubSystem().equals(SubSystem.RESOLVER)) {
-            onError(identifier, ResolverErrorCode.NOT_A_TYPE, identifier, elementKind);
-          } else {
-            onError(identifier, TypeErrorCode.NOT_A_TYPE, identifier, elementKind);
-          }
-        }
-        return typeProvider.getDynamicType();
-    }
-  }
-
-  InterfaceType instantiateParameterizedType(ClassElement element, DartNode node,
-                                             List<DartTypeNode> typeArgumentNodes,
-                                             boolean isStatic,
-                                             boolean isFactory,
-                                             ErrorCode errorCode,
-                                             ErrorCode wrongNumberErrorCode) {
-    List<Type> typeParameters = element.getTypeParameters();
-    Type[] typeArguments;
-    if (typeArgumentNodes == null || typeArgumentNodes.size() != typeParameters.size()) {
-      typeArguments = new Type[typeParameters.size()];
-      for (int i = 0; i < typeArguments.length; i++) {
-        typeArguments[i] = typeProvider.getDynamicType();
-      }
-      if (typeArgumentNodes != null && typeArgumentNodes.size() > 0) {
-        onError(node, wrongNumberErrorCode, element.getType(), typeArgumentNodes.size(), typeParameters.size());
-      }
-      int index = 0;
-      if (typeArgumentNodes != null) {
-        for (DartTypeNode typeNode : typeArgumentNodes) {
-          Type type = resolveType(typeNode, isStatic, isFactory, false, errorCode,
-              wrongNumberErrorCode);
-          typeNode.setType(type);
-          if (index < typeArguments.length) {
-            typeArguments[index] = type;
-          }
-          index++;
-        }
-      }
-    } else {
-      typeArguments = new Type[typeArgumentNodes.size()];
-      for (int i = 0; i < typeArguments.length; i++) {
-        typeArguments[i] = resolveType(typeArgumentNodes.get(i), isStatic, isFactory, false, errorCode,
-            wrongNumberErrorCode);
-        typeArgumentNodes.get(i).setType(typeArguments[i]);
-      }
-    }
-    return element.getType().subst(Arrays.asList(typeArguments), typeParameters);
-  }
-
-  private TypeVariable makeTypeVariable(TypeVariableElement element,
-                                        List<DartTypeNode> typeArguments) {
-    for (DartTypeNode typeArgument : typeArguments) {
-      onError(typeArgument, ResolverErrorCode.EXTRA_TYPE_ARGUMENT);
-    }
-    return element.getTypeVariable();
-  }
-
-  /*
-   * Interpret this node as a name reference,
-   */
-  Element resolveName(DartNode node) {
-    Element result = node.accept(new Selector());
-    if (result == null) {
-      if (Elements.isIdentifierName(node, "void")) {
-        return typeProvider.getVoidType().getElement();
-      }
-      if (Elements.isIdentifierName(node, "dynamic")) {
-        return typeProvider.getDynamicType().getElement();
-      }
-    }
-    return result;
-  }
-
-  MethodElement declareFunction(DartFunctionExpression node) {
-    MethodElement element = Elements.methodFromFunctionExpression(node, Modifiers.NONE);
-    if (node.getFunctionName() != null) {
-      declare(
-          element,
-          ResolverErrorCode.DUPLICATE_FUNCTION_EXPRESSION);
-    }
-    return element;
-  }
-
-  void pushFunctionScope(DartFunctionExpression x) {
-    pushScope(x.getFunctionName() == null ? "<function>" : x.getFunctionName());
-  }
-
-  void pushFunctionAliasScope(DartFunctionTypeAlias x) {
-    pushScope(x.getName().getName() == null ? "<function>" : x.getName().getName());
-  }
-  
-  void pushClassAliasScope(DartClassTypeAlias x) {
-    pushScope(x.getName().getName() == null ? "<classTypeAlias>" : x.getName().getName());
-  }
-
-  AssertionError internalError(HasSourceInfo node, String message, Object... arguments) {
-    message = String.format(message, arguments);
-    context.onError(new DartCompilationError(node, ResolverErrorCode.INTERNAL_ERROR,
-                                                      message));
-    return new AssertionError("Internal error: " + message);
-  }
-
-  @Override
-  public void onError(HasSourceInfo hasSourceInfo, ErrorCode errorCode, Object... arguments) {
-    onError(hasSourceInfo.getSourceInfo(), errorCode, arguments);
-  }
-
-  public void onError(SourceInfo sourceInfo, ErrorCode errorCode, Object... arguments) {
-    if (suppressSdkWarnings) {
-      ErrorSeverity errorSeverity = errorCode.getErrorSeverity();
-      if (errorSeverity == ErrorSeverity.WARNING || errorSeverity == ErrorSeverity.INFO) {
-        Source source = sourceInfo.getSource();
-        if (source != null && PackageLibraryManager.isDartUri(source.getUri())) {
-          return;
-        }
-      }
-    }
-    context.onError(new DartCompilationError(sourceInfo, errorCode, arguments));
-  }
-
-  class Selector extends ASTVisitor<Element> {
-    @Override
-    public Element visitNode(DartNode node) {
-      throw internalError(node, "Unexpected node: %s", node);
-    }
-
-    @Override
-    public Element visitPropertyAccess(DartPropertyAccess node) {
-      Element element = node.getQualifier().accept(this);
-      if (element != null) {
-        switch (element.getKind()) {
-          case LIBRARY_PREFIX :
-            Scope elementScope = ((LibraryPrefixElement) element).getScope();
-            return elementScope.findElement(scope.getLibrary(), node.getPropertyName());
-          case CLASS :
-            return Elements.findElement((ClassElement) element, node.getPropertyName());
-        }
-      }
-      return null;
-    }
-
-    @Override
-    public Element visitIdentifier(DartIdentifier node) {
-      String name = node.getName();
-      return scope.findElement(scope.getLibrary(), name);
-    }
-
-    @Override
-    public Element visitSyntheticErrorIdentifier(DartSyntheticErrorIdentifier node) {
-      return Elements.dynamicElement();
-    }
-  }
-}
diff --git a/compiler/java/com/google/dart/compiler/resolver/ResolutionErrorListener.java b/compiler/java/com/google/dart/compiler/resolver/ResolutionErrorListener.java
deleted file mode 100644
index ff69939..0000000
--- a/compiler/java/com/google/dart/compiler/resolver/ResolutionErrorListener.java
+++ /dev/null
@@ -1,13 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.resolver;
-
-import com.google.dart.compiler.ErrorCode;
-import com.google.dart.compiler.common.HasSourceInfo;
-
-public interface ResolutionErrorListener {
-
-  void onError(HasSourceInfo hasSourceInfo, ErrorCode errorCode, Object... arguments);
-}
diff --git a/compiler/java/com/google/dart/compiler/resolver/ResolveVisitor.java b/compiler/java/com/google/dart/compiler/resolver/ResolveVisitor.java
deleted file mode 100644
index 20559ef..0000000
--- a/compiler/java/com/google/dart/compiler/resolver/ResolveVisitor.java
+++ /dev/null
@@ -1,162 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.resolver;
-
-import com.google.dart.compiler.ErrorCode;
-import com.google.dart.compiler.ast.ASTNodes;
-import com.google.dart.compiler.ast.ASTVisitor;
-import com.google.dart.compiler.ast.DartFunction;
-import com.google.dart.compiler.ast.DartFunctionTypeAlias;
-import com.google.dart.compiler.ast.DartIdentifier;
-import com.google.dart.compiler.ast.DartNode;
-import com.google.dart.compiler.ast.DartParameter;
-import com.google.dart.compiler.ast.DartThisExpression;
-import com.google.dart.compiler.ast.DartTypeNode;
-import com.google.dart.compiler.ast.DartTypeParameter;
-import com.google.dart.compiler.common.HasSourceInfo;
-import com.google.dart.compiler.type.FunctionType;
-import com.google.dart.compiler.type.Type;
-import com.google.dart.compiler.type.Types;
-
-import java.util.ArrayList;
-import java.util.HashSet;
-import java.util.List;
-
-/**
- * Shared visitor between Resolver and MemberBuilder.
- */
-abstract class ResolveVisitor extends ASTVisitor<Element> {
-  private final CoreTypeProvider typeProvider;
-
-  ResolveVisitor(CoreTypeProvider typeProvider) {
-    this.typeProvider = typeProvider;
-  }
-
-  abstract ResolutionContext getContext();
-
-  final MethodElement resolveFunction(DartFunction node, MethodElement element) {
-    for (DartParameter parameter : node.getParameters()) {
-      Elements.addParameter(element, (VariableElement) parameter.accept(this));
-    }
-    resolveFunctionWithParameters(node, element);
-    Type returnType =
-        resolveType(
-            node.getReturnTypeNode(),
-            element.getModifiers().isStatic(),
-            element.getModifiers().isFactory(),
-            true,
-            TypeErrorCode.NO_SUCH_TYPE,
-            TypeErrorCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS);
-    ClassElement functionElement = typeProvider.getFunctionType().getElement();
-    FunctionType type = Types.makeFunctionType(getContext(), functionElement,
-                                               element.getParameters(), returnType);
-    Elements.setType(element, type);
-    for (DartParameter parameter : node.getParameters()) {
-      if (!(parameter.getQualifier() instanceof DartThisExpression) &&
-          DartIdentifier.isPrivateName(parameter.getElement().getName())) {
-        if (parameter.getModifiers().isOptional()) {
-          getContext().onError(parameter.getName(),
-              ResolverErrorCode.OPTIONAL_PARAMETERS_CANNOT_START_WITH_UNDER);
-        }
-        if (parameter.getModifiers().isNamed()) {
-          getContext().onError(parameter.getName(),
-              ResolverErrorCode.NAMED_PARAMETERS_CANNOT_START_WITH_UNDER);
-        }
-      }
-    }
-    return element;
-  }
-
-  /**
-   * Allows subclass to process {@link DartFunction} element with parameters, but before
-   * {@link FunctionType} is created for it.
-   */
-  protected void resolveFunctionWithParameters(DartFunction node, MethodElement element) {
-  }
-
-  final FunctionAliasElement resolveFunctionAlias(DartFunctionTypeAlias node) {
-    HashSet<String> parameterNames = new HashSet<String>();
-    for (DartTypeParameter parameter : node.getTypeParameters()) {
-      TypeVariableElement typeVar = (TypeVariableElement) parameter.getElement();
-      String parameterName = typeVar.getName();
-      if (parameterNames.contains(parameterName)) {
-        getContext().onError(parameter, ResolverErrorCode.DUPLICATE_TYPE_VARIABLE, parameterName);
-      } else {
-        parameterNames.add(parameterName);
-      }
-      getContext().getScope().declareElement(parameterName, typeVar);
-    }
-    return null;
-  }
-
-  @Override
-  public Element visitParameter(DartParameter node) {
-    Type type = resolveType(node.getTypeNode(), ASTNodes.isStaticContext(node),
-        ASTNodes.isFactoryContext(node), true, TypeErrorCode.NO_SUCH_TYPE,
-        TypeErrorCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS);
-    VariableElement element =
-        Elements.parameterElement(
-            getEnclosingElement(),
-            node,
-            node.getParameterName(),
-            node.getModifiers());
-    List<DartParameter> functionParameters = node.getFunctionParameters();
-    if (functionParameters != null) {
-      List<VariableElement> parameterElements =
-          new ArrayList<VariableElement>(functionParameters.size());
-      for (DartParameter parameter: functionParameters) {
-        parameterElements.add((VariableElement) parameter.accept(this));
-      }
-      ClassElement functionElement = typeProvider.getFunctionType().getElement();
-      type = Types.makeFunctionType(getContext(), functionElement, parameterElements, type);
-    }
-    Elements.setType(element, type);
-    recordElement(node.getName(), element);
-    return recordElement(node, element);
-  }
-
-  protected EnclosingElement getEnclosingElement() {
-    return null;
-  }
-
-  final Type resolveType(DartTypeNode node, boolean isStatic, boolean isFactory,
-      boolean isAnnotation, ErrorCode errorCode, ErrorCode wrongNumberErrorCode) {
-    if (node == null) {
-      return getTypeProvider().getDynamicType();
-    }
-//    assert node.getType() == null || node.getType() instanceof DynamicType;
-    Type type = getContext().resolveType(node, isStatic, isFactory, isAnnotation, errorCode,
-        wrongNumberErrorCode);
-    if (type == null) {
-      type = getTypeProvider().getDynamicType();
-    }
-    node.setType(type);
-    Element element = type.getElement();
-    recordElement(node.getIdentifier(), element);
-    checkDeprecated(node, element);
-    return type;
-  }
-
-  protected final void checkDeprecated(HasSourceInfo nameNode, Element element) {
-    if (element != null && element.getMetadata().isDeprecated()) {
-      getContext().onError(nameNode, TypeErrorCode.DEPRECATED_ELEMENT,
-         Elements.getDeprecatedElementTitle(element));
-    }
-  }
-
-  protected <E extends Element> E recordElement(DartNode node, E element) {
-    node.getClass();
-    if (element == null) {
-      // TypeAnalyzer will diagnose unresolved identifiers.
-      return null;
-    }
-    node.setElement(element);
-    return element;
-  }
-
-  CoreTypeProvider getTypeProvider() {
-    return typeProvider;
-  }
-}
diff --git a/compiler/java/com/google/dart/compiler/resolver/Resolver.java b/compiler/java/com/google/dart/compiler/resolver/Resolver.java
deleted file mode 100644
index 9a4cbf1..0000000
--- a/compiler/java/com/google/dart/compiler/resolver/Resolver.java
+++ /dev/null
@@ -1,2523 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.resolver;
-
-import com.google.common.annotations.VisibleForTesting;
-import com.google.common.base.Objects;
-import com.google.common.collect.Lists;
-import com.google.common.collect.Sets;
-import com.google.dart.compiler.DartCompilationPhase;
-import com.google.dart.compiler.DartCompilerContext;
-import com.google.dart.compiler.ErrorCode;
-import com.google.dart.compiler.Source;
-import com.google.dart.compiler.ast.ASTNodes;
-import com.google.dart.compiler.ast.ASTVisitor;
-import com.google.dart.compiler.ast.DartArrayLiteral;
-import com.google.dart.compiler.ast.DartBinaryExpression;
-import com.google.dart.compiler.ast.DartBlock;
-import com.google.dart.compiler.ast.DartBooleanLiteral;
-import com.google.dart.compiler.ast.DartBreakStatement;
-import com.google.dart.compiler.ast.DartCase;
-import com.google.dart.compiler.ast.DartCatchBlock;
-import com.google.dart.compiler.ast.DartClass;
-import com.google.dart.compiler.ast.DartClassTypeAlias;
-import com.google.dart.compiler.ast.DartComment;
-import com.google.dart.compiler.ast.DartCommentNewName;
-import com.google.dart.compiler.ast.DartCommentRefName;
-import com.google.dart.compiler.ast.DartContinueStatement;
-import com.google.dart.compiler.ast.DartDirective;
-import com.google.dart.compiler.ast.DartDoWhileStatement;
-import com.google.dart.compiler.ast.DartDoubleLiteral;
-import com.google.dart.compiler.ast.DartExprStmt;
-import com.google.dart.compiler.ast.DartExpression;
-import com.google.dart.compiler.ast.DartField;
-import com.google.dart.compiler.ast.DartFieldDefinition;
-import com.google.dart.compiler.ast.DartForInStatement;
-import com.google.dart.compiler.ast.DartForStatement;
-import com.google.dart.compiler.ast.DartFunction;
-import com.google.dart.compiler.ast.DartFunctionExpression;
-import com.google.dart.compiler.ast.DartFunctionObjectInvocation;
-import com.google.dart.compiler.ast.DartFunctionTypeAlias;
-import com.google.dart.compiler.ast.DartGotoStatement;
-import com.google.dart.compiler.ast.DartIdentifier;
-import com.google.dart.compiler.ast.DartIfStatement;
-import com.google.dart.compiler.ast.DartImportDirective;
-import com.google.dart.compiler.ast.DartInitializer;
-import com.google.dart.compiler.ast.DartIntegerLiteral;
-import com.google.dart.compiler.ast.DartInvocation;
-import com.google.dart.compiler.ast.DartLabel;
-import com.google.dart.compiler.ast.DartMapLiteral;
-import com.google.dart.compiler.ast.DartMethodDefinition;
-import com.google.dart.compiler.ast.DartMethodInvocation;
-import com.google.dart.compiler.ast.DartNamedExpression;
-import com.google.dart.compiler.ast.DartNativeBlock;
-import com.google.dart.compiler.ast.DartNewExpression;
-import com.google.dart.compiler.ast.DartNode;
-import com.google.dart.compiler.ast.DartParameter;
-import com.google.dart.compiler.ast.DartParameterizedTypeNode;
-import com.google.dart.compiler.ast.DartPartOfDirective;
-import com.google.dart.compiler.ast.DartPropertyAccess;
-import com.google.dart.compiler.ast.DartRedirectConstructorInvocation;
-import com.google.dart.compiler.ast.DartReturnStatement;
-import com.google.dart.compiler.ast.DartStatement;
-import com.google.dart.compiler.ast.DartStringInterpolation;
-import com.google.dart.compiler.ast.DartStringLiteral;
-import com.google.dart.compiler.ast.DartSuperConstructorInvocation;
-import com.google.dart.compiler.ast.DartSuperExpression;
-import com.google.dart.compiler.ast.DartSwitchMember;
-import com.google.dart.compiler.ast.DartSwitchStatement;
-import com.google.dart.compiler.ast.DartThisExpression;
-import com.google.dart.compiler.ast.DartThrowExpression;
-import com.google.dart.compiler.ast.DartTryStatement;
-import com.google.dart.compiler.ast.DartTypeExpression;
-import com.google.dart.compiler.ast.DartTypeNode;
-import com.google.dart.compiler.ast.DartTypeParameter;
-import com.google.dart.compiler.ast.DartUnaryExpression;
-import com.google.dart.compiler.ast.DartUnit;
-import com.google.dart.compiler.ast.DartUnqualifiedInvocation;
-import com.google.dart.compiler.ast.DartVariable;
-import com.google.dart.compiler.ast.DartVariableStatement;
-import com.google.dart.compiler.ast.DartWhileStatement;
-import com.google.dart.compiler.ast.LibraryImport;
-import com.google.dart.compiler.ast.LibraryUnit;
-import com.google.dart.compiler.ast.Modifiers;
-import com.google.dart.compiler.common.HasSourceInfo;
-import com.google.dart.compiler.common.SourceInfo;
-import com.google.dart.compiler.parser.Token;
-import com.google.dart.compiler.resolver.LabelElement.LabeledStatementType;
-import com.google.dart.compiler.type.InterfaceType;
-import com.google.dart.compiler.type.InterfaceType.Member;
-import com.google.dart.compiler.type.Type;
-import com.google.dart.compiler.type.TypeAnalyzer;
-import com.google.dart.compiler.type.TypeKind;
-import com.google.dart.compiler.type.TypeQuality;
-import com.google.dart.compiler.type.TypeVariable;
-import com.google.dart.compiler.type.Types;
-
-import java.util.EnumSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Set;
-/**
- * Resolves unqualified elements in a compilation unit.
- */
-public class Resolver {
-
-  private final ResolutionContext topLevelContext;
-  private final CoreTypeProvider typeProvider;
-  private final InterfaceType rawArrayType;
-  private final InterfaceType defaultLiteralMapType;
-
-
-  private static final EnumSet<ElementKind> INVOKABLE_ELEMENTS = EnumSet.<ElementKind>of(
-      ElementKind.FIELD,
-      ElementKind.PARAMETER,
-      ElementKind.VARIABLE,
-      ElementKind.FUNCTION_OBJECT,
-      ElementKind.METHOD);
-
-  @VisibleForTesting
-  public Resolver(DartCompilerContext compilerContext, Scope libraryScope,
-                  CoreTypeProvider typeProvider) {
-    compilerContext.getClass(); // Fast null-check.
-    libraryScope.getClass(); // Fast null-check.
-    typeProvider.getClass(); // Fast null-check.
-    this.topLevelContext = new ResolutionContext(libraryScope, compilerContext, typeProvider);
-    this.typeProvider = typeProvider;
-    Type dynamicType = typeProvider.getDynamicType();
-    Type stringType = typeProvider.getStringType();
-    this.defaultLiteralMapType = typeProvider.getMapType(stringType, dynamicType);
-    this.rawArrayType = typeProvider.getArrayType(dynamicType);
-  }
-
-  @VisibleForTesting
-  public DartUnit exec(DartUnit unit) {
-    // Visits all top level elements of a compilation unit and resolves names used in method
-    // bodies.
-    LibraryElement library = unit.getLibrary() != null ? unit.getLibrary().getElement() : null;
-    unit.accept(new ResolveElementsVisitor(topLevelContext, library));
-    return unit;
-  }
-
-  /**
-   * Main entry point for IDE. Resolves a member (method or field)
-   * incrementally in the given context.
-   *
-   * @param classElement the class enclosing the member.
-   * @param member the member to resolve.
-   * @param context a resolution context corresponding to classElement.
-   */
-  public void resolveMember(ClassNodeElement classElement, NodeElement member, ResolutionContext context) {
-    ResolveElementsVisitor visitor;
-    if(member == null) {
-      return;
-    }
-    switch (member.getKind()) {
-      case CONSTRUCTOR:
-      case METHOD:
-        ResolutionContext methodContext = context.extend(member.getName());
-        visitor = new ResolveElementsVisitor(methodContext, classElement,
-                                             (MethodElement) member);
-        break;
-
-        case FIELD:
-          ResolutionContext fieldContext = context;
-          if (member.getModifiers().isAbstractField()) {
-            fieldContext = context.extend(member.getName());
-          }
-          visitor = new ResolveElementsVisitor(fieldContext, classElement);
-          break;
-
-      default:
-        throw topLevelContext.internalError(member,
-                                            "unexpected element kind: %s", member.getKind());
-    }
-    member.getNode().accept(visitor);
-  }
-
-  /**
-   * Resolves names in a method body.
-   *
-   * TODO(ngeoffray): Errors reported:
-   *  - A default implementation not providing the default methods.
-   *  - An interface with default methods but without a default implementation.
-   *  - A member method shadowing a super property.
-   *  - A member property shadowing a super method.
-   *  - A formal parameter in a non-constructor shadowing a member.
-   *  - A local variable shadowing another variable.
-   *  - A local variable shadowing a formal parameter.
-   *  - A local variable shadowing a class member.
-   *  - Using 'this' or 'super' in a static or factory method, or in an initializer.
-   *  - Using 'super' in a class without a super class.
-   *  - Incorrectly using a resolved element.
-   */
-  @VisibleForTesting
-  public class ResolveElementsVisitor extends ResolveVisitor {
-    private EnclosingElement currentHolder;
-    private EnclosingElement enclosingElement;
-    private MethodElement currentMethod;
-    private boolean inInstanceVariableInitializer;
-    private boolean inInitializer;
-    private MethodElement innermostFunction;
-    private ResolutionContext context;
-    private Set<LabelElement> referencedLabels = Sets.newHashSet();
-    private Set<LabelElement> labelsInScopes = Sets.newHashSet();
-    private Set<FieldElement> finalsNeedingInitializing = Sets.newHashSet();
-    private Set<FieldElement> resolvedFields = Sets.newHashSet();
-
-    @VisibleForTesting
-    public ResolveElementsVisitor(ResolutionContext context,
-                                  EnclosingElement currentHolder,
-                                  MethodElement currentMethod) {
-      super(typeProvider);
-      this.context = context;
-      this.currentMethod = currentMethod;
-      this.innermostFunction = currentMethod;
-      this.currentHolder = currentHolder;
-      this.enclosingElement = currentHolder;
-      this.inInitializer = false;
-    }
-
-    private ResolveElementsVisitor(ResolutionContext context, EnclosingElement currentHolder) {
-      this(context, currentHolder, null);
-    }
-
-    @Override
-    ResolutionContext getContext() {
-      return context;
-    }
-
-    @Override
-    protected EnclosingElement getEnclosingElement() {
-      return enclosingElement;
-    }
-
-    @Override
-    public Element visitUnit(DartUnit unit) {
-      List<DartImportDirective> importDirectives = Lists.newArrayList();
-      for (DartDirective directive : unit.getDirectives()) {
-        if (directive instanceof DartImportDirective) {
-          importDirectives.add((DartImportDirective) directive);
-        }
-        if (directive instanceof DartPartOfDirective) {
-          directive.accept(this);
-        }
-      }
-      // set LibraryElement for "import" directives
-      {
-        LibraryUnit library = unit.getLibrary();
-        if (library != null) {
-          Iterator<LibraryImport> importIterator = library.getImports().iterator();
-          Iterator<DartImportDirective> directiveIterator = importDirectives.iterator();
-          while (importIterator.hasNext() && directiveIterator.hasNext()) {
-            LibraryImport imp = importIterator.next();
-            DartImportDirective dir = directiveIterator.next();
-            DartStringLiteral uri = dir.getLibraryUri();
-            LibraryUnit impLibrary = imp.getLibrary();
-            if (uri != null && impLibrary != null) {
-              uri.setElement(impLibrary.getElement());
-            }
-          }
-        }
-      }
-      // visit top-level nodes
-      for (DartNode node : unit.getTopLevelNodes()) {
-        node.accept(this);
-      }
-      checkRedirectingFactoryConstructorsCycle(unit);
-      return null;
-    }
-
-    private void checkRedirectingFactoryConstructorsCycle(DartUnit unit) {
-      unit.accept(new ASTVisitor<Void>() {
-        @Override
-        public Void visitMethodDefinition(DartMethodDefinition node) {
-          MethodNodeElement element = node.getElement();
-          if (ElementKind.of(element) == ElementKind.CONSTRUCTOR) {
-            ConstructorElement constructor = (ConstructorElement) element;
-            if (hasRedirectingFactoryConstructorCycle(constructor)) {
-              onError(constructor.getNameLocation(),
-                  ResolverErrorCode.REDIRECTION_CONSTRUCTOR_CYCLE);
-            }
-          }
-          return super.visitMethodDefinition(node);
-        }
-      });
-    }
-    
-    private boolean hasRedirectingFactoryConstructorCycle(ConstructorElement element) {
-      Set<ConstructorElement> constructors = Sets.newHashSet();
-      while (element != null) {
-        if (constructors.contains(element)) {
-          return true;
-        }
-        constructors.add(element);
-        element = element.getRedirectingFactoryConstructor();
-      }
-      return false;
-    }
-    
-    @Override
-    public Element visitFunctionTypeAlias(DartFunctionTypeAlias alias) {
-      alias.getMetadata().accept(this);
-      getContext().pushFunctionAliasScope(alias);
-      resolveFunctionAlias(alias);
-
-      getContext().pushScope("<parameters>");
-      try {
-        List<DartParameter> parameters = alias.getParameters();
-        for (DartParameter parameter : parameters) {
-          assert parameter.getElement() != null;
-          if (parameter.getQualifier() instanceof DartThisExpression) {
-            onError(parameter.getName(), ResolverErrorCode.PARAMETER_INIT_OUTSIDE_CONSTRUCTOR);
-          } else {
-            if (DartIdentifier.isPrivateName(parameter.getElement().getName())) {
-              if (parameter.getModifiers().isOptional()) {
-                onError(parameter.getName(),
-                    ResolverErrorCode.OPTIONAL_PARAMETERS_CANNOT_START_WITH_UNDER);
-              }
-              if (parameter.getModifiers().isNamed()) {
-                onError(parameter.getName(),
-                    ResolverErrorCode.NAMED_PARAMETERS_CANNOT_START_WITH_UNDER);
-              }
-            }
-            getContext().declare(parameter.getElement(), ResolverErrorCode.DUPLICATE_PARAMETER);
-          }
-        }
-      } finally {
-        getContext().popScope();
-      }
-
-      getContext().popScope();
-      return null;
-    }
-
-    @Override
-    public Element visitCommentRefName(DartCommentRefName node) {
-      Scope scope = getContext().getScope();
-      String name = node.getName();
-      Element element = scope.findElement(scope.getLibrary(), name);
-      return recordElement(node, element);
-    }
-
-    @Override
-    public Element visitCommentNewName(DartCommentNewName node) {
-      String className = node.getClassName();
-      String constructorName = node.getConstructorName();
-      Scope scope = getContext().getScope();
-      Element element = scope.findElement(scope.getLibrary(), className);
-      if (ElementKind.of(element) == ElementKind.CLASS) {
-        ClassElement classElement = (ClassElement) element;
-        for (ConstructorElement constructor : classElement.getConstructors()) {
-          if (constructor.getName().equals(constructorName)) {
-            node.setElements(classElement, constructor);
-            return constructor;
-          }
-        }
-      }
-      return null;
-    }
-    
-    @Override
-    public Element visitClassTypeAlias(DartClassTypeAlias cls) {
-      ClassNodeElement classElement = cls.getElement();
-      try {
-        classElement.getAllSupertypes();
-      } catch (CyclicDeclarationException e) {
-        HasSourceInfo errorTarget = e.getElement();
-        if (errorTarget == null) {
-          errorTarget = cls;
-        }
-        onError(errorTarget, ResolverErrorCode.CYCLIC_CLASS, e.getElement().getName());
-      }
-      checkMixinObjectIsSupertype(cls.getMixins());
-      checkMixinNoConstructors(cls.getMixins());
-      checkMixinNoSuperInvocations(cls.getMixins());
-      return classElement;
-    }
-
-    @Override
-    public Element visitClass(DartClass cls) {
-      assert currentMethod == null : "nested class?";
-      ClassNodeElement classElement = cls.getElement();
-      try {
-        classElement.getAllSupertypes();
-      } catch (CyclicDeclarationException e) {
-        HasSourceInfo errorTarget = e.getElement();
-        if (errorTarget == null) {
-          errorTarget = cls;
-        }
-        onError(errorTarget, ResolverErrorCode.CYCLIC_CLASS, e.getElement().getName());
-      }
-      checkClassTypeVariables(classElement);
-      cls.getMetadata().accept(this);
-
-      // Push new resolution context.
-      ResolutionContext previousContext = context;
-      EnclosingElement previousHolder = currentHolder;
-      EnclosingElement previousEnclosingElement = enclosingElement;
-      currentHolder = classElement;
-      enclosingElement = classElement;
-      context = topLevelContext.extend(classElement);
-
-      // members
-      this.finalsNeedingInitializing.clear();
-      for (DartNode member : cls.getMembers()) {
-        if (ElementKind.of(member.getElement()) == ElementKind.CONSTRUCTOR) {
-          continue;
-        }
-        member.accept(this);
-      }
-
-      // constructors
-      boolean testForAllConstantFields = false;
-      for (DartNode member : cls.getMembers()) {
-        if (member instanceof DartMethodDefinition) {
-          DartMethodDefinition method = (DartMethodDefinition) member;
-          if (method.getElement().isConstructor()) {
-            method.accept(this);
-            if (method.getModifiers().isConstant()) {
-              testForAllConstantFields = true;
-            }
-          }
-        }
-      }
-
-      if (testForAllConstantFields) {
-        InterfaceType interfaceType = classElement.getType();
-        while (interfaceType != null && interfaceType != typeProvider.getObjectType()) {
-          ClassElement interfaceElement = interfaceType.getElement();
-          constVerifyMembers(interfaceElement.getMembers(), classElement, interfaceElement);
-          interfaceType = interfaceElement.getSupertype();
-        }
-      }
-
-      checkRedirectConstructorCycle(classElement.getConstructors(), context);
-      if (Elements.needsImplicitDefaultConstructor(classElement)) {
-        checkImplicitDefaultDefaultSuperInvocation(cls, classElement);
-      }
-
-      if (cls.getDefaultClass() != null && classElement.getDefaultClass() == null) {
-        onError(cls.getDefaultClass(), ResolverErrorCode.NO_SUCH_TYPE, cls.getDefaultClass());
-      } else if (classElement.getDefaultClass() != null) {
-        recordElement(cls.getDefaultClass().getExpression(),
-                      classElement.getDefaultClass().getElement());
-        bindDefaultTypeParameters(classElement.getDefaultClass().getElement().getTypeParameters(),
-                                  cls.getDefaultClass().getTypeParameters(),
-                                  context);
-
-        // Make sure the 'default' clause matches the referenced class type parameters
-        checkDefaultClassTypeParamsToDefaultDecl(classElement.getDefaultClass(),
-                                                 cls.getDefaultClass());
-
-        ClassElement defaultClass = classElement.getDefaultClass().getElement();
-        if (defaultClass.isInterface()) {
-          onError(cls.getDefaultClass().getExpression(),
-              ResolverErrorCode.DEFAULT_MUST_SPECIFY_CLASS);
-        }
-
-        // Make sure the default class matches the interface type parameters
-        checkInterfaceTypeParamsToDefault(classElement, defaultClass);
-      }
-
-      if (!classElement.isInterface() && Elements.needsImplicitDefaultConstructor(classElement)) {
-        // Check to see that all final fields are initialized when no explicit
-        // generative constructor is declared
-        cls.accept(new ASTVisitor<DartNode>() {
-          @Override
-          public DartNode visitField(DartField node) {
-            FieldElement fieldElement = node.getElement();
-            if (fieldElement != null && fieldElement.getModifiers().isFinal()
-                && !fieldElement.isStatic()
-                && !fieldElement.getModifiers().isConstant()
-                && !fieldElement.getModifiers().isGetter()
-                && !fieldElement.getModifiers().isSetter()
-                && !fieldElement.getModifiers().isInitialized()) {
-              onError(node, ResolverErrorCode.FINAL_FIELD_MUST_BE_INITIALIZED,
-                  fieldElement.getName());
-            }
-            return null;
-          }
-        });
-      }
-
-      {
-        DartComment comment = cls.getDartDoc();
-        if (comment != null) {
-          comment.accept(this);
-        }
-      }
-
-      // check mixins
-      checkMixinObjectIsSupertype(cls.getMixins());
-      checkMixinNoConstructors(cls.getMixins());
-      checkMixinNoSuperInvocations(cls.getMixins());
-
-      context = previousContext;
-      currentHolder = previousHolder;
-      enclosingElement = previousEnclosingElement;
-      return classElement;
-    }
-
-    /**
-     * Checks that the types of the given mixin type node don't have explicit constructors.
-     */
-    private void checkMixinNoConstructors(List<DartTypeNode> mixins) {
-      for (DartTypeNode mixNode : mixins) {
-        if (mixNode.getType() instanceof InterfaceType) {
-          InterfaceType mixType = (InterfaceType) mixNode.getType();
-          for (ConstructorElement constructor : mixType.getElement().getConstructors()) {
-            if (!constructor.getModifiers().isFactory()) {
-              topLevelContext.onError(mixNode, ResolverErrorCode.CANNOT_MIXIN_CLASS_WITH_CONSTRUCTOR);
-              break;
-            }
-          }
-        }
-      }
-    }
-    
-    /**
-     * Checks that the types of the given mixin type nodes se subtypes of Object.
-     */
-    private void checkMixinObjectIsSupertype(List<DartTypeNode> mixins) {
-      for (DartTypeNode mixNode : mixins) {
-        if (mixNode.getType() instanceof InterfaceType) {
-          InterfaceType mixType = (InterfaceType) mixNode.getType();
-          ClassElement mixElement = mixType.getElement();
-          if (!mixElement.getMixins().isEmpty()) {
-            topLevelContext.onError(mixNode, ResolverErrorCode.CANNOT_MIXIN_CLASS_WITH_MIXINS);
-            continue;
-          }
-          if (!Objects.equal(mixElement.getSupertype(), typeProvider.getObjectType())) {
-            topLevelContext.onError(mixNode, ResolverErrorCode.ONLY_OBJECT_MIXIN_SUPERCLASS);
-            continue;
-          }
-        }
-      }
-    }
-    
-    /**
-     * Checks that the types of the given mixin type nodes don't have super invocations.
-     */
-    private void checkMixinNoSuperInvocations(List<DartTypeNode> mixins) {
-      for (DartTypeNode mixNode : mixins) {
-        if (mixNode.getType() instanceof InterfaceType) {
-          InterfaceType mixType = (InterfaceType) mixNode.getType();
-          if (mixType.getElement() instanceof ClassElement) {
-            ClassElement mixElement = (ClassElement) mixType.getElement();
-            if (mixElement.hasSuperInvocation()) {
-              topLevelContext.onError(mixNode, ResolverErrorCode.CANNOT_MIXIN_CLASS_WITH_SUPER);
-              break;
-            }
-          }
-        }
-      }
-    }
-
-    private void constVerifyMembers(Iterable<? extends Element> members, ClassElement originalClass,
-        ClassElement currentClass) {
-      for (Element element : members) {
-        Modifiers modifiers = element.getModifiers();
-        if (ElementKind.of(element).equals(ElementKind.FIELD) && !modifiers.isFinal()
-            && !modifiers.isStatic() && !modifiers.isAbstractField()) {
-          FieldElement field = (FieldElement) element;
-          HasSourceInfo errorNode = field.getSetter() == null ? element : field.getSetter();
-          onError(errorNode, currentClass == originalClass
-              ? ResolverErrorCode.CONST_CLASS_WITH_NONFINAL_FIELDS
-              : ResolverErrorCode.CONST_CLASS_WITH_INHERITED_NONFINAL_FIELDS,
-              originalClass.getName(), field.getName(), currentClass.getName());
-        }
-      }
-    }
-
-    /**
-     * Sets the type in the AST of the default clause of an interface so that the type
-     * parameters to resolve back to the default class.
-     */
-    private void bindDefaultTypeParameters(List<Type> parameterTypes,
-                                           List<DartTypeParameter> parameterNodes,
-                                           ResolutionContext classContext) {
-      Iterator<? extends Type> typeIterator = parameterTypes.iterator();
-      Iterator<DartTypeParameter> nodeIterator = parameterNodes.iterator();
-
-      while(typeIterator.hasNext() && nodeIterator.hasNext()) {
-
-        Type type = typeIterator.next();
-        DartTypeParameter node = nodeIterator.next();
-
-        if (type.getElement().getName().equals(node.getName().getName())) {
-          node.setType(type);
-          recordElement(node.getName(), type.getElement());
-        } else {
-          node.setType(typeProvider.getDynamicType());
-        }
-
-        DartTypeNode boundNode = node.getBound();
-        if (boundNode != null) {
-          Type bound =
-              classContext.resolveType(
-                  boundNode,
-                  false,
-                  false,
-                  true,
-                  ResolverErrorCode.NO_SUCH_TYPE,
-                  ResolverErrorCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS);
-          boundNode.setType(bound);
-        }
-      }
-
-      while (nodeIterator.hasNext()) {
-        DartTypeParameter node = nodeIterator.next();
-        node.setType(typeProvider.getDynamicType());
-      }
-    }
-    /**
-     * If type parameters are present, the type parameters of the default statement
-     * must exactly match those of those declared in the class it references.
-     *
-     */
-    private void checkDefaultClassTypeParamsToDefaultDecl(InterfaceType defaultClassType,
-                                                          DartParameterizedTypeNode defaultClassRef) {
-      if (defaultClassRef.getTypeParameters().isEmpty()) {
-        return;
-      }
-      ClassElement defaultClassElement = defaultClassType.getElement();
-      boolean match = true;
-      if (defaultClassElement.getTypeParameters().isEmpty()) {
-        match = false;
-      } else {
-        // TODO(zundel): This is effective in catching mistakes, but highlights the entire type
-        // expression - A more specific indication of where the error started might be appreciated.
-        String defaultClassSource = defaultClassElement.getDeclarationNameWithTypeParameters();
-        String refSource = defaultClassRef.toSource();
-        if (!refSource.equals(defaultClassSource)) {
-          match = false;
-        }
-      }
-      if (!match) {
-        // TODO(zundel): work harder to point out where the type param match failure starts.
-        onError(defaultClassRef, ResolverErrorCode.TYPE_PARAMETERS_MUST_MATCH_EXACTLY);
-      }
-    }
-
-    private void checkInterfaceTypeParamsToDefault(ClassElement interfaceElement,
-                                                   ClassElement defaultClassElement) {
-
-      List<Type> interfaceTypeParams = interfaceElement.getTypeParameters();
-
-      List<Type> defaultTypeParams = defaultClassElement.getTypeParameters();
-
-
-      if (defaultTypeParams.size() != interfaceTypeParams.size()) {
-
-        onError(interfaceElement.getNameLocation(),
-                ResolverErrorCode.DEFAULT_CLASS_MUST_HAVE_SAME_TYPE_PARAMS);
-      } else {
-        Iterator<? extends Type> interfaceIterator = interfaceTypeParams.iterator();
-        Iterator<? extends Type> defaultIterator = defaultTypeParams.iterator();
-        while (interfaceIterator.hasNext()) {
-          Type iVar = interfaceIterator.next();
-          Type dVar = defaultIterator.next();
-          String iVarName = iVar.getElement().getName();
-          String dVarName = dVar.getElement().getName();
-          if (!iVarName.equals(dVarName)) {
-            onError(iVar.getElement(), ResolverErrorCode.TYPE_VARIABLE_DOES_NOT_MATCH,
-                    iVarName, dVarName, defaultClassElement.getName());
-          }
-        }
-      }
-    }
-
-    /**
-     * Check that used type variables are unique and don't shadow and existing elements.
-     */
-    private void checkClassTypeVariables(ClassElement classElement) {
-      Set<String> declaredVariableNames = Sets.newHashSet();
-      for (Type type : classElement.getTypeParameters()) {
-        if (type instanceof TypeVariable) {
-          Element typeVariableElement = type.getElement();
-          String name = typeVariableElement.getName();
-          // Check that type variables are unique in this Class  declaration.
-          if (declaredVariableNames.contains(name)) {
-            onError(typeVariableElement, ResolverErrorCode.DUPLICATE_TYPE_VARIABLE, name);
-          } else {
-            declaredVariableNames.add(name);
-          }
-        }
-      }
-    }
-
-    /**
-     * Returns <code>true</code> if the {@link ClassElement} has an implicit or a declared
-     * default constructor.
-     */
-    boolean hasDefaultConstructor(ClassElement classElement) {
-      if (Elements.needsImplicitDefaultConstructor(classElement)) {
-        return true;
-      }
-
-      ConstructorElement defaultCtor = Elements.lookupConstructor(classElement, "");
-      if (defaultCtor != null) {
-        return defaultCtor.getParameters().isEmpty();
-      }
-
-      return false;
-    }
-
-    private void checkImplicitDefaultDefaultSuperInvocation(DartClass cls,
-        ClassElement classElement) {
-      assert (Elements.needsImplicitDefaultConstructor(classElement));
-
-      InterfaceType supertype = classElement.getSupertype();
-      if (supertype != null) {
-        ClassElement superElement = supertype.getElement();
-        if (!superElement.isDynamic()) {
-          ConstructorElement superCtor = Elements.lookupConstructor(superElement, "");
-          boolean superHasDefaultCtor =
-              (superCtor != null && superCtor.getParameters().isEmpty())
-                  || (superCtor == null && Elements.needsImplicitDefaultConstructor(superElement));
-          if (!superHasDefaultCtor) {
-            onError(cls.getName(),
-                ResolverErrorCode.CANNOT_RESOLVE_IMPLICIT_CALL_TO_SUPER_CONSTRUCTOR,
-                cls.getSuperclass());
-          }
-          if (superCtor != null && superCtor.getModifiers().isFactory()) {
-            onError(cls.getName(), ResolverErrorCode.NOT_GENERATIVE_SUPER_CONSTRUCTOR, "<default>",
-                supertype);
-          }
-        }
-      }
-    }
-
-    private Element resolve(DartNode node) {
-      if (node == null) {
-        return null;
-      } else {
-        return node.accept(this);
-      }
-    }
-
-    @Override
-    public Element visitTypeParameter(DartTypeParameter node) {
-      node.getMetadata().accept(this);
-      return super.visitTypeParameter(node);
-    }
-
-    @Override
-    public MethodElement visitMethodDefinition(DartMethodDefinition node) {
-      node.getMetadata().accept(this);
-      MethodElement member = node.getElement();
-      ResolutionContext previousContext = context;
-      context = context.extend(member.getName());
-      assert currentMethod == null : "Nested methods?";
-      innermostFunction = currentMethod = member;
-      EnclosingElement previousEnclosingElement = enclosingElement;
-      enclosingElement = member;
-
-      DartFunction functionNode = node.getFunction();
-      List<DartParameter> parameters = functionNode.getParameters();
-      Set<FieldElement> initializedFields = Sets.newHashSet();
-      
-      // remember field with initializers
-      if (previousEnclosingElement instanceof ClassElement) {
-        ClassElement classElement = (ClassElement) previousEnclosingElement;
-        for (Element classMember : classElement.getMembers()) {
-          if (ElementKind.of(classMember) == ElementKind.FIELD) {
-            FieldElement fieldMember = (FieldElement) classMember;
-            if (fieldMember.getModifiers().isFinal() && fieldMember.getModifiers().isInitialized()) {
-              initializedFields.add(fieldMember);
-            }
-          }
-        }
-      }
-
-      // First declare all normal parameters in the scope, putting them in the
-      // scope of the default expressions so we can report better errors.
-      for (DartParameter parameter : parameters) {
-        assert parameter.getElement() != null;
-        parameter.getMetadata().accept(this);
-
-        if (!(parameter.getQualifier() instanceof DartThisExpression)) {
-          getContext().declare(
-              parameter.getElement(),
-              ResolverErrorCode.DUPLICATE_PARAMETER);
-        }
-      }
-      for (DartParameter parameter : parameters) {
-        // Then resolve the default values.
-        resolve(parameter.getDefaultExpr());
-        if (parameter.getQualifier() instanceof DartThisExpression && parameter.getElement() != null
-            && !initializedFields.add(parameter.getElement().getParameterInitializerElement())) {
-          onError(parameter, ResolverErrorCode.DUPLICATE_INITIALIZATION, parameter.getName());
-        }
-      }
-      
-      {
-        DartComment comment = node.getDartDoc();
-        if (comment != null) {
-          comment.accept(this);
-        }
-      }
-
-      DartBlock body = functionNode.getBody();
-      if (body == null) {
-        if (member.getModifiers().isStatic() && !member.getModifiers().isExternal()) {
-          onError(functionNode, ResolverErrorCode.STATIC_METHOD_MUST_HAVE_BODY);
-        }
-      }
-      resolve(functionNode.getBody());
-
-      if (Elements.isNonFactoryConstructor(member) && !(body instanceof DartNativeBlock)) {
-        resolveInitializers(node, initializedFields);
-      }
-
-      // only generative constructor can have initializers, so resolve them, but report error 
-      if (!member.isConstructor() || member.getModifiers().isFactory()) {
-        for (DartInitializer initializer : node.getInitializers()) {
-          resolve(initializer);
-          if (initializer.getName() != null) {
-            onError(initializer, ResolverErrorCode.INITIALIZER_ONLY_IN_GENERATIVE_CONSTRUCTOR);
-          }
-        }
-      }
-      
-      // resolve redirecting factory constructor
-      {
-        DartTypeNode rcTypeName = node.getRedirectedTypeName();
-        if (rcTypeName != null) {
-          Type rcType = resolveType(rcTypeName, true, true, false,
-              TypeErrorCode.NO_SUCH_TYPE, ResolverErrorCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS);
-          switch (TypeKind.of(rcType)) {
-            case INTERFACE:
-              ConstructorElement targetConstructor = null;
-              Element element = recordType(rcTypeName, rcType);
-              DartIdentifier rcName = node.getRedirectedConstructorName();
-              if (rcName != null) {
-                element = ((ClassElement) element).lookupConstructor(rcName.getName());
-                switch (ElementKind.of(element)) {
-                  case CONSTRUCTOR:
-                    targetConstructor = (ConstructorElement) element;
-                    recordElement(rcName, element);
-                    if (member.getModifiers().isConstant() && !element.getModifiers().isConstant()) {
-                      onError(rcName,
-                          ResolverErrorCode.REDIRECTION_CONSTRUCTOR_TARGET_MUST_BE_CONST);
-                    }
-                    break;
-                }
-              } else {
-                targetConstructor = ((ClassElement) element).lookupConstructor("");
-              }
-              Elements.setRedirectingFactoryConstructor(((ConstructorElement) member),
-                  targetConstructor);
-              break;
-            default:
-              onError(rcTypeName, ResolverErrorCode.REDIRECTION_CONSTRUCTOR_TARGET_TYPE);
-          }
-        }
-      }
-
-      context = previousContext;
-      innermostFunction = currentMethod = null;
-      enclosingElement = previousEnclosingElement;
-      return member;
-    }
-
-    @Override
-    public Element visitField(DartField node) {
-      DartExpression expression = node.getValue();
-      Modifiers modifiers = node.getModifiers();
-      boolean isFinal = modifiers.isFinal();
-      boolean isTopLevel = ElementKind.of(currentHolder).equals(ElementKind.LIBRARY);
-      boolean isStatic = modifiers.isStatic();
-
-      if (expression != null) {
-        inInstanceVariableInitializer = !isTopLevel;
-        try {
-          resolve(expression);
-        } finally {
-          inInstanceVariableInitializer = false;
-        }
-        // Now, this constant has a type. Save it for future reference.
-        Element element = node.getElement();
-        Type expressionType = expression.getType();
-        if (isFinal && expressionType != null && TypeKind.of(element.getType()) == TypeKind.DYNAMIC) {
-          TypeQuality typeQuality = TypeAnalyzer.getTypeQuality(expression);
-          Type fieldType = Types.makeInferred(expressionType, typeQuality);
-          Elements.setType(element, fieldType);
-        }
-      } else if (isFinal) {
-        if (modifiers.isConstant()) {
-          onError(node, ResolverErrorCode.CONST_REQUIRES_VALUE);
-        } else if (isStatic) {
-          onError(node, ResolverErrorCode.STATIC_FINAL_REQUIRES_VALUE);
-        } else if (isTopLevel) {
-          onError(node, ResolverErrorCode.TOPLEVEL_FINAL_REQUIRES_VALUE);
-        } else {
-          // If a final instance field wasn't initialized at declaration, we must check
-          // at construction time.
-          this.finalsNeedingInitializing.add(node.getElement());
-        }
-      }
-
-      // If field is an accessor, both getter and setter need to be visited (if present).
-      // We check for duplicates because top-level fields are visited twice - for each accessor.
-      FieldNodeElement field = node.getElement();
-      if (!resolvedFields.contains(field)) {
-        resolvedFields.add(field);
-        if (field.getGetter() != null) {
-          resolve(field.getGetter().getNode());
-        }
-        if (field.getSetter() != null) {
-          resolve(field.getSetter().getNode());
-        }
-      }
-      return null;
-    }
-
-    @Override
-    public Element visitFieldDefinition(DartFieldDefinition node) {
-      node.getMetadata().accept(this);
-      visit(node.getFields());
-      return null;
-    }
-
-    @Override
-    public Element visitFunction(DartFunction node) {
-      throw context.internalError(node, "should not be called.");
-    }
-
-    @Override
-    public Element visitParameter(DartParameter x) {
-      x.getMetadata().accept(this);
-      Element element = super.visitParameter(x);
-      resolve(x.getDefaultExpr());
-      getContext().declare(
-          element,
-          ResolverErrorCode.DUPLICATE_PARAMETER);
-      return element;
-    }
-
-    @Override
-    public Element visitVariable(DartVariable node) {
-      node.getMetadata().accept(this);
-      return super.visitVariable(node);
-    }
-
-    public VariableElement resolveVariable(DartVariable x, Modifiers modifiers) {
-      final DartIdentifier nameNode = x.getName();
-      final String name = nameNode.getName();
-      // Visit the initializer first.
-      DartExpression value = x.getValue();
-      if (value != null) {
-        // It is a compile-time error if e refers to the name v or the name v=.
-        value.accept(new ASTVisitor<Void>() {
-          @Override
-          public Void visitIdentifier(DartIdentifier node) {
-            // ignore cases when name is used with some qualifier
-            if (node.getParent() instanceof DartPropertyAccess) {
-              DartPropertyAccess x = (DartPropertyAccess) node.getParent();
-              if (x.getName() == node) {
-                return null;
-              }
-            }
-            if (node.getParent() instanceof DartMethodInvocation) {
-              DartMethodInvocation x = (DartMethodInvocation) node.getParent();
-              if (x.getFunctionName() == node) {
-                return null;
-              }
-            }
-            // TODO(scheglov) remove this after http://code.google.com/p/dart/issues/detail?id=6869
-            {
-              Source source = node.getSourceInfo().getSource();
-              if (Elements.isSourceName(source, "dart://json/json.dart/json.dart")) {
-                return null;
-              }
-            }
-            if (Objects.equal(node.getName(), name)) {
-              onError(node, ResolverErrorCode.VARIABLE_REFERENCES_SAME_NAME_IN_INITIALIZER, name,
-                  name);
-              node.markResolutionAlreadyReportedThatTheMethodCouldNotBeFound();
-            }
-            return null;
-          }
-        });
-        // do resolve
-        resolve(value);
-      }
-      // declare variable
-      VariableElement element = Elements.variableElement(enclosingElement, x, name, modifiers);
-      getContext().declare(recordElement(x, element),
-          ResolverErrorCode.DUPLICATE_LOCAL_VARIABLE_ERROR);
-      recordElement(nameNode, element);
-      return element;
-    }
-
-    @Override
-    public Element visitVariableStatement(DartVariableStatement node) {
-      resolveVariableStatement(node, false);
-      return null;
-    }
-
-    private void resolveVariableStatement(DartVariableStatement node,
-                                          boolean isImplicitlyInitialized) {
-      Type type =
-          resolveType(
-              node.getTypeNode(),
-              ASTNodes.isStaticContext(node),
-              ASTNodes.isFactoryContext(node),
-              true,
-              TypeErrorCode.NO_SUCH_TYPE,
-              TypeErrorCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS);
-      for (DartVariable variable : node.getVariables()) {
-        String name = variable.getVariableName();
-        getContext().getScope().removeDeclaredButNotReachedVariable(name);
-        Elements.setType(resolveVariable(variable, node.getModifiers()), type);
-        checkVariableStatement(node, variable, isImplicitlyInitialized);
-      }
-     }
-
-    @Override
-    public Element visitLabel(DartLabel x) {
-      DartNode parent = x.getParent();
-      if (!(parent instanceof DartSwitchMember && ((DartSwitchMember) parent).getLabels().contains(
-          x))) {
-        LabelElement labelElement;
-        DartStatement childStatement = x.getStatement();
-        while (childStatement instanceof DartLabel) {
-          childStatement = ((DartLabel) childStatement).getStatement();
-        }
-        if (childStatement instanceof DartSwitchStatement) {
-          labelElement = Elements.switchLabelElement(x, x.getName(), innermostFunction);
-        } else {
-          labelElement = Elements.statementLabelElement(x, x.getName(), innermostFunction);
-        }
-        recordElement(x.getLabel(), labelElement);
-        recordElement(x, labelElement);
-      }
-      x.visitChildren(this);
-      return null;
-    }
-
-    @Override
-    public Element visitFunctionExpression(DartFunctionExpression x) {
-      MethodElement element;
-      if (x.isStatement()) {
-        // Function statement names live in the outer scope.
-        element = getContext().declareFunction(x);
-        getContext().pushFunctionScope(x);
-      } else {
-        // Function expression names live in their own scope.
-        getContext().pushFunctionScope(x);
-        element = getContext().declareFunction(x);
-      }
-      // record element
-      if (x.getName() != null) {
-        recordElement(x.getName(), element);
-      }
-      recordElement(x, element);
-      // visit function
-      MethodElement previousFunction = innermostFunction;
-      innermostFunction = element;
-      {
-        DartFunction functionNode = x.getFunction();
-        EnclosingElement previousEnclosingElement = enclosingElement;
-        enclosingElement = element;
-        getContext().pushFunctionScope(x);
-        try {
-          resolveFunction(functionNode, element);
-          resolve(functionNode.getBody());
-        } finally {
-          getContext().popScope();
-          enclosingElement = previousEnclosingElement;
-        }
-      }
-      innermostFunction = previousFunction;
-      getContext().popScope();
-      return element;
-    }
-
-    @Override
-    public Element visitBlock(DartBlock x) {
-      getContext().pushScope("<block>");
-      addLabelToStatement(x);
-      // Remember names of Block variables.
-      for (DartStatement statement : x.getStatements()) {
-        if (statement instanceof DartVariableStatement) {
-          DartVariableStatement node = (DartVariableStatement) statement;
-          List<DartVariable> variables = node.getVariables();
-          for (DartVariable variable : variables) {
-            String name = variable.getVariableName();
-            getContext().getScope().addDeclaredButNotReachedVariable(name);
-          }
-        }
-      }
-      // Visit statements.
-      x.visitChildren(this);
-      getContext().popScope();
-      return null;
-    }
-
-    @Override
-    public Element visitBreakStatement(DartBreakStatement x) {
-      // Handle corner case of L: break L;
-      DartNode parent = x.getParent();
-      if (parent instanceof DartLabel && x.getLabel() != null) {
-        if (((DartLabel) parent).getLabel().getName().equals(x.getLabel().getName())) {
-          getContext().pushScope("<break>");
-          addLabelToStatement(x);
-          visitGotoStatement(x);
-          getContext().popScope();
-          return null;
-        }
-      }
-      return visitGotoStatement(x);
-    }
-
-    @Override
-    public Element visitTryStatement(DartTryStatement x) {
-      getContext().pushScope("<try>");
-      addLabelToStatement(x);
-      x.visitChildren(this);
-      getContext().popScope();
-      return null;
-    }
-
-    @Override
-    public Element visitCatchBlock(DartCatchBlock x) {
-      getContext().pushScope("<block>");
-      addLabelToStatement(x);
-      x.visitChildren(this);
-      getContext().popScope();
-      return null;
-    }
-
-    @Override
-    public Element visitDoWhileStatement(DartDoWhileStatement x) {
-      getContext().pushScope("<do>");
-      addLabelToStatement(x);
-      x.visitChildren(this);
-      getContext().popScope();
-      return null;
-    }
-
-    @Override
-    public Element visitWhileStatement(DartWhileStatement x) {
-      getContext().pushScope("<while>");
-      addLabelToStatement(x);
-      x.visitChildren(this);
-      getContext().popScope();
-      return null;
-    }
-
-    @Override
-    public Element visitIfStatement(DartIfStatement x) {
-      getContext().pushScope("<if>");
-      addLabelToStatement(x);
-      x.visitChildren(this);
-      getContext().popScope();
-      return null;
-    }
-
-    @Override
-    public Element visitForInStatement(DartForInStatement x) {
-      getContext().pushScope("<for in>");
-      addLabelToStatement(x);
-
-      x.getIterable().accept(this);
-      if (x.introducesVariable()) {
-        resolveVariableStatement(x.getVariableStatement(), true);
-      } else {
-        x.getIdentifier().accept(this);
-      }
-      x.getBody().accept(this);
-      getContext().popScope();
-      return null;
-    }
-
-    private void addLabelToStatement(DartNode x) {
-      DartNode parent = x.getParent();
-      while (parent instanceof DartLabel) {
-        DartLabel label = (DartLabel) parent;
-        LabelElement currentLabel = label.getElement();
-        getContext().getScope().addLabel(currentLabel);
-        labelsInScopes.add(currentLabel);
-        parent = parent.getParent();
-      }
-    }
-
-    @Override
-    public Element visitForStatement(DartForStatement x) {
-      getContext().pushScope("<for>");
-      addLabelToStatement(x);
-      x.visitChildren(this);
-      getContext().popScope();
-      return null;
-    }
-
-
-    @Override
-    public Element visitSwitchStatement(DartSwitchStatement x) {
-      getContext().pushScope("<switch>");
-      addLabelToStatement(x);
-      // The scope of a label on the case statement is the case statement itself. These labels
-      // need to be resolved before the continue <label>; statements can be resolved.
-      for (DartSwitchMember member : x.getMembers()) {
-        recordSwitchMemberLabel(member);
-      }
-      x.visitChildren(this);
-      getContext().popScope();
-      return null;
-    }
-
-    private boolean isValidLastSwitchCaseStatement(DartStatement statement) {
-      if (statement instanceof DartExprStmt) {
-        DartExprStmt exprStmt = (DartExprStmt) statement;
-        if (exprStmt.getExpression() instanceof DartThrowExpression) {
-          return true;
-        }
-      }
-      return statement instanceof DartBreakStatement || statement instanceof DartContinueStatement
-          || statement instanceof DartReturnStatement;
-    }
-
-    @Override
-    public Element visitSwitchMember(DartSwitchMember x) {
-      getContext().pushScope("<switch member>");
-      x.visitChildren(this);
-      getContext().popScope();
-      return null;
-    }
-    
-    @Override
-    public Element visitCase(DartCase x) {
-      super.visitCase(x);
-      // check fall-through
-      {
-        List<DartStatement> statements = x.getStatements();
-        // the last statement should be: break, continue, return, throw
-        if (!statements.isEmpty()) {
-          DartStatement lastStatement = statements.get(statements.size() - 1);
-          if (!isValidLastSwitchCaseStatement(lastStatement)) {
-            onError(lastStatement, ResolverErrorCode.SWITCH_CASE_FALL_THROUGH);
-          }
-        }
-      }
-      return null;
-    }
-
-    private void recordSwitchMemberLabel(DartSwitchMember x) {
-      List<DartLabel> labels = x.getLabels();
-      for (DartLabel label : labels) {
-        LabelElement labelElement =  Elements.switchMemberLabelElement(label, label.getName(),
-            innermostFunction);
-        recordElement(label.getLabel(), labelElement);
-        recordElement(label, labelElement);
-        if (getContext().getScope().hasLocalLabel(label.getName())) {
-          onError(label, ResolverErrorCode.DUPLICATE_LABEL_IN_SWITCH_STATEMENT);
-        }
-        getContext().getScope().addLabel(labelElement);
-        labelsInScopes.add(labelElement);
-      }
-    }
-
-    @Override
-    public Element visitThisExpression(DartThisExpression x) {
-      if (ElementKind.of(currentHolder).equals(ElementKind.LIBRARY)) {
-        onError(x, ResolverErrorCode.THIS_ON_TOP_LEVEL);
-      } else if (currentMethod == null) {
-        onError(x, ResolverErrorCode.THIS_OUTSIDE_OF_METHOD);
-      } else if (currentMethod.getModifiers().isStatic()) {
-        onError(x, ResolverErrorCode.THIS_IN_STATIC_METHOD);
-      } else if (currentMethod.getModifiers().isFactory()) {
-        onError(x, ResolverErrorCode.THIS_IN_FACTORY_CONSTRUCTOR);
-      } else if (inInitializer) {
-        onError(x, ResolverErrorCode.THIS_IN_INITIALIZER_AS_EXPRESSION);
-      }
-      return null;
-    }
-
-    @Override
-    public Element visitDirective(DartDirective node) {
-      node.getMetadata().accept(this);
-      return super.visitDirective(node);
-    }
-
-    @Override
-    public Element visitPartOfDirective(DartPartOfDirective node) {
-      node.getMetadata().accept(this);
-      String elementName = "__library_" + node.getLibraryName();
-      Element element = context.getScope().findElement(null, elementName);
-      if (ElementKind.of(element) == ElementKind.LIBRARY) {
-        node.getName().setElement(element);
-        return element;
-      }
-      return null;
-    }
-
-    @Override
-    public Element visitSuperExpression(DartSuperExpression x) {
-      if (ElementKind.of(currentHolder).equals(ElementKind.LIBRARY)) {
-        onError(x, ResolverErrorCode.SUPER_ON_TOP_LEVEL);
-      } else if (currentMethod == null) {
-        onError(x, ResolverErrorCode.SUPER_OUTSIDE_OF_METHOD);
-      } else if (currentMethod.getModifiers().isStatic()) {
-        onError(x, ResolverErrorCode.SUPER_IN_STATIC_METHOD);
-      } else if  (currentMethod.getModifiers().isFactory()) {
-        onError(x, ResolverErrorCode.SUPER_IN_FACTORY_CONSTRUCTOR);
-      } else {
-        return recordElement(x, Elements.superElement(
-            x, ((ClassElement) currentHolder).getSupertype().getElement()));
-      }
-      return null;
-    }
-
-    @Override
-    public Element visitSuperConstructorInvocation(DartSuperConstructorInvocation x) {
-      visit(x.getArguments());
-      // check if correct place for super()
-      if (ElementKind.of(currentHolder) != ElementKind.CLASS || currentMethod == null
-          || !currentMethod.isConstructor()) {
-        onError(x, ResolverErrorCode.SUPER_OUTSIDE_OF_CONSTRUCTOR);
-        return recordElement(x, null);
-      }
-      InterfaceType supertype = ((ClassElement) currentHolder).getSupertype();
-      // prepare ConstructorElement
-      String name = x.getName() == null ? "" : x.getName().getName();
-      ConstructorElement element;
-      if (supertype == null) {
-        element = null;
-      } else {
-        ClassElement classElement = supertype.getElement();
-        element = Elements.lookupConstructor(classElement, name);
-        if (element != null && element.getModifiers().isFactory()) {
-          onError(x, ResolverErrorCode.NOT_GENERATIVE_SUPER_CONSTRUCTOR, name, supertype);
-        }
-        if (element == null && "".equals(name) && x.getArguments().isEmpty()
-            && Elements.needsImplicitDefaultConstructor(classElement)) {
-          element = new SyntheticDefaultConstructorElement(null, classElement, typeProvider);
-        }
-      }
-      if (element == null) {
-        onError(x, ResolverErrorCode.CANNOT_RESOLVE_SUPER_CONSTRUCTOR, name);
-      }
-      if (x.getName() != null) {
-        recordElement(x.getName(), element);
-      }
-      return recordElement(x, element);
-    }
-
-    @Override
-    public Element visitNamedExpression(DartNamedExpression node) {
-      // Intentionally skip the expression's name -- it's stored as an identifier, but doesn't need
-      // to be resolved.
-      return node.getExpression().accept(this);
-    }
-
-    @Override
-    public Element visitIdentifier(DartIdentifier x) {
-      return resolveIdentifier(x, false);
-    }
-
-    private Element resolveIdentifier(DartIdentifier x, boolean isQualifier) {
-      if (x.getParent() instanceof DartLabel) {
-        return x.getElement();
-      }
-      Scope scope = getContext().getScope();
-      String name = x.getName();
-      Element element = scope.findElement(scope.getLibrary(), name);
-      if (element == null) {
-        element = scope.findElement(scope.getLibrary(), "setter " + name);
-      }
-      if (element == null) {
-        // A private identifier could refer to a field in a different library. In this case
-        // we want to provide a more useful error message in the type analyzer.
-        if (DartIdentifier.isPrivateName(name)) {
-          Element found = scope.findElement(null, name);
-          if (found != null) {
-            Element enclosingElement = found.getEnclosingElement();
-            String referencedElementName = enclosingElement == null
-                ? name : String.format("%s.%s", enclosingElement.getName(), name);
-            onError(x, ResolverErrorCode.ILLEGAL_ACCESS_TO_PRIVATE_MEMBER,
-                            name, referencedElementName);
-          }
-        }
-        if (isStaticOrFactoryContextOrInitializer(x) && !isQualifier) {
-          if (!x.isResolutionAlreadyReportedThatTheMethodCouldNotBeFound()) {
-            onError(x, TypeErrorCode.CANNOT_BE_RESOLVED, name);
-            x.markResolutionAlreadyReportedThatTheMethodCouldNotBeFound();
-          }
-        }
-      } else if (x.getParent() instanceof DartComment) {
-      } else {
-        element = checkResolvedIdentifier(x, isQualifier, scope, name, element);
-      }
-      
-      if (ElementKind.of(element) == ElementKind.DUPLICATE) {
-        DuplicateElement duplicateElement = (DuplicateElement) element;
-        List<String> locations = duplicateElement.getLocations();
-        onError(x, ResolverErrorCode.DUPLICATE_IMPORTED_NAME, element.getName(), locations.size(),
-            locations);
-        return null;
-      }
-
-      if (inInitializer && ElementKind.of(element) == ElementKind.FIELD) {
-        if (!element.getModifiers().isStatic() && !Elements.isTopLevel(element)) {
-          onError(x, ResolverErrorCode.CANNOT_ACCESS_FIELD_IN_INIT);
-        }
-      }
-
-      if (ElementKind.of(element) == ElementKind.FIELD) {
-        FieldElement fieldElement = (FieldElement) element;
-        if (fieldElement.getModifiers().isAbstractField()) {
-          if (fieldElement.getGetter() == null && ASTNodes.inGetterContext(x)) {
-            topLevelContext.onError(x, ResolverErrorCode.FIELD_DOES_NOT_HAVE_A_GETTER);
-            x.markResolutionAlreadyReportedThatTheMethodCouldNotBeFound();
-          }
-          if (fieldElement.getSetter() == null && ASTNodes.inSetterContext(x)) {
-            topLevelContext.onError(x, ResolverErrorCode.FIELD_DOES_NOT_HAVE_A_SETTER);
-            x.markResolutionAlreadyReportedThatTheMethodCouldNotBeFound();
-          }
-        }
-      }
-
-      // May be local variable declared in lexical scope, but its declaration is not visited yet.
-      if (getContext().getScope().isDeclaredButNotReachedVariable(name)) {
-        onError(x, ResolverErrorCode.USING_LOCAL_VARIABLE_BEFORE_DECLARATION, x);
-      }
-
-      if (!isQualifier && !(x.getParent() instanceof DartComment)) {
-        switch (ElementKind.of(element)) {
-          case FUNCTION_TYPE_ALIAS:
-            onError(x, ResolverErrorCode.CANNOT_USE_TYPE, name);
-            break;
-          case TYPE_VARIABLE:
-            onError(x, ResolverErrorCode.CANNOT_USE_TYPE_VARIABLE, name);
-            break;
-          case DUPLICATE:
-            DuplicateElement duplicateElement = (DuplicateElement) element;
-            List<String> locations = duplicateElement.getLocations();
-            onError(x, ResolverErrorCode.DUPLICATE_IMPORTED_NAME, element.getName(),
-                locations.size(), locations);
-            return null;
-        }
-      }
-
-      // If we we haven't resolved the identifier, it will be normalized to
-      // this.<identifier>.
-
-      checkDeprecated(x, element);
-      return recordElement(x, element);
-    }
-
-    /**
-     * Possibly recursive check on the resolved identifier.
-     */
-    private Element checkResolvedIdentifier(DartIdentifier x, boolean isQualifier, Scope scope,
-                                            String name, Element element) {
-      switch (element.getKind()) {
-        case FIELD:
-          if (!Elements.isStaticContext(element)) {
-            if (!element.getModifiers().isConstant()) {
-              if (inInstanceVariableInitializer) {
-                onError(x, ResolverErrorCode.CANNOT_USE_INSTANCE_FIELD_IN_INSTANCE_FIELD_INITIALIZER);
-              }
-            }
-            if (ASTNodes.isStaticContext(x)) {
-              onError(x, ResolverErrorCode.ILLEGAL_FIELD_ACCESS_FROM_STATIC, name);
-            }
-            if (ASTNodes.isFactoryContext(x)) {
-              onError(x, ResolverErrorCode.ILLEGAL_FIELD_ACCESS_FROM_FACTORY, name);
-            }
-          }
-          if (isIllegalPrivateAccess(x, enclosingElement, element, x.getName())) {
-            return null;
-          }
-          break;
-        case METHOD:
-          if (ASTNodes.isStaticContext(x) && !Elements.isStaticContext(element)) {
-            onError(x, ResolverErrorCode.ILLEGAL_METHOD_ACCESS_FROM_STATIC,
-                name);
-          }
-          if (isIllegalPrivateAccess(x, enclosingElement, element, x.getName())) {
-            return null;
-          }
-          if (!element.getModifiers().isStatic() && !Elements.isTopLevel(element)) {
-            if (referencedFromInitializer(x)) {
-              onError(x, ResolverErrorCode.INSTANCE_METHOD_FROM_INITIALIZER);
-            }
-          }
-          break;
-        case CLASS:
-          if (!isQualifier) {
-            return typeProvider.getTypeType().getElement();
-          }
-          break;
-        case FUNCTION_TYPE_ALIAS:
-        case TYPE_VARIABLE:
-          return typeProvider.getTypeType().getElement();
-        default:
-          break;
-      }
-      return element;
-    }
-
-    @Override
-    public Element visitTypeNode(DartTypeNode x) {
-      // prepare ErrorCode, depends on the context
-      ErrorCode errorCode = ResolverErrorCode.NO_SUCH_TYPE;
-      ErrorCode wrongNumberErrorCode = ResolverErrorCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS;
-      {
-        DartNode p = x.getParent();
-        if (p instanceof DartTypeExpression) {
-          DartTypeExpression typeExpression = (DartTypeExpression) p;
-          if (typeExpression.getTypeNode() == x) {
-            DartNode pp = p.getParent();
-            if (pp instanceof DartBinaryExpression) {
-              Token operator = ((DartBinaryExpression) pp).getOperator();
-              if (operator == Token.AS || operator == Token.IS) {
-                errorCode = TypeErrorCode.NO_SUCH_TYPE;
-              }
-            }
-          }
-        }
-      }
-      // do Type resolve
-      return resolveType(x, ASTNodes.isStaticContext(x), ASTNodes.isFactoryContext(x), false,
-          errorCode, wrongNumberErrorCode).getElement();
-    }
-
-    @Override
-    public Element visitPropertyAccess(DartPropertyAccess x) {
-      Element qualifier = resolveQualifier(x.getRealTarget());
-      Element element = null;
-      switch (ElementKind.of(qualifier)) {
-        case CLASS:
-          // Must be a static field.
-          element = Elements.findElement(((ClassElement) qualifier), x.getPropertyName());
-          if (element == null) {
-            element = Elements.findElement(((ClassElement) qualifier), "setter " + x.getPropertyName());
-          }
-          if (isIllegalPrivateAccess(x.getName(), qualifier, element, x.getPropertyName())) {
-            // break;
-            return null;
-          }
-          switch (ElementKind.of(element)) {
-            case FIELD:
-              FieldElement field = (FieldElement) element;
-              x.setType(field.getType());
-              if (!field.getModifiers().isStatic()) {
-                onError(x.getName(), ResolverErrorCode.NOT_A_STATIC_FIELD,
-                    x.getPropertyName());
-              }
-              if (ASTNodes.inSetterContext(x)) {
-                if (field.getGetter() != null) {
-                  if (field.getSetter() == null) {
-                    onError(x.getName(), ResolverErrorCode.FIELD_DOES_NOT_HAVE_A_SETTER);
-                  }
-                }
-              }
-              if (ASTNodes.inGetterContext(x)) {
-                if (field.getSetter() != null) {
-                  if (field.getGetter() == null) {
-                    onError(x.getName(), ResolverErrorCode.FIELD_DOES_NOT_HAVE_A_GETTER);
-                  }
-                }
-              }
-              break;
-
-            case NONE:
-              x.getName().markResolutionAlreadyReportedThatTheMethodCouldNotBeFound();
-              onError(x.getName(), TypeErrorCode.CANNOT_BE_RESOLVED,
-                  x.getPropertyName());
-              break;
-
-            case METHOD:
-              MethodElement method = (MethodElement) element;
-              if (!method.getModifiers().isStatic()) {
-                onError(x.getName(), ResolverErrorCode.NOT_A_STATIC_METHOD,
-                    x.getPropertyName());
-              }
-              break;
-
-            default:
-              onError(x.getName(), ResolverErrorCode.EXPECTED_STATIC_FIELD,
-                  element.getKind());
-              break;
-          }
-          break;
-
-        case SUPER:
-          if (isIllegalPrivateAccess(x.getName(), qualifier, element, x.getPropertyName())) {
-            return null;
-          }
-          ClassElement cls = ((SuperElement) qualifier).getClassElement();
-          Member member = cls.getType().lookupMember(x.getPropertyName());
-          if (member != null) {
-            element = member.getElement();
-          }
-          switch (ElementKind.of(element)) {
-            case FIELD:
-              FieldElement field = (FieldElement) element;
-              if (field.getModifiers().isStatic()) {
-                onError(x.getName(), ResolverErrorCode.NOT_AN_INSTANCE_FIELD,
-                  x.getPropertyName());
-              }
-              break;
-            case METHOD:
-              MethodElement method = (MethodElement) element;
-              if (method.isStatic()) {
-                onError(x.getName(), ResolverErrorCode.NOT_AN_INSTANCE_FIELD,
-                  x.getPropertyName());
-              }
-              break;
-
-            case NONE:
-              onError(x.getName(), TypeErrorCode.CANNOT_BE_RESOLVED,
-                  x.getPropertyName());
-              break;
-
-            default:
-              onError(x.getName(),
-                ResolverErrorCode.EXPECTED_AN_INSTANCE_FIELD_IN_SUPER_CLASS,
-                element.getKind());
-              break;
-          }
-          break;
-
-        case LIBRARY_PREFIX:
-          // Library prefix, lookup the element in the referenced library.
-          Scope scope = ((LibraryPrefixElement) qualifier).getScope();
-          element = scope.findElement(scope.getLibrary(), x.getPropertyName());
-          if (element != null) {
-            recordElement(x.getQualifier(), element.getEnclosingElement());
-          } else {
-            onError(x, ResolverErrorCode.CANNOT_BE_RESOLVED_LIBRARY,
-                x.getPropertyName(), qualifier.getName());
-          }
-          break;
-
-        case NONE: {
-          // TODO(zundel): This is a bit awkward.  Maybe it would be better to have an
-          // ElementKind of THIS just like we have for SUPER?
-          if (x.getRealTarget() instanceof DartThisExpression) {
-            Element foundElement = Elements.findElement(currentHolder, x.getPropertyName());
-            if (foundElement != null && !foundElement.getModifiers().isStatic()) {
-              if (ElementKind.of(foundElement) == ElementKind.TYPE_VARIABLE) {
-                onError(x.getRealTarget(), ResolverErrorCode.TYPE_VARIABLE_NOT_ALLOWED_IN_IDENTIFIER);
-                break;
-              }
-              element = foundElement;
-            }
-          }
-        }
-
-        default:
-          break;
-      }
-      if (ElementKind.of(element) == ElementKind.DUPLICATE) {
-        DuplicateElement duplicateElement = (DuplicateElement) element;
-        List<String> locations = duplicateElement.getLocations();
-        onError(x.getName(), ResolverErrorCode.DUPLICATE_IMPORTED_NAME, duplicateElement.getName(),
-            locations.size(), locations);
-        return null;
-      }
-      return recordElement(x, element);
-    }
-
-    private boolean isIllegalPrivateAccess(DartNode diagnosticNode, Element qualifier,
-        Element element, String name) {
-      if (DartIdentifier.isPrivateName(name)) {
-        if (element == null) {
-          element = getContext().getScope().findElement(null, name);
-        }
-        if (!Elements.areSameLibrary(enclosingElement, element)) {
-          onError(diagnosticNode, ResolverErrorCode.ILLEGAL_ACCESS_TO_PRIVATE, name);
-          return true;
-        }
-      }
-      return false;
-    }
-
-    private Element resolveQualifier(DartNode qualifier) {
-      if (qualifier == null) {
-        return null;
-      }
-      return (qualifier instanceof DartIdentifier)
-          ? resolveIdentifier((DartIdentifier) qualifier, true)
-          : qualifier.accept(this);
-    }
-
-    @Override
-    public Element visitMethodInvocation(DartMethodInvocation x) {
-      DartIdentifier name = x.getFunctionName();
-      Element target = resolveQualifier(x.getRealTarget());
-      Element element = null;
-
-      switch (ElementKind.of(target)) {
-        case CLASS: {
-          // Must be a static method or field.
-          ClassElement classElement = (ClassElement) target;
-          element = Elements.lookupLocalMethod(classElement, x.getFunctionNameString());
-          if (element == null) {
-            element = Elements.lookupLocalField(classElement, x.getFunctionNameString());
-          }
-          if (element == null || !element.getModifiers().isStatic()) {
-            diagnoseErrorInMethodInvocation(x, classElement, element);
-          } else {
-            if (isIllegalPrivateAccess(x.getFunctionName(), target, element,
-                x.getFunctionNameString())) {
-              break;
-            }
-          }
-          break;
-        }
-
-        case SUPER: {
-          if (x.getParent() instanceof DartInitializer) {
-            onError(x, ResolverErrorCode.SUPER_METHOD_INVOCATION_IN_CONSTRUCTOR_INITIALIZER);
-          }
-          // Must be a superclass' method or field.
-          ClassElement classElement = ((SuperElement) target).getClassElement();
-          InterfaceType type = classElement.getType();
-          Member member = type.lookupMember(x.getFunctionNameString());
-          if (member != null) {
-            if (!member.getElement().getModifiers().isStatic()) {
-              element = member.getElement();
-              // Must be accessible.
-              if (!Elements.isAccessible(context.getScope().getLibrary(), element)) {
-                name.markResolutionAlreadyReportedThatTheMethodCouldNotBeFound();
-                onError(name, ResolverErrorCode.CANNOT_ACCESS_METHOD, x.getFunctionNameString());
-              }
-            }
-          }
-          break;
-        }
-
-        case LIBRARY_PREFIX:
-          // Library prefix, lookup the element in the reference library.
-          LibraryPrefixElement library = ((LibraryPrefixElement) target);
-          element = library.getScope().findElement(context.getScope().getLibrary(),
-                                                   x.getFunctionNameString());
-          if (element == null) {
-            diagnoseErrorInMethodInvocation(x, library, null);
-          } else {
-            recordElement(x.getTarget(), element.getEnclosingElement());
-            name.setElement(element);
-          }
-          break;
-      }
-
-      checkInvocationTarget(x, currentMethod, target);
-      visit(x.getArguments());
-      if (name != null) {
-        recordElement(name, element);
-      }
-      return recordElement(x, element);
-    }
-
-    @Override
-    public Element visitUnqualifiedInvocation(DartUnqualifiedInvocation x) {
-      Scope scope = getContext().getScope();
-      Element element = scope.findElement(scope.getLibrary(), x.getTarget().getName());
-      if (element == null) {
-        element = scope.findElement(scope.getLibrary(), "setter " + x.getTarget().getName());
-      }
-      ElementKind kind = ElementKind.of(element);
-      if (kind == ElementKind.DUPLICATE) {
-        DuplicateElement duplicateElement = (DuplicateElement) element;
-        List<String> locations = duplicateElement.getLocations();
-        onError(x.getTarget(), ResolverErrorCode.DUPLICATE_IMPORTED_NAME, element.getName(),
-            locations.size(), locations);
-        return null;
-      } else if (!INVOKABLE_ELEMENTS.contains(kind)) {
-        diagnoseErrorInUnqualifiedInvocation(x);
-      } else {
-        checkInvocationTarget(x, currentMethod, element);
-      }
-      if (Elements.isAbstractFieldWithoutGetter(element)) {
-        String name = element.getName();
-        if (isStaticOrFactoryContextOrInitializer(x)) {
-          onError(x.getTarget(), ResolverErrorCode.USE_ASSIGNMENT_ON_SETTER, name);
-        } else {
-          onError(x.getTarget(), TypeErrorCode.USE_ASSIGNMENT_ON_SETTER, name);
-        }
-      }
-      recordElement(x, element);
-      recordElement(x.getTarget(), element);
-      visit(x.getArguments());
-      return null;
-    }
-
-    @Override
-    public Element visitFunctionObjectInvocation(DartFunctionObjectInvocation x) {
-      x.getTarget().accept(this);
-      visit(x.getArguments());
-      return null;
-    }
-
-    @Override
-    public Element visitNewExpression(final DartNewExpression x) {
-      this.visit(x.getArguments());
-
-      Element element = x.getConstructor().accept(getContext().new Selector() {
-        // Only 'new' expressions can have a type in a property access.
-        @Override
-        public Element visitTypeNode(DartTypeNode type) {
-          ErrorCode errorCode = x.isConst() ? ResolverErrorCode.NO_SUCH_TYPE_CONST : TypeErrorCode.NO_SUCH_TYPE;
-          return recordType(type, resolveType(type, ASTNodes.isStaticContext(x),
-                                              ASTNodes.isFactoryContext(x),
-                                              false,
-                                              errorCode,
-                                              ResolverErrorCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS));
-        }
-
-        @Override public Element visitPropertyAccess(DartPropertyAccess node) {
-          Element element = node.getQualifier().accept(this);
-          if (ElementKind.of(element).equals(ElementKind.CLASS)) {
-            assert node.getQualifier() instanceof DartTypeNode;
-            recordType(node, node.getQualifier().getType());
-            return Elements.lookupConstructor(((ClassElement) element), node.getPropertyName());
-          } else {
-            return null;
-          }
-        }
-      });
-
-
-      switch (ElementKind.of(element)) {
-        case DYNAMIC:
-          return null;
-        case CLASS:
-        // Check for default constructor.
-        ClassElement classElement = (ClassElement) element;
-        element = Elements.lookupConstructor(classElement, "");
-        // If no default constructor, may be use implicit default constructor.
-        if (element == null
-            && x.getArguments().isEmpty()
-            && Elements.needsImplicitDefaultConstructor(classElement)) {
-          element = new SyntheticDefaultConstructorElement(null, classElement, typeProvider);
-        }
-        break;
-        case CONSTRUCTOR:
-          if (enclosingElement != null) {
-            if (element != null && DartIdentifier.isPrivateName(element.getName())
-                && !Elements.areSameLibrary(enclosingElement, element)) {
-              onError(x.getConstructor(), ResolverErrorCode.ILLEGAL_ACCESS_TO_PRIVATE,
-                  element.getName());
-              return null;
-            }
-          }
-        break;
-        case TYPE_VARIABLE:
-          if (x.isConst() ) {
-            onError(x.getConstructor(), ResolverErrorCode.CONST_EXPRESSION_CANT_USE_TYPE_VAR);
-          } else {
-            onError(x.getConstructor(), ResolverErrorCode.NEW_EXPRESSION_CANT_USE_TYPE_VAR);
-          }
-          return null;
-        default:
-          break;
-      }
-
-      // Will check that element is not null.
-      ConstructorElement constructor = checkIsConstructor(x, element);
-
-      // Check constructor.
-      if (constructor != null) {
-        boolean constConstructor = constructor.getModifiers().isConstant();
-        // Check for using "const" to non-const constructor.
-        if (x.isConst() && !constConstructor) {
-          onError(x, ResolverErrorCode.CONST_AND_NONCONST_CONSTRUCTOR);
-        }
-        // Check for using "const" with type variables as type arguments.
-        if (x.isConst() && constConstructor) {
-          DartTypeNode typeNode = Types.constructorTypeNode(x);
-          List<DartTypeNode> typeArguments = typeNode.getTypeArguments();
-          for (DartTypeNode typeArgument : typeArguments) {
-            if (typeArgument.getType() instanceof TypeVariable) {
-              onError(typeArgument, ResolverErrorCode.CONST_WITH_TYPE_VARIABLE);
-            }
-          }
-        }
-      }
-
-      return recordElement(x, constructor);
-    }
-
-    @Override
-    public Element visitGotoStatement(DartGotoStatement x) {
-      // Don't bother unless there's a target.
-      if (x.getTargetName() != null) {
-        Element element = getContext().getScope().findLabel(x.getTargetName(), innermostFunction);
-        if (ElementKind.of(element).equals(ElementKind.LABEL)) {
-          LabelElement labelElement = (LabelElement) element;
-          if (x instanceof DartBreakStatement
-              && labelElement.getStatementType() == LabeledStatementType.SWITCH_MEMBER_STATEMENT) {
-            onError(x.getLabel(), ResolverErrorCode.BREAK_LABEL_RESOLVES_TO_CASE_OR_DEFAULT);
-            return null;
-          }
-          if (x instanceof DartContinueStatement
-              && labelElement.getStatementType() == LabeledStatementType.SWITCH_STATEMENT) {
-            onError(x.getLabel(), ResolverErrorCode.CONTINUE_LABEL_RESOLVES_TO_SWITCH);
-            return null;
-          }
-          MethodElement enclosingFunction = (labelElement).getEnclosingFunction();
-          if (enclosingFunction == innermostFunction) {
-            referencedLabels.add(labelElement);
-            return recordElement(x, element);
-          }
-        }
-        diagnoseErrorInGotoStatement(x, element);
-      }
-      return null;
-    }
-
-    public void diagnoseErrorInGotoStatement(DartGotoStatement x, Element element) {
-      if (element == null) {
-        onError(x.getLabel(), ResolverErrorCode.CANNOT_RESOLVE_LABEL,
-            x.getTargetName());
-      } else if (ElementKind.of(element).equals(ElementKind.LABEL)) {
-        onError(x.getLabel(), ResolverErrorCode.CANNOT_ACCESS_OUTER_LABEL,
-            x.getTargetName());
-      } else {
-        onError(x.getLabel(), ResolverErrorCode.NOT_A_LABEL, x.getTargetName());
-      }
-    }
-
-    private void diagnoseErrorInMethodInvocation(DartMethodInvocation node, Element classOrLibrary,
-                                                 Element element) {
-      String name = node.getFunctionNameString();
-      ElementKind kind = ElementKind.of(element);
-      DartNode errorNode = node.getFunctionName();
-      switch (kind) {
-        case NONE:
-          switch (ElementKind.of(classOrLibrary)) {
-            case CLASS:
-              onError(errorNode, ResolverErrorCode.CANNOT_RESOLVE_METHOD_IN_CLASS, name,
-                      classOrLibrary.getName());
-              node.getFunctionName().markResolutionAlreadyReportedThatTheMethodCouldNotBeFound();
-              break;
-            case LIBRARY:
-              onError(errorNode, ResolverErrorCode.CANNOT_RESOLVE_METHOD_IN_LIBRARY, name,
-                      classOrLibrary.getName());
-              break;
-            default:
-              onError(errorNode, ResolverErrorCode.CANNOT_RESOLVE_METHOD, name);
-          }
-
-          break;
-
-        case CONSTRUCTOR:
-          onError(errorNode, ResolverErrorCode.IS_A_CONSTRUCTOR, classOrLibrary.getName(),
-              name);
-          break;
-
-        case METHOD: {
-          assert !((MethodElement) element).getModifiers().isStatic();
-          onError(errorNode, ResolverErrorCode.IS_AN_INSTANCE_METHOD,
-              classOrLibrary.getName(), name);
-          break;
-        }
-
-        case FIELD: {
-          onError(errorNode, ResolverErrorCode.IS_AN_INSTANCE_FIELD,
-              classOrLibrary.getName(), name);
-          break;
-        }
-
-        default:
-          throw context.internalError(errorNode, "Unexpected kind of element: %s", kind);
-      }
-    }
-
-    private void diagnoseErrorInUnqualifiedInvocation(DartUnqualifiedInvocation node) {
-      String name = node.getTarget().getName();
-      Scope scope = getContext().getScope();
-      Element element = scope.findElement(scope.getLibrary(), name);
-      ElementKind kind = ElementKind.of(element);
-      switch (kind) {
-        case NONE:
-          if (isStaticOrFactoryContextOrInitializer(node) || ASTNodes.isFactoryContext(node)) {
-            node.getTarget().markResolutionAlreadyReportedThatTheMethodCouldNotBeFound();
-            onError(node.getTarget(), ResolverErrorCode.CANNOT_RESOLVE_METHOD, name);
-          }
-          if (scope.findElement(null, name) != null) {
-            node.getTarget().markResolutionAlreadyReportedThatTheMethodCouldNotBeFound();
-            onError(node.getTarget(), ResolverErrorCode.CANNOT_ACCESS_METHOD, name);
-          }
-          break;
-
-        case CONSTRUCTOR:
-          onError(node, ResolverErrorCode.DID_YOU_MEAN_NEW, name, "constructor");
-          break;
-
-        case CLASS:
-          onError(node, ResolverErrorCode.DID_YOU_MEAN_NEW, name, "class");
-          break;
-
-        case TYPE_VARIABLE:
-          onError(node, ResolverErrorCode.DID_YOU_MEAN_NEW, name, "type variable");
-          break;
-
-        case FUNCTION_TYPE_ALIAS:
-          onError(node, ResolverErrorCode.CANNOT_CALL_FUNCTION_TYPE_ALIAS);
-          break;
-
-        case LIBRARY_PREFIX:
-          onError(node, ResolverErrorCode.CANNOT_CALL_LIBRARY_PREFIX);
-          break;
-
-        default:
-          throw context.internalError(node, "Unexpected kind of element: %s", kind);
-      }
-    }
-
-    private void diagnoseErrorInInitializer(DartIdentifier x) {
-      String name = x.getName();
-      Scope scope = getContext().getScope();
-      Element element = scope.findElement(scope.getLibrary(), name);
-      ElementKind kind = ElementKind.of(element);
-      switch (kind) {
-        case NONE:
-          onError(x, ResolverErrorCode.CANNOT_RESOLVE_FIELD, name);
-          break;
-
-        case FIELD:
-          FieldElement field = (FieldElement) element;
-          recordElement(x, field);
-          if (field.isStatic()) {
-            onError(x, ResolverErrorCode.CANNOT_INIT_STATIC_FIELD_IN_INITIALIZER);
-          } else if (field.getModifiers().isAbstractField()) {
-            /*
-             * If we get here then we know that this is a property accessor and not a true field.
-             * If there was a field and property accessor with the same name a name collision error
-             * would keep us from reaching this point.
-             */
-            onError(x, ResolverErrorCode.CANNOT_INIT_STATIC_FIELD_IN_INITIALIZER);
-          } else {
-            onError(x, ResolverErrorCode.INIT_FIELD_ONLY_IMMEDIATELY_SURROUNDING_CLASS);
-          }
-          break;
-
-        case METHOD:
-          onError(x, ResolverErrorCode.EXPECTED_FIELD_NOT_METHOD, name);
-          break;
-
-        case CLASS:
-          onError(x, ResolverErrorCode.EXPECTED_FIELD_NOT_CLASS, name);
-          break;
-
-        case PARAMETER:
-          onError(x, ResolverErrorCode.EXPECTED_FIELD_NOT_PARAMETER, name);
-          break;
-
-        case TYPE_VARIABLE:
-          onError(x, ResolverErrorCode.EXPECTED_FIELD_NOT_TYPE_VAR, name);
-          break;
-
-        case VARIABLE:
-        case LABEL:
-        default:
-          throw context.internalError(x, "Unexpected kind of element: %s", kind);
-      }
-    }
-
-    @Override
-    public Element visitInitializer(DartInitializer x) {
-      if (x.getName() != null) {
-        // Make sure the identifier is a local instance field.
-        FieldElement element = Elements.lookupLocalField(
-            (ClassElement) currentHolder, x.getName().getName());
-        if (element == null || element.isStatic() || element.getModifiers().isAbstractField()) {
-          diagnoseErrorInInitializer(x.getName());
-       }
-        recordElement(x.getName(), element);
-      }
-
-      assert !inInitializer;
-      DartExpression value = x.getValue();
-      if (value == null) {
-        return null;
-      }
-      inInitializer = true;
-      Element element = value.accept(this);
-      inInitializer = false;
-      return element;
-    }
-
-    @Override
-    public Element visitRedirectConstructorInvocation(DartRedirectConstructorInvocation x) {
-
-      visit(x.getArguments());
-      String name = x.getName() != null ? x.getName().getName() : "";
-      ConstructorElement element = Elements.lookupConstructor((ClassElement) currentHolder, name);
-      if (element == null) {
-        onError(x, ResolverErrorCode.CANNOT_RESOLVE_CONSTRUCTOR, name);
-      }
-      return recordElement(x, element);
-    }
-
-    @Override
-    public Element visitReturnStatement(DartReturnStatement x) {
-      if (x.getValue() != null) {
-        // Dart Spec v0.03, section 11.10.
-        // Generative constructors cannot return arbitrary expressions in the form: 'return e;'
-        // they can though have return statement in the form: 'return;'
-        if ((currentMethod == innermostFunction)
-            && Elements.isNonFactoryConstructor(currentMethod)) {
-          onError(x, ResolverErrorCode.INVALID_RETURN_IN_CONSTRUCTOR);
-        }
-        return x.getValue().accept(this);
-      }
-      return null;
-    }
-
-    @Override
-    public Element visitIntegerLiteral(DartIntegerLiteral node) {
-      recordType(node, typeProvider.getIntType());
-      return null;
-    }
-
-    @Override
-    public Element visitDoubleLiteral(DartDoubleLiteral node) {
-      recordType(node, typeProvider.getDoubleType());
-      return null;
-    }
-
-    @Override
-    public Element visitBooleanLiteral(DartBooleanLiteral node) {
-      recordType(node, typeProvider.getBoolType());
-      return null;
-    }
-
-    @Override
-    public Element visitStringLiteral(DartStringLiteral node) {
-      recordType(node, typeProvider.getStringType());
-      return null;
-    }
-
-    @Override
-    public Element visitStringInterpolation(DartStringInterpolation node) {
-      node.visitChildren(this);
-      recordType(node, typeProvider.getStringType());
-      return null;
-    }
-
-    Element recordType(DartNode node, Type type) {
-      node.setType(type);
-      return type.getElement();
-    }
-
-    @Override
-    public Element visitBinaryExpression(DartBinaryExpression node) {
-      Element lhs = resolve(node.getArg1());
-      resolve(node.getArg2());
-      if (node.getOperator().isAssignmentOperator()) {
-        switch (ElementKind.of(lhs)) {
-          case FIELD:
-          case PARAMETER:
-          case VARIABLE:
-            if (lhs.getModifiers().isFinal()) {
-              if (Elements.isFieldOfSameClassAsEnclosingConstructor(lhs, enclosingElement)) {
-                topLevelContext.onError(node.getArg1(),
-                    ResolverErrorCode.CANNOT_ASSIGN_TO_FINAL_ERROR, lhs.getName());
-              } else {
-                topLevelContext.onError(node.getArg1(), ResolverErrorCode.CANNOT_ASSIGN_TO_FINAL,
-                    lhs.getName());
-              }
-            }
-            break;
-          case METHOD:
-            if (!lhs.getModifiers().isSetter() && !lhs.getModifiers().isGetter()) {
-              topLevelContext.onError(node.getArg1(), ResolverErrorCode.CANNOT_ASSIGN_TO_METHOD,
-                  lhs.getName());
-            }
-            if (lhs.getModifiers().isSetter()) {
-              node.setElement(lhs);
-            }
-            break;
-        }
-      }
-
-      return null;
-    }
-
-    @Override
-    public Element visitUnaryExpression(DartUnaryExpression node) {
-      DartExpression arg = node.getArg();
-      Element argElement = resolve(arg);
-      if (node.getOperator().isCountOperator()) {
-        switch (ElementKind.of(argElement)) {
-          case FIELD:
-          case PARAMETER:
-          case VARIABLE:
-            if (argElement.getModifiers().isFinal()) {
-              topLevelContext.onError(arg, ResolverErrorCode.CANNOT_ASSIGN_TO_FINAL,
-                  argElement.getName());
-            }
-            break;
-        }
-      }
-      if (node.getOperator() == Token.CONDITIONAL) {
-        if (ElementKind.of(argElement) != ElementKind.PARAMETER) {
-          onError(arg, ResolverErrorCode.FORMAL_PARAMETER_NAME_EXPECTED);
-        }
-      }
-      return null;
-    }
-
-    @Override
-    public Element visitMapLiteral(DartMapLiteral node) {
-      List<DartTypeNode> originalTypeArgs = node.getTypeArguments();
-      List<DartTypeNode> typeArgs = Lists.newArrayList();
-      DartTypeNode implicitKey = new DartTypeNode(
-          new DartIdentifier("String"));
-      switch (originalTypeArgs.size()) {
-        case 1:
-          // Old (pre spec 0.11) map specification
-          typeArgs.add(implicitKey);
-          typeArgs.add(originalTypeArgs.get(0));
-          // TODO(scheglov) enable this warning
-//          topLevelContext.onError(originalTypeArgs.get(0), ResolverErrorCode.DEPRECATED_MAP_LITERAL_SYNTAX);
-          break;
-        case 2:
-          typeArgs.add(originalTypeArgs.get(0));
-          typeArgs.add(originalTypeArgs.get(1));
-          break;
-        default:
-          topLevelContext.onError(node, ResolverErrorCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS,
-                                  defaultLiteralMapType,
-                                  originalTypeArgs.size(), 1);
-          // fall through
-        case 0:
-          typeArgs.add(implicitKey);
-          DartTypeNode implicitValue = new DartTypeNode(new DartIdentifier("dynamic"));
-          typeArgs.add(implicitValue);
-          break;
-      }
-
-      InterfaceType type =
-          context.instantiateParameterizedType(
-              defaultLiteralMapType.getElement(),
-              node,
-              typeArgs,
-              ASTNodes.isStaticContext(node),
-              ASTNodes.isFactoryContext(node),
-              ResolverErrorCode.NO_SUCH_TYPE,
-              ResolverErrorCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS);
-      // instantiateParametersType() will complain for wrong number of parameters (!=2)
-      if (node.isConst()) {
-        checkTypeArgumentsInConstLiteral(typeArgs, ResolverErrorCode.CONST_MAP_WITH_TYPE_VARIABLE);
-      }
-      recordType(node, type);
-      visit(node.getEntries());
-      return null;
-    }
-
-    @Override
-    public Element visitArrayLiteral(DartArrayLiteral node) {
-      List<DartTypeNode> typeArgs = node.getTypeArguments();
-      InterfaceType type =
-          context.instantiateParameterizedType(
-              rawArrayType.getElement(),
-              node,
-              typeArgs,
-              ASTNodes.isStaticContext(node),
-              ASTNodes.isFactoryContext(node),
-              ResolverErrorCode.NO_SUCH_TYPE,
-              ResolverErrorCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS);
-      // instantiateParametersType() will complain for wrong number of parameters (!=1)
-      if (node.isConst()) {
-        checkTypeArgumentsInConstLiteral(typeArgs, ResolverErrorCode.CONST_ARRAY_WITH_TYPE_VARIABLE);
-      }
-      recordType(node, type);
-      visit(node.getExpressions());
-      return null;
-    }
-
-    private void checkTypeArgumentsInConstLiteral(List<DartTypeNode> typeArgs, ErrorCode errorCode) {
-      for (DartTypeNode typeNode : typeArgs) {
-        Type type = typeNode.getType();
-        if (type != null && type.getKind() == TypeKind.VARIABLE) {
-          onError(typeNode, errorCode);
-        }
-      }
-    }
-
-    private ConstructorElement checkIsConstructor(DartNewExpression node, Element element) {
-      if (!ElementKind.of(element).equals(ElementKind.CONSTRUCTOR)) {
-        ErrorCode errorCode = node.isConst()
-            ? ResolverErrorCode.NEW_EXPRESSION_NOT_CONST_CONSTRUCTOR
-            : TypeErrorCode.NEW_EXPRESSION_NOT_CONSTRUCTOR;
-        onError(ASTNodes.getConstructorNameNode(node), errorCode);
-        return null;
-      }
-      return (ConstructorElement) element;
-    }
-
-    private void checkConstructor(DartMethodDefinition node,
-                                  ConstructorElement superCall) {
-      ClassElement currentClass = (ClassElement) currentHolder;
-      if (superCall == null) {
-        // Look for a default constructor in our super type
-        InterfaceType supertype = currentClass.getSupertype();
-        if (supertype != null) {
-          superCall = Elements.lookupConstructor(supertype.getElement(), "");
-        }
-        if (superCall != null) {
-
-          // Do positional parameters match?
-          int superPositionalCount = Elements.getNumberOfRequiredParameters(superCall);
-          if (superPositionalCount > 0) {
-            onError(node, ResolverErrorCode.TOO_FEW_ARGUMENTS_IN_IMPLICIT_SUPER,
-                superCall.getType().toString());
-          }
-        }
-      }
-
-      if (superCall == null
-          && !currentClass.isObject()
-          && !currentClass.isObjectChild()) {
-        InterfaceType supertype = currentClass.getSupertype();
-        if (supertype != null) {
-          ClassElement superElement = supertype.getElement();
-          if (superElement != null) {
-            if (!hasDefaultConstructor(superElement)) {
-              onError(node,
-                  ResolverErrorCode.CANNOT_RESOLVE_IMPLICIT_CALL_TO_SUPER_CONSTRUCTOR,
-                  superElement.getName());
-            }
-          }
-        }
-      } else if (superCall != null
-          && node.getModifiers().isConstant()
-          && !superCall.getModifiers().isConstant()) {
-        onError(node.getName(),
-            ResolverErrorCode.CONST_CONSTRUCTOR_MUST_CALL_CONST_SUPER);
-      }
-    }
-
-    private void checkInvocationTarget(DartInvocation node,
-                                       MethodElement callSite,
-                                       Element target) {
-
-      if (ElementKind.of(target).equals(ElementKind.METHOD)) {
-        if (callSite != null && callSite.isStatic())
-          if (!target.getModifiers().isStatic() && !Elements.isTopLevel(target)) {
-            onError(node, ResolverErrorCode.INSTANCE_METHOD_FROM_STATIC);
-          }
-        if (!target.getModifiers().isStatic() && !Elements.isTopLevel(target)) {
-          if (referencedFromRedirectConstructor(node)) {
-            onError(node, ResolverErrorCode.INSTANCE_METHOD_FROM_REDIRECT);
-          } else if (referencedFromInitializer(node)) {
-            onError(node, ResolverErrorCode.INSTANCE_METHOD_FROM_INITIALIZER);
-          }
-        }
-      }
-    }
-
-    private boolean referencedFromInitializer(DartNode node) {
-      do {
-        if (node instanceof DartInitializer) {
-          return true;
-        }
-        node = node.getParent();
-      } while (node != null);
-      return false;
-    }
-
-    private boolean referencedFromRedirectConstructor(DartNode node) {
-      do {
-        if (node instanceof DartRedirectConstructorInvocation) {
-          return true;
-        }
-        node = node.getParent();
-      } while (node != null);
-      return false;
-    }
-
-    private void checkVariableStatement(DartVariableStatement node,
-                                        DartVariable variable,
-                                        boolean isImplicitlyInitialized) {
-      Modifiers modifiers = node.getModifiers();
-      if (modifiers.isFinal()) {
-        if (!isImplicitlyInitialized && (variable.getValue() == null)) {
-          onError(variable.getName(), ResolverErrorCode.CONSTANTS_MUST_BE_INITIALIZED);
-        } else if (modifiers.isStatic() && variable.getValue() != null) {
-          resolve(variable.getValue());
-          node.setType(variable.getValue().getType());
-        }
-      }
-    }
-
-    private void resolveInitializers(DartMethodDefinition node, Set<FieldElement> initializedFields) {
-      ClassElement classElement = (ClassElement) enclosingElement.getEnclosingElement();
-
-      ConstructorElement constructorElement = null;
-      boolean hasSuperInvocation = false;
-      for (DartInitializer initializer : node.getInitializers()) {
-        hasSuperInvocation |= initializer.getValue() instanceof DartSuperConstructorInvocation;
-        Element element = resolve(initializer);
-        if ((ElementKind.of(element) == ElementKind.CONSTRUCTOR) && initializer.isInvocation()) {
-          constructorElement = (ConstructorElement) element;
-        } else if (initializer.getName() != null && initializer.getName().getElement() != null
-            && initializer.getName().getElement().getModifiers() != null
-            && !initializedFields.add((FieldElement)initializer.getName().getElement())) {
-          onError(initializer, ResolverErrorCode.DUPLICATE_INITIALIZATION, initializer.getName());
-        }
-      }
-
-      // If no explicit super() invocation, then implicit call of default super-type constructor.
-      // Check that it is not factory, i.e. generative.
-      if (!hasSuperInvocation && currentHolder instanceof ClassElement) {
-        InterfaceType superType = classElement.getSupertype();
-        if (superType != null) {
-          ClassElement superElement = superType.getElement();
-          ConstructorElement superConstructor = Elements.lookupConstructor(superElement, "");
-          if (superConstructor != null && superConstructor.getModifiers().isFactory()) {
-            onError(node.getName(), ResolverErrorCode.NOT_GENERATIVE_SUPER_CONSTRUCTOR,
-                "<default>", superType);
-          }
-        }
-      }
-
-      // Look for final fields that are not initialized
-      Element methodElement = node.getElement();
-      if (classElement != null && methodElement != null
-          && !classElement.isInterface()
-          && !classElement.getModifiers().isNative()
-          && !methodElement.getModifiers().isExternal()
-          && !methodElement.getModifiers().isRedirectedConstructor()) {
-        for (Element member : classElement.getMembers()) {
-          switch (ElementKind.of(member)) {
-            case FIELD:
-              FieldElement fieldMember = (FieldElement)member;
-              if (fieldMember.getModifiers().isFinal()
-                  && !fieldMember.getModifiers().isInitialized()
-                  && !initializedFields.contains(fieldMember)) {
-                FieldNodeElement n = (FieldNodeElement)fieldMember;
-                onError(n.getNode(), ResolverErrorCode.FINAL_FIELD_MUST_BE_INITIALIZED,
-                    fieldMember.getName());
-              }
-          }
-        }
-      }
-
-      checkConstructor(node, constructorElement);
-    }
-
-    private void onError(HasSourceInfo target, ErrorCode errorCode, Object... arguments) {
-      context.onError(target, errorCode, arguments);
-    }
-
-    private void onError(SourceInfo target, ErrorCode errorCode, Object... arguments) {
-      context.onError(target, errorCode, arguments);
-    }
-
-    boolean isStaticOrFactoryContextOrInitializer(DartNode x) {
-      return ASTNodes.isStaticOrFactoryContext(x) || inInitializer;
-    }
-  }
-
-  public static class Phase implements DartCompilationPhase {
-    /**
-     * Executes element resolution on the given compilation unit.
-     *
-     * @param context The listener through which compilation errors are reported
-     *          (not <code>null</code>)
-     */
-    @Override
-    public DartUnit exec(DartUnit unit, DartCompilerContext context,
-                         CoreTypeProvider typeProvider) {
-      Scope unitScope = unit.getLibrary().getElement().getScope();
-      return new Resolver(context, unitScope, typeProvider).exec(unit);
-    }
-  }
-
-  private void checkRedirectConstructorCycle(List<ConstructorNodeElement> constructors,
-                                             ResolutionContext context) {
-    for (ConstructorNodeElement element : constructors) {
-      if (hasRedirectedConstructorCycle(element)) {
-        context.onError(element, ResolverErrorCode.REDIRECTED_CONSTRUCTOR_CYCLE);
-      }
-    }
-  }
-
-  private boolean hasRedirectedConstructorCycle(ConstructorNodeElement constructorElement) {
-    Set<ConstructorNodeElement> visited = Sets.newHashSet();
-    ConstructorNodeElement next = getNextConstructorInvocation(constructorElement);
-    while (next != null) {
-      if (visited.contains(next)) {
-        return true;
-      }
-      if (constructorElement.getName().equals(next.getName())) {
-        return true;
-      }
-      visited.add(next);
-      next = getNextConstructorInvocation(next);
-    }
-    return false;
-  }
-
-  private ConstructorNodeElement getNextConstructorInvocation(ConstructorNodeElement constructor) {
-    List<DartInitializer> inits = ((DartMethodDefinition) constructor.getNode()).getInitializers();
-    // Parser ensures that redirected constructors can be the only item in the initialization list.
-    if (inits.size() == 1) {
-      DartExpression value = inits.get(0).getValue();
-      if (value != null) {
-        Element element = value.getElement();
-        if (ElementKind.of(element).equals(ElementKind.CONSTRUCTOR)) {
-          ConstructorElement nextConstructorElement = (ConstructorElement) element;
-          ClassElement nextClass = (ClassElement) nextConstructorElement.getEnclosingElement();
-          ClassElement currentClass = (ClassElement) constructor.getEnclosingElement();
-          if (nextClass == currentClass) {
-            return (ConstructorNodeElement) nextConstructorElement;
-          }
-        }
-      }
-    }
-    return null;
-  }
-}
diff --git a/compiler/java/com/google/dart/compiler/resolver/ResolverErrorCode.java b/compiler/java/com/google/dart/compiler/resolver/ResolverErrorCode.java
deleted file mode 100644
index 1087830..0000000
--- a/compiler/java/com/google/dart/compiler/resolver/ResolverErrorCode.java
+++ /dev/null
@@ -1,269 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-package com.google.dart.compiler.resolver;
-
-import com.google.dart.compiler.ErrorCode;
-import com.google.dart.compiler.ErrorSeverity;
-import com.google.dart.compiler.SubSystem;
-
-/**
- * {@link ErrorCode}s for resolver.
- */
-public enum ResolverErrorCode implements ErrorCode {
-  BLACK_LISTED_EXTENDS("'%s' can not be used as superclass"),
-  BLACK_LISTED_IMPLEMENTS("'%s' can not be used as superinterface"),
-  BLACK_LISTED_MIXINS("'%s' can not be used as mixin"),
-  BREAK_LABEL_RESOLVES_TO_CASE_OR_DEFAULT("break label resolves to case or default statement"),
-  BUILT_IN_IDENTIFIER_AS_TYPE("Built-in identifier '%s' cannot be used as a type annotation"),
-  CANNOT_ACCESS_FIELD_IN_INIT("Cannot access an instance field in an initializer expression"),
-  CANNOT_ACCESS_METHOD(ErrorSeverity.WARNING, "Cannot access private method '%s'"),
-  CANNOT_ACCESS_OUTER_LABEL("Cannot access label %s declared in an outer function"),
-  CANNOT_ASSIGN_TO_FINAL(ErrorSeverity.WARNING, "cannot assign value to final variable \"%s\"."),
-  CANNOT_ASSIGN_TO_FINAL_ERROR("cannot assign value to final variable \"%s\"."),
-  CANNOT_ASSIGN_TO_METHOD(ErrorSeverity.WARNING, "cannot assign value to method '%s'."),
-  CANNOT_BE_RESOLVED("cannot resolve %s"),
-  // TODO(zundel): error message needs JUnit test - how to test #imports in junit?
-  CANNOT_BE_RESOLVED_LIBRARY(ErrorSeverity.WARNING, "cannot resolve %s in library %s"),
-  CANNOT_CALL_FUNCTION_TYPE_ALIAS("Function type aliases cannot be called"),
-  // TODO(zundel): error message needs JUnit test - how to test #imports in junit?
-  CANNOT_CALL_LIBRARY_PREFIX("Library prefixes cannot be called"),
-  CANNOT_DECLARE_NON_FACTORY_CONSTRUCTOR(ErrorSeverity.WARNING,
-      "Cannot declare a non-factory named constructor of another class."),
-  CANNOT_HIDE_IMPORT_PREFIX("Cannot hide import prefix '%s'"),
-  CANNOT_INIT_STATIC_FIELD_IN_INITIALIZER("Cannot initialize a static field in an initializer list"),
-  CANNOT_MIXIN_CLASS_WITH_CONSTRUCTOR("Cannot use class with constructor as a mixin."),
-  CANNOT_MIXIN_CLASS_WITH_MIXINS("Cannot use class with mixins as a mixin."),
-  CANNOT_MIXIN_CLASS_WITH_SUPER("Cannot use class with super invocation as a mixin."),
-  CANNOT_OVERRIDE_INSTANCE_MEMBER("static member cannot override instance member %s of %s"),
-  CANNOT_OVERRIDE_METHOD_NUM_REQUIRED_PARAMS(
-      "cannot override method %s from %s, wrong number of required parameters"),
-  CANNOT_OVERRIDE_METHOD_NAMED_PARAMS("cannot override method %s, named parameters don't match"),
-  CANNOT_OVERRIDE_METHOD_OPTIONAL_PARAMS("cannot override method %s, optional positional parameters don't match"),
-  CANNOT_RESOLVE_CONSTRUCTOR("cannot resolve constructor %s"),
-  CANNOT_RESOLVE_FIELD("cannot resolve field %s"),
-  CANNOT_RESOLVE_LABEL("cannot resolve label %s"),
-  CANNOT_RESOLVE_METHOD("cannot resolve method '%s'"),
-  CANNOT_RESOLVE_METHOD_IN_CLASS(ErrorSeverity.WARNING, "cannot resolve method '%s' in class '%s'"),
-  // TODO(zundel): error message needs JUnit test - how to test #imports in junit?
-  CANNOT_RESOLVE_METHOD_IN_LIBRARY("cannot resolve method '%s' in library '%s'"),
-  // TODO(zundel): To exercise this requires simulating a corrupted SDK?
-  CANNOT_RESOLVE_SDK_TYPE("cannot resolve SDK type %s"),
-  CANNOT_RESOLVE_SUPER_CONSTRUCTOR("cannot resolve super constructor '%s'"),
-  CANNOT_RESOLVE_IMPLICIT_CALL_TO_SUPER_CONSTRUCTOR(
-      "super type %s does not have a default constructor"),
-  CANNOT_USE_INSTANCE_FIELD_IN_INSTANCE_FIELD_INITIALIZER(
-      "Cannot use instance field in instance field initializer"),
-  CANNOT_USE_THIS_IN_INSTANCE_FIELD_INITIALIZER("Cannot use 'this' in instance field initializer"),
-  CANNOT_USE_TYPE("Cannot reference the type '%s' in this context"),
-  // TODO(zundel): error message needs JUnit test (reachable code?)
-  CANNOT_USE_TYPE_VARIABLE("Cannot reference the type variable '%s' in this context"),
-  CIRCULAR_REFERENCE(
-      "Circular reference detected:  compile-time constants cannot reference themselves."),
-  CONST_REQUIRES_VALUE("Constant fields must have an initial value"),
-  CONSTRUCTOR_CANNOT_BE_ABSTRACT("A constructor cannot be abstract"),
-  CONSTRUCTOR_CANNOT_BE_STATIC("A constructor cannot be static"),
-  CONSTRUCTOR_CANNOT_HAVE_RETURN_TYPE("Generative constructors cannot have return type"),
-  CONST_AND_NONCONST_CONSTRUCTOR("Cannot reference to non-const constructor."),
-  CONST_ARRAY_WITH_TYPE_VARIABLE("Const array literals cannot have a type variable as a type argument"),
-  CONST_CLASS_WITH_INHERITED_NONFINAL_FIELDS(
-      "Const class %s cannot have non-final, inherited field %s from class %s"),
-  CONST_CLASS_WITH_NONFINAL_FIELDS("Const class %s cannot have non-final field %s"),
-  CONST_CONSTRUCTOR_CANNOT_HAVE_BODY("A const constructor cannot have a body"),
-  CONST_CONSTRUCTOR_MUST_CALL_CONST_SUPER("const constructor must call const super constructor"),
-  CONST_EXPRESSION_CANT_USE_TYPE_VAR("Const expression cannot be invoked on type variable"),
-  CONST_MAP_WITH_TYPE_VARIABLE("Const map literals cannot have a type variable as a type argument"),
-  CONST_WITH_TYPE_VARIABLE("Const constructor cannot be invoked with a type variable as a type argument"),
-  CONSTANTS_EVALUATION_EXCEPTION("Exception during constant evaluation"),
-  CONSTANTS_MUST_BE_INITIALIZED("constants must be initialized"),
-  CONTINUE_LABEL_RESOLVES_TO_SWITCH("continue label resolves to switch, must be loop or switch member"),
-  CYCLIC_CLASS("%s causes a cycle in the supertype graph"),
-  DEFAULT_CLASS_MUST_HAVE_SAME_TYPE_PARAMS(
-      "default class must have the same type parameters as declared in the interface"),
-  DEFAULT_CONSTRUCTOR_UNRESOLVED("Cannot resolve constructor with name '%s' in default class '%s'"),
-  DEFAULT_CONSTRUCTOR_NUMBER_OF_REQUIRED_PARAMETERS(
-      "Constructor '%s' in '%s' has %s required parameters, doesn't match '%s' in '%s' with %s"),
-  DEFAULT_CONSTRUCTOR_OPTIONAL_POSITIONAL_PARAMETERS(
-      "Constructor '%s' in '%s' has %s optional positional parameters, doesn't match '%s' in '%s' with %s"),
-  DEFAULT_CONSTRUCTOR_NAMED_PARAMETERS(
-      "Constructor '%s' in '%s' has named parameters %s, doesn't match '%s' in '%s' with %s"),
-  DEFAULT_MUST_SPECIFY_CLASS("default must indicate a class, not an interface"),
-  DEPRECATED_MAP_LITERAL_SYNTAX(ErrorSeverity.WARNING,
-      "Deprecated Map literal syntax. Both String (as key) and value type arguments required."),
-  DID_YOU_MEAN_NEW("%1$s is a %2$s. Did you mean (new %1$s)?"),
-  DUPLICATE_EXPORTED_NAME("%s already exported from '%s'"),
-  DUPLICATE_IMPLEMENTS_TYPE("Duplicate type in the implements clause"),
-  DUPLICATE_IMPORTED_NAME("Element '%s' is introduced by %s imports: %s"),
-  DUPLICATE_IMPORTED_NAME_TYPE(ErrorSeverity.WARNING, "Element '%s' is introduced by %s imports: %s"),
-  DUPLICATE_INITIALIZATION("Duplicate initialization of '%s'"),
-  DUPLICATE_FUNCTION_EXPRESSION("Duplicate function expression '%s'"),
-  DUPLICATE_LABEL_IN_SWITCH_STATEMENT("Duplicate label in switch statement"),
-  DUPLICATE_LOCAL_VARIABLE_ERROR("Duplicate local variable '%s'"),
-  DUPLICATE_MEMBER("Duplicate member '%s'"),
-  DUPLICATE_NAMED_ARGUMENT("Duplicate named parameter argument"),
-  DUPLICATE_PARAMETER("Duplicate parameter '%s'"),
-  DUPLICATE_TOP_LEVEL_DECLARATION("duplicate top-level declaration %s at %s"),
-  DUPLICATE_TYPE_VARIABLE("Duplicate type variable '%s'"),
-  DUPLICATE_WITH_TYPE("Duplicate type in the with clause"),
-  // TODO(zundel): error message needs JUnit test, (reachable code?)
-  EXPECTED_AN_INSTANCE_FIELD_IN_SUPER_CLASS(
-      "expected an instance field in the super class, but got %s"),
-  EXPECTED_CONSTANT_EXPRESSION("Expected constant expression"),
-  EXPECTED_CONSTANT_EXPRESSION_BOOLEAN("Expected constant expression of type bool, got %s"),
-  EXPECTED_CONSTANT_EXPRESSION_INT("Expected constant expression of type int, got %s"),
-  EXPECTED_CONSTANT_EXPRESSION_STRING("Expected constant expression of type String, got %s"),
-  EXPECTED_CONSTANT_EXPRESSION_NUMBER("Expected constant expression of type num, got %s"),
-  EXPECTED_CONSTANT_EXPRESSION_STRING_NUMBER_BOOL(
-      "Expected constant expression of type String, num or bool, got %s"),
-  EXPECTED_FIELD_NOT_CLASS("%s is a class, expected a local field"),
-  EXPECTED_FIELD_NOT_METHOD("%s is a method, expected a local field"),
-  EXPECTED_FIELD_NOT_PARAMETER("%s is a parameter, expected a local field"),
-  EXPECTED_FIELD_NOT_TYPE_VAR("%s is a type variable, expected a local field"),
-  // TODO(zundel): error message needs JUnit test (reachable code?)
-  EXPECTED_STATIC_FIELD("expected a static field, but got %s"),
-  // TODO(zundel): error message needs JUnit test, (reachable code?)
-  EXTRA_TYPE_ARGUMENT(ErrorSeverity.WARNING, "Type variables may not have type arguments"),
-  FACTORY_CANNOT_BE_CONST("A factory cannot be const"),
-  FIELD_DOES_NOT_HAVE_A_GETTER(ErrorSeverity.WARNING, "Field does not have a getter"),
-  FIELD_DOES_NOT_HAVE_A_SETTER(ErrorSeverity.WARNING, "Field does not have a setter"),
-  FINAL_FIELD_MUST_BE_INITIALIZED("The final field %s must be initialized"),
-  FORMAL_PARAMETER_NAME_EXPECTED("Formal parameter name expected"),
-  // TODO(zundel): error message needs JUnit test - how to test #imports in junit?
-  ILLEGAL_ACCESS_TO_PRIVATE(ErrorSeverity.WARNING, "'%s' is private and not defined in this library"),
-  // TODO(zundel): error message needs JUnit test - how to test #imports in junit?
-  ILLEGAL_ACCESS_TO_PRIVATE_MEMBER("ErrorSeverity.WARNING, \"%s\" refers to \"%s\" which is in a different library"),
-  ILLEGAL_FIELD_ACCESS_FROM_FACTORY("Illegal access of instance field %s from factory"),
-  ILLEGAL_FIELD_ACCESS_FROM_STATIC("Illegal access of instance field %s from static scope"),
-  ILLEGAL_METHOD_ACCESS_FROM_STATIC("Illegal access of instance method %s from static scope"),
-  INITIALIZER_ONLY_IN_GENERATIVE_CONSTRUCTOR("Initializers are allowed only in non-redirecting generative constructors"),
-  INIT_FIELD_ONLY_IMMEDIATELY_SURROUNDING_CLASS(
-      "Only fields of immediately surrounding class can be initialized"),
-  INSTANCE_METHOD_FROM_INITIALIZER("Instance methods cannot be referenced from constructor initializer"),
-  INSTANCE_METHOD_FROM_REDIRECT("Instance methods cannot be referenced from constructor redirects"),
-  INSTANCE_METHOD_FROM_STATIC("Instance methods cannot be referenced from static methods"),
-  INTERNAL_ERROR("internal error: %s"),
-  INVALID_OVERRIDE_METADATA(ErrorSeverity.WARNING, "Method marked with @override, but does not override any superclass element"),
-  INVALID_RETURN_IN_CONSTRUCTOR("Generative constructors cannot return arbitrary expressions"),
-  // TODO(zundel): error message needs JUnit test (reachable code?)
-  INVALID_TYPE_NAME_IN_CONSTRUCTOR("Invalid type in constructor name"),
-  // TODO(zundel): error message needs JUnit test (reachable code?)
-  IS_A_CONSTRUCTOR("%s.%s is a constructor, expected a  method"),
-  IS_AN_INSTANCE_FIELD(ErrorSeverity.WARNING, "%s.%s is an instance field, not a static method"),
-  IS_AN_INSTANCE_METHOD(ErrorSeverity.WARNING, "%s.%s is an instance method, not a static method"),
-  // TODO(zundel): error message needs JUnit test (requires development mode checks)
-  LIST_LITERAL_ELEMENT_TYPE(
-      "List literal element type must match declaration '%s' when type checks are on."),
-  MAIN_FUNCTION_PARAMETERS(
-      ErrorSeverity.WARNING, "Top-level function 'main' should not have parameters."),
-  // TODO(zundel): error message needs JUnit test (requires development mode checks)
-  MAP_LITERAL_ELEMENT_TYPE(
-      "Map literal element type must match declaration '%s' when type checks are on."),
-  MEMBER_WITH_NAME_OF_CLASS("Class member should not have the same name as the enclosing class"),
-  CONSTRUCTOR_WITH_NAME_OF_MEMBER(
-      "Constructor cannot have the same name as the name of a member declared in the enclosing class"),
-  CONSTRUCTOR_NAME_NOT_ENCLOSING_CLASS("Name of the immediately enclosing class expected"),
-  CONSTRUCTOR_NAME_NOT_ENCLOSING_CLASS_ID(ErrorSeverity.WARNING, "Not a valid constructor name"),
-  METHOD_MUST_HAVE_BODY(ErrorSeverity.WARNING, "Method must have a body in a non-abstract class"),
-  NAMED_PARAMETERS_CANNOT_START_WITH_UNDER("Named parameters cannot start with an '_' character"),
-  NEW_EXPRESSION_CANT_USE_TYPE_VAR(ErrorSeverity.WARNING, "New expression cannot be invoked on type variable"),
-  NEW_EXPRESSION_NOT_CONST_CONSTRUCTOR("New expression does not resolve to a const constructor"),
-  NO_SUCH_TYPE("no such type \"%s\""),
-  NO_SUCH_TYPE_CONSTRUCTOR("no such type \"%s\" in constructor"),
-  NO_SUCH_TYPE_CONST("no such type \"%s\" in constant constructor"),
-  NOT_A_CLASS("\"%s\" is not a class"),
-  NOT_A_CLASS_OR_INTERFACE("\"%s\" is not a class or interface"),
-  // TODO(zundel): error message needs JUnit test (reachable code?)
-  NOT_A_LABEL("\"%s\" is not a label"),
-  NOT_A_STATIC_FIELD(ErrorSeverity.WARNING, "\"%s\" is not a static field"),
-  NOT_A_STATIC_METHOD("\"%s\" is not a static method"),
-  NOT_A_TYPE("type \"%s\" expected, but \"%s\" found"),
-  // TODO(zundel): error message needs JUnit test (reachable code?)
-  NOT_AN_INSTANCE_FIELD("%s is not an instance field"),
-  NOT_GENERATIVE_SUPER_CONSTRUCTOR("Constructor '%s' in class '%s' is not generative."),
-  ONLY_OBJECT_MIXIN_SUPERCLASS("Only Object is allowed to be a superclass of a mixin."),
-  OPTIONAL_PARAMETERS_CANNOT_START_WITH_UNDER("Optional parameters cannot start with an '_' character"),
-  PARAMETER_INIT_OUTSIDE_CONSTRUCTOR("Parameter initializers can only be used in constructors"),
-  SUPER_METHOD_INVOCATION_IN_CONSTRUCTOR_INITIALIZER(
-      "Super method invocation is not allowed in constructor initializer"),
-  PARAMETER_INIT_STATIC_FIELD(
-      "Parameter initializer cannot be use to initialize a static field '%s'"),
-  // TODO(zundel): error message needs JUnit test (reachable code?)
-  PARAMETER_INIT_WITH_REDIR_CONSTRUCTOR(
-      "Parameter initializers cannot be used with redirected constructors"),
-  // TODO(zundel): error message needs JUnit test
-  PARAMETER_NOT_MATCH_FIELD("Could not match parameter initializer '%s' with any field"),
-  REDIRECTED_CONSTRUCTOR_CYCLE("Redirected constructor call has a cycle."),
-  REDIRECTION_CONSTRUCTOR_TARGET_TYPE(
-      "Target of redirecting factory constructor is not a type"),
-  REDIRECTION_CONSTRUCTOR_TARGET_MUST_BE_CONST(
-      "Target of constant redirecting factory constructor also should be constant"),
-  REDIRECTION_CONSTRUCTOR_CYCLE("Cycle in redirecting constructors"),
-  RETHROW_NOT_IN_CATCH("Re-throw not in a catch block"),
-  STATIC_FINAL_REQUIRES_VALUE("Static final fields must have an initial value"),
-  STATIC_METHOD_MUST_HAVE_BODY("Static method must have a body"),
-  SUPER_CLASS_IN_IMPLEMENTS("Superclass in implements clause"),
-  SUPER_CLASS_IN_WITH("Superclass in with clause"),
-  SUPER_IN_FACTORY_CONSTRUCTOR("Cannot use 'super' in a factory constructor"),
-  SUPER_IN_STATIC_METHOD("Cannot use 'super' in a static method"),
-  SUPER_OUTSIDE_OF_CONSTRUCTOR("Cannot use 'super' constructor outside of a constructor"),
-  SUPER_OUTSIDE_OF_METHOD("Cannot use 'super' outside of a method"),
-  SUPER_ON_TOP_LEVEL("Cannot use 'super' in a top-level element"),
-  SWITCH_CASE_FALL_THROUGH(ErrorSeverity.WARNING, "Switch case should end with break, continue, return or throw"),
-  THIS_IN_STATIC_METHOD("Cannot use 'this' in a static method"),
-  THIS_IN_INITIALIZER_AS_EXPRESSION("Cannot reference 'this' as expression in initializer list"),
-  THIS_ON_TOP_LEVEL("Cannot use 'this' in a top-level element"),
-  THIS_OUTSIDE_OF_METHOD("Cannot use 'this' outside of a method"),
-  THIS_IN_FACTORY_CONSTRUCTOR("Cannot use 'this' in a factory constructor"),
-  TOO_FEW_ARGUMENTS_IN_IMPLICIT_SUPER("Too few arguments in implicit super() constructor invocation in '%s'"),
-  TOO_MANY_QUALIFIERS_FOR_METHOD("Too many qualifiers for method or constructor"),
-  TOPLEVEL_FINAL_REQUIRES_VALUE("Top-level final fields must have an initial value"),
-  TYPE_VARIABLE_DOES_NOT_MATCH("Type variable %s does not match %s in default class %s."),
-  TYPE_PARAMETERS_MUST_MATCH_EXACTLY(
-      "Type parameters in default declaration must match referenced class exactly"),
-  TYPE_VARIABLE_IN_STATIC_CONTEXT(ErrorSeverity.WARNING, "cannot access type variable %s in static context"),
-  TYPE_VARIABLE_IN_STATIC_CONTEXT_ERROR("cannot access type variable %s in static context"),
-  TYPE_VARIABLE_NOT_ALLOWED_IN_IDENTIFIER(
-      "type variables are not allowed in identifier expressions"),
-  USE_ASSIGNMENT_ON_SETTER("Use assignment to set field '%s'"),
-  USING_LOCAL_VARIABLE_BEFORE_DECLARATION(ErrorSeverity.WARNING, "Using local variable '%s' before its declaration in lexical scope"),
-  VARIABLE_REFERENCES_SAME_NAME_IN_INITIALIZER("Initializer of variable \"%s\" cannot refer to the name \"%s\""),
-  WRONG_NUMBER_OF_TYPE_ARGUMENTS("%s: wrong number of type arguments (%d).  Expected %d");
-
-  private final ErrorSeverity severity;
-  private final String message;
-
-  /**
-   * Initialize a newly created error code to have the given message and ERROR severity.
-   */
-  private ResolverErrorCode(String message) {
-    this(ErrorSeverity.ERROR, message);
-  }
-
-  /**
-   * Initialize a newly created error code to have the given severity and message.
-   */
-  private ResolverErrorCode(ErrorSeverity severity, String message) {
-    this.severity = severity;
-    this.message = message;
-  }
-
-  @Override
-  public String getMessage() {
-    return message;
-  }
-
-  @Override
-  public ErrorSeverity getErrorSeverity() {
-    return severity;
-  }
-
-  @Override
-  public SubSystem getSubSystem() {
-    return SubSystem.RESOLVER;
-  }
-
-  @Override
-  public boolean needsRecompilation() {
-    return true;
-  }
-}
\ No newline at end of file
diff --git a/compiler/java/com/google/dart/compiler/resolver/Scope.java b/compiler/java/com/google/dart/compiler/resolver/Scope.java
deleted file mode 100644
index 3655f4e..0000000
--- a/compiler/java/com/google/dart/compiler/resolver/Scope.java
+++ /dev/null
@@ -1,161 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.resolver;
-
-import com.google.common.annotations.VisibleForTesting;
-import com.google.common.collect.Sets;
-import com.google.dart.compiler.ast.DartBlock;
-import com.google.dart.compiler.ast.DartIdentifier;
-import com.google.dart.compiler.ast.DartVariableStatement;
-
-import java.util.ArrayList;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-/**
- * A scope used by {@link Resolver}.
- */
-public class Scope {
-
-  private final Map<String, Element> elements = new LinkedHashMap<String, Element>();
-  private final Set<String> declaredButNotReachedVariables = Sets.newHashSet();
-  private final Scope parent;
-  private final String name;
-  private List<LabelElement> labels;
-  private LibraryElement library;
-  private boolean stateReady;
-
-  @VisibleForTesting
-  public Scope(String name, LibraryElement library, Scope parent) {
-    this.name = name;
-    this.parent = parent;
-    this.library = library;
-  }
-
-  @VisibleForTesting
-  public Scope(String name, LibraryElement element) {
-    this(name, element, null);
-  }
-
-  public void clear() {
-    elements.clear();
-  }
-
-  public Element declareElement(String name, Element element) {
-    return elements.put(name, element);
-  }
-
-  public Element findLocalElement(String name) {
-    return elements.get(name);
-  }
-
-  public Element findElement(LibraryElement fromLibrary, String name) {
-    Element element = null;
-    // Only lookup a private name in this scope if we are in the correct library
-    // or we are ignoring libraries (i.e., fromLibrary == null).
-    if (fromLibrary == null
-        || !DartIdentifier.isPrivateName(name)
-        || fromLibrary.equals(library)) {
-      element = findLocalElement(name);
-    }
-    if (element == null) {
-      if (parent != null) {
-        element = parent.findElement(fromLibrary, name);
-      } else {
-        element = null;
-      }
-    }
-    return element;
-  }
-
-  public LibraryElement getLibrary() {
-    return library;
-  }
-
-  public Element findLabel(String targetName, MethodElement innermostFunction) {
-    if (labels != null) {
-      for (LabelElement label : labels) {
-        if (label.getName().equals(targetName)
-          && innermostFunction == label.getEnclosingFunction()) {
-          return label;
-        }
-      }
-    }
-    return parent == null ? null :
-      parent.findLabel(targetName, innermostFunction);
-  }
-
-  public boolean hasLocalLabel(String labelName) {
-    if (labels != null) {
-      for (LabelElement label : labels) {
-        if (label.getName().equals(labelName)) {
-            return true;
-        }
-      }
-    }
-    return false;
-  }
-  
-  public void markStateReady() {
-    this.stateReady = true;
-  }
-  
-  public boolean isStateReady() {
-    return stateReady;
-  }
-
-  public Map<String, Element> getElements() {
-    return elements;
-  }
-
-  /**
-   * @return <code>true</code> if local variable with given name is declared in the lexical context
-   *         of {@link DartBlock}, but corresponding {@link DartVariableStatement} is not visited
-   *         yet. So, using this variable is error.
-   */
-  public boolean isDeclaredButNotReachedVariable(String name) {
-    return declaredButNotReachedVariables.contains(name);
-  }
-
-  /**
-   * @see #isDeclaredButNotReachedVariable(String)
-   */
-  public void addDeclaredButNotReachedVariable(String name) {
-    declaredButNotReachedVariables.add(name);
-  }
-
-  /**
-   * @see #isDeclaredButNotReachedVariable(String)
-   */
-  public void removeDeclaredButNotReachedVariable(String name) {
-    declaredButNotReachedVariables.remove(name);
-  }
-
-  public String getName() {
-    return name;
-  }
-
-  public Scope getParent() {
-    return parent;
-  }
-
-  public boolean isClear() {
-    return elements.size() == 0;
-  }
-
-  public void addLabel(LabelElement label) {
-    if (labels == null) {
-      labels = new ArrayList<LabelElement>();
-    }
-    labels.add(label);
-  }
-
-  @Override
-  public String toString() {
-    return getName() + " : \n" + elements.toString();
-  }
-}
diff --git a/compiler/java/com/google/dart/compiler/resolver/SuperElement.java b/compiler/java/com/google/dart/compiler/resolver/SuperElement.java
deleted file mode 100644
index 0d3a69a..0000000
--- a/compiler/java/com/google/dart/compiler/resolver/SuperElement.java
+++ /dev/null
@@ -1,13 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.resolver;
-
-/**
- * Resolved element for a Dart 'super' expression.
- */
-public interface SuperElement extends Element {
-
-  public ClassElement getClassElement();
-}
diff --git a/compiler/java/com/google/dart/compiler/resolver/SuperElementImplementation.java b/compiler/java/com/google/dart/compiler/resolver/SuperElementImplementation.java
deleted file mode 100644
index 281b877..0000000
--- a/compiler/java/com/google/dart/compiler/resolver/SuperElementImplementation.java
+++ /dev/null
@@ -1,29 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.resolver;
-
-import com.google.dart.compiler.ast.DartSuperExpression;
-
-/**
- * Resolved element for a Dart 'super' expression.
- */
-public class SuperElementImplementation extends AbstractNodeElement implements SuperElement {
-
-  public ClassElement classElement;
-
-  public SuperElementImplementation(DartSuperExpression node, ClassElement cls) {
-    super(node, "");
-    this.classElement = cls;
-  }
-
-  public ClassElement getClassElement() {
-    return classElement;
-  }
-
-  @Override
-  public ElementKind getKind() {
-    return ElementKind.SUPER;
-  }
-}
diff --git a/compiler/java/com/google/dart/compiler/resolver/SupertypeResolver.java b/compiler/java/com/google/dart/compiler/resolver/SupertypeResolver.java
deleted file mode 100644
index ed9505e..0000000
--- a/compiler/java/com/google/dart/compiler/resolver/SupertypeResolver.java
+++ /dev/null
@@ -1,217 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.resolver;
-
-import com.google.common.base.Objects;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.Sets;
-import com.google.dart.compiler.DartCompilerContext;
-import com.google.dart.compiler.Source;
-import com.google.dart.compiler.ast.ASTVisitor;
-import com.google.dart.compiler.ast.DartClass;
-import com.google.dart.compiler.ast.DartClassTypeAlias;
-import com.google.dart.compiler.ast.DartFunctionTypeAlias;
-import com.google.dart.compiler.ast.DartParameterizedTypeNode;
-import com.google.dart.compiler.ast.DartTypeNode;
-import com.google.dart.compiler.ast.DartTypeParameter;
-import com.google.dart.compiler.ast.DartUnit;
-import com.google.dart.compiler.type.InterfaceType;
-import com.google.dart.compiler.type.Type;
-import com.google.dart.compiler.type.TypeKind;
-
-import java.util.List;
-import java.util.Set;
-
-/**
- * Resolves the super class, interfaces, default implementation and
- * bounds type parameters of classes in a DartUnit.
- */
-public class SupertypeResolver {
-  private static final Set<String> BLACK_LISTED_TYPES = ImmutableSet.of(
-      "dynamic",
-      "Function",
-      "bool",
-      "num",
-      "int",
-      "double",
-      "String");
-
-  private ResolutionContext topLevelContext;
-  private CoreTypeProvider typeProvider;
-
-  public void exec(DartUnit unit, DartCompilerContext context, CoreTypeProvider typeProvider) {
-    exec(unit, context, unit.getLibrary().getElement().getScope(), typeProvider);
-  }
-
-  public void exec(DartUnit unit, DartCompilerContext compilerContext, Scope libraryScope,
-                   CoreTypeProvider typeProvider) {
-    this.typeProvider = typeProvider;
-    this.topLevelContext = new ResolutionContext(libraryScope, compilerContext, typeProvider);
-    unit.accept(new ClassElementResolver());
-  }
-
-  // Resolves super class, interfaces and default class of all classes.
-  private class ClassElementResolver extends ASTVisitor<Void> {
-    @Override
-    public Void visitClass(DartClass node) {
-      ClassElement classElement = node.getElement();
-
-      // Make sure that the type parameters are in scope before resolving the
-      // super class and interfaces
-      ResolutionContext classContext = topLevelContext.extend(classElement);
-
-      DartTypeNode superclassNode = node.getSuperclass();
-      List<DartTypeNode> mixins = node.getMixins();
-      List<DartTypeNode> interfaces = node.getInterfaces();
-
-      visitClassLike(classElement, classContext, superclassNode, mixins, interfaces,
-          node.getDefaultClass());
-      return null;
-    }
-
-    @Override
-    public Void visitClassTypeAlias(DartClassTypeAlias node) {
-      ClassElement classElement = node.getElement();
-      
-      // Make sure that the type parameters are in scope before resolving the
-      // super class and interfaces
-      ResolutionContext classContext = topLevelContext.extend(classElement);
-      
-      DartTypeNode superclassNode = node.getSuperclass();
-      List<DartTypeNode> mixins = node.getMixins();
-      List<DartTypeNode> interfaces = node.getInterfaces();
-      
-      visitClassLike(classElement, classContext, superclassNode, mixins, interfaces, null);
-      return null;
-    }
-
-    private void visitClassLike(ClassElement classElement, ResolutionContext classContext,
-        DartTypeNode superclassNode, List<DartTypeNode> mixins, List<DartTypeNode> interfaces,
-        DartParameterizedTypeNode defaultClassNode) {
-      Source source = classElement.getSourceInfo().getSource();
-      InterfaceType supertype;
-      if (superclassNode == null) {
-        supertype = typeProvider.getObjectType();
-        if (supertype.equals(classElement.getType())) {
-          // Object has no supertype.
-          supertype = null;
-        }
-      } else {
-        supertype = classContext.resolveClass(superclassNode, false, false);
-        supertype.getClass(); // Quick null check.
-      }
-      if (supertype != null) {
-        if (Elements.isTypeNode(superclassNode, BLACK_LISTED_TYPES)
-            && !Elements.isCoreLibrarySource(source)) {
-          topLevelContext.onError(
-              superclassNode,
-              ResolverErrorCode.BLACK_LISTED_EXTENDS,
-              superclassNode);
-        }
-        classElement.setSupertype(supertype);
-      } else {
-        assert classElement.getName().equals("Object") : classElement;
-      }
-
-      if (defaultClassNode != null) {
-        Element defaultClassElement = classContext.resolveName(defaultClassNode.getExpression());
-        if (ElementKind.of(defaultClassElement).equals(ElementKind.CLASS)) {
-          Elements.setDefaultClass(classElement, (InterfaceType)defaultClassElement.getType());
-          defaultClassNode.setType(defaultClassElement.getType());
-        }
-      }
-
-      if (interfaces != null) {
-        Set<InterfaceType> seenImplement = Sets.newHashSet();
-        for (DartTypeNode intNode : interfaces) {
-          InterfaceType intType = classContext.resolveInterface(intNode, false, false);
-          // May be type which can not be used as interface.
-          if (Elements.isTypeNode(intNode, BLACK_LISTED_TYPES)
-              && !Elements.isCoreLibrarySource(source)) {
-            topLevelContext.onError(intNode, ResolverErrorCode.BLACK_LISTED_IMPLEMENTS, intNode);
-            continue;
-          }
-          // May be unresolved type, error already reported, ignore.
-          if (intType.getKind() == TypeKind.DYNAMIC) {
-            continue;
-          }
-          // check for uniqueness
-          if (!classElement.isInterface()) {
-            if (seenImplement.contains(intType)) {
-              topLevelContext.onError(intNode, ResolverErrorCode.DUPLICATE_IMPLEMENTS_TYPE);
-              continue;
-            }
-            if (Objects.equal(intType, supertype)) {
-              topLevelContext.onError(intNode, ResolverErrorCode.SUPER_CLASS_IN_IMPLEMENTS);
-              continue;
-            }
-            seenImplement.add(intType);
-          }
-          // OK, add
-          Elements.addInterface(classElement, intType);
-        }
-      }
-      
-      if (mixins != null) {
-        Set<InterfaceType> seenMixin = Sets.newHashSet();
-        for (DartTypeNode mixNode : mixins) {
-          InterfaceType mixType = classContext.resolveInterface(mixNode, false, false);
-          // May be type which can not be used as interface.
-          if (Elements.isTypeNode(mixNode, BLACK_LISTED_TYPES)
-              && !Elements.isCoreLibrarySource(source)) {
-            topLevelContext.onError(mixNode, ResolverErrorCode.BLACK_LISTED_MIXINS, mixNode);
-            continue;
-          }
-          // May be unresolved type, error already reported, ignore.
-          if (mixType.getKind() == TypeKind.DYNAMIC) {
-            continue;
-          }
-          // check for uniqueness
-          if (seenMixin.contains(mixType)) {
-            topLevelContext.onError(mixNode, ResolverErrorCode.DUPLICATE_WITH_TYPE);
-            continue;
-          }
-          if (Objects.equal(mixType, supertype)) {
-            topLevelContext.onError(mixNode, ResolverErrorCode.SUPER_CLASS_IN_WITH);
-            continue;
-          }
-          seenMixin.add(mixType);
-          // OK, add
-          Elements.addMixin(classElement, mixType);
-        }
-      }
-      setBoundsOnTypeParameters(classElement.getTypeParameters(), classContext);
-    }
-
-    @Override
-    public Void visitFunctionTypeAlias(DartFunctionTypeAlias node) {
-      ResolutionContext resolutionContext = topLevelContext.extend(node.getElement());
-      Elements.addInterface(node.getElement(), typeProvider.getFunctionType());
-      setBoundsOnTypeParameters(node.getElement().getTypeParameters(), resolutionContext);
-      return null;
-    }
-  }
-
-  private void setBoundsOnTypeParameters(List<Type> typeParameters,
-                                         ResolutionContext resolutionContext) {
-    for (Type typeParameter : typeParameters) {
-      TypeVariableNodeElement variable = (TypeVariableNodeElement) typeParameter.getElement();
-      DartTypeParameter typeParameterNode = (DartTypeParameter) variable.getNode();
-      DartTypeNode boundNode = typeParameterNode.getBound();
-      if (boundNode != null) {
-        Type bound =
-            resolutionContext.resolveType(
-                boundNode,
-                false,
-                false,
-                true,
-                ResolverErrorCode.NO_SUCH_TYPE,
-                ResolverErrorCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS);
-        boundNode.setType(bound);
-      }
-    }
-  }
-
-}
diff --git a/compiler/java/com/google/dart/compiler/resolver/SyntheticDefaultConstructorElement.java b/compiler/java/com/google/dart/compiler/resolver/SyntheticDefaultConstructorElement.java
deleted file mode 100644
index 493d11b..0000000
--- a/compiler/java/com/google/dart/compiler/resolver/SyntheticDefaultConstructorElement.java
+++ /dev/null
@@ -1,137 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-package com.google.dart.compiler.resolver;
-
-import com.google.common.collect.ImmutableSet;
-import com.google.dart.compiler.ast.DartMethodDefinition;
-import com.google.dart.compiler.type.FunctionType;
-import com.google.dart.compiler.type.Type;
-import com.google.dart.compiler.type.Types;
-
-import java.util.Collections;
-import java.util.List;
-import java.util.Set;
-
-/**
- * {@link ConstructorElement} for implicit default constructor.
- */
-public class SyntheticDefaultConstructorElement extends AbstractNodeElement
-    implements
-      ConstructorNodeElement {
-  private final ClassElement enclosingClass;
-  private final FunctionType functionType;
-  private ConstructorElement defaultConstructor;
-
-  public SyntheticDefaultConstructorElement(DartMethodDefinition method,
-      ClassElement enclosingClass,
-      CoreTypeProvider typeProvider) {
-    super(method, "");
-    this.enclosingClass = enclosingClass;
-    if (typeProvider != null) {
-      this.functionType =
-          Types.makeFunctionType(
-              null,
-              typeProvider.getFunctionType().getElement(),
-              getParameters(),
-              typeProvider.getDynamicType());
-    } else {
-      functionType = null;
-    }
-  }
-
-  @Override
-  public Type getType() {
-    return functionType;
-  }
-
-  @Override
-  public ElementKind getKind() {
-    return ElementKind.CONSTRUCTOR;
-  }
-
-  @Override
-  public EnclosingElement getEnclosingElement() {
-    return enclosingClass;
-  }
-  
-  @Override
-  public String getRawName() {
-    return enclosingClass.getName();
-  }
-
-  @Override
-  public boolean isStatic() {
-    return false;
-  }
-
-  @Override
-  public boolean isConstructor() {
-    return true;
-  }
-  
-  @Override
-  public boolean isSynthetic() {
-    return true;
-  }
-  
-  @Override
-  public boolean hasBody() {
-    return false;
-  }
-
-  @Override
-  public ConstructorElement getDefaultConstructor() {
-    return defaultConstructor;
-  }
-
-  @Override
-  public ConstructorElement getRedirectingFactoryConstructor() {
-    return null;
-  }
-
-  @Override
-  public void setDefaultConstructor(ConstructorElement defaultConstructor) {
-    this.defaultConstructor = defaultConstructor;
-  }
-
-  @Override
-  public Type getReturnType() {
-    return functionType.getReturnType();
-  }
-
-  @Override
-  public List<VariableElement> getParameters() {
-    return Collections.emptyList();
-  }
-
-  @Override
-  public FunctionType getFunctionType() {
-    return functionType;
-  }
-
-  @Override
-  public ClassElement getConstructorType() {
-    return enclosingClass;
-  }
-
-  @Override
-  public boolean isInterface() {
-    return false;
-  }
-
-  @Override
-  public Iterable<Element> getMembers() {
-    return Collections.emptyList();
-  }
-
-  @Override
-  public Element lookupLocalElement(String name) {
-    return null;
-  }
-
-  @Override
-  public Set<Element> getOverridden() {
-    return ImmutableSet.of();
-  }
-}
diff --git a/compiler/java/com/google/dart/compiler/resolver/TopLevelElementBuilder.java b/compiler/java/com/google/dart/compiler/resolver/TopLevelElementBuilder.java
deleted file mode 100644
index 9e461a1..0000000
--- a/compiler/java/com/google/dart/compiler/resolver/TopLevelElementBuilder.java
+++ /dev/null
@@ -1,323 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.resolver;
-
-import com.google.common.annotations.VisibleForTesting;
-import com.google.common.collect.Lists;
-import com.google.common.collect.Maps;
-import com.google.common.collect.Sets;
-import com.google.dart.compiler.DartCompilationError;
-import com.google.dart.compiler.DartCompilerContext;
-import com.google.dart.compiler.DartCompilerListener;
-import com.google.dart.compiler.ErrorCode;
-import com.google.dart.compiler.ast.ASTVisitor;
-import com.google.dart.compiler.ast.DartClass;
-import com.google.dart.compiler.ast.DartClassTypeAlias;
-import com.google.dart.compiler.ast.DartField;
-import com.google.dart.compiler.ast.DartFieldDefinition;
-import com.google.dart.compiler.ast.DartFunctionTypeAlias;
-import com.google.dart.compiler.ast.DartIdentifier;
-import com.google.dart.compiler.ast.DartLibraryDirective;
-import com.google.dart.compiler.ast.DartMethodDefinition;
-import com.google.dart.compiler.ast.DartNode;
-import com.google.dart.compiler.ast.DartTypeParameter;
-import com.google.dart.compiler.ast.DartUnit;
-import com.google.dart.compiler.ast.LibraryExport;
-import com.google.dart.compiler.ast.LibraryImport;
-import com.google.dart.compiler.ast.LibraryUnit;
-import com.google.dart.compiler.ast.Modifiers;
-import com.google.dart.compiler.common.SourceInfo;
-import com.google.dart.compiler.type.Type;
-import com.google.dart.compiler.type.TypeVariable;
-import com.google.dart.compiler.type.Types;
-import com.google.dart.compiler.util.apache.StringUtils;
-
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-/**
- * Builds all class elements and types of a library. Once all libraries
- * of an application have built their types, the library scope per
- * library can be computed.
- */
-public class TopLevelElementBuilder {
-
-  public void exec(LibraryUnit library, DartCompilerContext context) {
-    assert library.getElement().getScope().isClear();
-    for (DartUnit unit : library.getUnits()) {
-      unit.accept(new Builder(library.getElement()));
-    }
-  }
-
-  public void exec(LibraryUnit library, DartUnit unit, DartCompilerContext context) {
-    unit.accept(new Builder(library.getElement()));
-  }
-
-  public void exec(LibraryUnit library, DartClass cls, DartCompilerContext context) {
-    cls.accept(new Builder(library.getElement()));
-  }
-
-  /**
-   * Fill the scope for this library, using its own top-level elements and elements from imported
-   * libraries.
-   */
-  public void fillInLibraryScope(LibraryUnit library, DartCompilerListener listener) {
-    fillInLibraryScope(library, listener, Sets.newHashSet());
-  }
-    
-    /**
-     * Fill the scope for this library, using its own top-level elements and elements from imported
-     * libraries.
-     */
-  private void fillInLibraryScope(LibraryUnit library, DartCompilerListener listener,
-      Set<Object> processedObjects) {
-    Scope importScope = library.getElement().getImportScope();
-    Scope scope = library.getElement().getScope();
-    
-    // We are done with this library. 
-    if (library.getElement().getScope().isStateReady()) {
-      return;
-    }
-
-    // Fill "library" scope.
-    if (processedObjects.add(library)) {
-      List<Element> exportedElements = Lists.newArrayList();
-      {
-        DartUnit selfUnit = library.getSelfDartUnit();
-        if (selfUnit != null && !selfUnit.getDirectives().isEmpty()
-            && selfUnit.getDirectives().get(0) instanceof DartLibraryDirective) {
-          DartLibraryDirective libraryDirective = (DartLibraryDirective) selfUnit.getDirectives().get(
-              0);
-          if (!libraryDirective.isObsoleteFormat()) {
-            String name = libraryDirective.getLibraryName();
-            if (name != null) {
-              String elementName = "__library_" + name;
-              scope.declareElement(elementName, library.getElement());
-            }
-          }
-        }
-      }
-      for (DartUnit unit : library.getUnits()) {
-        fillInUnitScope(unit, listener, scope, exportedElements);
-      }
-      // Remember exported elements.
-      for (Element exportedElement : exportedElements) {
-        Elements.addExportedElement(library.getElement(), exportedElement);
-      }
-    }
-
-    // Fill "import" scope.
-    Map<String, LibraryPrefixElement> libraryPrefixElements = Maps.newHashMap();
-    for (LibraryImport libraryImport : library.getImports()) {
-      if (!processedObjects.add(libraryImport)) {
-        continue;
-      }
-      LibraryUnit lib = libraryImport.getLibrary();
-      // Prepare scope for this import.
-      Scope scopeForImport;
-      String prefix = libraryImport.getPrefix();
-      {
-        if (prefix != null) {
-          // Put the prefix in the scope.
-          LibraryPrefixElement libraryPrefixElement = libraryPrefixElements.get(prefix);
-          if (libraryPrefixElement == null) {
-            libraryPrefixElement = new LibraryPrefixElementImplementation(prefix, scope);
-            libraryPrefixElements.put(prefix, libraryPrefixElement);
-            Element existingElement = scope.declareElement(prefix, libraryPrefixElement);
-            // Check for conflict between import prefix and top-level element.
-            if (existingElement != null) {
-              listener.onError(new DartCompilationError(existingElement.getNameLocation(),
-                  ResolverErrorCode.CANNOT_HIDE_IMPORT_PREFIX, prefix));
-            }
-          }
-          libraryPrefixElement.addLibrary(lib.getElement());
-          // Fill prefix scope.
-          scopeForImport = libraryPrefixElement.getScope();
-        } else {
-          scopeForImport = importScope;
-        }
-      }
-      // Prepare "lib" scope.
-      fillInLibraryScope(lib, listener, processedObjects);
-      // Fill "library" scope with element exported from "lib".
-      for (Element element : lib.getElement().getExportedElements()) {
-        String name = element.getName();
-        if (libraryImport.isVisible(name)) {
-          Element oldElement = scopeForImport.declareElement(name, element);
-          if (oldElement != null) {
-            scopeForImport.declareElement(name,
-                Elements.createDuplicateElement(oldElement, element));
-          }
-        }
-      }
-    }
-
-    // Fill "library" export scope with re-exports.
-    for (LibraryExport export : library.getExports()) {
-      if (!processedObjects.add(export)) {
-        continue;
-      }
-      LibraryUnit lib = export.getLibrary();
-      fillInLibraryScope(lib, listener, processedObjects);
-      for (Element element : lib.getElement().getExportedElements()) {
-        String name = element.getName();
-        // re-export only if not defined locally
-        if (scope.findLocalElement(name) != null) {
-          continue;
-        }
-        // check if show/hide combinators of "export" are satisfied
-        if (!export.isVisible(name)) {
-          continue;
-        }
-        // do export
-        Element oldElement = Elements.addExportedElement(library.getElement(), element);
-        if (oldElement != null && oldElement.getEnclosingElement() instanceof LibraryElement) {
-          LibraryElement oldLibrary = (LibraryElement) oldElement.getEnclosingElement();
-          SourceInfo sourceInfo = export.getSourceInfo();
-          if (sourceInfo != null) {
-            String oldLibraryName = oldLibrary.getLibraryUnit().getName();
-            listener.onError(new DartCompilationError(sourceInfo,
-                ResolverErrorCode.DUPLICATE_EXPORTED_NAME, Elements.getUserElementTitle(oldElement),
-                oldLibraryName));
-          }
-        }
-      }
-    }
-
-    // Done.
-    library.getElement().getScope().markStateReady();
-  }
-  
-  @VisibleForTesting
-  public void fillInUnitScope(DartUnit unit, DartCompilerListener listener, Scope scope,
-      List<Element> exportedElements) {
-    for (DartNode node : unit.getTopLevelNodes()) {
-      if (node instanceof DartFieldDefinition) {
-        for (DartField field : ((DartFieldDefinition) node).getFields()) {
-          declareNodeInScope(field, listener, scope, exportedElements);
-        }
-      } else {
-        declareNodeInScope(node, listener, scope, exportedElements);
-      }
-    }
-  }
-
-  void declareNodeInScope(DartNode node, DartCompilerListener listener, Scope scope,
-      List<Element> exportedElements) {
-    Element element = node.getElement();
-    String name = element.getName();
-    declare(element, listener, scope);
-    if (exportedElements != null && !DartIdentifier.isPrivateName(name)) {
-      exportedElements.add(element);
-    }
-  }
-  
-  private static void compilationError(DartCompilerListener listener, SourceInfo node, ErrorCode errorCode,
-                        Object... args) {
-    DartCompilationError error = new DartCompilationError(node, errorCode, args);
-    listener.onError(error);
-  }
-
-  private void declare(Element newElement, DartCompilerListener listener, Scope scope) {
-    String name = newElement.getName();
-    Element oldElement = scope.findLocalElement(name);
-    if (oldElement == null && newElement instanceof FieldElement) {
-      FieldElement eField = (FieldElement) newElement;
-      if (!eField.getModifiers().isAbstractField()) {
-        oldElement = scope.findLocalElement("setter " + name);
-      }
-      if (eField.getModifiers().isAbstractField()
-          && StringUtils.startsWith(name, "setter ")) {
-        Element other2 = scope.findLocalElement(StringUtils.removeStart(name, "setter "));
-        if (other2 instanceof FieldElement) {
-          FieldElement otherField = (FieldElement) other2;
-          if (!otherField.getModifiers().isAbstractField()) {
-            oldElement = otherField;
-          }
-        }
-      }
-    }
-    if (oldElement != null) {
-      reportDuplicateDeclaration(listener, oldElement, newElement);
-      reportDuplicateDeclaration(listener, newElement, oldElement);
-    }
-    scope.declareElement(name, newElement);
-  }
-  
-  /**
-   * Reports {@link ResolverErrorCode#DUPLICATE_TOP_LEVEL_DECLARATION} for given named element.
-   */
-  private void reportDuplicateDeclaration(DartCompilerListener listener, Element element,
-      Element otherElement) {
-    compilationError(listener, element.getNameLocation(),
-        ResolverErrorCode.DUPLICATE_TOP_LEVEL_DECLARATION,
-        Elements.getUserElementTitle(otherElement),
-        Elements.getRelativeElementLocation(element, otherElement));
-  }
-
-  /**
-   * Creates a ClassElement for a class.
-   */
-  private class Builder extends ASTVisitor<Void> {
-
-    private LibraryElement library;
-
-    public Builder(LibraryElement library) {
-      this.library = library;
-    }
-
-    @Override
-    public Void visitClass(DartClass node) {
-      ClassElement element = Elements.classFromNode(node, library);
-      List<DartTypeParameter> parameterNodes = node.getTypeParameters();
-      List<TypeVariable> typeVariables = Elements.makeTypeVariables(parameterNodes, element);
-      element.setType(Types.interfaceType(
-          element,
-          Collections.<Type>unmodifiableList(typeVariables)));
-      node.setElement(element);
-      node.getName().setElement(element);
-      return null;
-    }
-
-    @Override
-    public Void visitClassTypeAlias(DartClassTypeAlias node) {
-      ClassAliasElement element = Elements.classFromNode(node, library);
-      List<DartTypeParameter> parameterNodes = node.getTypeParameters();
-      List<TypeVariable> typeVariables = Elements.makeTypeVariables(parameterNodes, element);
-      element.setType(Types.interfaceType(
-          element,
-          Collections.<Type>unmodifiableList(typeVariables)));
-      node.setElement(element);
-      node.getName().setElement(element);
-      return null;
-    }
-    
-    @Override
-    public Void visitFunctionTypeAlias(DartFunctionTypeAlias node) {
-      FunctionAliasElement element = Elements.functionTypeAliasFromNode(node, library);
-      List<DartTypeParameter> parameterNodes = node.getTypeParameters();
-      element.setType(Types.functionAliasType(element,
-                                              Elements.makeTypeVariables(parameterNodes, element)));
-      node.getName().setElement(element);
-      node.setElement(element);
-      return null;
-    }
-
-    @Override
-    public Void visitMethodDefinition(DartMethodDefinition node) {
-      node.setElement(Elements.methodFromMethodNode(node, library));
-      return null;
-    }
-
-    @Override
-    public Void visitField(DartField node) {
-      Modifiers modifiers = node.getModifiers();
-      node.setElement(Elements.fieldFromNode(node, library, node.getObsoleteMetadata(), modifiers));
-      return null;
-    }
-  }
-}
diff --git a/compiler/java/com/google/dart/compiler/resolver/TypeErrorCode.java b/compiler/java/com/google/dart/compiler/resolver/TypeErrorCode.java
deleted file mode 100644
index c121dbe..0000000
--- a/compiler/java/com/google/dart/compiler/resolver/TypeErrorCode.java
+++ /dev/null
@@ -1,130 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-package com.google.dart.compiler.resolver;
-
-import com.google.dart.compiler.ErrorCode;
-import com.google.dart.compiler.ErrorSeverity;
-import com.google.dart.compiler.SubSystem;
-
-/**
- * {@link ErrorCode}s for type resolver.
- */
-public enum TypeErrorCode implements ErrorCode {
-  ASSERT_BOOL("assert requires  'bool' expression or '() -> bool' function"),
-  CANNOT_ASSIGN_TO("cannot assign to '%s'"),
-  CANNOT_BE_RESOLVED("cannot resolve %s", true),
-  CANNOT_OVERRIDE_TYPED_MEMBER("cannot override %s of %s because %s is not assignable to %s"),
-  CANNOT_OVERRIDE_METHOD_DEFAULT_VALUE("cannot override method '%s', default value doesn't match '%s'"),
-  CANNOT_OVERRIDE_METHOD_NOT_SUBTYPE("cannot override %s of %s because %s is not a subtype of %s"),
-  CONCRETE_CLASS_WITH_UNIMPLEMENTED_MEMBERS("Concrete class %s has unimplemented member(s) %s"),
-  CYCLIC_REFERENCE_TO_TYPE_VARIABLE(
-      "Invalid type expression, cyclic reference to type variable '%s'"),
-  DEPRECATED_ELEMENT(ErrorSeverity.INFO, "%s is deprecated"),
-  DEFAULT_CONSTRUCTOR_TYPES(
-      "Constructor '%s' in '%s' has parameters types (%s), doesn't match '%s' in '%s' with (%s)"),
-  DUPLICATE_NAMED_ARGUMENT("Named parameter argument already provided as positional argument"),
-  CASE_EXPRESSION_TYPE_SHOULD_NOT_HAVE_EQUALS(ErrorSeverity.ERROR,
-      "Case expression type '%s' should not implement operator =="),
-  CASE_EXPRESSIONS_SHOULD_BE_SAME_TYPE(ErrorSeverity.ERROR,
-      "All case expressions should be compiler-time constants of the same type - 'int' or 'String'. '%s' expected but '%s' found"),
-  EXPECTED_POSITIONAL_ARGUMENT("Expected positional argument of type %s before named arguments"),
-  EXTRA_ARGUMENT("extra argument"),
-  FIELD_GETTER_SETTER_SAME_STATIC("Field's getter and setter should be both static or not static"),
-  FIELD_HAS_NO_GETTER("Field '%s' has no getter"),
-  FIELD_HAS_NO_SETTER("Field '%s' has no setter"),
-  FIELD_IS_FINAL("Field '%s' is final"),
-  FOR_IN_WITH_ITERATOR_FIELD("iterator is a field, expected an iterator() method"),
-  FOR_IN_WITH_INVALID_ITERATOR_RETURN_TYPE("iterator method's return type is not assignable to %s"),
-  ILLEGAL_ACCESS_TO_PRIVATE("'%s' is private and not defined in this library"),
-  INCOMPATIBLE_TYPES_IN_HIERARCHY(ErrorSeverity.INFO,
-      "Class inherits two variations of the same interface '%s' and '%s' with parameters that are not assignable to each other."),
-  INSTANTIATION_OF_ABSTRACT_CLASS("instantiation of an abstract class '%s'"),
-  INTERFACE_HAS_NO_METHOD_NAMED("\"%s\" has no method named \"%s\""),
-  INTERFACE_HAS_NO_METHOD_NAMED_INFERRED(ErrorSeverity.INFO, "\"%s\" has no method named \"%s\""),
-  INTERNAL_ERROR("internal error: %s", true),
-  IS_STATIC_FIELD_IN("\"%s\" is a static field in \"%s\""),
-  IS_STATIC_METHOD_IN("\"%s\" is a static method in \"%s\""),
-  MAP_LITERAL_KEY_UNIQUE("Map literal keys should be unique."),
-  MEMBER_IS_A_CONSTRUCTOR("%s is a constructor in %s"),
-  MISSING_ARGUMENT("missing argument of type %s"),
-  MISSING_RETURN_VALUE("no return value; expected a value of type %s"),
-  NEW_EXPRESSION_NOT_CONSTRUCTOR("New expression does not resolve to a constructor"),
-  NO_SUCH_NAMED_PARAMETER("no such named parameter \"%s\" defined"),
-  NO_SUCH_TYPE("no such type \"%s\"", true),
-  NOT_A_FUNCTION_TYPE("\"%s\" is not a function type"),
-  NOT_A_FUNCTION_TYPE_FIELD("'%s' is a field of type '%s', not a function; remove parentheses"),
-  NOT_A_MEMBER_OF("\"%s\" is not a member of %s"),
-  NOT_A_MEMBER_OF_INFERRED(ErrorSeverity.INFO, "\"%s\" is not a member of %s"),
-  NOT_A_METHOD_IN("\"%s\" is not a method in %s"),
-  NOT_A_METHOD_IN_INFERRED(ErrorSeverity.INFO, "\"%s\" is not a method in %s"),
-  NOT_A_TYPE("type \"%s\" expected, but \"%s\" found"),
-  OPERATOR_EQUALS_BOOL_RETURN_TYPE("operator 'equals' should return bool type"),
-  OPERATOR_INDEX_ASSIGN_VOID_RETURN_TYPE("operator '[]=' must have a return type of 'void'"),
-  OPERATOR_WRONG_OPERAND_TYPE("operand of \"%s\" must be assignable to \"%s\", found \"%s\""),
-  OVERRIDING_STATIC_MEMBER("overriding static member \"%s\" of \"%s\""),
-  REDIRECTION_CONSTRUCTOR_TARGET_MUST_BE_SUBTYPE(
-      "Target type of redirecting factory constructor '%s' is not subtype of '%s'"),
-  SETTER_RETURN_TYPE("Specified return type of setter '%s' is non-void"),
-  SETTER_TYPE_MUST_BE_ASSIGNABLE("Setter type '%s' must be assignable to getter type '%s'"),
-  STATIC_MEMBER_ACCESSED_THROUGH_INSTANCE(
-      "static member %s of %s cannot be accessed through an instance"),
-  SUPERTYPE_HAS_FIELD(ErrorSeverity.ERROR, "%s is a field in %s"),
-  SUPERTYPE_HAS_METHOD(ErrorSeverity.ERROR, "%s is a method in %s"),
-  TYPE_ALIAS_CANNOT_REFERENCE_ITSELF(ErrorSeverity.ERROR,
-      "Type alias cannot reference itself directly of via other typedefs"),
-  TYPE_NOT_ASSIGNMENT_COMPATIBLE("'%s' is not assignable to '%s'"),
-  TYPE_NOT_ASSIGNMENT_COMPATIBLE_INFERRED(ErrorSeverity.INFO, "'%s' is not assignable to '%s'"),
-  USE_ASSIGNMENT_ON_SETTER("Use assignment to set field '%s'"),
-  USE_INTEGER_DIVISION(ErrorSeverity.INFO, "Use integer division ~/ instead"),
-  VOID("expression does not yield a value"),
-  WRONG_NUMBER_OF_TYPE_ARGUMENTS("%s: wrong number of type arguments (%d), Expected %d");
-
-  private final ErrorSeverity severity;
-  private final String message;
-  private final boolean needsRecompilation;
-
-  /**
-   * Initialize a newly created error code to have the given message.
-   */
-  private TypeErrorCode(String message) {
-    this(message, false);
-  }
-
-  /**
-   * Initialize a newly created error code to have the given message and compilation flag.
-   */
-  private TypeErrorCode(String message, boolean needsRecompilation) {
-    this(ErrorSeverity.WARNING, message, needsRecompilation);
-  }
-
-  private TypeErrorCode(ErrorSeverity severity, String message) {
-    this(severity, message, false);
-  }
-
-  private TypeErrorCode(ErrorSeverity severity, String message, boolean needsRecompilation) {
-    this.severity = severity;
-    this.message = message;
-    this.needsRecompilation = needsRecompilation;
-  }
-
-  @Override
-  public String getMessage() {
-    return message;
-  }
-
-  @Override
-  public ErrorSeverity getErrorSeverity() {
-    return severity;
-  }
-
-  @Override
-  public SubSystem getSubSystem() {
-    return SubSystem.STATIC_TYPE;
-  }
-
-  @Override
-  public boolean needsRecompilation() {
-    return this.needsRecompilation;
-  }
-}
diff --git a/compiler/java/com/google/dart/compiler/resolver/TypeVariableElement.java b/compiler/java/com/google/dart/compiler/resolver/TypeVariableElement.java
deleted file mode 100644
index 8287c70..0000000
--- a/compiler/java/com/google/dart/compiler/resolver/TypeVariableElement.java
+++ /dev/null
@@ -1,23 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.resolver;
-
-import com.google.dart.compiler.type.Type;
-import com.google.dart.compiler.type.TypeVariable;
-
-/**
- * Represention of a type variable.
- *
- * <p>For example, in {@code class Foo<T> { ... }}, {@code T} is a
- * type variable.
- */
-public interface TypeVariableElement extends Element {
-  // Workaround JDK 6 bug. Should @Override getType().
-  TypeVariable getTypeVariable();
-
-  Type getBound();
-
-  Element getDeclaringElement();
-}
diff --git a/compiler/java/com/google/dart/compiler/resolver/TypeVariableElementImplementation.java b/compiler/java/com/google/dart/compiler/resolver/TypeVariableElementImplementation.java
deleted file mode 100644
index 62c1a01..0000000
--- a/compiler/java/com/google/dart/compiler/resolver/TypeVariableElementImplementation.java
+++ /dev/null
@@ -1,88 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.resolver;
-
-import com.google.dart.compiler.ast.DartTypeNode;
-import com.google.dart.compiler.ast.DartTypeParameter;
-import com.google.dart.compiler.type.Type;
-import com.google.dart.compiler.type.TypeVariable;
-import com.google.dart.compiler.type.Types;
-
-/**
- * Representation of a type variable.
- * 
- * <p>
- * For example, in {@code class Foo<T> ... } , {@code T} is a type variable.
- */
-class TypeVariableElementImplementation extends AbstractNodeElement implements TypeVariableNodeElement {
-
-  private final EnclosingElement owner;
-  private TypeVariable type;
-  private Type bound;
-  private final DartTypeNode boundNode;
-
-  TypeVariableElementImplementation(String name, Type bound) {
-    this(null, name, null);
-    this.bound = bound;
-  }
-
-  TypeVariableElementImplementation(DartTypeParameter node, String name, EnclosingElement owner) {
-    super(node, name);
-    this.owner = owner;
-    this.boundNode = node != null ? node.getBound() : null;
-  }
-
-  @Override
-  public TypeVariable getType() {
-    return type;
-  }
-
-  @Override
-  public ElementKind getKind() {
-    return ElementKind.TYPE_VARIABLE;
-  }
-
-  static TypeVariableElementImplementation fromNode(DartTypeParameter node, EnclosingElement owner) {
-    TypeVariableElementImplementation element =
-        new TypeVariableElementImplementation(node, node.getName().getName(), owner);
-    element.setType(Types.typeVariable(element));
-    return element;
-  }
-
-  @Override
-  public TypeVariable getTypeVariable() {
-    return getType();
-  }
-
-  @Override
-  void setType(Type type) {
-    this.type = (TypeVariable) type;
-  }
-
-  @Override
-  public Type getBound() {
-    if (boundNode != null) {
-      return boundNode.getType();
-    }
-    // no explicit bound, try to get Object
-    if (bound == null) {
-      if (owner instanceof ClassElement) {
-        Scope libraryScope = ((ClassElement) owner).getLibrary().getScope();
-        bound = libraryScope.findElement(null, "Object").getType();
-      }
-    }
-    return bound;
-  }
-
-  @Override
-  public Element getDeclaringElement() {
-    return owner;
-  }
-
-  @Override
-  public EnclosingElement getEnclosingElement() {
-    return owner;
-  }
-}
diff --git a/compiler/java/com/google/dart/compiler/resolver/TypeVariableNodeElement.java b/compiler/java/com/google/dart/compiler/resolver/TypeVariableNodeElement.java
deleted file mode 100644
index 875aa77..0000000
--- a/compiler/java/com/google/dart/compiler/resolver/TypeVariableNodeElement.java
+++ /dev/null
@@ -1,13 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.resolver;
-
-import com.google.dart.compiler.ast.DartNode;
-
-/**
- * Extension of {@link TypeVariableElement} which is based on {@link DartNode}.
- */
-public interface TypeVariableNodeElement extends NodeElement, TypeVariableElement {
-}
diff --git a/compiler/java/com/google/dart/compiler/resolver/VariableElement.java b/compiler/java/com/google/dart/compiler/resolver/VariableElement.java
deleted file mode 100644
index 7a2b589..0000000
--- a/compiler/java/com/google/dart/compiler/resolver/VariableElement.java
+++ /dev/null
@@ -1,16 +0,0 @@
-// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.resolver;
-
-import com.google.dart.compiler.ast.DartExpression;
-
-public interface VariableElement extends Element {
-  FieldElement getParameterInitializerElement();
-
-  boolean isOptional();
-  boolean isNamed();
-
-  DartExpression getDefaultValue();
-}
diff --git a/compiler/java/com/google/dart/compiler/resolver/VariableElementImplementation.java b/compiler/java/com/google/dart/compiler/resolver/VariableElementImplementation.java
deleted file mode 100644
index 7e67b3c..0000000
--- a/compiler/java/com/google/dart/compiler/resolver/VariableElementImplementation.java
+++ /dev/null
@@ -1,96 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.resolver;
-
-import com.google.dart.compiler.ast.DartExpression;
-import com.google.dart.compiler.ast.DartNode;
-import com.google.dart.compiler.ast.Modifiers;
-import com.google.dart.compiler.common.SourceInfo;
-import com.google.dart.compiler.type.Type;
-
-class VariableElementImplementation extends AbstractNodeElement implements VariableElement {
-  private final EnclosingElement owner;
-  private final ElementKind kind;
-  private final Modifiers modifiers;
-  private final boolean isNamed;
-  private final DartExpression defaultValue;
-  private final SourceInfo nameLocation;
-
-  // The field element is set for constructor parameters of the form
-  // this.foo by the resolver.
-  private FieldElement fieldElement;
-  private Type type;
-
-  VariableElementImplementation(EnclosingElement owner,
-      DartNode node,
-      SourceInfo nameLocation,
-      String name,
-      ElementKind kind,
-      Modifiers modifiers,
-      boolean isNamed,
-      DartExpression defaultValue) {
-    super(node, name);
-    this.owner = owner;
-    this.isNamed = isNamed;
-    this.kind = kind;
-    this.modifiers = modifiers;
-    this.defaultValue = defaultValue;
-    this.nameLocation = nameLocation;
-  }
-
-  @Override
-  public ElementKind getKind() {
-    return kind;
-  }
-
-  @Override
-  public SourceInfo getNameLocation() {
-    return nameLocation;
-  }
-
-  @Override
-  public Modifiers getModifiers() {
-    return modifiers;
-  }
-
-  @Override
-  void setType(Type type) {
-    this.type = type;
-  }
-
-  @Override
-  public Type getType() {
-    return type;
-  }
-
-  @Override
-  public boolean isOptional() {
-    return modifiers.isOptional();
-  }
-  
-  @Override
-  public boolean isNamed() {
-    return isNamed;
-  }
-
-  @Override
-  public DartExpression getDefaultValue() {
-    return defaultValue;
-  }
-
-  void setParameterInitializerElement(FieldElement element) {
-    this.fieldElement = element;
-  }
-
-  @Override
-  public FieldElement getParameterInitializerElement() {
-    return fieldElement;
-  }
-
-  @Override
-  public EnclosingElement getEnclosingElement() {
-    return owner;
-  }
-}
diff --git a/compiler/java/com/google/dart/compiler/resolver/VoidElement.java b/compiler/java/com/google/dart/compiler/resolver/VoidElement.java
deleted file mode 100644
index 4d2624d..0000000
--- a/compiler/java/com/google/dart/compiler/resolver/VoidElement.java
+++ /dev/null
@@ -1,34 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.resolver;
-
-/**
- * Implementation of "void". There is no public interface for this class as Element already exposes
- * all the functionality needed.
- */
-class VoidElement extends AbstractNodeElement {
-  private VoidElement() {
-    super(null, "void");
-  }
-
-  @Override
-  public ElementKind getKind() {
-    return ElementKind.VOID;
-  }
-
-  static Element getInstance() {
-    return new VoidElement();
-  }
-
-  @Override
-  public boolean equals(Object other) {
-    return other instanceof VoidElement;
-  }
-
-  @Override
-  public int hashCode() {
-    return VoidElement.class.hashCode();
-  }
-}
diff --git a/compiler/java/com/google/dart/compiler/testing/TestCompilerConfiguration.java b/compiler/java/com/google/dart/compiler/testing/TestCompilerConfiguration.java
deleted file mode 100644
index b886fb7..0000000
--- a/compiler/java/com/google/dart/compiler/testing/TestCompilerConfiguration.java
+++ /dev/null
@@ -1,99 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.testing;
-
-import com.google.dart.compiler.CommandLineOptions.CompilerOptions;
-import com.google.dart.compiler.CompilerConfiguration;
-import com.google.dart.compiler.DartCompilationPhase;
-import com.google.dart.compiler.LibrarySource;
-import com.google.dart.compiler.PackageLibraryManager;
-import com.google.dart.compiler.UrlLibrarySource;
-import com.google.dart.compiler.metrics.CompilerMetrics;
-
-import java.io.File;
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.util.Collections;
-import java.util.List;
-
-/**
- * A mock configuration for use in tests.
- */
-public class TestCompilerConfiguration implements CompilerConfiguration {
-  private final CompilerOptions compilerOptions = new CompilerOptions();
-  private final PackageLibraryManager systemLibraryManager =
-      new PackageLibraryManager();
-
-  @Override
-  public boolean developerModeChecks() {
-    return false;
-  }
-
-  @Override
-  public boolean warningsAreFatal() {
-    return false;
-  }
-
-  @Override
-  public boolean typeErrorsAreFatal() {
-    return false;
-  }
-
-  @Override
-  public boolean resolveDespiteParseErrors() {
-    return true;
-  }
-
-  @Override
-  public boolean incremental() {
-    return false;
-  }
-
-  @Override
-  public List<DartCompilationPhase> getPhases() {
-    return Collections.emptyList();
-  }
-
-  @Override
-  public File getOutputDirectory() {
-    throw new AssertionError();
-  }
-
-  @Override
-  public CompilerMetrics getCompilerMetrics() {
-    return null;
-  }
-
-  @Override
-  public String getJvmMetricOptions() {
-    return null;
-  }
-
-  @Override
-  public LibrarySource getSystemLibraryFor(String importSpec) {
-    URI systemUri;
-    try {
-      systemUri = new URI(importSpec);
-    } catch (URISyntaxException e) {
-      throw new RuntimeException(e);
-    }
-    return new UrlLibrarySource(systemUri, this.systemLibraryManager);
-  }
-
-  @Override
-  public CompilerOptions getCompilerOptions() {
-    return compilerOptions;
-  }
-
-  @Override
-  public ErrorFormat printErrorFormat() {
-    return ErrorFormat.MACHINE;
-  }
-
-  @Override
-  public PackageLibraryManager getPackageLibraryManager() {
-    return systemLibraryManager;
-  }
-}
diff --git a/compiler/java/com/google/dart/compiler/testing/TestCompilerContext.java b/compiler/java/com/google/dart/compiler/testing/TestCompilerContext.java
deleted file mode 100644
index 9da4ecc..0000000
--- a/compiler/java/com/google/dart/compiler/testing/TestCompilerContext.java
+++ /dev/null
@@ -1,157 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.testing;
-
-import com.google.dart.compiler.CompilerConfiguration;
-import com.google.dart.compiler.DartCompilationError;
-import com.google.dart.compiler.DartCompilerContext;
-import com.google.dart.compiler.DartCompilerListener;
-import com.google.dart.compiler.DartSource;
-import com.google.dart.compiler.DefaultCompilerConfiguration;
-import com.google.dart.compiler.ErrorCode;
-import com.google.dart.compiler.ErrorSeverity;
-import com.google.dart.compiler.LibrarySource;
-import com.google.dart.compiler.Source;
-import com.google.dart.compiler.SubSystem;
-import com.google.dart.compiler.ast.DartUnit;
-import com.google.dart.compiler.ast.LibraryUnit;
-import com.google.dart.compiler.metrics.CompilerMetrics;
-
-import java.io.IOException;
-import java.io.Reader;
-import java.io.Writer;
-import java.net.URI;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.EnumSet;
-import java.util.List;
-import java.util.Set;
-
-/**
- * Common context for test cases.
- */
-public class TestCompilerContext implements DartCompilerListener, DartCompilerContext {
-
-  private final Set<EventKind> ignoredEvents;
-  final List<ErrorCode> errors;
-  private int typeErrorCount;
-  private int warningCount;
-  private int errorCount;
-  private final CompilerConfiguration compilerConfiguration = new DefaultCompilerConfiguration();
-
-  /**
-   * @param ignored list of events that will be ignored. All other events cause an AssertionError.
-   */
-  public TestCompilerContext(EventKind... ignored) {
-    EnumSet<EventKind> set = EnumSet.noneOf(EventKind.class);
-    for (EventKind kind : ignored) {
-      set.add(kind);
-    }
-    this.ignoredEvents = Collections.unmodifiableSet(set);
-    this.errors = new ArrayList<ErrorCode>();
-  }
-
-  @Override
-  public LibraryUnit getApplicationUnit() {
-    throw new AssertionError();
-  }
-
-  @Override
-  public LibraryUnit getAppLibraryUnit() {
-    throw new AssertionError();
-  }
-
-  @Override
-  public LibraryUnit getLibraryUnit(LibrarySource lib) {
-    throw new AssertionError(lib.getName());
-  }
-
-  @Override
-  public void onError(DartCompilationError event) {
-    if (event.getErrorCode().getSubSystem() == SubSystem.STATIC_TYPE) {
-      typeErrorCount++;
-      handleEvent(event, EventKind.TYPE_ERROR);
-    } else if (event.getErrorCode().getErrorSeverity() == ErrorSeverity.ERROR) {
-      errorCount++;
-      handleEvent(event, EventKind.ERROR);
-    } else if (event.getErrorCode().getErrorSeverity() == ErrorSeverity.WARNING) {
-      warningCount++;
-      handleEvent(event, EventKind.WARNING);
-    }
-  }
-
-  protected void handleEvent(DartCompilationError event, EventKind kind) {
-    errors.add(event.getErrorCode());
-    if (!ignoredEvents.contains(kind)) {
-      System.err.println("Unexpected Event: " + event + " of kind " + kind);
-      throw new AssertionError(event);
-    }
-  }
-
-  @Override
-  public Reader getArtifactReader(Source source, String part, String extension) throws IOException {
-    throw new AssertionError(source.getName() + " " + part + "." + extension);
-  }
-
-  @Override
-  public URI getArtifactUri(DartSource source, String part, String extension) {
-    throw new AssertionError(source.getName() + " " + part + "." + extension);
-  }
-
-  @Override
-  public Writer getArtifactWriter(Source source, String part, String extension) throws IOException {
-    throw new AssertionError(source.getName() + " " + part + "." + extension);
-  }
-
-  @Override
-  public boolean isOutOfDate(Source source, Source base, String extension) {
-    throw new AssertionError(source.getName() + " " + base.getName() + " " + extension);
-  }
-
-  @Override
-  public CompilerMetrics getCompilerMetrics() {
-    return null;
-  }
-
-  public int getErrorCount() {
-    return errorCount;
-  }
-
-  public int getWarningCount() {
-    return warningCount;
-  }
-
-  public int getTypeErrorCount() {
-    return typeErrorCount;
-  }
-
-  public List<ErrorCode> getErrorCodes() {
-    return errors;
-  }
-
-  @Override
-  public CompilerConfiguration getCompilerConfiguration() {
-    return compilerConfiguration;
-  }
-
-  public enum EventKind {
-    ERROR,
-    TYPE_ERROR,
-    WARNING;
-  }
-
-  @Override
-  public LibrarySource getSystemLibraryFor(String importSpec) {
-    return null;
-  }
-
-  @Override
-  public void unitAboutToCompile(DartSource source, boolean diet) {
-  }
-
-  @Override
-  public void unitCompiled(DartUnit unit) {
-  }
-}
diff --git a/compiler/java/com/google/dart/compiler/testing/TestDartArtifactProvider.java b/compiler/java/com/google/dart/compiler/testing/TestDartArtifactProvider.java
deleted file mode 100644
index 70405ae..0000000
--- a/compiler/java/com/google/dart/compiler/testing/TestDartArtifactProvider.java
+++ /dev/null
@@ -1,38 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.testing;
-
-import com.google.dart.compiler.DartArtifactProvider;
-import com.google.dart.compiler.Source;
-
-import java.io.Reader;
-import java.io.StringWriter;
-import java.io.Writer;
-import java.net.URI;
-
-/**
- * A mock artifact provider for use in tests.
- */
-public class TestDartArtifactProvider extends DartArtifactProvider {
-  @Override
-  public boolean isOutOfDate(Source source, Source base, String extension) {
-    return true;
-  }
-
-  @Override
-  public Writer getArtifactWriter(Source source, String part, String extension) {
-    return new StringWriter();
-  }
-
-  @Override
-  public URI getArtifactUri(Source source, String part, String extension) {
-    throw new AssertionError();
-  }
-
-  @Override
-  public Reader getArtifactReader(Source source, String part, String extension) {
-    return null;
-  }
-}
diff --git a/compiler/java/com/google/dart/compiler/testing/TestLibrarySource.java b/compiler/java/com/google/dart/compiler/testing/TestLibrarySource.java
deleted file mode 100644
index 82af147..0000000
--- a/compiler/java/com/google/dart/compiler/testing/TestLibrarySource.java
+++ /dev/null
@@ -1,153 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.testing;
-
-import com.google.dart.compiler.DartSource;
-import com.google.dart.compiler.LibrarySource;
-
-import java.io.Reader;
-import java.io.StringReader;
-import java.net.URI;
-import java.util.LinkedHashMap;
-import java.util.Map;
-
-/**
- * A mock library source for use in tests.
- */
-public class TestLibrarySource implements LibrarySource {
-  private abstract class TestDartSource implements DartSource {
-    private final String srcName;
-    private final URI srcUri;
-
-    private TestDartSource(String name, URI uri) {
-      this.srcName = name;
-      this.srcUri = uri;
-    }
-
-    @Override
-    public String getUniqueIdentifier() {
-      return srcUri.toString();
-    }
-
-    @Override
-    public URI getUri() {
-      return srcUri;
-    }
-
-    @Override
-    public String getName() {
-      return srcName;
-    }
-
-    @Override
-    public boolean exists() {
-      return true;
-    }
-
-    @Override
-    public long getLastModified() {
-      return 0;
-    }
-
-    @Override
-    public LibrarySource getLibrary() {
-      return TestLibrarySource.this;
-    }
-
-    @Override
-    public String getRelativePath() {
-      return srcName;
-    }
-  }
-
-  private final String name;
-  private URI uri;
-  private final Map<String, DartSource> sourceMap = new LinkedHashMap<String, DartSource>();
-
-  public TestLibrarySource(String name) {
-    this.name = name;
-    uri = URI.create(name);
-  }
-
-  @Override
-  public String getUniqueIdentifier() {
-    return uri.toString();
-  }
-
-  @Override
-  public URI getUri() {
-    return uri;
-  }
-
-  @Override
-  public Reader getSourceReader() {
-    StringBuilder sb = new StringBuilder();
-    sb.append("library ");
-    sb.append(name);
-    sb.append(";\n");
-    for (DartSource source : sourceMap.values()) {
-      sb.append("part '");
-      sb.append(source.getName());
-      sb.append("';\n");
-    }
-    return new StringReader(sb.toString());
-  }
-
-  /**
-   * Add a source file to this library.
-   * @param name the relative name (uri) of the source file.
-   * @param sourceLines the lines of the source (automatically separated by newlines)
-   */
-  public DartSource addSource(final String name, String... sourceLines) {
-    StringBuilder sb = new StringBuilder();
-    for (String line : sourceLines) {
-      sb.append(line);
-      sb.append("\n");
-    }
-    final String source = sb.toString();
-    final URI uri = URI.create(name);
-    DartSource dartSource = new TestDartSource(name, uri){
-      @Override
-      public Reader getSourceReader() {
-        return new StringReader(source);
-      }};
-    return sourceMap.put(dartSource.getName(), dartSource);
-  }
-
-  @Override
-  public String getName() {
-    return name;
-  }
-
-  @Override
-  public boolean exists() {
-    return true;
-  }
-
-  @Override
-  public long getLastModified() {
-    return 0;
-  }
-
-  @Override
-  public DartSource getSourceFor(String relPath) {
-    if (!name.equals(relPath)) {
-      return sourceMap.get(relPath);
-    }
-    
-    // Return DartSource for the library itself
-    return new TestDartSource(name, uri) {
-      @Override
-      public Reader getSourceReader() {
-        return TestLibrarySource.this.getSourceReader();
-      }
-    };
-  }
-
-  @Override
-  public LibrarySource getImportFor(String relPath) {
-    throw new AssertionError(relPath);
-  }
-}
diff --git a/compiler/java/com/google/dart/compiler/type/AbstractType.java b/compiler/java/com/google/dart/compiler/type/AbstractType.java
deleted file mode 100644
index 3a5892a..0000000
--- a/compiler/java/com/google/dart/compiler/type/AbstractType.java
+++ /dev/null
@@ -1,15 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.type;
-
-/**
- * Common superclass for all types.
- */
-abstract class AbstractType implements Type {
-  @Override
-  public TypeQuality getQuality() {
-    return TypeQuality.EXACT;
-  }
-}
diff --git a/compiler/java/com/google/dart/compiler/type/DynamicType.java b/compiler/java/com/google/dart/compiler/type/DynamicType.java
deleted file mode 100644
index 373968b..0000000
--- a/compiler/java/com/google/dart/compiler/type/DynamicType.java
+++ /dev/null
@@ -1,24 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.type;
-
-import com.google.dart.compiler.resolver.DynamicElement;
-
-import java.util.List;
-
-/**
- * Type of untyped expressions.
- */
-public interface DynamicType extends FunctionAliasType, TypeVariable, FunctionType {
-
-  @Override
-  DynamicType subst(List<Type> arguments, List<Type> parameters);
-
-  @Override
-  public DynamicElement getElement();
-
-  @Override
-  public DynamicType asRawType();
-}
diff --git a/compiler/java/com/google/dart/compiler/type/DynamicTypeImplementation.java b/compiler/java/com/google/dart/compiler/type/DynamicTypeImplementation.java
deleted file mode 100644
index f439eef..0000000
--- a/compiler/java/com/google/dart/compiler/type/DynamicTypeImplementation.java
+++ /dev/null
@@ -1,151 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.type;
-
-import com.google.common.collect.Lists;
-import com.google.dart.compiler.resolver.ClassElement;
-import com.google.dart.compiler.resolver.DynamicElement;
-import com.google.dart.compiler.resolver.Element;
-import com.google.dart.compiler.resolver.Elements;
-
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-
-/**
- * Type of untyped expressions.
- */
-class DynamicTypeImplementation extends AbstractType implements DynamicType {
-
-  @Override
-  public DynamicTypeImplementation subst(List<Type> arguments,
-                                         List<Type> parameters) {
-    return this;
-  }
-
-  @Override
-  public DynamicElement getElement() {
-    return Elements.dynamicElement();
-  }
-
-  @Override
-  public DynamicElement getTypeVariableElement() {
-    return getElement();
-  }
-
-  @Override
-  public String toString() {
-    return "dynamic";
-  }
-
-  @Override
-  public boolean equals(Object obj) {
-    return obj instanceof DynamicType;
-  }
-
-  @Override
-  public int hashCode() {
-    return DynamicType.class.hashCode();
-  }
-
-  @Override
-  public List<Type> getArguments() {
-    return Collections.<Type>emptyList();
-  }
-
-  @Override
-  public boolean isRaw() {
-    return false;
-  }
-
-  @Override
-  public boolean hasDynamicTypeArgs() {
-    return false;
-  }
-
-  @Override
-  public DynamicType asRawType() {
-    return this;
-  }
-
-  @Override
-  public TypeKind getKind() {
-    return TypeKind.DYNAMIC;
-  }
-
-  @Override
-  public Type getReturnType() {
-    return this;
-  }
-
-  @Override
-  public List<Type> getParameterTypes() {
-    return Collections.emptyList();
-  }
-
-  @Override
-  public Member lookupMember(String name) {
-    return new Member() {
-
-      @Override
-      public Type getGetterType() {
-        return DynamicTypeImplementation.this;
-      }
-
-      @Override
-      public Type getSetterType() {
-        return DynamicTypeImplementation.this;
-      }
-
-      @Override
-      public Type getType() {
-        return DynamicTypeImplementation.this;
-      }
-
-      @Override
-      public InterfaceType getHolder() {
-        return DynamicTypeImplementation.this;
-      }
-
-      @Override
-      public Element getElement() {
-        return Elements.dynamicElement();
-      }
-    };
-  }
-
-  @Override
-  public Type getRest() {
-    return null;
-  }
-
-  @Override
-  public boolean hasRest() {
-    return false;
-  }
-  
-  @Override
-  public Map<String, Type> getOptionalParameterTypes() {
-    return null;
-  }
-
-  @Override
-  public Map<String, Type> getNamedParameterTypes() {
-    return null;
-  }
-  
-  @Override
-  public void registerSubClass(ClassElement subClass) {
-  }
-  
-  @Override
-  public void unregisterSubClass(ClassElement subClass) {
-  }
-
-  @Override
-  public List<Member> lookupSubTypeMembers(String name) {
-    return Lists.newArrayList();
-  }
-}
diff --git a/compiler/java/com/google/dart/compiler/type/ExternalTypeAnalyzers.java b/compiler/java/com/google/dart/compiler/type/ExternalTypeAnalyzers.java
deleted file mode 100644
index fb6b481..0000000
--- a/compiler/java/com/google/dart/compiler/type/ExternalTypeAnalyzers.java
+++ /dev/null
@@ -1,172 +0,0 @@
-// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.type;
-
-import com.google.common.collect.Maps;
-import com.google.dart.compiler.ast.DartExpression;
-import com.google.dart.compiler.ast.DartMethodInvocation;
-import com.google.dart.compiler.ast.DartStringLiteral;
-import com.google.dart.compiler.ast.DartUnqualifiedInvocation;
-import com.google.dart.compiler.resolver.Element;
-import com.google.dart.compiler.resolver.ElementKind;
-import com.google.dart.compiler.resolver.Elements;
-import com.google.dart.compiler.resolver.LibraryElement;
-import com.google.dart.compiler.util.apache.StringUtils;
-
-import java.util.List;
-import java.util.Map;
-
-/**
- * Provides type information which cannot be inferred from source itself.
- */
-public class ExternalTypeAnalyzers {
-  private static final Map<String, String> tagToElementType = Maps.newHashMap();
-  static {
-    tagToElementType.put("A", "AnchorElement");
-    tagToElementType.put("AREA", "AreaElement");
-    tagToElementType.put("BR", "BRElement");
-    tagToElementType.put("BASE", "BaseElement");
-    tagToElementType.put("BODY", "BodyElement");
-    tagToElementType.put("BUTTON", "ButtonElement");
-    tagToElementType.put("CANVAS", "CanvasElement");
-    tagToElementType.put("DL", "DListElement");
-    tagToElementType.put("DETAILS", "DetailsElement");
-    tagToElementType.put("DIV", "DivElement");
-    tagToElementType.put("EMBED", "EmbedElement");
-    tagToElementType.put("FIELDSET", "FieldSetElement");
-    tagToElementType.put("FORM", "FormElement");
-    tagToElementType.put("HR", "HRElement");
-    tagToElementType.put("HEAD", "HeadElement");
-    tagToElementType.put("H1", "HeadingElement");
-    tagToElementType.put("H2", "HeadingElement");
-    tagToElementType.put("H3", "HeadingElement");
-    tagToElementType.put("H4", "HeadingElement");
-    tagToElementType.put("H5", "HeadingElement");
-    tagToElementType.put("H6", "HeadingElement");
-    tagToElementType.put("HTML", "HtmlElement");
-    tagToElementType.put("IFRAME", "IFrameElement");
-    tagToElementType.put("IMG", "ImageElement");
-    tagToElementType.put("INPUT", "InputElement");
-    tagToElementType.put("KEYGEN", "KeygenElement");
-    tagToElementType.put("LI", "LIElement");
-    tagToElementType.put("LABEL", "LabelElement");
-    tagToElementType.put("LEGEND", "LegendElement");
-    tagToElementType.put("LINK", "LinkElement");
-    tagToElementType.put("MAP", "MapElement");
-    tagToElementType.put("MENU", "MenuElement");
-    tagToElementType.put("METER", "MeterElement");
-    tagToElementType.put("OL", "OListElement");
-    tagToElementType.put("OBJECT", "ObjectElement");
-    tagToElementType.put("OPTGROUP", "OptGroupElement");
-    tagToElementType.put("OUTPUT", "OutputElement");
-    tagToElementType.put("P", "ParagraphElement");
-    tagToElementType.put("PARAM", "ParamElement");
-    tagToElementType.put("PRE", "PreElement");
-    tagToElementType.put("PROGRESS", "ProgressElement");
-    tagToElementType.put("SCRIPT", "ScriptElement");
-    tagToElementType.put("SELECT", "SelectElement");
-    tagToElementType.put("SOURCE", "SourceElement");
-    tagToElementType.put("SPAN", "SpanElement");
-    tagToElementType.put("STYLE", "StyleElement");
-    tagToElementType.put("CAPTION", "TableCaptionElement");
-    tagToElementType.put("TD", "TableCellElement");
-    tagToElementType.put("COL", "TableColElement");
-    tagToElementType.put("TABLE", "TableElement");
-    tagToElementType.put("TR", "TableRowElement");
-    tagToElementType.put("TEXTAREA", "TextAreaElement");
-    tagToElementType.put("TITLE", "TitleElement");
-    tagToElementType.put("TRACK", "TrackElement");
-    tagToElementType.put("UL", "UListElement");
-    tagToElementType.put("VIDEO", "VideoElement");
-    tagToElementType.put("DART_EDITOR_NO_SUCH_TYPE", "DartEditorNoSuchElement");
-  }
-
-  /**
-   * Attempts to make better guess about return type of invocation.
-   * 
-   * @return the better {@link Type} guess, may be "defaultType" if cannot make better guess.
-   */
-  public static Type resolve(Types types, DartUnqualifiedInvocation invocation, Element element,
-      Type defaultType) {
-    if (element == null) {
-      return defaultType;
-    }
-    String name = element.getName();
-    List<DartExpression> arguments = invocation.getArguments();
-    LibraryElement libraryElement = Elements.getDeclaringLibrary(element);
-    // html.query(String)
-    if ("query".equals(name) && isHtmlLibraryFunction(element)) {
-      return analyzeQuery(arguments, libraryElement, defaultType);
-    }
-    // no guess
-    return defaultType;
-  }
-
-  /**
-   * Attempts to make better guess about return type of invocation.
-   * 
-   * @return the better {@link Type} guess, may be "defaultType" if cannot make better guess.
-   */
-  public static Type resolve(Types types, DartMethodInvocation invocation, Element element,
-      Type defaultType) {
-    if (element == null) {
-      return defaultType;
-    }
-    String name = element.getName();
-    List<DartExpression> arguments = invocation.getArguments();
-    LibraryElement libraryElement = Elements.getDeclaringLibrary(element);
-    // Document.query(String)
-    if ("query".equals(name) && isDeclaredInHtmlLibrary(element)) {
-      return analyzeQuery(arguments, libraryElement, defaultType);
-    }
-    // no guess
-    return defaultType;
-  }
-
-  private static Type analyzeQuery(List<DartExpression> arguments, LibraryElement libraryElement,
-      Type defaultType) {
-    if (arguments.size() == 1 && arguments.get(0) instanceof DartStringLiteral) {
-      String selectors = ((DartStringLiteral) arguments.get(0)).getValue();
-      // if has spaces, full parsing required, because may be: E[text='warning text']
-      if (selectors.contains(" ")) {
-        return defaultType;
-      }
-      // try to extract tag
-      // http://www.w3.org/TR/CSS2/selector.html
-      String tag = selectors;
-      tag = StringUtils.substringBefore(tag, ":");
-      tag = StringUtils.substringBefore(tag, "[");
-      tag = StringUtils.substringBefore(tag, ".");
-      tag = StringUtils.substringBefore(tag, "#");
-      tag = tag.toUpperCase();
-      // prepare Element type name
-      String tagTypeName = tagToElementType.get(tag);
-      if (tagTypeName == null) {
-        return defaultType;
-      }
-      // lookup tag Element
-      Element tagTypeElement = libraryElement.lookupLocalElement(tagTypeName);
-      if (tagTypeElement == null) {
-        return defaultType;
-      }
-      // OK, we know more specific return type
-      Type tagType = tagTypeElement.getType();
-      if (tagType != null) {
-        return Types.makeInferred(tagType, TypeQuality.INFERRED_EXACT);
-      }
-    }
-    // no guess
-    return defaultType;
-  }
-
-  private static boolean isHtmlLibraryFunction(Element element) {
-    return ElementKind.of(element) == ElementKind.METHOD && isDeclaredInHtmlLibrary(element);
-  }
-
-  private static boolean isDeclaredInHtmlLibrary(Element element) {
-    LibraryElement libraryElement = Elements.getDeclaringLibrary(element);
-    return StringUtils.startsWith(libraryElement.getName(), "dart://html");
-  }
-}
diff --git a/compiler/java/com/google/dart/compiler/type/FunctionAliasType.java b/compiler/java/com/google/dart/compiler/type/FunctionAliasType.java
deleted file mode 100644
index 8682b93..0000000
--- a/compiler/java/com/google/dart/compiler/type/FunctionAliasType.java
+++ /dev/null
@@ -1,15 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.type;
-
-import com.google.dart.compiler.resolver.FunctionAliasElement;
-
-/**
- * A type corresponding to a function alias definition.
- */
-public interface FunctionAliasType extends InterfaceType {
-  @Override
-  public FunctionAliasElement getElement();
-}
diff --git a/compiler/java/com/google/dart/compiler/type/FunctionAliasTypeImplementation.java b/compiler/java/com/google/dart/compiler/type/FunctionAliasTypeImplementation.java
deleted file mode 100644
index 7f944e8..0000000
--- a/compiler/java/com/google/dart/compiler/type/FunctionAliasTypeImplementation.java
+++ /dev/null
@@ -1,36 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.type;
-
-import com.google.dart.compiler.resolver.FunctionAliasElement;
-
-import java.util.List;
-
-class FunctionAliasTypeImplementation extends InterfaceTypeImplementation
-    implements FunctionAliasType {
-
-  FunctionAliasTypeImplementation(FunctionAliasElement element, List<Type> arguments) {
-    super(element, arguments);
-  }
-
-  @Override
-  public TypeKind getKind() {
-    return TypeKind.FUNCTION_ALIAS;
-  }
-
-  @Override
-  public FunctionAliasElement getElement() {
-    return (FunctionAliasElement) super.getElement();
-  }
-
-  @Override
-  public FunctionAliasType subst(List<Type> arguments, List<Type> parameters) {
-    if (arguments.isEmpty() && parameters.isEmpty()) {
-      return this;
-    }
-    List<Type> substitutedArguments = Types.subst(getArguments(), arguments, parameters);
-    return new FunctionAliasTypeImplementation(getElement(), substitutedArguments);
-  }
-}
diff --git a/compiler/java/com/google/dart/compiler/type/FunctionType.java b/compiler/java/com/google/dart/compiler/type/FunctionType.java
deleted file mode 100644
index b8d62a3..0000000
--- a/compiler/java/com/google/dart/compiler/type/FunctionType.java
+++ /dev/null
@@ -1,47 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.type;
-
-import com.google.dart.compiler.resolver.ClassElement;
-import com.google.dart.compiler.resolver.MethodElement;
-
-import java.util.List;
-import java.util.Map;
-
-/**
- * Function type representation. A function type may correspond to method,
- * constructor, or function in which case its element is the corresponding
- * {@link MethodElement}. Otherwise, the function type can correspond to a named
- * function-type alias or variable type, in which case its element is the class
- * element of the Dart interface Function.
- */
-public interface FunctionType extends Type {
-  Type getReturnType();
-
-  /**
-   * @return "normal" parameter types, i.e. required, does not include "named".
-   */
-  List<Type> getParameterTypes();
-
-  /**
-   * Return the class element corresponding to the interface Function.
-   */
-  @Override
-  ClassElement getElement();
-
-  Type getRest();
-
-  boolean hasRest();
-
-  /**
-   * @return "optional" parameter types.
-   */
-  Map<String, Type> getOptionalParameterTypes();
-  
-  /**
-   * @return "named" parameter types.
-   */
-  Map<String, Type> getNamedParameterTypes();
-}
diff --git a/compiler/java/com/google/dart/compiler/type/FunctionTypeImplementation.java b/compiler/java/com/google/dart/compiler/type/FunctionTypeImplementation.java
deleted file mode 100644
index c4c2377..0000000
--- a/compiler/java/com/google/dart/compiler/type/FunctionTypeImplementation.java
+++ /dev/null
@@ -1,196 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.type;
-
-import com.google.dart.compiler.resolver.ClassElement;
-
-import java.util.Collections;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-
-class FunctionTypeImplementation extends AbstractType implements FunctionType {
-  private static final Map<String, Type> EMPTY_MAP = Collections.<String, Type>emptyMap();
-  private final ClassElement classElement;
-  private final List<Type> parameterTypes;
-  private final Type returnType;
-  private final Map<String, Type> optionalParameterTypes;
-  private final Map<String, Type> namedParameterTypes;
-  private final Type rest;
-
-  private FunctionTypeImplementation(ClassElement element,
-                                     List<Type> parameterTypes,
-                                     Map<String, Type> optionalParameterTypes,
-                                     Map<String, Type> namedParameterTypes,
-                                     Type rest,
-                                     Type returnType) {
-    this.classElement = element;
-    this.parameterTypes = parameterTypes;
-    this.optionalParameterTypes = optionalParameterTypes == null ? EMPTY_MAP : optionalParameterTypes;
-    this.namedParameterTypes = namedParameterTypes == null ? EMPTY_MAP : namedParameterTypes;
-    this.rest = rest;
-    this.returnType = returnType;
-  }
-
-  @Override
-  public Type subst(List<Type> arguments,
-                    List<Type> parameters) {
-    List<Type> substitutedParameterTypes = Types.subst(getParameterTypes(), arguments, parameters);
-
-    Map<String, Type> substitutedOptionalParameterTypes = null;
-    if (!getOptionalParameterTypes().isEmpty()) {
-      substitutedOptionalParameterTypes = new LinkedHashMap<String, Type>();
-      for (Map.Entry<String, Type> entry : getOptionalParameterTypes().entrySet()) {
-        substitutedOptionalParameterTypes.put(entry.getKey(),
-                                           entry.getValue().subst(arguments, parameters));
-      }
-    }
-    
-    Map<String, Type> substitutedNamedParameterTypes = null;
-    if (!getNamedParameterTypes().isEmpty()) {
-      substitutedNamedParameterTypes = new LinkedHashMap<String, Type>();
-      for (Map.Entry<String, Type> entry : getNamedParameterTypes().entrySet()) {
-        substitutedNamedParameterTypes.put(entry.getKey(),
-            entry.getValue().subst(arguments, parameters));
-      }
-    }
-
-    Type substitutedRest = null;
-    if (getRest() != null) {
-      substitutedRest = getRest().subst(arguments, parameters);
-    }
-    Type substitutedReturnType = getReturnType().subst(arguments, parameters);
-    return new FunctionTypeImplementation(getElement(),
-                                          substitutedParameterTypes,
-                                          substitutedOptionalParameterTypes,
-                                          substitutedNamedParameterTypes,
-                                          substitutedRest, substitutedReturnType);
-  }
-
-  @Override
-  public ClassElement getElement() {
-    return classElement;
-  }
-
-  @Override
-  public Type getReturnType() {
-    return returnType;
-  }
-
-  @Override
-  public List<Type> getParameterTypes() {
-    return parameterTypes;
-  }
-
-  @Override
-  public TypeKind getKind() {
-    return TypeKind.FUNCTION;
-  }
-
-  public Map<String, Type> getOptionalParameterTypes() {
-    return optionalParameterTypes;
-  }
-  
-  @Override
-  public Map<String, Type> getNamedParameterTypes() {
-    return namedParameterTypes;
-  }
-
-  @Override
-  public Type getRest() {
-    return rest;
-  }
-
-  @Override
-  public boolean hasRest() {
-    return rest != null;
-  }
-
-  @Override
-  public String toString() {
-    StringBuilder sb = new StringBuilder();
-    sb.append("(");
-    boolean first = true;
-    for (Type argument : getParameterTypes()) {
-      if (!first) {
-        sb.append(", ");
-      }
-      sb.append(argument);
-      first = false;
-    }
-    Type rest = getRest();
-    if (rest != null) {
-      if (!first) {
-        sb.append(", ");
-      }
-      sb.append(rest);
-      sb.append("...");
-      first = false;
-    }
-    Map<String, Type> namedParameterTypes = getNamedParameterTypes();
-    if (!namedParameterTypes.isEmpty()) {
-      if (!first) {
-        sb.append(", ");
-      }
-      sb.append("[");
-      first = true;
-      for (Entry<String, Type> entry : namedParameterTypes.entrySet()) {
-        if (!first) {
-          sb.append(", ");
-        }
-        sb.append(entry.getValue());
-        sb.append(" ");
-        sb.append(entry.getKey());
-        first = false;
-      }
-      sb.append("]");
-    }
-    sb.append(") -> ");
-    sb.append(getReturnType());
-    return sb.toString();
-  }
-
-  @Override
-  public boolean equals(Object o) {
-    // Two FunctionType objects representing the "same" type may not be equal,
-    // because they may have different elements.
-    if (o instanceof FunctionType) {
-      FunctionType other = (FunctionType) o;
-      return getElement().equals(other.getElement())
-          && getReturnType().equals(other.getReturnType())
-          && getParameterTypes().equals(other.getParameterTypes())
-          && hasRest() == other.hasRest()
-          && (!hasRest() || getRest().equals(other.getRest()))
-          && getNamedParameterTypes().equals(other.getNamedParameterTypes());
-    }
-    return false;
-  }
-
-  @Override
-  public int hashCode() {
-    Type rest = getRest();
-    Map<String, Type> namedParameterTypes = getNamedParameterTypes();
-    return getElement().hashCode()
-        + getReturnType().hashCode()
-        + getParameterTypes().hashCode()
-        + (rest == null ? 0 : rest.hashCode())
-        + (namedParameterTypes == null ? 0 : namedParameterTypes.hashCode());
-  }
-
-  /**
-   * Returns a function type with the given parameter types and return type. The
-   * {@link ClassElement} should always be the element corresponding to the
-   * interface Function in the core library.
-   */
-  static FunctionType of(ClassElement element, List<Type> parameterTypes,
-                         Map<String, Type> optionalParameterTypes,
-                         Map<String, Type> namedParameterTypes,
-                         Type rest, Type returnType) {
-    assert element.isDynamic() || element.getName().equals("Function");
-    return new FunctionTypeImplementation(element, parameterTypes, optionalParameterTypes,
-        namedParameterTypes, rest, returnType);
-  }
-}
diff --git a/compiler/java/com/google/dart/compiler/type/InterfaceType.java b/compiler/java/com/google/dart/compiler/type/InterfaceType.java
deleted file mode 100644
index 2f76916..0000000
--- a/compiler/java/com/google/dart/compiler/type/InterfaceType.java
+++ /dev/null
@@ -1,53 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.type;
-
-import com.google.dart.compiler.resolver.ClassElement;
-import com.google.dart.compiler.resolver.Element;
-
-import java.util.List;
-
-/**
- * An interface type.
- */
-public interface InterfaceType extends Type {
-  @Override
-  InterfaceType subst(List<Type> arguments,
-                      List<Type> parameters);
-
-  @Override
-  ClassElement getElement();
-
-  List<Type> getArguments();
-
-  boolean isRaw();
-
-  /**
-   * @return Whether type args for this interface instance is of type DYNAMIC.
-   */
-  boolean hasDynamicTypeArgs();
-
-  InterfaceType asRawType();
-
-  Member lookupMember(String name);
-  
-  void registerSubClass(ClassElement subClass);
-  void unregisterSubClass(ClassElement subClass);
-
-  /**
-   * @return the {@link Member}s with given name, defined in one of the subtypes. May be empty, but
-   *         not <code>null</code>.
-   */
-  List<Member> lookupSubTypeMembers(String name);
-
-  interface Member {
-    InterfaceType getHolder();
-    Element getElement();
-    Type getType();
-    Type getSetterType();
-    Type getGetterType();
-
-  }
-}
diff --git a/compiler/java/com/google/dart/compiler/type/InterfaceTypeImplementation.java b/compiler/java/com/google/dart/compiler/type/InterfaceTypeImplementation.java
deleted file mode 100644
index c9f05fd..0000000
--- a/compiler/java/com/google/dart/compiler/type/InterfaceTypeImplementation.java
+++ /dev/null
@@ -1,281 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.type;
-
-import com.google.common.annotations.VisibleForTesting;
-import com.google.common.collect.Lists;
-import com.google.common.collect.MapMaker;
-import com.google.dart.compiler.resolver.ClassElement;
-import com.google.dart.compiler.resolver.Element;
-import com.google.dart.compiler.resolver.ElementKind;
-import com.google.dart.compiler.resolver.Elements;
-import com.google.dart.compiler.resolver.FieldElement;
-import com.google.dart.compiler.resolver.MethodElement;
-import com.google.dart.compiler.util.apache.StringUtils;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-import java.util.Map;
-
-/**
- * An interface type.
- */
-@VisibleForTesting
-public class InterfaceTypeImplementation extends AbstractType implements InterfaceType {
-  private final ClassElement element;
-  private final List<Type> arguments;
-  private final Map<ClassElement, Object> subClasses = new MapMaker().weakKeys().makeMap();
-
-  InterfaceTypeImplementation(ClassElement element, List<Type> arguments) {
-    this.element = element;
-    this.arguments = arguments;
-  }
-
-  @Override
-  public ClassElement getElement() {
-    return element;
-  }
-
-  @Override
-  public List<Type> getArguments() {
-    return arguments;
-  }
-
-  @Override
-  public String toString() {
-    if (getArguments().isEmpty()) {
-      return getElement().getName();
-    } else {
-      StringBuilder sb = new StringBuilder();
-      sb.append(getElement().getName());
-      Types.printTypesOn(sb, getArguments(), "<", ">");
-      return sb.toString();
-    }
-  }
-
-  @Override
-  public boolean hasDynamicTypeArgs() {
-    for (Type t : getArguments()) {
-      if (t.getKind() == TypeKind.DYNAMIC) {
-        return true;
-      }
-    }
-    return false;
-  }
-
-  @Override
-  public boolean isRaw() {
-    return getArguments().size() != getElement().getTypeParameters().size();
-  }
-
-  @Override
-  public InterfaceType subst(List<Type> arguments, List<Type> parameters) {
-    if (arguments.isEmpty() && parameters.isEmpty()) {
-      return this;
-    }
-    List<Type> substitutedArguments = Types.subst(getArguments(), arguments, parameters);
-    return new InterfaceTypeImplementation(getElement(), substitutedArguments);
-  }
-
-  @Override
-  public boolean equals(Object obj) {
-    if (obj instanceof InterfaceType) {
-      InterfaceType other = (InterfaceType) obj;
-      return getElement().equals(other.getElement()) && getArguments().equals(other.getArguments());
-    }
-    return false;
-  }
-
-  @Override
-  public int hashCode() {
-    int hashCode = 31;
-    hashCode += getElement().hashCode();
-    hashCode += 31 * hashCode + getArguments().hashCode();
-    return hashCode;
-  }
-
-  @Override
-  public InterfaceType asRawType() {
-    return new InterfaceTypeImplementation(getElement(), Arrays.<Type>asList());
-  }
-
-  @Override
-  public TypeKind getKind() {
-    return TypeKind.INTERFACE;
-  }
-
-  @Override
-  public Member lookupMember(String name) {
-    Member member = lookupMember0(this, name);
-    if (member != null) {
-      return member;
-    }
-    InterfaceType supertype = getSupertype();
-    if (supertype != null) {
-      member = supertype.lookupMember(name);
-      if (member != null) {
-        return member;
-      }
-    }
-    for (InterfaceType intrface : getInterfaces()) {
-      member = intrface.lookupMember(name);
-      if (member != null) {
-        return member;
-      }
-    }
-    for (InterfaceType mixin : getMixins()) {
-      member = lookupMember0(mixin, name);
-      if (member != null) {
-        return member;
-      }
-    }
-    return null;
-  }
-
-  private static Member lookupMember0(InterfaceType type, String name) {
-    Element element = type.getElement().lookupLocalElement(name);
-    if (element != null) {
-      return new MemberImplementation(type, element);
-    }
-    return null;
-  }
-
-  private InterfaceType getSupertype() {
-    InterfaceType supertype = getElement().getSupertype();
-    if (supertype == null) {
-      return null;
-    } else {
-      return supertype.subst(getArguments(), getElement().getTypeParameters());
-    }
-  }
-
-  private List<InterfaceType> getInterfaces() {
-    List<InterfaceType> result = new ArrayList<InterfaceType>();
-    List<Type> typeArguments = getArguments();
-    List<Type> typeParameters = getElement().getTypeParameters();
-    for (InterfaceType type : getElement().getInterfaces()) {
-      result.add(type.subst(typeArguments, typeParameters));
-    }
-    return result;
-  }
-  
-  private List<InterfaceType> getMixins() {
-    List<InterfaceType> result = new ArrayList<InterfaceType>();
-    List<Type> typeArguments = getArguments();
-    List<Type> typeParameters = getElement().getTypeParameters();
-    for (InterfaceType type : getElement().getMixins()) {
-      result.add(type.subst(typeArguments, typeParameters));
-    }
-    return result;
-  }
-
-  private static class MemberImplementation implements Member {
-    private final InterfaceType holder;
-    private final Element member;
-
-    MemberImplementation(InterfaceType holder, Element member) {
-      this.holder = holder;
-      this.member = member;
-    }
-
-    @Override
-    public InterfaceType getHolder() {
-      return holder;
-    }
-
-    @Override
-    public Element getElement() {
-      return member;
-    }
-
-    @Override
-    public Type getType() {
-      List<Type> typeArguments = getHolder().getArguments();
-      List<Type> typeParameters = getHolder().getElement().getTypeParameters();
-      return getElement().getType().subst(typeArguments, typeParameters);
-    }
-
-    @Override
-    public Type getSetterType() {
-      Element element = getElement();
-      if (!ElementKind.of(element).equals(ElementKind.FIELD)) {
-        return getType();
-      }
-      FieldElement field = (FieldElement) element;
-      MethodElement setter = field.getSetter();
-      if (setter == null) {
-        setter = Elements.lookupFieldElementSetter(holder.getElement(), member.getName());
-        if (setter == null) {
-          setter = Elements.lookupFieldElementSetter(holder.getElement(), "setter " + member.getName());
-        }
-        if (setter == null) {
-          return null;
-        }
-      }
-      if (setter.getParameters().size() == 0) {
-        return null;
-      }
-      Type setterType = setter.getParameters().get(0).getType();
-      List<Type> typeArguments = getHolder().getArguments();
-      List<Type> typeParameters = getHolder().getElement().getTypeParameters();
-      return setterType.subst(typeArguments, typeParameters);
-    }
-
-    @Override
-    public Type getGetterType() {
-      Element element = getElement();
-      if (!ElementKind.of(element).equals(ElementKind.FIELD)) {
-        return getType();
-      }
-      FieldElement field = (FieldElement) element;
-      MethodElement getter = field.getGetter();
-      if (getter == null) {
-        String name = member.getName();
-        name = StringUtils.stripStart(name, "setter ");
-        getter = Elements.lookupFieldElementGetter(holder.getElement(), name);
-        if (getter == null) {
-          return null;
-        }
-      }
-      Type getterType = getter.getReturnType();
-      List<Type> typeArguments = getHolder().getArguments();
-      List<Type> typeParameters = getHolder().getElement().getTypeParameters();
-      return getterType.subst(typeArguments, typeParameters);
-    }
-  }
-  
-  @Override
-  public void registerSubClass(ClassElement subClass) {
-    subClasses.put(subClass, this);
-  }
-  
-  @Override
-  public void unregisterSubClass(ClassElement subClass) {
-    subClasses.remove(subClass);
-  }
-  
-  @Override
-  public List<Member> lookupSubTypeMembers(String name) {
-    List<Member> members = Lists.newArrayList();
-    fillSubTypeMember(members, name);
-    return members;
-  }
-  
-  private void fillSubTypeMember(List<Member> members, String name) {
-    {
-      Member member = lookupMember(name);
-      if (member != null) {
-        members.add(member);
-      }
-    }
-    for (ClassElement subClass : subClasses.keySet()) {
-      InterfaceType type = subClass.getType();
-      if (type instanceof InterfaceTypeImplementation) {
-        ((InterfaceTypeImplementation)type).fillSubTypeMember(members, name);
-      }
-    }
-  }
-}
diff --git a/compiler/java/com/google/dart/compiler/type/InterfaceTypeUnion.java b/compiler/java/com/google/dart/compiler/type/InterfaceTypeUnion.java
deleted file mode 100644
index 87a6c9c..0000000
--- a/compiler/java/com/google/dart/compiler/type/InterfaceTypeUnion.java
+++ /dev/null
@@ -1,17 +0,0 @@
-// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.type;
-
-import java.util.List;
-
-/**
- * Artificial {@link InterfaceType} which is union of several {@link InterfaceType}s.
- */
-public interface InterfaceTypeUnion extends InterfaceType {
-  /**
-   * @return the {@link InterfaceType} making this union.
-   */
-  List<InterfaceType> getTypes();
-}
diff --git a/compiler/java/com/google/dart/compiler/type/InterfaceTypeUnionImplementation.java b/compiler/java/com/google/dart/compiler/type/InterfaceTypeUnionImplementation.java
deleted file mode 100644
index 50f0006..0000000
--- a/compiler/java/com/google/dart/compiler/type/InterfaceTypeUnionImplementation.java
+++ /dev/null
@@ -1,116 +0,0 @@
-// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.type;
-
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.Lists;
-import com.google.dart.compiler.resolver.ClassElement;
-import com.google.dart.compiler.resolver.ClassElementUnion;
-
-import java.util.List;
-
-/**
- * Implementation of {@link InterfaceTypeUnion}.
- */
-class InterfaceTypeUnionImplementation implements InterfaceTypeUnion {
-
-  private final List<InterfaceType> types;
-  private final ClassElement element;
-
-  public InterfaceTypeUnionImplementation(List<InterfaceType> types) {
-    this.types = types;
-    this.element = new ClassElementUnion(this, types);
-  }
-
-  @Override
-  public boolean equals(Object obj) {
-    if (obj instanceof InterfaceTypeUnionImplementation) {
-      InterfaceTypeUnionImplementation other = (InterfaceTypeUnionImplementation) obj;
-      return getElement().equals(other.getElement());
-    }
-    return false;
-  }
-
-  @Override
-  public int hashCode() {
-    int hashCode = 31;
-    hashCode += getElement().hashCode();
-    hashCode += 31 * hashCode + getArguments().hashCode();
-    return hashCode;
-  }
-
-  @Override
-  public String toString() {
-    return types.toString();
-  }
-
-  @Override
-  public TypeKind getKind() {
-    return TypeKind.INTERFACE;
-  }
-
-  @Override
-  public TypeQuality getQuality() {
-    return TypeQuality.EXACT;
-  }
-
-  @Override
-  public InterfaceType subst(List<Type> arguments, List<Type> parameters) {
-    return null;
-  }
-
-  @Override
-  public ClassElement getElement() {
-    return element;
-  }
-
-  @Override
-  public List<Type> getArguments() {
-    return ImmutableList.of();
-  }
-
-  @Override
-  public boolean isRaw() {
-    return true;
-  }
-
-  @Override
-  public boolean hasDynamicTypeArgs() {
-    return false;
-  }
-
-  @Override
-  public InterfaceType asRawType() {
-    return this;
-  }
-
-  @Override
-  public Member lookupMember(String name) {
-    for (InterfaceType type : types) {
-      Member member = type.lookupMember(name);
-      if (member != null) {
-        return member;
-      }
-    }
-    return null;
-  }
-
-  @Override
-  public void registerSubClass(ClassElement subClass) {
-  }
-
-  @Override
-  public void unregisterSubClass(ClassElement subClass) {
-  }
-
-  @Override
-  public List<Member> lookupSubTypeMembers(String name) {
-    return Lists.newArrayList();
-  }
-
-  public List<InterfaceType> getTypes() {
-    return types;
-  }
-}
diff --git a/compiler/java/com/google/dart/compiler/type/Type.java b/compiler/java/com/google/dart/compiler/type/Type.java
deleted file mode 100644
index 3fa6a0b..0000000
--- a/compiler/java/com/google/dart/compiler/type/Type.java
+++ /dev/null
@@ -1,31 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.type;
-
-import com.google.dart.compiler.resolver.Element;
-
-import java.util.List;
-
-/**
- * Common supertype of all types.
- */
-public interface Type {
-  /**
-   * Performs the substitution [arguments[i]/parameters[i]]this.
-   * The notation is known from this lambda calculus rule:
-   * (lambda x.e0)e1 -> [e1/x]e0.
-   * <p>See {@link TypeVariable} for a motivation for this method.
-   */
-  Type subst(List<Type> arguments, List<Type> parameters);
-
-  Element getElement();
-
-  TypeKind getKind();
-  
-  /**
-   * @return the {@link TypeQuality}, not <code>null</code>.
-   */
-  TypeQuality getQuality();
-}
diff --git a/compiler/java/com/google/dart/compiler/type/TypeAnalyzer.java b/compiler/java/com/google/dart/compiler/type/TypeAnalyzer.java
deleted file mode 100644
index 4a5539b..0000000
--- a/compiler/java/com/google/dart/compiler/type/TypeAnalyzer.java
+++ /dev/null
@@ -1,3725 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.type;
-
-import com.google.common.annotations.VisibleForTesting;
-import com.google.common.base.Joiner;
-import com.google.common.base.Objects;
-import com.google.common.collect.ArrayListMultimap;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.LinkedListMultimap;
-import com.google.common.collect.Lists;
-import com.google.common.collect.Maps;
-import com.google.common.collect.Multimap;
-import com.google.common.collect.Sets;
-import com.google.dart.compiler.CommandLineOptions.CompilerOptions;
-import com.google.dart.compiler.DartCompilationError;
-import com.google.dart.compiler.DartCompilationPhase;
-import com.google.dart.compiler.DartCompilerContext;
-import com.google.dart.compiler.ErrorCode;
-import com.google.dart.compiler.ErrorSeverity;
-import com.google.dart.compiler.PackageLibraryManager;
-import com.google.dart.compiler.Source;
-import com.google.dart.compiler.ast.ASTNodes;
-import com.google.dart.compiler.ast.ASTVisitor;
-import com.google.dart.compiler.ast.DartArrayAccess;
-import com.google.dart.compiler.ast.DartArrayLiteral;
-import com.google.dart.compiler.ast.DartAssertStatement;
-import com.google.dart.compiler.ast.DartBinaryExpression;
-import com.google.dart.compiler.ast.DartBlock;
-import com.google.dart.compiler.ast.DartBooleanLiteral;
-import com.google.dart.compiler.ast.DartBreakStatement;
-import com.google.dart.compiler.ast.DartCascadeExpression;
-import com.google.dart.compiler.ast.DartCase;
-import com.google.dart.compiler.ast.DartCatchBlock;
-import com.google.dart.compiler.ast.DartClass;
-import com.google.dart.compiler.ast.DartComment;
-import com.google.dart.compiler.ast.DartConditional;
-import com.google.dart.compiler.ast.DartContinueStatement;
-import com.google.dart.compiler.ast.DartDeclaration;
-import com.google.dart.compiler.ast.DartDefault;
-import com.google.dart.compiler.ast.DartDoWhileStatement;
-import com.google.dart.compiler.ast.DartDoubleLiteral;
-import com.google.dart.compiler.ast.DartEmptyStatement;
-import com.google.dart.compiler.ast.DartExportDirective;
-import com.google.dart.compiler.ast.DartExprStmt;
-import com.google.dart.compiler.ast.DartExpression;
-import com.google.dart.compiler.ast.DartField;
-import com.google.dart.compiler.ast.DartFieldDefinition;
-import com.google.dart.compiler.ast.DartForInStatement;
-import com.google.dart.compiler.ast.DartForStatement;
-import com.google.dart.compiler.ast.DartFunction;
-import com.google.dart.compiler.ast.DartFunctionExpression;
-import com.google.dart.compiler.ast.DartFunctionObjectInvocation;
-import com.google.dart.compiler.ast.DartFunctionTypeAlias;
-import com.google.dart.compiler.ast.DartIdentifier;
-import com.google.dart.compiler.ast.DartIfStatement;
-import com.google.dart.compiler.ast.DartImportDirective;
-import com.google.dart.compiler.ast.DartInitializer;
-import com.google.dart.compiler.ast.DartIntegerLiteral;
-import com.google.dart.compiler.ast.DartInvocation;
-import com.google.dart.compiler.ast.DartLabel;
-import com.google.dart.compiler.ast.DartLibraryDirective;
-import com.google.dart.compiler.ast.DartLiteral;
-import com.google.dart.compiler.ast.DartMapLiteral;
-import com.google.dart.compiler.ast.DartMapLiteralEntry;
-import com.google.dart.compiler.ast.DartMethodDefinition;
-import com.google.dart.compiler.ast.DartMethodInvocation;
-import com.google.dart.compiler.ast.DartNamedExpression;
-import com.google.dart.compiler.ast.DartNativeBlock;
-import com.google.dart.compiler.ast.DartNativeDirective;
-import com.google.dart.compiler.ast.DartNewExpression;
-import com.google.dart.compiler.ast.DartNode;
-import com.google.dart.compiler.ast.DartNullLiteral;
-import com.google.dart.compiler.ast.DartParameter;
-import com.google.dart.compiler.ast.DartParameterizedTypeNode;
-import com.google.dart.compiler.ast.DartParenthesizedExpression;
-import com.google.dart.compiler.ast.DartPropertyAccess;
-import com.google.dart.compiler.ast.DartRedirectConstructorInvocation;
-import com.google.dart.compiler.ast.DartReturnStatement;
-import com.google.dart.compiler.ast.DartSourceDirective;
-import com.google.dart.compiler.ast.DartStatement;
-import com.google.dart.compiler.ast.DartStringInterpolation;
-import com.google.dart.compiler.ast.DartStringLiteral;
-import com.google.dart.compiler.ast.DartSuperConstructorInvocation;
-import com.google.dart.compiler.ast.DartSuperExpression;
-import com.google.dart.compiler.ast.DartSwitchMember;
-import com.google.dart.compiler.ast.DartSwitchStatement;
-import com.google.dart.compiler.ast.DartSyntheticErrorExpression;
-import com.google.dart.compiler.ast.DartSyntheticErrorIdentifier;
-import com.google.dart.compiler.ast.DartSyntheticErrorStatement;
-import com.google.dart.compiler.ast.DartThisExpression;
-import com.google.dart.compiler.ast.DartThrowExpression;
-import com.google.dart.compiler.ast.DartTryStatement;
-import com.google.dart.compiler.ast.DartTypeExpression;
-import com.google.dart.compiler.ast.DartTypeNode;
-import com.google.dart.compiler.ast.DartTypeParameter;
-import com.google.dart.compiler.ast.DartUnaryExpression;
-import com.google.dart.compiler.ast.DartUnit;
-import com.google.dart.compiler.ast.DartUnqualifiedInvocation;
-import com.google.dart.compiler.ast.DartVariable;
-import com.google.dart.compiler.ast.DartVariableStatement;
-import com.google.dart.compiler.ast.DartWhileStatement;
-import com.google.dart.compiler.ast.Modifiers;
-import com.google.dart.compiler.common.HasSourceInfo;
-import com.google.dart.compiler.common.SourceInfo;
-import com.google.dart.compiler.parser.Token;
-import com.google.dart.compiler.resolver.ClassElement;
-import com.google.dart.compiler.resolver.ClassNodeElement;
-import com.google.dart.compiler.resolver.ConstructorElement;
-import com.google.dart.compiler.resolver.CoreTypeProvider;
-import com.google.dart.compiler.resolver.CyclicDeclarationException;
-import com.google.dart.compiler.resolver.Element;
-import com.google.dart.compiler.resolver.ElementKind;
-import com.google.dart.compiler.resolver.Elements;
-import com.google.dart.compiler.resolver.FieldElement;
-import com.google.dart.compiler.resolver.FunctionAliasElement;
-import com.google.dart.compiler.resolver.MethodElement;
-import com.google.dart.compiler.resolver.ResolverErrorCode;
-import com.google.dart.compiler.resolver.TypeErrorCode;
-import com.google.dart.compiler.resolver.VariableElement;
-import com.google.dart.compiler.type.InterfaceType.Member;
-import com.google.dart.compiler.util.apache.ObjectUtils;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Iterator;
-import java.util.LinkedHashMap;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
-
-/**
- * Analyzer of static type information.
- */
-public class TypeAnalyzer implements DartCompilationPhase {
-
-  private final Set<ClassElement> diagnosedAbstractClasses = Sets.newHashSet();
-
-  /**
-   * Perform type analysis on the given AST rooted at <code>node</code>.
-   *
-   * @param node The root of the tree to analyze
-   * @param typeProvider The source of pre-defined type definitions
-   * @param context The compilation context (DartCompilerContext)
-   * @param currentClass The class that contains <code>node</code>. Will be null
-   *        for top-level declarations.
-   * @return The type of <code>node</code>.
-   */
-  public static Type analyze(DartNode node, CoreTypeProvider typeProvider,
-                             DartCompilerContext context, InterfaceType currentClass) {
-    Set<ClassElement> diagnosed = Sets.newHashSet();
-    Analyzer analyzer = new Analyzer(context, typeProvider, diagnosed);
-    analyzer.setCurrentClass(currentClass);
-    return node.accept(analyzer);
-  }
-
-  @Override
-  public DartUnit exec(DartUnit unit, DartCompilerContext context, CoreTypeProvider typeProvider) {
-    unit.accept(new Analyzer(context, typeProvider, diagnosedAbstractClasses));
-    return unit;
-  }
-
-  @VisibleForTesting
-  static class Analyzer extends ASTVisitor<Type> {
-    private final DynamicType dynamicType;
-    private final Type stringType;
-    private final InterfaceType defaultLiteralMapType;
-    private final Type voidType;
-    private final DartCompilerContext context;
-    private final Types types;
-    private Type expected;
-    private MethodElement currentMethod;
-    private InterfaceType currentClass;
-    private final InterfaceType objectType;
-    private final InterfaceType boolType;
-    private final InterfaceType numType;
-    private final InterfaceType intType;
-    private final InterfaceType doubleType;
-    private final Type nullType;
-    private final InterfaceType functionType;
-    private final InterfaceType dynamicIteratorType;
-    private final boolean developerModeChecks;
-    private final boolean suppressSdkWarnings;
-    private final boolean typeChecksForInferredTypes;
-    private final boolean reportNoMemberWhenHasInterceptor;
-    private final Map<DartBlock, VariableElementsRestorer> restoreOnBlockExit = Maps.newHashMap();
-    /**
-     * When we see variable assignment, we remember here old {@link Type} (if not done already) and
-     * set new {@link Type} into {@link VariableElement}. On the exit from basic block we remove
-     * first element and merge new types with old types.
-     */
-    private final LinkedList<BlockTypeContext> blockOldTypes = Lists.newLinkedList();
-    private static class BlockTypeContext {
-      final Map<VariableElement, Type> oldTypes = Maps.newHashMap();
-      final Map<VariableElement, Type> newTypes = Maps.newHashMap();
-      void rememberOldType(VariableElement element, Type oriType) {
-        if (!oldTypes.containsKey(element)) {
-          oldTypes.put(element, oriType);
-        }
-      }
-      void setType(VariableElement element, Type newType) {
-        if (canSetType(element)) {
-          rememberOldType(element, element.getType());
-          newTypes.put(element, newType);
-          Elements.setType(element, newType);
-        }
-      }
-      boolean canSetType(VariableElement element) {
-        Type type = element.getType();
-        // no type declared, no assignment yet
-        if (TypeKind.of(type) == TypeKind.DYNAMIC) {
-          return true;
-        }
-        // was assignment, inferred
-        if (type != null && TypeQuality.isInferred(type)) {
-          return true;
-        }
-        // was declared with type, keep it
-        return false;
-      }
-      Map<VariableElement, Type> getNewTypesAndRestoreOld() {
-        for (Entry<VariableElement, Type> entry : oldTypes.entrySet()) {
-          VariableElement variable = entry.getKey();
-          Elements.setType(variable, entry.getValue());
-        }
-        return newTypes;
-      }
-    }
-
-    /**
-     * Keeps track of the number of nested catches, used to detect re-throws
-     * outside of any catch block.
-     */
-    private int catchDepth = 0;
-
-    Analyzer(DartCompilerContext context, CoreTypeProvider typeProvider,
-             Set<ClassElement> diagnosedAbstractClasses) {
-      this.context = context;
-      this.developerModeChecks = context.getCompilerConfiguration().developerModeChecks();
-      this.types = Types.getInstance(typeProvider);
-      this.dynamicType = typeProvider.getDynamicType();
-      this.stringType = typeProvider.getStringType();
-      this.defaultLiteralMapType = typeProvider.getMapType(stringType, dynamicType);
-      this.voidType = typeProvider.getVoidType();
-      this.objectType = typeProvider.getObjectType();
-      this.boolType = typeProvider.getBoolType();
-      this.numType = typeProvider.getNumType();
-      this.intType = typeProvider.getIntType();
-      this.doubleType = typeProvider.getDoubleType();
-      this.nullType = typeProvider.getNullType();
-      this.functionType = typeProvider.getFunctionType();
-      this.dynamicIteratorType = typeProvider.getIteratorType(dynamicType);
-      CompilerOptions compilerOptions = context.getCompilerConfiguration().getCompilerOptions();
-      this.suppressSdkWarnings = compilerOptions.suppressSdkWarnings();
-      this.typeChecksForInferredTypes = compilerOptions.typeChecksForInferredTypes();
-      this.reportNoMemberWhenHasInterceptor = compilerOptions.reportNoMemberWhenHasInterceptor();
-    }
-
-    @VisibleForTesting
-    void setCurrentClass(InterfaceType type) {
-      currentClass = type;
-    }
-
-    @VisibleForTesting
-    void pushBasicBlockContext() {
-      blockOldTypes.addFirst(new BlockTypeContext());
-    }
-
-    private InterfaceType getCurrentClass() {
-      return currentClass;
-    }
-
-    private DynamicType typeError(HasSourceInfo node, ErrorCode code, Object... arguments) {
-      onError(node, code, arguments);
-      return dynamicType;
-    }
-
-    private void onError(HasSourceInfo node, ErrorCode errorCode, Object... arguments) {
-      onError(node.getSourceInfo(), errorCode, arguments);
-    }
-
-    private void onError(SourceInfo errorTarget, ErrorCode errorCode, Object... arguments) {
-      if (suppressSdkWarnings) {
-        ErrorSeverity errorSeverity = errorCode.getErrorSeverity();
-        if (errorSeverity == ErrorSeverity.WARNING || errorSeverity == ErrorSeverity.INFO) {
-          Source source = errorTarget.getSource();
-          if (source != null && PackageLibraryManager.isDartUri(source.getUri())) {
-            return;
-          }
-        }
-      }
-      context.onError(new DartCompilationError(errorTarget, errorCode, arguments));
-    }
-
-    AssertionError internalError(HasSourceInfo node, String message, Object... arguments) {
-      message = String.format(message, arguments);
-      context.onError(new DartCompilationError(node, TypeErrorCode.INTERNAL_ERROR,
-                                                        message));
-      return new AssertionError("Internal error: " + message);
-    }
-
-    private Type typeOfLiteral(DartLiteral node) {
-      Type type = node.getType();
-      return type == null ? voidType : type;
-    }
-
-    private Token getBasicOperator(DartNode diagnosticNode, Token op) {
-      switch(op) {
-        case INC:
-          return Token.ADD;
-        case DEC:
-          return Token.SUB;
-        case ASSIGN_BIT_OR:
-          return Token.BIT_OR;
-        case ASSIGN_BIT_XOR:
-          return Token.BIT_XOR;
-        case ASSIGN_BIT_AND:
-          return Token.BIT_AND;
-        case ASSIGN_SHL:
-          return Token.SHL;
-        case ASSIGN_SAR:
-          return Token.SAR;
-        case ASSIGN_ADD:
-          return Token.ADD;
-        case ASSIGN_SUB:
-          return Token.SUB;
-        case ASSIGN_MUL:
-          return Token.MUL;
-        case ASSIGN_DIV:
-          return Token.DIV;
-        case ASSIGN_MOD:
-          return Token.MOD;
-        case ASSIGN_TRUNC:
-          return Token.TRUNC;
-        default:
-          internalError(diagnosticNode, "unexpected operator %s", op.name());
-          return null;
-      }
-    }
-
-    @Override
-    public Type visitRedirectConstructorInvocation(DartRedirectConstructorInvocation node) {
-      return checkConstructorForwarding(node, node.getElement());
-    }
-
-    private String methodNameForUnaryOperator(DartNode diagnosticNode, Token operator) {
-      if (operator == Token.SUB) {
-        return "operator -";
-      } else if (operator == Token.BIT_NOT) {
-        return "operator ~";
-      }
-      return "operator " + getBasicOperator(diagnosticNode, operator).getSyntax();
-    }
-
-    private String methodNameForBinaryOperator(Token operator) {
-      if (operator.getSyntax().equals("-")) {
-        return "operator -binary";
-      }
-      return "operator " + operator.getSyntax();
-    }
-
-    private Type analyzeBinaryOperator(DartNode node, Type lhsType, Token operator,
-        DartNode diagnosticNode, DartExpression rhs) {
-      Type rhsType = nonVoidTypeOf(rhs);
-      String methodName = methodNameForBinaryOperator(operator);
-      HasSourceInfo problemTarget = getOperatorHasSourceInfo(node);
-      Member member = lookupMember(lhsType, methodName, problemTarget);
-      if (member != null) {
-        Element element = member.getElement();
-        node.setElement(element);
-        FunctionType methodType = getMethodType(lhsType, member, methodName, diagnosticNode);
-        checkDeprecated(problemTarget, element);
-        Type returnType = checkInvocation(Collections.<DartExpression> singletonList(rhs),
-            Collections.<Type> singletonList(rhsType),
-            diagnosticNode, methodName, methodType, null);
-        // tweak return type for int/int and int/double operators
-        {
-          boolean lhsInt = intType.equals(lhsType);
-          boolean rhsInt = intType.equals(rhsType);
-          boolean lhsDouble = doubleType.equals(lhsType);
-          boolean rhsDouble = doubleType.equals(rhsType);
-          switch (operator) {
-            case ADD:
-            case SUB:
-            case MUL:
-            case TRUNC:
-            case MOD:
-              if (lhsInt && rhsInt) {
-                return intType;
-              }
-            case DIV:
-              if (lhsDouble || rhsDouble) {
-                return doubleType;
-              }
-          }
-        }
-        // done
-        return returnType;
-      } else {
-        return dynamicType;
-      }
-    }
-
-    private Type analyzeTernaryOperator(DartNode node, Type lhsType, Token operator,
-        DartNode diagnosticNode, DartExpression arg1, DartExpression arg2) {
-      String methodName = methodNameForBinaryOperator(operator);
-      HasSourceInfo problemTarget = getOperatorHasSourceInfo(node);
-      Member member = lookupMember(lhsType, methodName, problemTarget);
-      if (member != null) {
-        Element element = member.getElement();
-        node.setElement(element);
-        FunctionType methodType = getMethodType(lhsType, member, methodName, diagnosticNode);
-        checkDeprecated(problemTarget, element);
-        return checkInvocation(ImmutableList.of(arg1, arg2), diagnosticNode, methodName,
-            methodType, null);
-      } else {
-        return dynamicType;
-      }
-    }
-
-    @Override
-    public Type visitBinaryExpression(DartBinaryExpression node) {
-      DartExpression lhsNode = node.getArg1();
-      Type lhs = nonVoidTypeOf(lhsNode);
-      DartExpression rhsNode = node.getArg2();
-      Token operator = node.getOperator();
-      switch (operator) {
-        case ASSIGN: {
-          // prepare RHS type
-          Type rhs = getInvocationArgumentType(rhsNode);
-          try {
-            if (!hasInferredType(lhsNode)) {
-              if (checkAssignable(rhsNode, lhs, rhs)) {
-                inferFunctionLiteralParametersTypes(rhsNode, lhs);
-              }
-            }
-          } finally {
-            if (rhsNode instanceof DartFunctionExpression) {
-              rhsNode.accept(this);
-            }
-          }
-          // may be replace type of variable
-          setVariableElementType(lhsNode.getElement(), rhs, getTypeQuality(rhsNode));
-          checkAssignableElement(lhsNode);
-          // if cascade, then use type of "lhs" qualifier
-          if (lhsNode instanceof DartPropertyAccess) {
-            DartPropertyAccess lhsAccess = (DartPropertyAccess) lhsNode;
-            if (lhsAccess.isCascade()) {
-              return lhsAccess.getRealTarget().getType();
-            }
-          }
-          // use type or "rhs"
-          return rhs;
-        }
-
-        case ASSIGN_ADD:
-        case ASSIGN_SUB:
-        case ASSIGN_MUL:
-        case ASSIGN_DIV:
-        case ASSIGN_MOD:
-        case ASSIGN_TRUNC: {
-          Token basicOperator = getBasicOperator(node, operator);
-          Type type = analyzeBinaryOperator(node, lhs, basicOperator, lhsNode, rhsNode);
-          checkAssignable(node, lhs, type);
-          checkAssignableElement(lhsNode);
-          return type;
-        }
-
-        case OR:
-        case AND: {
-          checkAssignable(lhsNode, boolType, lhs);
-          checkAssignable(boolType, rhsNode);
-          return boolType;
-        }
-
-        case ASSIGN_BIT_OR:
-        case ASSIGN_BIT_XOR:
-        case ASSIGN_BIT_AND:
-        case ASSIGN_SHL:
-        case ASSIGN_SAR: {
-          // Bit operations are only supported by integers and
-          // thus cannot be looked up on num. To ease usage of
-          // bit operations, we currently allow them to be used
-          // if the left-hand-side is of type num.
-          // TODO(karlklose) find a clean solution, i.e., without a special case for num.
-          checkAssignableElement(lhsNode);
-          if (lhs.equals(numType)) {
-            checkAssignable(rhsNode, numType, typeOf(rhsNode));
-            return intType;
-          } else {
-            Token basicOperator = getBasicOperator(node, operator);
-            Type type = analyzeBinaryOperator(node, lhs, basicOperator, lhsNode, rhsNode);
-            checkAssignable(node, lhs, type);
-            return type;
-          }
-        }
-
-        case BIT_OR:
-        case BIT_XOR:
-        case BIT_AND:
-        case SHL:
-        case SAR: {
-          // Bit operations are only supported by integers and
-          // thus cannot be looked up on num. To ease usage of
-          // bit operations, we currently allow them to be used
-          // if the left-hand-side is of type num.
-          // TODO(karlklose) find a clean solution, i.e., without a special case for num.
-          if (lhs.equals(numType)) {
-            checkAssignable(rhsNode, numType, typeOf(rhsNode));
-            return intType;
-          } else {
-            return analyzeBinaryOperator(node, lhs, operator, lhsNode, rhsNode);
-          }
-        }
-
-        case ADD:
-        case SUB:
-        case MUL:
-        case DIV:
-        case TRUNC:
-        case MOD:
-        case LT:
-        case GT:
-        case LTE:
-        case GTE:
-          return analyzeBinaryOperator(node, lhs, operator, lhsNode, rhsNode);
-
-        case EQ: {
-          // try to resolve "==" to "operator equals()", but don't complain if can not find it
-          String methodName = methodNameForBinaryOperator(operator);
-          InterfaceType itype = types.getInterfaceType(lhs);
-          if (itype != null) {
-            Member member = itype.lookupMember(methodName);
-            if (member != null) {
-              node.setElement(member.getElement());
-            }
-          }
-        }
-       case NE:
-       case EQ_STRICT:
-       case NE_STRICT:
-         nonVoidTypeOf(rhsNode);
-         return boolType;
-
-       case AS:
-         return typeOf(rhsNode);
-
-       case IS:
-         if (rhsNode instanceof DartUnaryExpression) {
-           assert ((DartUnaryExpression) rhsNode).getOperator() == Token.NOT;
-           nonVoidTypeOf(((DartUnaryExpression) rhsNode).getArg());
-         } else {
-           nonVoidTypeOf(rhsNode);
-         }
-         return boolType;
-
-       case COMMA:
-         return typeOf(rhsNode);
-
-        default:
-          throw new AssertionError("Unknown operator: " + operator);
-      }
-    }
-
-    private void checkAssignableElement(DartExpression lhsNode) {
-      Element lhsElement = lhsNode.getElement();
-      switch (ElementKind.of(lhsElement)) {
-        case DYNAMIC:
-        case VARIABLE:
-        case PARAMETER:
-        case FIELD:
-        case NONE:
-          // OK or unknown
-          break;
-
-        case METHOD:
-          if (lhsElement.getModifiers().isSetter()
-           || lhsElement.getModifiers().isGetter()
-           || lhsElement.getModifiers().isOperator()) {
-            // The check for methods with setters is elsewhere.
-            break;
-          }
-        default:
-          onError(lhsNode, TypeErrorCode.CANNOT_ASSIGN_TO, ElementKind.of(lhsElement));
-        break;
-      }
-    }
-
-    /**
-     * @return the best guess for operator token location in the given {@link DartNode}.
-     */
-    private static HasSourceInfo getOperatorHasSourceInfo(DartNode node) {
-      Token operator = null;
-      int offset = 0;
-      if (node instanceof DartBinaryExpression) {
-        DartBinaryExpression binary = (DartBinaryExpression) node;
-        operator = binary.getOperator();
-        offset = binary.getOperatorOffset();
-      }
-      if (node instanceof DartUnaryExpression) {
-        DartUnaryExpression binary = (DartUnaryExpression) node;
-        operator = binary.getOperator();
-        offset = binary.getOperatorOffset();
-      }
-      if (operator != null) {
-        Source source = node.getSourceInfo().getSource();
-        int length = operator.getSyntax().length();
-        final SourceInfo sourceInfo = new SourceInfo(source, offset, length);
-        return new HasSourceInfo() {
-          @Override
-          public SourceInfo getSourceInfo() {
-            return sourceInfo;
-          }
-        };
-      }
-      return node;
-    }
-
-    @Override
-    public Type visitExprStmt(DartExprStmt node) {
-      Type type = typeOf(node.getExpression());
-      return type;
-    }
-
-    @Override
-    public Type visitVariableStatement(DartVariableStatement node) {
-      Type type = typeOf(node.getTypeNode());
-      visit(node.getVariables());
-      return type;
-    }
-
-    private Member lookupMember(Type receiver, String methodName, HasSourceInfo problemTarget) {
-      InterfaceType itype = types.getInterfaceType(receiver);
-      if (itype == null) {
-        diagnoseNonInterfaceType(problemTarget, receiver);
-        return null;
-      }
-      Member member = itype.lookupMember(methodName);
-      if (member == null) {
-        member = itype.lookupMember("setter " + methodName);
-      }
-      // is "receiver" is inferred, attempt to find member in one of the subtypes
-      boolean hasMemberInSubClasses = false;
-      if (member == null) {
-        if (TypeQuality.of(receiver) == TypeQuality.INFERRED && receiver instanceof InterfaceType) {
-          List<Member> subMembers = ((InterfaceType) receiver).lookupSubTypeMembers(methodName);
-          hasMemberInSubClasses = !subMembers.isEmpty();
-          if (subMembers.size() == 1) {
-            member = subMembers.get(0);
-          }
-        }
-      }
-      // report problem
-      if (member == null && problemTarget != null) {
-        if (reportNoMemberWhenHasInterceptor || !Elements.handlesNoSuchMethod(itype)) {
-          if (typeChecksForInferredTypes && !hasMemberInSubClasses
-              && !isTooGenericInferredType(receiver) || !TypeQuality.isInferred(receiver)) {
-            ErrorCode code = TypeQuality.isInferred(receiver)
-                ? TypeErrorCode.INTERFACE_HAS_NO_METHOD_NAMED_INFERRED
-                : TypeErrorCode.INTERFACE_HAS_NO_METHOD_NAMED;
-            typeError(problemTarget, code, receiver, methodName);
-          }
-        }
-        return null;
-      }
-      return member;
-    }
-
-    /**
-     * If left-hand-side is {@link VariableElement} with propagated type, then remember type before
-     * current "basic block" and set new type.
-     */
-    private void setVariableElementType(Element element, Type type, TypeQuality quality) {
-      if (ElementKind.of(element) == ElementKind.VARIABLE) {
-        VariableElement variableElement = (VariableElement) element;
-        Type newType = Types.makeInferred(type, quality);
-        blockOldTypes.getFirst().setType(variableElement, newType);
-      }
-    }
-
-    /**
-     * @return <code>true</code> if given {@link DartNode} has inferred {@link Type}.
-     */
-    private static boolean hasInferredType(DartNode node) {
-      return node != null && hasInferredType(node.getElement());
-    }
-
-    /**
-     * @return <code>true</code> if given {@link Element} is has inferred {@link Type}.
-     */
-    private static boolean hasInferredType(Element element) {
-      return element != null && element.getType() != null
-          && element.getType().getQuality() != TypeQuality.EXACT;
-    }
-
-    /**
-     * Helper for visiting {@link DartNode} which happens only if "condition" is satisfied. Attempts
-     * to infer types of {@link VariableElement}s from given "condition".
-     */
-    private void visitConditionalNode(DartExpression condition, DartNode node) {
-      final VariableElementsRestorer variableRestorer = new VariableElementsRestorer();
-      try {
-        inferVariableTypesFromIsConditions(condition, variableRestorer);
-        typeOf(node);
-      } finally {
-        variableRestorer.restore();
-      }
-    }
-
-    /**
-     * Helper for setting {@link Type}s of {@link VariableElement}s when given "condition" is
-     * satisfied.
-     */
-    private void inferVariableTypesFromIsConditions(DartExpression condition,
-        final VariableElementsRestorer variableRestorer) {
-      if (condition != null) {
-        condition.accept(new ASTVisitor<Void>() {
-          boolean negation = false;
-          @Override
-          public Void visitUnaryExpression(DartUnaryExpression node) {
-            boolean negationOld = negation;
-            try {
-              if (node.getOperator() == Token.NOT) {
-                negation = !negation;
-              }
-              return super.visitUnaryExpression(node);
-            } finally {
-              negation = negationOld;
-            }
-          }
-
-          @Override
-          public Void visitBinaryExpression(DartBinaryExpression node) {
-            // apply "as" always
-            // apply "is" only if not negated
-            if (node.getOperator() == Token.AS || node.getOperator() == Token.IS && !negation) {
-              DartExpression arg1 = node.getArg1();
-              DartExpression arg2 = node.getArg2();
-              if (arg1 instanceof DartIdentifier && arg1.getElement() instanceof VariableElement
-                  && arg2 instanceof DartTypeExpression) {
-                VariableElement variableElement = (VariableElement) arg1.getElement();
-                Type rhsType = arg2.getType();
-                Type varType = Types.makeInferred(rhsType);
-                variableRestorer.setType(variableElement, varType);
-              }
-            }
-            // operator || means that we can not be sure about types
-            if (node.getOperator() == Token.OR) {
-              return null;
-            }
-            // continue
-            return super.visitBinaryExpression(node);
-          }
-        });
-      }
-    }
-
-    /**
-     * Helper to temporarily set {@link Type} of {@link VariableElement} and restore original later.
-     */
-    private class VariableElementsRestorer {
-      private final Map<VariableElement, Type> typesMap = Maps.newHashMap();
-      void setType(VariableElement element, Type inferredType) {
-        if (element == null) {
-          return;
-        }
-        Type currentType = element.getType();
-        // remember original if not yet
-        if (!typesMap.containsKey(element)) {
-          typesMap.put(element, currentType);
-        }
-        // apply inferred type
-        if (inferredType != null) {
-          if (TypeKind.of(currentType) == TypeKind.DYNAMIC && TypeQuality.isInferred(currentType)) {
-            // if we fell back to Dynamic, keep it
-          } else {
-            Type unionType = getUnionType(currentType, inferredType);
-            if (unionType != currentType) {
-              unionType = Types.makeInferred(unionType);
-            }
-            blockOldTypes.getFirst().rememberOldType(element, element.getType());
-            Elements.setType(element, unionType);
-          }
-        }
-      }
-
-      void restore() {
-        for (Entry<VariableElement, Type> entry : typesMap.entrySet()) {
-          Elements.setType(entry.getKey(), entry.getValue());
-        }
-      }
-    }
-
-    /**
-     * @return the {@link Type} which is both "a" and "b" types. May be "dynamic" if "a" and "b"
-     *         don't form hierarchy.
-     */
-    private Type getUnionType(Type curType, Type newType) {
-      if (TypeKind.of(curType) == TypeKind.DYNAMIC) {
-        return newType;
-      }
-      if (TypeKind.of(newType) == TypeKind.DYNAMIC) {
-        return curType;
-      }
-      if (types.isSubtype(curType, newType)) {
-        return curType;
-      }
-      if (types.isSubtype(newType, curType)) {
-        return newType;
-      }
-      // if InterfaceType, use union
-      if (curType instanceof InterfaceType && newType instanceof InterfaceType) {
-        return types.unionTypes(ImmutableList.of((InterfaceType) curType, (InterfaceType) newType));
-      }
-      // keep type as is
-      return curType;
-    }
-
-    /**
-     * @return <code>true</code> if we can prove that given {@link DartStatement} always leads to
-     *         the exit from the enclosing function.
-     */
-    private static boolean isExitFromFunction(DartStatement statement) {
-      return isExitFromFunction(statement, false);
-    }
-
-    /**
-     * @return <code>true</code> if we can prove that given {@link DartStatement} always leads to
-     *         the exit from the enclosing function, or stops execution of the enclosing loop.
-     */
-    private static boolean isExitFromFunctionOrLoop(DartStatement statement) {
-      return isExitFromFunction(statement, true);
-    }
-
-    /**
-     * @return <code>true</code> if we can prove that given {@link DartStatement} always leads to
-     *         the exit from the enclosing function, or stops enclosing loop execution.
-     */
-    private static boolean isExitFromFunction(DartStatement statement, boolean orLoop) {
-      // "return" is always exit
-      if (statement instanceof DartReturnStatement) {
-        return true;
-      }
-      // "throw" is exit if no enclosing "try"
-      if (statement instanceof DartExprStmt && (((DartExprStmt) statement).getExpression() instanceof DartThrowExpression)) {
-        for (DartNode p = statement; p != null && !(p instanceof DartFunction); p = p.getParent()) {
-          // TODO(scheglov) Can be enhanced:
-          // 1. check if there is "catch" block which can catch this exception;
-          // 2. even if there is such "catch", we will not visit the rest of the "try".
-          if (p instanceof DartTryStatement) {
-            return false;
-          }
-        }
-        return true;
-      }
-      // "block" is exit if its last statement is exit
-      if (statement instanceof DartBlock) {
-        DartBlock block = (DartBlock) statement;
-        List<DartStatement> statements = block.getStatements();
-        if (!statements.isEmpty()) {
-          return isExitFromFunction(statements.get(statements.size() - 1), orLoop);
-        }
-      }
-      // check also if we stop execution of the loop body
-      if (orLoop) {
-        if (statement instanceof DartContinueStatement) {
-          return true;
-        }
-        if (statement instanceof DartBreakStatement) {
-          return true;
-        }
-      }
-      // can not prove that given statement is always exit
-      return false;
-    }
-
-    /**
-     * Helper for setting {@link Type}s of {@link VariableElement}s when given "condition" is NOT
-     * satisfied.
-     */
-    private static void inferVariableTypesFromIsNotConditions(DartExpression condition,
-        final VariableElementsRestorer variableRestorer) {
-      condition.accept(new ASTVisitor<Void>() {
-        boolean negation = false;
-
-        @Override
-        public Void visitUnaryExpression(DartUnaryExpression node) {
-          boolean negationOld = negation;
-          try {
-            if (node.getOperator() == Token.NOT) {
-              negation = !negation;
-            }
-            return super.visitUnaryExpression(node);
-          } finally {
-            negation = negationOld;
-          }
-        }
-
-        @Override
-        public Void visitBinaryExpression(DartBinaryExpression node) {
-          // analyze (v is Type)
-          if (node.getOperator() == Token.IS) {
-            DartExpression arg1 = node.getArg1();
-            DartExpression arg2 = node.getArg2();
-            if (arg1 instanceof DartIdentifier && arg1.getElement() instanceof VariableElement) {
-              VariableElement variableElement = (VariableElement) arg1.getElement();
-              // !(v is Type)
-              if (negation && arg2 instanceof DartTypeExpression) {
-                Type isType = arg2.getType();
-                Type varType = Types.makeInferred(isType);
-                variableRestorer.setType(variableElement, varType);
-              }
-              // (v is! Type)
-              if (!negation) {
-                if (arg2 instanceof DartUnaryExpression) {
-                  DartUnaryExpression unary2 = (DartUnaryExpression) arg2;
-                  if (unary2.getOperator() == Token.NOT
-                      && unary2.getArg() instanceof DartTypeExpression) {
-                    Type isType = unary2.getArg().getType();
-                    Type varType = Types.makeInferred(isType);
-                    variableRestorer.setType(variableElement, varType);
-                  }
-                }
-              }
-            }
-          }
-          // visit || expressions
-          if (node.getOperator() == Token.OR) {
-            return super.visitBinaryExpression(node);
-          }
-          // other operators, such as && - don't infer types
-          return null;
-        }
-      });
-    }
-
-    /**
-     * If type of variable-like {@link DartDeclaration} (i.e. variables, parameter, field) is not
-     * specified and we know somehow this type, then use it.
-     */
-    private static void inferVariableDeclarationType(DartDeclaration<?> node, DartExpression value) {
-      Type type = value.getType();
-      TypeQuality quality = getTypeQuality(value);
-      inferVariableDeclarationType(node, type, quality);
-    }
-
-    /**
-     * If type of variable-like {@link DartDeclaration} (i.e. variables, parameter, field) is not
-     * specified and we know somehow this type, then use it.
-     */
-    private static void inferVariableDeclarationType(DartDeclaration<?> node, Type type,
-        TypeQuality typeQuality) {
-      if (type != null && TypeKind.of(type) != TypeKind.DYNAMIC) {
-        Element element = node.getElement();
-        if (element != null && TypeKind.of(element.getType()) == TypeKind.DYNAMIC) {
-          Type inferredType = Types.makeInferred(type, typeQuality);
-          Elements.setType(element, inferredType);
-          node.getName().setType(inferredType);
-        }
-      }
-    }
-
-    /**
-     * If given "mayBeLiteral" is {@link DartFunctionExpression} without explicit parameters types
-     * and its required type is {@link FunctionAliasType}, then infer parameters types from
-     * {@link FunctionAliasType}.
-     */
-    private static void inferFunctionLiteralParametersTypes(DartExpression mayBeLiteral,
-        Type mayBeFunctionType) {
-      if (mayBeLiteral instanceof DartFunctionExpression) {
-        // prepare required type of function literal
-        FunctionType requiredType = null;
-        if (TypeKind.of(mayBeFunctionType) == TypeKind.FUNCTION) {
-          requiredType = (FunctionType) mayBeFunctionType;
-        }
-        if (TypeKind.of(mayBeFunctionType) == TypeKind.FUNCTION_ALIAS) {
-          FunctionAliasType functionAliasType = (FunctionAliasType) mayBeFunctionType;
-          requiredType = Types.asFunctionType(functionAliasType);
-        }
-        // OK, we can try to infer parameter types
-        if (requiredType != null) {
-          DartFunctionExpression literal = (DartFunctionExpression) mayBeLiteral;
-          List<DartParameter> parameterNodes = literal.getFunction().getParameters();
-          // try to infer types of "normal" parameters
-          List<Type> requiredNormalParameterTypes = requiredType.getParameterTypes();
-          int n = Math.min(requiredNormalParameterTypes.size(), parameterNodes.size());
-          for (int i = 0; i < n; i++) {
-            Type requiredNormalParameterType = requiredNormalParameterTypes.get(i);
-            DartParameter parameterNode = parameterNodes.get(i);
-            inferVariableDeclarationType(parameterNode, requiredNormalParameterType,
-                TypeQuality.INFERRED);
-          }
-        }
-      }
-    }
-
-    /**
-     * When we cannot prove that node was visited, then type is intersection of old/new types.
-     */
-    private void setMergedVariableTypes(BlockTypeContext blockTypeContext) {
-      for (VariableElement variable : blockTypeContext.newTypes.keySet()) {
-        Type newType = blockTypeContext.newTypes.get(variable);
-        Type oldType = blockTypeContext.oldTypes.get(variable);
-        Type mergedType = types.intersection(newType, oldType);
-        TypeQuality mergedTypeQuality = Types.getIntersectionQuality(newType, oldType);
-        setVariableElementType(variable, mergedType, mergedTypeQuality);
-      }
-    }
-
-    private boolean isAssignable(Type t, Type s) {
-      t.getClass(); // Null check.
-      s.getClass(); // Null check.
-      // ignore inferred types, treat them as Dynamic
-      if (!typeChecksForInferredTypes) {
-        if (TypeQuality.isInferred(t) || TypeQuality.isInferred(s)) {
-          return true;
-        }
-      }
-      // do check
-      return types.isAssignable(t, s);
-    }
-
-    private boolean checkAssignable(DartNode node, Type t, Type s) {
-      if (!isAssignable(t, s)) {
-        TypeErrorCode errorCode = TypeQuality.isInferred(t) || TypeQuality.isInferred(s)
-            ? TypeErrorCode.TYPE_NOT_ASSIGNMENT_COMPATIBLE_INFERRED
-                : TypeErrorCode.TYPE_NOT_ASSIGNMENT_COMPATIBLE;
-        typeError(node, errorCode, s, t);
-        return false;
-      }
-      return true;
-    }
-
-    private boolean checkAssignable(Type targetType, DartExpression node) {
-      // analyze "node"
-      Type nodeType = typeOf(node);
-      // target is Dynamic, any source type is good, even "void"
-      if (TypeKind.of(targetType) == TypeKind.DYNAMIC) {
-        return true;
-      }
-      // source was Dynamic
-      if (hasInferredType(node)) {
-        return true;
-      }
-      // OK, check types
-      checkNonVoid(node, nodeType);
-      return checkAssignable(node, targetType, nodeType);
-    }
-
-    private FunctionType getMethodType(Type receiver, Member member, String name,
-                                         DartNode diagnosticNode) {
-      FunctionType functionType = getMethodType0(receiver, member, name, diagnosticNode);
-      if (TypeQuality.isInferred(receiver)) {
-        functionType = (FunctionType) Types.makeInferred(functionType);
-      }
-      return functionType;
-    }
-
-    private FunctionType getMethodType0(Type receiver, Member member, String name,
-        DartNode diagnosticNode) {
-      if (member == null) {
-        return dynamicType;
-      }
-      Element element = member.getElement();
-      switch (ElementKind.of(element)) {
-        case METHOD: {
-          MethodElement method = (MethodElement) element;
-          if (method.getModifiers().isStatic()) {
-            return typeError(diagnosticNode, TypeErrorCode.IS_STATIC_METHOD_IN,
-                             name, receiver);
-          }
-          return (FunctionType) member.getType();
-        }
-        case FIELD: {
-          FieldElement field = (FieldElement) element;
-          if (field.getModifiers().isStatic()) {
-            return typeError(diagnosticNode, TypeErrorCode.IS_STATIC_FIELD_IN,
-                             name, receiver);
-          }
-          switch (TypeKind.of(member.getType())) {
-            case FUNCTION:
-              return (FunctionType) member.getType();
-            case FUNCTION_ALIAS:
-              return Types.asFunctionType((FunctionAliasType) member.getType());
-            default:
-              // target.field() as Function invocation.
-              if (Elements.isFieldWithGetter(field)) {
-                Type fieldType = field.getType();
-                if (!types.isAssignable(functionType, fieldType)) {
-                  onError(diagnosticNode, TypeErrorCode.NOT_A_FUNCTION_TYPE_FIELD, field.getName(), fieldType);
-                }
-              }
-              return dynamicType;
-          }
-        }
-        default:
-          if (typeChecksForInferredTypes || !TypeQuality.isInferred(receiver)) {
-            TypeErrorCode errorCode = TypeQuality.isInferred(receiver)
-                ? TypeErrorCode.NOT_A_METHOD_IN_INFERRED : TypeErrorCode.NOT_A_METHOD_IN;
-            typeError(diagnosticNode, errorCode, name, receiver);
-          }
-          return dynamicType;
-      }
-    }
-
-    private Type diagnoseNonInterfaceType(HasSourceInfo node, Type type) {
-      switch (TypeKind.of(type)) {
-        case DYNAMIC:
-          return type;
-
-        case FUNCTION:
-        case FUNCTION_ALIAS:
-        case INTERFACE:
-        case VARIABLE:
-          // Cannot happen.
-          throw internalError(node, type.toString());
-
-        case NONE:
-          throw internalError(node, "type is null");
-
-        case VOID:
-          return typeError(node, TypeErrorCode.VOID);
-
-        default:
-          throw internalError(node, type.getKind().name());
-      }
-    }
-
-    private Type checkArguments(DartNode diagnosticNode,
-                                List<DartExpression> argumentNodes,
-                                Iterator<Type> argumentTypes, FunctionType ftype,
-                                List<VariableElement> parameters) {
-      int argumentIndex = 0;
-      // Check positional parameters.
-      {
-        List<Type> parameterTypes = ftype.getParameterTypes();
-        for (Type parameterType : parameterTypes) {
-          parameterType.getClass(); // quick null check
-          if (argumentTypes.hasNext()) {
-            Type argumentType = argumentTypes.next();
-            argumentType.getClass(); // quick null check
-            DartExpression argumentNode = argumentNodes.get(argumentIndex);
-            if (argumentNode instanceof DartNamedExpression) {
-              onError(argumentNode, TypeErrorCode.EXPECTED_POSITIONAL_ARGUMENT, parameterType);
-              return ftype.getReturnType();
-            }
-            if (parameters != null) {
-              argumentNode.setInvocationParameterId(parameters.get(argumentIndex));
-            } else {
-              argumentNode.setInvocationParameterId(argumentIndex);
-            }
-            if (checkAssignable(argumentNode, parameterType, argumentType)) {
-              inferFunctionLiteralParametersTypes(argumentNode, parameterType);
-            }
-            argumentIndex++;
-          } else {
-            onError(diagnosticNode, TypeErrorCode.MISSING_ARGUMENT, parameterType);
-            return ftype.getReturnType();
-          }
-        }
-      }
-
-      // Check optional parameters.
-      {
-        Map<String, Type> optionalParameterTypes = ftype.getOptionalParameterTypes();
-        Iterator<Entry<String, Type>> optionalParameterTypesIterator =
-            optionalParameterTypes.entrySet().iterator();
-        while (optionalParameterTypesIterator.hasNext()
-            && argumentTypes.hasNext()
-            && !(argumentNodes.get(argumentIndex) instanceof DartNamedExpression)) {
-          Entry<String, Type> namedEntry = optionalParameterTypesIterator.next();
-          Type optionalType = namedEntry.getValue();
-          optionalType.getClass(); // quick null check
-          Type argumentType = argumentTypes.next();
-          argumentType.getClass(); // quick null check
-          DartExpression argumentNode = argumentNodes.get(argumentIndex);
-          if (parameters != null) {
-            argumentNode.setInvocationParameterId(parameters.get(argumentIndex));
-          } else {
-            argumentNode.setInvocationParameterId(argumentIndex);
-          }
-          if (checkAssignable(argumentNode, optionalType, argumentType)) {
-            inferFunctionLiteralParametersTypes(argumentNode, optionalType);
-          }
-          argumentIndex++;
-        }
-      }
-
-      // Check named parameters.
-      {
-        Set<String> usedNamedParametersPositional = Sets.newHashSet();
-        Set<String> usedNamedParametersNamed = Sets.newHashSet();
-        Map<String, Type> namedParameterTypes = ftype.getNamedParameterTypes();
-        while (argumentTypes.hasNext()
-            && argumentNodes.get(argumentIndex) instanceof DartNamedExpression) {
-          DartNamedExpression namedExpression =
-              (DartNamedExpression) argumentNodes.get(argumentIndex);
-          DartExpression argumentNode = namedExpression.getExpression();
-          // Prepare parameter name.
-          String parameterName = namedExpression.getName().getName();
-          if (parameters != null) {
-            for (VariableElement parameter : parameters) {
-              if (Objects.equal(parameter.getName(), parameterName)) {
-                namedExpression.setInvocationParameterId(parameter);
-                namedExpression.getName().setInvocationParameterId(parameter);
-                argumentNode.setInvocationParameterId(parameter);
-                break;
-              }
-            }
-          } else {
-            namedExpression.setInvocationParameterId(parameterName);
-            argumentNode.setInvocationParameterId(parameterName);
-          }
-          if (usedNamedParametersPositional.contains(parameterName)) {
-            onError(namedExpression, TypeErrorCode.DUPLICATE_NAMED_ARGUMENT);
-          } else if (usedNamedParametersNamed.contains(parameterName)) {
-            onError(namedExpression, ResolverErrorCode.DUPLICATE_NAMED_ARGUMENT);
-          } else {
-            usedNamedParametersNamed.add(parameterName);
-          }
-          // Check parameter type.
-          Type namedParameterType = namedParameterTypes.get(parameterName);
-          Type argumentType = argumentTypes.next();
-          if (namedParameterType != null) {
-            argumentType.getClass(); // quick null check
-            if (checkAssignable(argumentNode, namedParameterType, argumentType)) {
-              inferFunctionLiteralParametersTypes(argumentNode, namedParameterType);
-            }
-          } else {
-            onError(namedExpression, TypeErrorCode.NO_SUCH_NAMED_PARAMETER, parameterName);
-          }
-          argumentIndex++;
-        }
-      }
-      // Check rest (currently removed from specification).
-      if (ftype.hasRest()) {
-        while (argumentTypes.hasNext()) {
-          checkAssignable(argumentNodes.get(argumentIndex), ftype.getRest(), argumentTypes.next());
-          argumentIndex++;
-        }
-      }
-      // Report extra arguments.
-      while (argumentTypes.hasNext()) {
-        argumentTypes.next();
-        onError(argumentNodes.get(argumentIndex), TypeErrorCode.EXTRA_ARGUMENT);
-        argumentIndex++;
-      }
-
-      // Return type.
-      Type type = ftype.getReturnType();
-      type.getClass(); // quick null check
-      return type;
-    }
-
-    @Override
-    public Type visitTypeNode(DartTypeNode node) {
-      return validateTypeNode(node);
-    }
-
-    private Type validateTypeNode(DartTypeNode node) {
-      Type type = node.getType(); // Already calculated by resolver.
-      switch (TypeKind.of(type)) {
-        case NONE:
-          return typeError(node, TypeErrorCode.INTERNAL_ERROR,
-                           String.format("type \"%s\" is null", node));
-        case INTERFACE: {
-          InterfaceType itype = (InterfaceType) type;
-          validateBounds(node.getTypeArguments(),
-                         itype.getArguments(),
-                         itype.getElement().getTypeParameters());
-          return itype;
-        }
-        default:
-          return type;
-      }
-    }
-
-    private void validateBounds(List<? extends DartNode> diagnosticNodes,
-                                List<Type> arguments,
-                                List<Type> parameters) {
-      if (arguments.size() == parameters.size() && arguments.size() == diagnosticNodes.size()) {
-        List<Type> bounds = Lists.newArrayListWithCapacity(parameters.size());
-        for (Type parameter : parameters) {
-          TypeVariable variable = (TypeVariable) parameter;
-          Type bound = variable.getTypeVariableElement().getBound();
-          if (bound == null) {
-            internalError(variable.getElement(), "bound is null");
-          }
-          bounds.add(bound);
-        }
-        bounds = Types.subst(bounds, arguments, parameters);
-        for (int i = 0; i < arguments.size(); i++) {
-          Type t = bounds.get(i);
-          Type s = arguments.get(i);
-          if (!types.isSubtype(s, t)) {
-            onError(diagnosticNodes.get(i),
-                TypeErrorCode.TYPE_NOT_ASSIGNMENT_COMPATIBLE, s, t);
-          }
-        }
-      }
-    }
-
-    /* Check for a type variable is repeated in its own bounds:
-     * e.g. Foo<T extends T>
-     */
-    private void checkCyclicBounds(List<? extends Type> arguments) {
-      for (Type argument : arguments) {
-        if (TypeKind.of(argument).equals(TypeKind.VARIABLE)) {
-          TypeVariable typeVar = (TypeVariable) argument;
-          checkCyclicBound(typeVar, typeVar.getTypeVariableElement().getBound());
-        }
-      }
-    }
-
-    private void checkCyclicBound(TypeVariable variable, Type bound) {
-      switch(TypeKind.of(bound)) {
-        case VARIABLE: {
-          TypeVariable boundType = (TypeVariable)bound;
-          if (boundType.equals(variable)) {
-            onError(boundType.getElement(),
-                    TypeErrorCode.CYCLIC_REFERENCE_TO_TYPE_VARIABLE,
-                    boundType.getElement().getOriginalName());
-          }
-          break;
-        }
-        default:
-          break;
-      }
-    }
-
-    /**
-     * Returns the type of a node.  If a type of an expression can't be resolved,
-     * returns the dynamic type.
-     *
-     * @return a non-null type
-     */
-    Type typeOf(DartNode node) {
-      if (node == null) {
-        return dynamicType;
-      }
-      // prepare new type
-      Type result = node.accept(this);
-      if (result == null) {
-         return dynamicType;
-      }
-      // set new type, or keep existing
-      if (node.getType() == null) {
-        node.setType(result);
-      } else {
-        result = node.getType();
-      }
-      // done
-      return result;
-    }
-
-    /**
-     * Returns the type of a node, registering an error if the type is unresolved or
-     * void.
-     *
-     * @return a non-null type
-     */
-    private Type nonVoidTypeOf(DartNode node) {
-      Type type = typeOf(node);
-      return checkNonVoid(node, type);
-    }
-
-    /**
-     * @return the given {@link Type}, registering an error if it is unresolved or void.
-     */
-    private Type checkNonVoid(HasSourceInfo errorTarget, Type type) {
-      switch (TypeKind.of(type)) {
-        case VOID:
-        case NONE:
-          return typeError(errorTarget, TypeErrorCode.VOID);
-        default:
-          return type;
-      }
-    }
-
-    @Override
-    public Type visitArrayAccess(DartArrayAccess node) {
-      Type target = typeOf(node.getRealTarget());
-      DartExpression argKey = node.getKey();
-      // t[k] = v
-      if (node.getParent() instanceof DartBinaryExpression) {
-        DartBinaryExpression binary = (DartBinaryExpression) node.getParent();
-        if (binary.getArg1() == node && binary.getOperator() == Token.ASSIGN) {
-          DartExpression argValue = binary.getArg2();
-          analyzeTernaryOperator(node, target, Token.ASSIGN_INDEX, node, argKey, argValue);
-          binary.setElement(node.getElement());
-          return argValue.getType();
-        }
-      }
-      // print( t[k] )
-      Type result = analyzeBinaryOperator(node, target, Token.INDEX, node, argKey);
-      return Types.makeInferred(result, target.getQuality());
-    }
-
-    /**
-     * Asserts that given {@link DartExpression} is valid for using in "assert" statement.
-     */
-    private void checkAssertCondition(DartExpression conditionNode) {
-      Type condition = nonVoidTypeOf(conditionNode);
-      switch (condition.getKind()) {
-        case FUNCTION:
-          FunctionType ftype = (FunctionType) condition;
-          Type returnType = ftype.getReturnType();
-          if (!types.isAssignable(boolType, returnType) || !ftype.getParameterTypes().isEmpty()) {
-            typeError(conditionNode, TypeErrorCode.ASSERT_BOOL);
-          }
-          break;
-
-        default:
-          if (!types.isAssignable(boolType, condition)) {
-            typeError(conditionNode, TypeErrorCode.ASSERT_BOOL);
-          }
-          break;
-      }
-    }
-
-    @Override
-    public Type visitBlock(DartBlock node) {
-      try {
-        return typeAsVoid(node);
-      } finally {
-        VariableElementsRestorer variableRestorer = restoreOnBlockExit.remove(node);
-        if (variableRestorer != null) {
-          variableRestorer.restore();
-        }
-      }
-    }
-
-    private Type typeAsVoid(DartNode node) {
-      node.visitChildren(this);
-      return voidType;
-    }
-
-    @Override
-    public Type visitBreakStatement(DartBreakStatement node) {
-      return voidType;
-    }
-
-    @Override
-    public Type visitCascadeExpression(DartCascadeExpression node) {
-      DartExpression target = node.getTarget();
-      Type type = nonVoidTypeOf(target);
-      node.setType(type);
-      inferCascadeType(node);
-      node.visitChildren(this);
-      return type;
-    }
-
-    /**
-     * Infers {@link Type} of {@link DartCascadeExpression} from context.
-     */
-    private void inferCascadeType(DartCascadeExpression node) {
-      // field declaration
-      if (node.getParent() instanceof DartField) {
-        DartField field = (DartField) node.getParent();
-        Type varType = field.getElement().getType();
-        setCascadeUnionType(node, varType);
-      }
-      // variable declaration
-      if (node.getParent() instanceof DartVariable) {
-        DartVariable var = (DartVariable) node.getParent();
-        Type varType = var.getElement().getType();
-        setCascadeUnionType(node, varType);
-      }
-      // assignment
-      if (node.getParent() instanceof DartBinaryExpression) {
-        DartBinaryExpression binary = (DartBinaryExpression) node.getParent();
-        if (binary.getOperator() == Token.ASSIGN && binary.getArg2() == node
-            && binary.getArg1() != null) {
-          Element leftElement = binary.getArg1().getElement();
-          if (leftElement != null) {
-            Type varType = leftElement.getType();
-            setCascadeUnionType(node, varType);
-          }
-        }
-      }
-    }
-
-    /**
-     * Sets for given {@link DartCascadeExpression} and its target {@link Type} which is union of
-     * existing type and "newType".
-     */
-    private void setCascadeUnionType(DartCascadeExpression node, Type newType) {
-      DartExpression target = node.getTarget();
-      Type type = node.getType();
-      if (isExplicitlySpecifiedType(newType) && types.isAssignable(type, newType)) {
-        Type unionType = getUnionType(type, newType);
-        unionType = Types.makeInferred(unionType);
-        node.setType(unionType);
-        target.setType(unionType);
-      }
-    }
-
-    @Override
-    public Type visitFunctionObjectInvocation(DartFunctionObjectInvocation node) {
-      ClassElement element = functionType.getElement();
-      node.setElement(element);
-      checkDeprecated(node, element);
-      return checkInvocation(node, node, null, typeOf(node.getTarget()));
-    }
-
-    @Override
-    public Type visitMethodInvocation(DartMethodInvocation node) {
-      if (node.getFunctionName().isResolutionAlreadyReportedThatTheMethodCouldNotBeFound()) {
-        return dynamicType;
-      }
-      DartNode target = node.getRealTarget();
-      DartIdentifier nameNode = node.getFunctionName();
-      String name = node.getFunctionNameString();
-      Element element = node.getElement();
-      if (element != null && (element.getModifiers().isStatic()
-                              || Elements.isTopLevel(element))) {
-        typeOf(target);
-        node.setElement(element);
-        checkDeprecated(nameNode, element);
-        return checkInvocation(node, nameNode, name, element.getType());
-      }
-      Type receiver = nonVoidTypeOf(target);
-      Member member = lookupMember(receiver, name, nameNode);
-      if (member != null) {
-        element = member.getElement();
-        checkIllegalPrivateAccess(node.getFunctionName(), element, name);
-        node.setElement(element);
-        if (nameNode != null) {
-          nameNode.setElement(element);
-        }
-      }
-      if (Elements.isAbstractFieldWithoutGetter(element)) {
-        onError(nameNode, TypeErrorCode.USE_ASSIGNMENT_ON_SETTER, name);
-      }
-      checkDeprecated(nameNode, nameNode.getElement());
-      FunctionType methodType = getMethodType(receiver, member, name, nameNode);
-      Type returnType = checkInvocation(node, nameNode, name, methodType);
-      returnType = ExternalTypeAnalyzers.resolve(types, node, element, returnType);
-      warningEffectiveIntegerDivision(node, element);
-      return returnType;
-    }
-
-    /**
-     * http://code.google.com/p/dart/issues/detail?id=5652
-     */
-    private void warningEffectiveIntegerDivision(DartMethodInvocation node, Element element) {
-      if (element != null && element.getName().equals("toInt")
-          && element.getEnclosingElement() != null
-          && element.getEnclosingElement().getName().equals("num")) {
-        DartExpression target = node.getTarget();
-        while (target instanceof DartParenthesizedExpression) {
-          target = ((DartParenthesizedExpression) target).getExpression();
-        }
-        if (target instanceof DartBinaryExpression) {
-          DartBinaryExpression binary = (DartBinaryExpression) target;
-          if (binary.getOperator() == Token.DIV && intType.equals(binary.getArg1().getType())
-              && intType.equals(binary.getArg2().getType())) {
-            typeError(node, TypeErrorCode.USE_INTEGER_DIVISION);
-          }
-        }
-      }
-    }
-
-    private void checkIllegalPrivateAccess(DartNode diagnosticNode, Element element, String name) {
-      if (DartIdentifier.isPrivateName(name)) {
-        if (!Elements.areSameLibrary(currentMethod, element)) {
-          onError(diagnosticNode, TypeErrorCode.ILLEGAL_ACCESS_TO_PRIVATE, name);
-        }
-      }
-    }
-
-    @Override
-    public Type visitSuperConstructorInvocation(DartSuperConstructorInvocation node) {
-      return checkConstructorForwarding(node, node.getElement());
-    }
-
-    private Type checkConstructorForwarding(DartInvocation node, ConstructorElement element) {
-      if (element == null) {
-        visit(node.getArguments());
-        return voidType;
-      } else {
-        node.setElement(element);
-        checkDeprecated(node, element);
-        checkInvocation(node, node, null, typeAsMemberOf(element, currentClass));
-        return voidType;
-      }
-    }
-
-    @Override
-    public Type visitCase(DartCase node) {
-      node.visitChildren(this);
-      return voidType;
-    }
-
-    @Override
-    public Type visitClass(DartClass node) {
-      ClassNodeElement element = node.getElement();
-      InterfaceType type = element.getType();
-      checkCyclicBounds(type.getArguments());
-      // remember unimplemented members
-      {
-        List<Element> unimplementedMembers = findUnimplementedMembers(element);
-        if (!node.getModifiers().isAbstract() && !unimplementedMembers.isEmpty() &&
-            (reportNoMemberWhenHasInterceptor || !Elements.handlesNoSuchMethod(type))) {
-          StringBuilder sb = getUnimplementedMembersMessage(element, unimplementedMembers);
-          onError(node.getName(), TypeErrorCode.CONCRETE_CLASS_WITH_UNIMPLEMENTED_MEMBERS,
-              node.getName(), sb.toString());
-        }
-      }
-      //
-      setCurrentClass(type);
-      visit(node.getTypeParameters());
-      if (node.getSuperclass() != null) {
-        validateTypeNode(node.getSuperclass());
-      }
-      if (node.getInterfaces() != null) {
-        for (DartTypeNode interfaceNode : node.getInterfaces()) {
-          validateTypeNode(interfaceNode);
-        }
-      }
-      visit(node.getMembers());
-      checkInterfaceConstructors(element);
-      try {
-        checkClassDuplicateInterfaces(node, element, element.getAllSupertypes());
-      } catch (CyclicDeclarationException ignored) {
-      }
-
-      // Finish current class.
-      setCurrentClass(null);
-      return type;
-    }
-
-    /**
-     * Check for duplicate interfaces that aren't assignable to each other due to parameterization.
-     *
-     * Issue 3803: This isn't in the spec as of 0.10, adding as a 'value added' check, because there is no
-     * way to satisfy the method override rules without either causing errors in checked mode or
-     * causing override errors for every method implemented for this interface.
-     *
-     * @param classElement
-     */
-    private void checkClassDuplicateInterfaces(DartClass node, ClassElement classElement,
-        List<InterfaceType> allSupertypes) {
-      Map<Element, InterfaceType> elementMap = Maps.newHashMap();
-      for (InterfaceType supertype : allSupertypes) {
-        Element e = supertype.getElement();
-        if (e != null) {
-          InterfaceType foundType = elementMap.get(e);
-          if (foundType != null && ! types.isAssignable(supertype, foundType)) {
-            typeError(node.getName(), TypeErrorCode.INCOMPATIBLE_TYPES_IN_HIERARCHY, foundType.toString(),
-                supertype.toString());
-          } else {
-            elementMap.put(e, supertype);
-          }
-        }
-      }
-    }
-    /**
-     * Checks that interface constructors have corresponding methods in default class.
-     */
-    private void checkInterfaceConstructors(ClassElement interfaceElement) {
-      // If no default class, do nothing.
-      if (interfaceElement.getDefaultClass() == null) {
-        return;
-      }
-      // Analyze all constructors.
-      String interfaceClassName = interfaceElement.getName();
-      String defaultClassName = interfaceElement.getDefaultClass().getElement().getName();
-      for (ConstructorElement interfaceConstructor : interfaceElement.getConstructors()) {
-        ConstructorElement defaultConstructor = interfaceConstructor.getDefaultConstructor();
-        if (defaultConstructor != null) {
-          // TODO(scheglov)
-          // It is a compile-time error if kI and kF do not have identical type parameters
-          // TODO /end
-          // Validate types of required and optional parameters.
-          {
-            List<String> interfaceTypes = Elements.getParameterTypeNames(interfaceConstructor);
-            List<String> defaultTypes = Elements.getParameterTypeNames(defaultConstructor);
-            if (interfaceTypes.size() == defaultTypes.size()
-                && !interfaceTypes.equals(defaultTypes)) {
-              onError(
-                  interfaceConstructor,
-                  TypeErrorCode.DEFAULT_CONSTRUCTOR_TYPES,
-                  Elements.getRawMethodName(interfaceConstructor),
-                  interfaceClassName,
-                  Joiner.on(",").join(interfaceTypes),
-                  Elements.getRawMethodName(defaultConstructor),
-                  defaultClassName,
-                  Joiner.on(",").join(defaultTypes));
-            }
-          }
-        }
-      }
-    }
-
-    private List<Element> findUnimplementedMembers(ClassElement classElement) {
-      // May be has members already (cached or already analyzed ClassNodeElement).
-      List<Element> members = classElement.getUnimplementedMembers();
-      if (members != null) {
-        return members;
-      }
-      // If no cached result, then should be node based.
-      ClassNodeElement classNodeElement = (ClassNodeElement) classElement;
-      // Analyze ClassElement node.
-      AbstractMethodFinder finder = new AbstractMethodFinder(classNodeElement.getType());
-      classNodeElement.getNode().accept(finder);
-      // Prepare unimplemented members.
-      if (classNodeElement.isInterface()) {
-        members = Collections.emptyList();
-      } else {
-        members = finder.unimplementedElements;
-      }
-      // Remember unimplemented methods.
-      classNodeElement.setUnimplementedMembers(members);
-      return members;
-    }
-
-    @Override
-    public Type visitConditional(DartConditional node) {
-      checkCondition(node.getCondition());
-      Type left = typeOf(node.getThenExpression());
-      Type right = typeOf(node.getElseExpression());
-      return types.intersection(left, right);
-    }
-
-    private Type checkCondition(DartExpression condition) {
-      Type type = nonVoidTypeOf(condition);
-      checkAssignable(condition, boolType, type);
-      return type;
-    }
-
-    @Override
-    public Type visitContinueStatement(DartContinueStatement node) {
-      return voidType;
-    }
-
-    @Override
-    public Type visitDefault(DartDefault node) {
-      node.visitChildren(this);
-      return typeAsVoid(node);
-    }
-
-    @Override
-    public Type visitDoWhileStatement(DartDoWhileStatement node) {
-      checkCondition(node.getCondition());
-      typeOf(node.getBody());
-      return voidType;
-    }
-
-    @Override
-    public Type visitEmptyStatement(DartEmptyStatement node) {
-      return typeAsVoid(node);
-    }
-
-    @Override
-    public Type visitFieldDefinition(DartFieldDefinition node) {
-      node.visitChildren(this);
-      return voidType;
-    }
-
-    @Override
-    public Type visitForInStatement(DartForInStatement node) {
-      Type variableType;
-      VariableElement variableElement = null;
-      if (node.introducesVariable()) {
-        variableType = typeOf(node.getVariableStatement());
-        variableElement = node.getVariableStatement().getVariables().get(0).getElement();
-      } else {
-        variableType = typeOf(node.getIdentifier());
-        // in most cases variable, but sometimes field
-        Element identifierElement = node.getIdentifier().getElement();
-        if (identifierElement instanceof VariableElement) {
-          variableElement = (VariableElement) identifierElement;
-        }
-      }
-      // prepare Iterable type
-      DartExpression iterableExpression = node.getIterable();
-      Type iterableType = typeOf(iterableExpression);
-      // analyze compatibility of variable and Iterator elements types
-      Member iteratorMember = lookupMember(iterableType, "iterator", iterableExpression);
-      Type elementType = null;
-      if (iteratorMember != null) {
-        Type memberReturnType = null;
-        if (TypeKind.of(iteratorMember.getType()) == TypeKind.FUNCTION) {
-          FunctionType iteratorMethod = (FunctionType) iteratorMember.getType();
-          memberReturnType = iteratorMethod.getReturnType();
-        } else if (ElementKind.of(iteratorMember.getElement()) == ElementKind.FIELD) {
-          memberReturnType = iteratorMember.getType();
-        }
-        if (memberReturnType != null) {
-          InterfaceType asInstanceOf = types.asInstanceOf(memberReturnType,
-              dynamicIteratorType.getElement());
-          if (asInstanceOf != null) {
-            elementType = asInstanceOf.getArguments().get(0);
-            checkAssignable(iterableExpression, variableType, elementType);
-          } else {
-            InterfaceType expectedIteratorType = dynamicIteratorType.subst(
-                Arrays.asList(variableType), dynamicIteratorType.getElement().getTypeParameters());
-            typeError(iterableExpression, TypeErrorCode.FOR_IN_WITH_INVALID_ITERATOR_RETURN_TYPE,
-                expectedIteratorType);
-          }
-        } else {
-          // Not a function
-          typeError(iterableExpression, TypeErrorCode.FOR_IN_WITH_ITERATOR_FIELD);
-        }
-      }
-      // visit body with inferred variable type
-      VariableElementsRestorer variableRestorer = new VariableElementsRestorer();
-      try {
-        if (variableElement != null && elementType != null) {
-          variableRestorer.setType(variableElement, elementType);
-        }
-        BlockTypeContext blockTypeContext = new BlockTypeContext();
-        blockOldTypes.addFirst(blockTypeContext);
-        try {
-          return typeAsVoid(node.getBody());
-        } finally {
-          blockOldTypes.removeFirst();
-          setMergedVariableTypes(blockTypeContext);
-        }
-      } finally {
-        variableRestorer.restore();
-      }
-    }
-
-    @Override
-    public Type visitForStatement(DartForStatement node) {
-      typeOf(node.getInit());
-      DartExpression condition = node.getCondition();
-      checkCondition(condition);
-      // visit body
-      BlockTypeContext blockTypeContext = new BlockTypeContext();
-      blockOldTypes.addFirst(blockTypeContext);
-      try {
-        visitConditionalNode(condition, node.getBody());
-        visitConditionalNode(condition, node.getIncrement());
-      } finally {
-        blockOldTypes.removeFirst();
-        setMergedVariableTypes(blockTypeContext);
-      }
-      // done
-      return voidType;
-    }
-
-    @Override
-    public Type visitFunction(DartFunction node) {
-      blockOldTypes.addFirst(new BlockTypeContext());
-      try {
-        Type previous = expected;
-        visit(node.getParameters());
-        expected = typeOf(node.getReturnTypeNode());
-        typeOf(node.getBody());
-        expected = previous;
-      } finally {
-        blockOldTypes.removeFirst();
-      }
-      return voidType;
-    }
-
-    @Override
-    public Type visitFunctionExpression(DartFunctionExpression node) {
-      node.visitChildren(this);
-      Type result = node.getElement().getType();
-      result.getClass(); // quick null check
-      return result;
-    }
-
-    @Override
-    public Type visitFunctionTypeAlias(DartFunctionTypeAlias node) {
-      FunctionAliasElement element = node.getElement();
-      FunctionAliasType type = element.getType();
-      if (TypeKind.of(type) == TypeKind.FUNCTION_ALIAS) {
-        checkCyclicBounds(type.getElement().getTypeParameters());
-        if (hasFunctionTypeAliasSelfReference(element)) {
-          onError(node, TypeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF);
-        }
-      }
-      return typeAsVoid(node);
-    }
-
-    @Override
-    public Type visitSyntheticErrorIdentifier(DartSyntheticErrorIdentifier node) {
-      return dynamicType;
-    }
-
-    @Override
-    public Type visitIdentifier(DartIdentifier node) {
-      if (node.getType() != null) {
-        return node.getType();
-      }
-      if (node.getParent() instanceof DartDeclaration<?>
-          && ((DartDeclaration<?>) node.getParent()).getName() == node) {
-        return node.getType();
-      }
-      if (node.getParent() instanceof DartComment) {
-        return dynamicType;
-      }
-      Element element = node.getElement();
-      Type type;
-      switch (ElementKind.of(element)) {
-        case VARIABLE:
-        case PARAMETER:
-        case FUNCTION_OBJECT:
-          type = element.getType();
-          type.getClass(); // quick null check
-
-          break;
-
-        case CLASS:
-          return element.getType();
-
-        case FIELD:
-          type = typeAsMemberOf(element, currentClass);
-          // try to resolve as getter/setter
-          FieldElement fieldElement = (FieldElement) element;
-          DartNode properyAccess = ASTNodes.getPropertyAccessNode(node);
-          if (ASTNodes.inGetterContext(properyAccess)) {
-            MethodElement getter = fieldElement.getGetter();
-            if (getter != null) {
-              type = ((FunctionType) typeAsMemberOf(getter, currentClass)).getReturnType();
-              node.setType(type);
-            }
-          } else if (ASTNodes.inSetterContext(properyAccess)) {
-            MethodElement setter = fieldElement.getSetter();
-            if (setter != null) {
-              if (setter.getParameters().size() > 0) {
-                type = setter.getParameters().get(0).getType();
-                node.setType(type);
-              }
-            }
-          }
-          type.getClass(); // quick null check
-          break;
-
-        case METHOD:
-          type = typeAsMemberOf(element, currentClass);
-          type.getClass(); // quick null check
-          break;
-
-        case NONE:
-          if (!node.isResolutionAlreadyReportedThatTheMethodCouldNotBeFound()) {
-            typeError(node, TypeErrorCode.CANNOT_BE_RESOLVED, node.getName());
-          }
-          return dynamicType;
-
-        case DYNAMIC:
-          return element.getType();
-
-        default:
-          return voidType;
-      }
-      return type;
-    }
-
-    @Override
-    public Type visitIfStatement(DartIfStatement node) {
-      DartExpression condition = node.getCondition();
-      checkCondition(condition);
-      // visit "then"
-      BlockTypeContext thenTypeContext = new BlockTypeContext();
-      blockOldTypes.addFirst(thenTypeContext);
-      DartStatement thenStatement = node.getThenStatement();
-      visitConditionalNode(condition, thenStatement);
-      blockOldTypes.removeFirst();
-      Map<VariableElement, Type> thenVariableTypes = thenTypeContext.getNewTypesAndRestoreOld();
-      // visit "else"
-      DartStatement elseStatement = node.getElseStatement();
-      BlockTypeContext elseTypeContext = new BlockTypeContext();
-      {
-        VariableElementsRestorer variableRestorer = new VariableElementsRestorer();
-        // if has "else", then types inferred from "is! Type" applied only to "else"
-        if (elseStatement != null) {
-          blockOldTypes.addFirst(elseTypeContext);
-          inferVariableTypesFromIsNotConditions(condition, variableRestorer);
-          typeOf(elseStatement);
-          variableRestorer.restore();
-          blockOldTypes.removeFirst();
-        }
-        // if no "else", then inferred types applied to the end of the method/loop
-        if (elseStatement == null) {
-          if (isExitFromFunction(thenStatement)) {
-            inferVariableTypesFromIsNotConditions(condition, variableRestorer);
-          } else if (isExitFromFunctionOrLoop(thenStatement)) {
-            DartBlock restoreBlock = getBlockForLoopTypesInference(node);
-            variableRestorer = restoreOnBlockExit.get(restoreBlock);
-            if (variableRestorer == null) {
-              variableRestorer = new VariableElementsRestorer();
-              restoreOnBlockExit.put(restoreBlock, variableRestorer);
-            }
-            restoreOnBlockExit.put(restoreBlock, variableRestorer);
-            inferVariableTypesFromIsNotConditions(condition, variableRestorer);
-          }
-        }
-      }
-      Map<VariableElement, Type> elseVariableTypes = elseTypeContext.getNewTypesAndRestoreOld();
-      // merge variable types
-      {
-        Set<VariableElement> variables = Sets.newHashSet();
-        variables.addAll(thenVariableTypes.keySet());
-        variables.addAll(elseVariableTypes.keySet());
-        for (VariableElement variable : variables) {
-          List<Type> possibleTypes = Lists.newArrayList();
-          Type thenType = thenVariableTypes.get(variable);
-          Type elseType = elseVariableTypes.get(variable);
-          if (thenType != null && elseType != null) {
-            possibleTypes.add(thenType);
-            possibleTypes.add(elseType);
-          }
-          if (thenType != null && elseType == null) {
-            possibleTypes.add(thenType);
-            possibleTypes.add(variable.getType());
-          }
-          if (thenType == null && elseType != null) {
-            possibleTypes.add(variable.getType());
-            possibleTypes.add(elseType);
-          }
-          // do merge
-          Type mergedType = types.intersection(possibleTypes);
-          TypeQuality mergedTypeQuality = Types.getIntersectionQuality(possibleTypes);
-          setVariableElementType(variable, mergedType, mergedTypeQuality);
-        }
-      }
-      // done
-      return voidType;
-    }
-
-    @Override
-    public Type visitInitializer(DartInitializer node) {
-      DartIdentifier name = node.getName();
-      if (name != null) {
-        checkAssignable(typeOf(name), node.getValue());
-      } else {
-        typeOf(node.getValue());
-      }
-      return voidType;
-    }
-
-    @Override
-    public Type visitLabel(DartLabel node) {
-      return typeAsVoid(node);
-    }
-
-    @Override
-    public Type visitMapLiteral(DartMapLiteral node) {
-      visit(node.getTypeArguments());
-      InterfaceType type = node.getType();
-
-      // The Map literal has an implicit key type of String, so only one parameter is
-      // specified <V> where V is the type of the value.
-      checkAssignable(node, defaultLiteralMapType, type);
-
-      // Check the map literal entries against the return type.
-      {
-        Type valueType = type.getArguments().get(1);
-        for (DartMapLiteralEntry literalEntry : node.getEntries()) {
-          boolean isValueAssignable = checkAssignable(literalEntry, typeOf(literalEntry), valueType);
-          if (developerModeChecks && !isValueAssignable) {
-            typeError(literalEntry, ResolverErrorCode.MAP_LITERAL_ELEMENT_TYPE, valueType);
-          }
-        }
-      }
-
-      // Check that each key literal is unique.
-      Set<String> keyValues = Sets.newHashSet();
-      for (DartMapLiteralEntry literalEntry : node.getEntries()) {
-        if (literalEntry.getKey() instanceof DartStringLiteral) {
-          DartStringLiteral keyLiteral = (DartStringLiteral) literalEntry.getKey();
-          String keyValue = keyLiteral.getValue();
-          if (keyValues.contains(keyValue)) {
-            typeError(keyLiteral, TypeErrorCode.MAP_LITERAL_KEY_UNIQUE);
-          }
-          keyValues.add(keyValue);
-        }
-      }
-
-      return type;
-    }
-
-    @Override
-    public Type visitMapLiteralEntry(DartMapLiteralEntry node) {
-      nonVoidTypeOf(node.getKey());
-      return nonVoidTypeOf(node.getValue());
-    }
-
-    @Override
-    public Type visitMethodDefinition(DartMethodDefinition node) {
-      MethodElement methodElement = node.getElement();
-      Modifiers modifiers = methodElement.getModifiers();
-      DartTypeNode returnTypeNode = node.getFunction().getReturnTypeNode();
-      if (modifiers.isFactory()
-          && ElementKind.of(methodElement).equals(ElementKind.CONSTRUCTOR)) {
-        analyzeFactory(node, node.getName(), (ConstructorElement) methodElement);
-      } else if (modifiers.isSetter()) {
-        if (returnTypeNode != null && returnTypeNode.getType() != voidType) {
-          typeError(returnTypeNode, TypeErrorCode.SETTER_RETURN_TYPE, methodElement.getName());
-        }
-        if (methodElement.getParameters().size() > 0) {
-          Element parameterElement = methodElement.getParameters().get(0);
-          Type setterType = parameterElement.getType();
-          MethodElement getterElement = Elements.lookupFieldElementGetter(
-              methodElement.getEnclosingElement(), methodElement.getName());
-
-          if (getterElement != null) {
-            // prepare "getter" type
-            Type getterType;
-
-            // prepare super types between "getter" and "setter" enclosing types
-            Type getterDeclarationType = getterElement.getEnclosingElement().getType();
-            List<InterfaceType> superTypes;
-            if (currentClass != null) {
-              superTypes = getIntermediateSuperTypes(currentClass, getterDeclarationType);
-            } else {
-              superTypes = Lists.newArrayList();
-            }
-            // convert "getter" function type to use "setter" type parameters
-            FunctionType getterFunctionType = (FunctionType) getterElement.getType();
-            for (InterfaceType superType : superTypes) {
-              List<Type> superArguments = superType.getArguments();
-              List<Type> superParameters = superType.getElement().getTypeParameters();
-              getterFunctionType = (FunctionType) getterFunctionType.subst(superArguments,
-                  superParameters);
-            }
-            // get return type
-            getterType = getterFunctionType.getReturnType();
-
-            // compare "getter" and "setter" types
-            if (!types.isAssignable(setterType, getterType)) {
-              typeError(parameterElement, TypeErrorCode.SETTER_TYPE_MUST_BE_ASSIGNABLE,
-                  setterType.getElement().getName(), getterType.getElement().getName());
-            }
-
-            // getter and setter should have same "static" flag
-            if (modifiers.isStatic() != getterElement.getModifiers().isStatic()) {
-              onError(node.getName(), TypeErrorCode.FIELD_GETTER_SETTER_SAME_STATIC);
-            }
-          }
-        }
-      }
-      // operator == should return "bool"
-      if (modifiers.isOperator() && methodElement.getName().equals("==")
-          && returnTypeNode != null) {
-        Type returnType = node.getElement().getFunctionType().getReturnType();
-        if (!Objects.equal(returnType, boolType)) {
-          typeError(returnTypeNode, TypeErrorCode.OPERATOR_EQUALS_BOOL_RETURN_TYPE);
-
-        }
-      }
-      // operator "[]=" should return void
-      if (modifiers.isOperator() && methodElement.getName().equals("[]=")
-          && returnTypeNode != null) {
-        Type returnType = node.getElement().getFunctionType().getReturnType();
-        if (TypeKind.of(returnType) != TypeKind.VOID) {
-          typeError(returnTypeNode, TypeErrorCode.OPERATOR_INDEX_ASSIGN_VOID_RETURN_TYPE);
-        }
-      }
-      // visit children
-      MethodElement prevMethod = currentMethod;
-      currentMethod = methodElement;
-      try {
-        return typeAsVoid(node);
-      } finally {
-        currentMethod = prevMethod;
-      }
-    }
-
-    /**
-     * @return "super" {@link InterfaceType}s used in declarations from "subType" to "superType",
-     *         first item is given "superType". May be empty, but not <code>null</code>.
-     */
-    private List<InterfaceType> getIntermediateSuperTypes(InterfaceType subType, Type superType) {
-      LinkedList<InterfaceType> superTypes = Lists.newLinkedList();
-      InterfaceType t = subType.getElement().getSupertype();
-      while (t != null) {
-        superTypes.addFirst(t);
-        if (Objects.equal(t.getElement().getType(), superType)) {
-          break;
-        }
-        t = t.getElement().getSupertype();
-      }
-      return superTypes;
-    }
-
-    private void analyzeFactory(DartMethodDefinition node, DartExpression name,
-        final ConstructorElement constructorElement) {
-      ASTVisitor<Void> visitor = new ASTVisitor<Void>() {
-        @Override
-        public Void visitParameterizedTypeNode(DartParameterizedTypeNode node) {
-          DartExpression expression = node.getExpression();
-          Element e = null;
-          if (expression instanceof DartIdentifier) {
-            e = ((DartIdentifier) expression).getElement();
-          } else if (expression instanceof DartPropertyAccess) {
-            e = ((DartPropertyAccess) expression).getElement();
-          }
-          if (!ElementKind.of(e).equals(ElementKind.CLASS)) {
-            return null;
-          }
-          List<DartTypeParameter> parameterNodes = node.getTypeParameters();
-          assert (parameterNodes.size() == 0);
-          return null;
-        }
-      };
-      name.accept(visitor);
-      // redirecting factory constructor
-      {
-        ConstructorElement targetElement = constructorElement.getRedirectingFactoryConstructor();
-        if (targetElement != null) {
-          ClassElement targetEnclosingClass = (ClassElement) targetElement.getEnclosingElement();
-          Type sourceMethodType = constructorElement.getType();
-          Type targetMethodType = targetElement.getType();
-          InterfaceType targetClassType = (InterfaceType) node.getRedirectedTypeName().getType();
-          targetMethodType = targetMethodType.subst(targetClassType.getArguments(),
-              targetEnclosingClass.getTypeParameters());
-          if (!types.isSubtype(targetMethodType, sourceMethodType)) {
-            DartNode errorNode = node.getRedirectedConstructorName() != null
-                ? node.getRedirectedConstructorName() : node.getRedirectedTypeName();
-            typeError(errorNode, TypeErrorCode.REDIRECTION_CONSTRUCTOR_TARGET_MUST_BE_SUBTYPE,
-                targetMethodType, sourceMethodType);
-          }
-        }
-      }
-    }
-
-    @Override
-    public Type visitNewExpression(DartNewExpression node) {
-      ConstructorElement constructorElement = node.getElement();
-
-      DartTypeNode typeNode = Types.constructorTypeNode(node);
-      Type type = null;
-
-      // When using a constructor defined in an interface, the bounds can be tighter
-      // in the default class than defined in the interface.
-      if (TypeKind.of(typeNode.getType()).equals(TypeKind.INTERFACE)
-          && ((InterfaceType)typeNode.getType()).getElement().isInterface()) {
-        InterfaceType itype = (InterfaceType)typeNode.getType();
-        ClassElement interfaceElement = itype.getElement();
-        InterfaceType defaultClassType = interfaceElement.getDefaultClass();
-        if (defaultClassType != null && defaultClassType.getElement() != null) {
-          validateBounds(typeNode.getTypeArguments(),
-                         itype.getArguments(),
-                         defaultClassType.getElement().getTypeParameters());
-          type = itype;
-        }
-      }
-      if (type == null) {
-        type = validateTypeNode(typeNode);
-      }
-
-      DartNode typeName = typeNode.getIdentifier();
-
-      if (constructorElement == null) {
-        visit(node.getArguments());
-      } else {
-        ClassElement cls = (ClassElement) constructorElement.getEnclosingElement();
-        // Add warning for instantiating abstract class.
-        if (cls.getModifiers().isAbstract()) {
-          if (!constructorElement.getModifiers().isFactory()) {
-            typeError(typeName, TypeErrorCode.INSTANTIATION_OF_ABSTRACT_CLASS, cls.getName());
-          }
-        }
-        // Check type arguments.
-        FunctionType ftype = (FunctionType) constructorElement.getType();
-
-        if (ftype != null && TypeKind.of(type).equals(TypeKind.INTERFACE)) {
-          InterfaceType ifaceType = (InterfaceType) type;
-
-          List<Type> substParams;
-          if (ifaceType.getElement().isInterface()) {
-            // The constructor in the interface is resolved to the type parameters declared in
-            // the interface, but the constructor body has type parameters resolved to the type
-            // parameters in the default class.  This substitution patches up the type variable
-            // references used in parameters so they match the concrete class.
-            substParams = ((ClassElement)constructorElement.getEnclosingElement()).getType().getArguments();
-          } else {
-            substParams = ifaceType.getElement().getTypeParameters();
-          }
-          List<Type> arguments = ifaceType.getArguments();
-          ftype = (FunctionType) ftype.subst(arguments, substParams);
-          checkDeprecated(ASTNodes.getConstructorNameNode(node), constructorElement);
-          checkInvocation(node, node, constructorElement.getName(), ftype);
-        }
-      }
-      type.getClass(); // quick null check
-      return type;
-    }
-
-    /**
-     * @param cls the {@link ClassElement}  which has unimplemented members.
-     * @param unimplementedMembers the unimplemented members {@link Element}s.
-     * @return the {@link StringBuilder} with message about unimplemented members.
-     */
-    private StringBuilder getUnimplementedMembersMessage(ClassElement cls,
-        List<Element> unimplementedMembers) {
-      // Prepare groups of unimplemented members for each type.
-      Multimap<String, String> membersByTypes = ArrayListMultimap.create();
-      for (Element member : unimplementedMembers) {
-        ClassElement enclosingElement = (ClassElement) member.getEnclosingElement();
-        InterfaceType instance = types.asInstanceOf(cls.getType(), enclosingElement);
-        Type memberType = member.getType().subst(instance.getArguments(),
-                                                 enclosingElement.getTypeParameters());
-        if (memberType.getKind().equals(TypeKind.FUNCTION)) {
-          FunctionType ftype = (FunctionType) memberType;
-          StringBuilder sb = new StringBuilder();
-          sb.append(ftype.getReturnType());
-          sb.append(" ");
-          sb.append(member.getName());
-          String string = ftype.toString();
-          sb.append(string, 0, string.lastIndexOf(" -> "));
-          membersByTypes.put(enclosingElement.getName(), sb.toString());
-        } else {
-          StringBuilder sb = new StringBuilder();
-          sb.append(memberType);
-          sb.append(" ");
-          sb.append(member.getName());
-          membersByTypes.put(enclosingElement.getName(), sb.toString());
-        }
-      }
-      // Output unimplemented members with grouping by class.
-      StringBuilder sb = new StringBuilder();
-      for (String typeName : membersByTypes.keySet()) {
-        sb.append("\n    # From ");
-        sb.append(typeName);
-        sb.append(":");
-        for (String memberString : membersByTypes.get(typeName)) {
-          sb.append("\n        ");
-          sb.append(memberString);
-        }
-      }
-      return sb;
-    }
-
-    @Override
-    public Type visitNullLiteral(DartNullLiteral node) {
-      return nullType;
-    }
-
-    @Override
-    public Type visitParameter(DartParameter node) {
-      VariableElement parameter = node.getElement();
-      FieldElement initializerElement = parameter.getParameterInitializerElement();
-      if (initializerElement != null) {
-        checkAssignable(node, parameter.getType(), initializerElement.getType());
-      }
-      return checkInitializedDeclaration(node, node.getDefaultExpr());
-    }
-
-    @Override
-    public Type visitParenthesizedExpression(DartParenthesizedExpression node) {
-      Type type = nonVoidTypeOf(node.getExpression());
-      type.getClass(); // quick null check
-      return type;
-    }
-
-    @Override
-    public Type visitPropertyAccess(DartPropertyAccess node) {
-      if (node.getType() != null) {
-        return node.getType();
-      }
-      Element element = node.getElement();
-      if (element != null) {
-        return element.getType();
-      }
-      if (node.getName().isResolutionAlreadyReportedThatTheMethodCouldNotBeFound()) {
-        return dynamicType;
-      }
-      DartNode qualifier = node.getRealTarget();
-      Type receiver = nonVoidTypeOf(qualifier);
-      // convert into InterfaceType
-      InterfaceType cls = types.getInterfaceType(receiver);
-      if (cls == null) {
-        return diagnoseNonInterfaceType(qualifier, receiver);
-      }
-      // Do not visit the name, it may not have been resolved.
-      String name = node.getPropertyName();
-      InterfaceType.Member member;
-      if (ASTNodes.inSetterContext(node)) {
-        member = cls.lookupMember("setter " + name);
-        if (member == null) {
-          member = cls.lookupMember(name);
-        }
-      } else {
-        member = cls.lookupMember(name);
-        if (member == null) {
-          member = cls.lookupMember("setter " + name);
-        }
-      }
-      // is "receiver" is inferred, attempt to find member in one of the subtypes
-      boolean hasMemberInSubClasses = false;
-      if (member == null) {
-        if (TypeQuality.of(receiver) == TypeQuality.INFERRED && receiver instanceof InterfaceType) {
-          List<Member> subMembers = ((InterfaceType) receiver).lookupSubTypeMembers(name);
-          hasMemberInSubClasses = !subMembers.isEmpty();
-          if (subMembers.size() == 1) {
-            member = subMembers.get(0);
-          }
-        }
-      }
-      // report "not a member"
-      if (member == null) {
-        if (reportNoMemberWhenHasInterceptor || !Elements.handlesNoSuchMethod(cls)) {
-          if (typeChecksForInferredTypes && !hasMemberInSubClasses
-              && !isTooGenericInferredType(receiver) || !TypeQuality.isInferred(receiver)) {
-            TypeErrorCode errorCode = TypeQuality.isInferred(receiver)
-                ? TypeErrorCode.NOT_A_MEMBER_OF_INFERRED : TypeErrorCode.NOT_A_MEMBER_OF;
-            typeError(node.getName(), errorCode, name, cls);
-          }
-        }
-        return dynamicType;
-      }
-      // set resolved element
-      element = member.getElement();
-      node.setElement(element);
-      Modifiers modifiers = element.getModifiers();
-      if (modifiers.isStatic()) {
-        return typeError(node.getName(),
-                         TypeErrorCode.STATIC_MEMBER_ACCESSED_THROUGH_INSTANCE,
-                         name, element.getName());
-      }
-      // @deprecated
-      if (element != null && element.getMetadata().isDeprecated()) {
-        onError(node.getName(), TypeErrorCode.DEPRECATED_ELEMENT,
-            Elements.getDeprecatedElementTitle(element));
-      }
-      // analyze Element
-      switch (element.getKind()) {
-        case DYNAMIC:
-          return dynamicType;
-        case CONSTRUCTOR:
-          return typeError(node.getName(), TypeErrorCode.MEMBER_IS_A_CONSTRUCTOR,
-                           name, element.getName());
-
-        case METHOD:
-          return member.getType();
-
-        case FIELD:
-          FieldElement fieldElement = (FieldElement) element;
-          Modifiers fieldModifiers = fieldElement.getModifiers();
-
-          // Prepare getter/setter members.
-          Member getterMember;
-          Member setterMember;
-          {
-            getterMember = cls.lookupMember(name);
-            if (getterMember == null && TypeQuality.of(cls) == TypeQuality.INFERRED) {
-              List<Member> members = cls.lookupSubTypeMembers(name);
-              if (members.size() == 1) {
-                getterMember = members.get(0);
-              }
-            }
-          }
-          {
-            setterMember = cls.lookupMember("setter " + name);
-            if (setterMember == null) {
-              setterMember = cls.lookupMember(name);
-            }
-          }
-          boolean inSetterContext = ASTNodes.inSetterContext(node);
-          boolean inGetterContext = ASTNodes.inGetterContext(node);
-
-          // Implicit field declared as "final".
-          if (!fieldModifiers.isAbstractField() && fieldModifiers.isFinal() && inSetterContext) {
-            return typeError(node.getName(), TypeErrorCode.FIELD_IS_FINAL, node.getName());
-          }
-
-          Type result = member.getType();
-          if (fieldModifiers.isAbstractField()) {
-            if (inSetterContext) {
-              result = setterMember != null ? setterMember.getSetterType() : null;
-              if (result == null) {
-                return typeError(node.getName(), TypeErrorCode.FIELD_HAS_NO_SETTER, node.getName());
-              }
-            }
-            if (inGetterContext) {
-              result = getterMember != null ? getterMember.getGetterType() : null;
-              if (result == null) {
-                return typeError(node.getName(), TypeErrorCode.FIELD_HAS_NO_GETTER, node.getName());
-              }
-            }
-          }
-          result = Types.makeInferred(result, receiver.getQuality());
-          node.setType(result);
-          return result;
-
-        default:
-          throw internalError(node.getName(), "unexpected kind %s", element.getKind());
-      }
-    }
-
-    @Override
-    public Type visitReturnStatement(DartReturnStatement node) {
-      DartExpression value = node.getValue();
-      if (value == null) {
-        if (!types.isSubtype(voidType, expected)) {
-          typeError(node, TypeErrorCode.MISSING_RETURN_VALUE, expected);
-        }
-      } else {
-        checkAssignable(value == null ? node : value, expected, typeOf(value));
-      }
-      return voidType;
-    }
-
-    @Override
-    public Type visitSuperExpression(DartSuperExpression node) {
-      if (currentClass == null) {
-        return dynamicType;
-      }
-      Type type = currentClass.getElement().getSupertype();
-      type.getClass(); // quick null check
-      return type;
-    }
-
-    @Override
-    public Type visitSwitchStatement(DartSwitchStatement node) {
-      node.visitChildren(this);
-      // analyze "expression"
-      DartExpression expression = node.getExpression();
-      Type switchType = nonVoidTypeOf(expression);
-      // check "case" expressions compatibility
-      Type sameCaseType = null;
-      for (DartSwitchMember switchMember : node.getMembers()) {
-        if (switchMember instanceof DartCase) {
-          DartCase caseMember = (DartCase) switchMember;
-          DartExpression caseExpr = caseMember.getExpr();
-          // no expression, parser already reported about this
-          if (caseExpr == null) {
-            continue;
-          }
-          Type caseType = nonVoidTypeOf(caseExpr);
-          // all "case expressions" should be same type
-          if (sameCaseType == null) {
-            sameCaseType = caseType;
-          }
-          if (!Objects.equal(caseType, sameCaseType)) {
-            onError(caseExpr, TypeErrorCode.CASE_EXPRESSIONS_SHOULD_BE_SAME_TYPE, sameCaseType,
-                caseType);
-          }
-          // compatibility of "switch expression" and "case expression" types
-          checkAssignable(caseExpr, switchType, caseType);
-          // should not have "operator =="
-          if (!Objects.equal(caseType, intType) && !Objects.equal(caseType, doubleType)
-              && !Objects.equal(caseType, stringType)) {
-            Member operator = lookupMember(caseType, methodNameForBinaryOperator(Token.EQ), null);
-            if (operator != null && !Objects.equal(operator.getHolder(), objectType)) {
-              onError(caseExpr, TypeErrorCode.CASE_EXPRESSION_TYPE_SHOULD_NOT_HAVE_EQUALS, caseType);
-            }
-          }
-        }
-      }
-      return voidType;
-    }
-
-    @Override
-    public Type visitSyntheticErrorExpression(DartSyntheticErrorExpression node) {
-      return dynamicType;
-    }
-
-    @Override
-    public Type visitSyntheticErrorStatement(DartSyntheticErrorStatement node) {
-      return dynamicType;
-    }
-
-    @Override
-    public Type visitThisExpression(DartThisExpression node) {
-      Type type = getCurrentClass();
-      if (type == null) {
-        // this was used in a static context, so it should have already generated a fatal error
-        return voidType;
-      }
-      return type;
-    }
-
-    @Override
-    public Type visitThrowExpression(DartThrowExpression node) {
-      if (catchDepth == 0 && node.getException() == null) {
-        context.onError(new DartCompilationError(node,
-            ResolverErrorCode.RETHROW_NOT_IN_CATCH));
-      }
-      return typeAsVoid(node);
-    }
-
-    @Override
-    public Type visitCatchBlock(DartCatchBlock node) {
-      ++catchDepth;
-      typeOf(node.getException());
-      // TODO(karlklose) Check type of stack trace variable.
-      typeOf(node.getStackTrace());
-      typeOf(node.getBlock());
-      --catchDepth;
-      return voidType;
-    }
-
-    @Override
-    public Type visitTryStatement(DartTryStatement node) {
-      return typeAsVoid(node);
-    }
-
-    @Override
-    public Type visitUnaryExpression(DartUnaryExpression node) {
-      DartExpression expression = node.getArg();
-      Type type = nonVoidTypeOf(expression);
-      Token operator = node.getOperator();
-      switch (operator) {
-        case BIT_NOT:
-          // Bit operations are only supported by integers and
-          // thus cannot be looked up on num. To ease usage of
-          // bit operations, we currently allow them to be used
-          // if the left-hand-side is of type num.
-          // TODO(karlklose) find a clean solution, i.e., without a special case for num.
-          if (type.equals(numType)) {
-            return intType;
-          } else {
-            String name = methodNameForUnaryOperator(node, operator);
-            HasSourceInfo problemTarget = getOperatorHasSourceInfo(node);
-            Member member = lookupMember(type, name, problemTarget);
-            if (member != null) {
-              Element element = member.getElement();
-              node.setElement(element);
-              FunctionType methodType = getMethodType(type, member, name, node);
-              checkDeprecated(problemTarget, element);
-              return checkInvocation(Collections.<DartExpression>emptyList(), node, name, methodType, null);
-            } else {
-              return dynamicType;
-            }
-          }
-        case NOT:
-          checkAssignable(boolType, expression);
-          return boolType;
-        case SUB:
-        case INC:
-        case DEC: {
-          if (type.getElement().isDynamic()) {
-            return type;
-          }
-          InterfaceType itype = types.getInterfaceType(type);
-          String operatorMethodName = methodNameForUnaryOperator(node, operator);
-          if (operator == Token.DEC) {
-            operatorMethodName = "operator -binary";
-          }
-          Member member = itype.lookupMember(operatorMethodName);
-          if (member == null) {
-            HasSourceInfo errorTarget = getOperatorHasSourceInfo(node);
-            return typeError(errorTarget, TypeErrorCode.CANNOT_BE_RESOLVED,
-                             operatorMethodName);
-          }
-          MethodElement element = ((MethodElement) member.getElement());
-          node.setElement(element);
-          Type returnType = ((FunctionType) member.getType()).getReturnType();
-          if (operator == Token.INC || operator == Token.DEC) {
-            // For INC and DEC, "operator +" and "operator -" are used to add and subtract one,
-            // respectively. Check that the resolved operator has a compatible parameter type.
-            Iterator<VariableElement> it = element.getParameters().iterator();
-            Type operandType = it.next().getType();
-            if  (!types.isAssignable(numType, operandType)) {
-              typeError(node, TypeErrorCode.OPERATOR_WRONG_OPERAND_TYPE,
-                  operatorMethodName, numType.toString(), operandType.toString());
-            }
-            // Check that the return type of the operator is compatible with the receiver.
-            checkAssignable(node, type, returnType);
-          }
-          return node.isPrefix() ? returnType : type;
-        }
-        case CONDITIONAL:
-          return boolType;
-        default:
-          throw internalError(node, "unknown operator %s", operator.toString());
-      }
-    }
-
-    @Override
-    public Type visitUnit(DartUnit node) {
-      blockOldTypes.addFirst(new BlockTypeContext());
-      return typeAsVoid(node);
-    }
-
-    @Override
-    public Type visitAssertStatement(DartAssertStatement node) {
-      DartExpression condition = node.getCondition();
-      checkAssertCondition(condition);
-      // infer types, which are valid until the end of the enclosing control block
-      if (node.getParent() instanceof DartBlock) {
-        DartBlock restoreBlock = getBlockForAssertTypesInference(node);
-        VariableElementsRestorer variableRestorer = restoreOnBlockExit.get(restoreBlock);
-        if (variableRestorer == null) {
-          variableRestorer = new VariableElementsRestorer();
-          restoreOnBlockExit.put(restoreBlock, variableRestorer);
-        }
-        restoreOnBlockExit.put(restoreBlock, variableRestorer);
-        inferVariableTypesFromIsConditions(condition, variableRestorer);
-      }
-      // done for "assert"
-      return voidType;
-    }
-
-    @Override
-    public Type visitUnqualifiedInvocation(DartUnqualifiedInvocation node) {
-      DartIdentifier target = node.getTarget();
-      String name = target.getName();
-      Element element = target.getElement();
-      node.setElement(element);
-      Type type;
-      switch (ElementKind.of(element)) {
-        case FIELD:
-        case METHOD:
-          type = typeAsMemberOf(element, currentClass);
-          break;
-        case NONE:
-          if (!target.isResolutionAlreadyReportedThatTheMethodCouldNotBeFound()) {
-            onError(target, TypeErrorCode.INTERFACE_HAS_NO_METHOD_NAMED, currentClass, target);
-          }
-          return dynamicType;
-        default:
-          type = element.getType();
-          // attempt to resolve to "call()" method invocation
-          if (type instanceof InterfaceType) {
-            InterfaceType interfaceType = (InterfaceType) type;
-            Element callElement = interfaceType.getElement().lookupLocalElement("call");
-            if (ElementKind.of(callElement) == ElementKind.METHOD) {
-              node.setElement(callElement);
-              type = typeAsMemberOf(callElement, interfaceType);
-            }
-          }
-          break;
-      }
-      checkDeprecated(target, element);
-      Type returnType = checkInvocation(node, target, name, type);
-      returnType = ExternalTypeAnalyzers.resolve(types, node, element, returnType);
-      return returnType;
-    }
-
-    private static DartBlock getBlockForAssertTypesInference(DartNode node) {
-      while (node != null) {
-        if (node instanceof DartBlock) {
-          DartBlock block = (DartBlock) node;
-          DartNode p = block.getParent();
-          if (p instanceof DartIfStatement || p instanceof DartForStatement
-              || p instanceof DartForInStatement || p instanceof DartWhileStatement) {
-            return block;
-          }
-        }
-        node = node.getParent();
-      }
-      return null;
-    }
-
-    private static DartBlock getBlockForLoopTypesInference(DartNode node) {
-      while (node != null) {
-        if (node instanceof DartBlock) {
-          DartBlock block = (DartBlock) node;
-          DartNode p = block.getParent();
-          if (p instanceof DartForStatement || p instanceof DartForInStatement
-              || p instanceof DartWhileStatement) {
-            return block;
-          }
-        }
-        node = node.getParent();
-      }
-      return null;
-    }
-
-    /**
-     * Report warning if given {@link Element} is deprecated.
-     */
-    private void checkDeprecated(HasSourceInfo nameNode, Element element) {
-      if (element != null && element.getMetadata() != null && element.getMetadata().isDeprecated()) {
-        onError(nameNode, TypeErrorCode.DEPRECATED_ELEMENT,
-            Elements.getDeprecatedElementTitle(element));
-      }
-    }
-
-    private Type checkInvocation(DartInvocation node, DartNode diagnosticNode, String name,
-        Type type) {
-      List<DartExpression> argumentNodes = node.getArguments();
-      List<VariableElement> parameters;
-      if (node.getElement() instanceof MethodElement) {
-        MethodElement methodElement = (MethodElement) node.getElement();
-        parameters = methodElement.getParameters();
-      } else {
-        parameters = null;
-      }
-      return checkInvocation(argumentNodes, diagnosticNode, name, type, parameters);
-    }
-
-    private Type checkInvocation(List<DartExpression> argumentNodes, DartNode diagnosticNode,
-        String name, Type type, List<VariableElement> parameters) {
-      // Prepare argument types.
-      List<Type> argumentTypes = Lists.newArrayListWithCapacity(argumentNodes.size());
-      for (DartExpression argumentNode : argumentNodes) {
-        Type argumentType = getInvocationArgumentType(argumentNode);
-        argumentTypes.add(argumentType);
-      }
-      return checkInvocation(argumentNodes, argumentTypes, diagnosticNode, name, type, parameters);
-    }
-
-    private Type checkInvocation(List<DartExpression> argumentNodes, List<Type> argumentTypes,
-        DartNode diagnosticNode, String name, Type type, List<VariableElement> parameters) {
-      // Check that argument types are compatible with type of invoked object.
-      try {
-        switch (TypeKind.of(type)) {
-          case FUNCTION_ALIAS:
-            return checkArguments(diagnosticNode, argumentNodes, argumentTypes.iterator(),
-                Types.asFunctionType((FunctionAliasType) type), parameters);
-          case FUNCTION:
-            return checkArguments(diagnosticNode, argumentNodes, argumentTypes.iterator(),
-                (FunctionType) type, parameters);
-          case DYNAMIC:
-            return type;
-          default:
-            if (isAssignable(functionType, type)) {
-              // A subtype of interface Function.
-              return dynamicType;
-            } else if (name == null || currentClass == null) {
-              if (reportNoMemberWhenHasInterceptor || !(type instanceof InterfaceType)
-                  || !Elements.handlesNoSuchMethod((InterfaceType) type)) {
-                return typeError(diagnosticNode, TypeErrorCode.NOT_A_FUNCTION_TYPE, type);
-              }
-              return dynamicType;
-            } else {
-              return typeError(diagnosticNode, TypeErrorCode.NOT_A_METHOD_IN, name, currentClass);
-            }
-        }
-      } finally {
-        // In any case visit body of function literals, so use inferred parameter types.
-        for (DartExpression argument : argumentNodes) {
-          if (argument instanceof DartNamedExpression) {
-            argument = ((DartNamedExpression) argument).getExpression();
-          }
-          if (argument instanceof DartFunctionExpression) {
-            argument.accept(this);
-          }
-        }
-      }
-    }
-
-    /**
-     * Almost same as {@link #nonVoidTypeOf(DartNode)}, but does not visit
-     * {@link DartFunctionExpression}, because we know its type already and want to infer types of
-     * arguments, and then propagate them into body.
-     */
-    private Type getInvocationArgumentType(DartExpression argument) {
-      // We are interesting in the type of expression, without name.
-      if (argument instanceof DartNamedExpression) {
-        argument = ((DartNamedExpression) argument).getExpression();
-      }
-      // Don't visit function literal, we know its "declared" type.
-      // But we want to visit it later, to use "inferred" type in body.
-      if (argument instanceof DartFunctionExpression) {
-        return argument.getElement().getType();
-      }
-      // General case - visit and prepare type.
-      return nonVoidTypeOf(argument);
-    }
-
-    /**
-     * Return the type of member as if it was a member of subtype. For example, the type of t in Sub
-     * should be String, not T:
-     *
-     * <pre>
-     *   class Super&lt;T> {
-     *     T t;
-     *   }
-     *   class Sub extends Super&lt;String> {
-     *   }
-     * </pre>
-     */
-    private Type typeAsMemberOf(Element member, InterfaceType subtype) {
-      Element holder = member.getEnclosingElement();
-      if (!ElementKind.of(holder).equals(ElementKind.CLASS)) {
-        return member.getType();
-      }
-      ClassElement superclass = (ClassElement) holder;
-      InterfaceType supertype = types.asInstanceOf(subtype, superclass);
-      Type type = member.getType().subst(supertype.getArguments(),
-                                         supertype.getElement().getTypeParameters());
-      type.getClass(); // quick null check
-      return type;
-    }
-
-    @Override
-    public Type visitVariable(DartVariable node) {
-      DartExpression value = node.getValue();
-      // if type is declared and right side is closure, infer its parameter types
-      if (value != null) {
-        Type varType = node.getElement().getType();
-        if (isExplicitlySpecifiedType(varType)) {
-          inferFunctionLiteralParametersTypes(value, varType);
-        }
-      }
-      // prepare type of value
-      Type result = checkInitializedDeclaration(node, value);
-      // if no type declared for variables, try to use type of value
-      if (value != null) {
-        inferVariableDeclarationType(node, value);
-      }
-      // done
-      return result;
-    }
-
-    @Override
-    public Type visitWhileStatement(DartWhileStatement node) {
-      DartExpression condition = node.getCondition();
-      checkCondition(condition);
-      // visit body
-      BlockTypeContext blockTypeContxt = new BlockTypeContext();
-      blockOldTypes.addFirst(blockTypeContxt);
-      try {
-        visitConditionalNode(condition, node.getBody());
-      } finally {
-        blockOldTypes.removeFirst();
-        setMergedVariableTypes(blockTypeContxt);
-      }
-      // done
-      return voidType;
-    }
-
-    @Override
-    public Type visitNamedExpression(DartNamedExpression node) {
-      // TODO(jgw): Checking of named parameters in progress.
-
-      // Intentionally skip the expression's name -- it's stored as an identifier, but doesn't need
-      // to be resolved or type-checked.
-      Type type = nonVoidTypeOf(node.getExpression());
-      type.getClass(); // quick null check
-      return type;
-    }
-
-    @Override
-    public Type visitTypeExpression(DartTypeExpression node) {
-      return typeOf(node.getTypeNode());
-    }
-
-    @Override
-    public Type visitTypeParameter(DartTypeParameter node) {
-      if (node.getBound() != null) {
-        validateTypeNode(node.getBound());
-      }
-      return voidType;
-    }
-
-    @Override
-    public Type visitNativeBlock(DartNativeBlock node) {
-      return typeAsVoid(node);
-    }
-
-    @Override
-    public void visit(List<? extends DartNode> nodes) {
-      if (nodes != null) {
-        for (DartNode node : nodes) {
-          node.accept(this);
-        }
-      }
-    }
-
-    @Override
-    public Type visitArrayLiteral(DartArrayLiteral node) {
-      visit(node.getTypeArguments());
-      InterfaceType interfaceType = node.getType();
-      if (interfaceType != null
-          && interfaceType.getArguments() != null
-          && interfaceType.getArguments().size() > 0) {
-        Type elementType = interfaceType.getArguments().get(0);
-        for (DartExpression expression : node.getExpressions()) {
-          boolean isValueAssignable = checkAssignable(elementType, expression);
-          if (developerModeChecks && !isValueAssignable) {
-            typeError(expression, ResolverErrorCode.LIST_LITERAL_ELEMENT_TYPE, elementType);
-          }
-        }
-      }
-      return interfaceType;
-    }
-
-    @Override
-    public Type visitBooleanLiteral(DartBooleanLiteral node) {
-      return typeOfLiteral(node);
-    }
-
-    @Override
-    public Type visitDoubleLiteral(DartDoubleLiteral node) {
-      return typeOfLiteral(node);
-    }
-
-    @Override
-    public Type visitField(DartField node) {
-      DartMethodDefinition accessor = node.getAccessor();
-      if (accessor != null) {
-        return typeOf(accessor);
-      } else {
-        DartExpression value = node.getValue();
-        // if type is declared and right side is closure, infer its parameter types
-        if (value != null) {
-          Type fieldType = node.getElement().getType();
-          if (isExplicitlySpecifiedType(fieldType)) {
-            inferFunctionLiteralParametersTypes(value, fieldType);
-          }
-        }
-        // prepare type of value
-        Type result = checkInitializedDeclaration(node, value);
-        // if no type declared for field, try to use type of value
-        // only final fields, because only in this case we can be sure that field is not assigned
-        // somewhere, may be even not in this unit
-        if (node.getModifiers().isFinal() && value != null) {
-          inferVariableDeclarationType(node, value);
-        }
-        // done
-        return result;
-      }
-    }
-
-    private Type checkInitializedDeclaration(DartDeclaration<?> node, DartExpression value) {
-      if (value != null && node.getElement() != null) {
-        checkAssignable(node.getElement().getType(), value);
-      }
-      return voidType;
-    }
-
-    /**
-     * @return <code>true</code> if given {@link FunctionAliasElement} has direct or indirect
-     *         reference to itself using other {@link FunctionAliasElement}s.
-     */
-    private boolean hasFunctionTypeAliasSelfReference(FunctionAliasElement target) {
-      Set<FunctionAliasElement> visited = Sets.newHashSet();
-      return hasFunctionTypeAliasReference(visited, target, target);
-    }
-
-    /**
-     * Checks if "target" is referenced by "current".
-     */
-    private boolean hasFunctionTypeAliasReference(Set<FunctionAliasElement> visited,
-        FunctionAliasElement target, FunctionAliasElement current) {
-      FunctionType type = current.getFunctionType();
-      // prepare Types directly referenced by "current"
-      Set<Type> referencedTypes = Sets.newHashSet();
-      if (type != null) {
-        // type parameters
-        for (Type typeParameter : current.getTypeParameters()) {
-          if (typeParameter instanceof TypeVariable) {
-            TypeVariable typeVariable = (TypeVariable) typeParameter;
-            Type bound = typeVariable.getTypeVariableElement().getBound();
-            referencedTypes.add(bound);
-          }
-        }
-        // return type
-        referencedTypes.add(type.getReturnType());
-        // parameters
-        referencedTypes.addAll(type.getParameterTypes());
-        referencedTypes.addAll(type.getOptionalParameterTypes().values());
-        referencedTypes.addAll(type.getNamedParameterTypes().values());
-      }
-      // check that referenced types do not have references on "target"
-      for (Type referencedType : referencedTypes) {
-        if (referencedType != null
-            && hasFunctionTypeAliasReference(visited, target, referencedType.getElement())) {
-          return true;
-        }
-      }
-      // no
-      return false;
-    }
-
-    /**
-     * Checks if "target" is referenced by "current".
-     */
-    private boolean hasFunctionTypeAliasReference(Set<FunctionAliasElement> visited,
-        FunctionAliasElement target, Element currentElement) {
-      // only if "current" in function type alias
-      if (!(currentElement instanceof FunctionAliasElement)) {
-        return false;
-      }
-      FunctionAliasElement current = (FunctionAliasElement) currentElement;
-      // found "target"
-      if (Objects.equal(target, current)) {
-        return true;
-      }
-      // prevent recursion
-      if (visited.contains(current)) {
-        return false;
-      }
-      visited.add(current);
-      // check type of "current" function type alias
-      return hasFunctionTypeAliasReference(visited, target, current);
-    }
-
-    @Override
-    public Type visitIntegerLiteral(DartIntegerLiteral node) {
-      return typeOfLiteral(node);
-    }
-
-    @Override
-    public Type visitStringLiteral(DartStringLiteral node) {
-      return typeOfLiteral(node);
-    }
-
-    @Override
-    public Type visitStringInterpolation(DartStringInterpolation node) {
-      visit(node.getExpressions());
-      return typeOfLiteral(node);
-    }
-
-    @Override
-    public Type visitParameterizedTypeNode(DartParameterizedTypeNode node) {
-      visit(node.getTypeParameters());
-      Type type = node.getType();
-      type.getClass(); // quick null check
-      return type;
-    }
-
-    @Override
-    public Type visitImportDirective(DartImportDirective node) {
-      return voidType;
-    }
-
-    @Override
-    public Type visitExportDirective(DartExportDirective node) {
-      return voidType;
-    }
-
-    @Override
-    public Type visitLibraryDirective(DartLibraryDirective node) {
-      //return typeAsVoid(node);
-      return voidType;
-    }
-
-    @Override
-    public Type visitNativeDirective(DartNativeDirective node) {
-      return typeAsVoid(node);
-    }
-
-    @Override
-    public Type visitSourceDirective(DartSourceDirective node) {
-      return typeAsVoid(node);
-    }
-
-    private class AbstractMethodFinder extends ASTVisitor<Void> {
-      private final InterfaceType currentClass;
-      private final Multimap<String, Element> superMembers = LinkedListMultimap.create();
-      private final List<Element> unimplementedElements = Lists.newArrayList();
-
-      private AbstractMethodFinder(InterfaceType currentClass) {
-        this.currentClass = currentClass;
-      }
-
-      @Override
-      public Void visitNode(DartNode node) {
-        throw new AssertionError();
-      }
-
-      @Override
-      public Void visitClass(DartClass node) {
-        assert node.getElement().getType() == currentClass;
-
-        // Prepare supertypes - all superclasses and interfaces.
-        List<InterfaceType> supertypes = Collections.emptyList();
-        boolean hasCyclicDeclaration = false;
-        try {
-          supertypes = currentClass.getElement().getAllSupertypes();
-        } catch (CyclicDeclarationException e) {
-          // Already reported by resolver.
-          hasCyclicDeclaration = true;
-        }
-
-        // Add all super members to resolve.
-        Element currentLibrary = currentClass.getElement().getEnclosingElement();
-
-        // cull out duplicate elements in the supertype list - inheriting more than one interface
-        // of the same type is valid.
-        Set<ClassElement> typesForAbstractMembers = Sets.newHashSet();
-        for (InterfaceType supertype : supertypes) {
-          typesForAbstractMembers.add(supertype.getElement());
-        }
-        Set<String> artificialNames = Sets.newHashSet();
-        for (ClassElement interfaceElement : typesForAbstractMembers) {
-          for (Element member : interfaceElement.getMembers()) {
-            if (interfaceElement == currentClass.getElement() && !Elements.isAbstractElement(member)) {
-              continue;
-            }
-            String name = member.getName();
-            if (DartIdentifier.isPrivateName(name)) {
-              if (currentLibrary != member.getEnclosingElement().getEnclosingElement()) {
-                continue;
-              }
-            }
-            superMembers.put(name, member);
-            if (member instanceof FieldElement) {
-              FieldElement field = (FieldElement) member;
-              if (!field.getModifiers().isAbstractField()) {
-                artificialNames.add("setter " + name);
-                superMembers.put("setter " + name, member);
-              } else if (field.getSetter() != null && !name.startsWith("setter ")) {
-                superMembers.put("setter " + name, member);
-              }
-            }
-          }
-        }
-
-        // Visit members, so resolve methods declared in this class.
-        this.visit(node.getMembers());
-
-        // If interface, we don't care about unimplemented methods.
-        if (currentClass.getElement().isInterface()) {
-          return null;
-        }
-
-        // If we have cyclic declaration, hierarchy is broken, no reason to report unimplemented.
-        if (hasCyclicDeclaration) {
-          return null;
-        }
-
-        // Visit superclasses (without interfaces) and mark methods as implemented.
-        {
-          List<InterfaceType> superTypes = Lists.newArrayList();
-          superTypes.add(currentClass.getElement().getSupertype());
-          for (InterfaceType supertype : superTypes) {
-            while (supertype != null) {
-              ClassElement superclass = supertype.getElement();
-              for (Element member : superclass.getMembers()) {
-                removeSuperMemberIfNotAbstract(member);
-              }
-              supertype = supertype.getElement().getSupertype();
-            }
-          }
-        }
-
-        // visit mixins
-        for (InterfaceType mixType : currentClass.getElement().getMixins()) {
-          ClassElement mixElement = mixType.getElement();
-          for (Element member : mixElement.getMembers()) {
-            removeSuperMemberIfNotAbstract(member);
-          }
-        }
-
-        // Remove artificial "setter " members.
-        for (String name : artificialNames) {
-          superMembers.removeAll(name);
-        }
-
-        // All remaining methods are unimplemented.
-        List<String> keys = new ArrayList<String>(superMembers.keys());
-        for (int i = 0; i < keys.size(); i++) {
-          String name = keys.get(i);
-          Collection<Element> elements = superMembers.removeAll(name);
-          for (Element element : elements) {
-            if (!element.getModifiers().isStatic()) {
-              unimplementedElements.add(element);
-              break; // Only report the first unimplemented element with this name.
-            }
-          }
-        }
-
-        // add abstract members of current class
-        for (Element member : currentClass.getElement().getMembers()) {
-          if (ElementKind.of(member) == ElementKind.FIELD && member.getModifiers().isAbstractField()) {
-            FieldElement field = (FieldElement) member;
-            MethodElement getter = field.getGetter();
-            MethodElement setter = field.getSetter();
-            if (getter != null && Elements.isAbstractElement(getter)) {
-              unimplementedElements.add(getter);
-            }
-            if (setter != null && Elements.isAbstractElement(setter)) {
-              unimplementedElements.add(setter);
-            }
-          } else if (Elements.isAbstractElement(member)) {
-            unimplementedElements.add(member);
-          }
-        }
-
-        return null;
-      }
-
-      private void removeSuperMemberIfNotAbstract(Element member) {
-        String name = member.getName();
-        if (ElementKind.of(member) == ElementKind.FIELD && member.getModifiers().isAbstractField()) {
-          FieldElement field = (FieldElement) member;
-          MethodElement getter = field.getGetter();
-          MethodElement setter = field.getSetter();
-          if (getter != null && !Elements.isAbstractElement(getter)) {
-            superMembers.removeAll(name);
-          }
-          if (setter != null && !Elements.isAbstractElement(setter)) {
-            if (!name.startsWith("setter ")) {
-              superMembers.removeAll("setter " + name);
-            } else {
-              superMembers.removeAll(name);
-            }
-          }
-        } else if (!Elements.isAbstractElement(member)) {
-          superMembers.removeAll(name);
-        }
-      }
-
-      @Override
-      public Void visitFieldDefinition(DartFieldDefinition node) {
-        this.visit(node.getFields());
-        return null;
-      }
-
-      @Override
-      public Void visitField(DartField node) {
-        if (superMembers == null) {
-          return null;
-        }
-        FieldElement field = node.getElement();
-        // prepare overridden elements
-        String name = field.getName();
-        Set<Element> overridden = Sets.newHashSet();
-        if (node.getAccessor() != null) {
-          if (node.getAccessor().getModifiers().isSetter()) {
-            if (!name.startsWith("setter ")) {
-              name = "setter " + name;
-            }
-          }
-          overridden.addAll(superMembers.removeAll(name));
-        } else {
-          overridden.addAll(superMembers.removeAll(name));
-          overridden.addAll(superMembers.removeAll("setter " + name));
-        }
-        // check override
-        for (Element superElement : overridden) {
-          if (!(field.isStatic() && superElement.getModifiers().isStatic())) {
-            if (canOverride(node.getName(), field.getModifiers(), superElement)
-                && !superElement.getModifiers().isStatic()) {
-              switch (superElement.getKind()) {
-                case FIELD:
-                  checkOverride(node.getName(), field, superElement);
-                  break;
-                case METHOD:
-                  typeError(node.getName(), TypeErrorCode.SUPERTYPE_HAS_METHOD, name,
-                      superElement.getEnclosingElement().getName());
-                  break;
-
-                default:
-                  typeError(node, TypeErrorCode.INTERNAL_ERROR, superElement);
-                  break;
-              }
-            }
-          }
-        }
-        // set super-elements for FieldElement
-        Elements.setOverridden(field, ImmutableSet.copyOf(overridden));
-        // set super-elements for getter/setter
-        if (node.getAccessor() != null) {
-          Set<Element> superGetters = Sets.newHashSet();
-          Set<Element> superSetters = Sets.newHashSet();
-          for (Element superElement : overridden) {
-            if (superElement instanceof FieldElement) {
-              FieldElement superField = (FieldElement) superElement;
-              if (superField.getGetter() != null) {
-                superGetters.add(superField.getGetter());
-              } else if (superField.getSetter() != null) {
-                superSetters.add(superField.getSetter());
-              } else {
-                superGetters.add(superField);
-                superSetters.add(superField);
-              }
-            }
-          }
-          if (node.getAccessor().getModifiers().isGetter()) {
-            Elements.setOverridden(node.getAccessor().getElement(), superGetters);
-          }
-          if (node.getAccessor().getModifiers().isSetter()) {
-            Elements.setOverridden(node.getAccessor().getElement(), superSetters);
-          }
-        }
-        return null;
-      }
-
-      @Override
-      public Void visitMethodDefinition(DartMethodDefinition node) {
-        MethodElement method = node.getElement();
-        String name = method.getName();
-        if (superMembers != null && !method.isConstructor()) {
-          Collection<Element> overridden = superMembers.removeAll(name);
-          Elements.setOverridden(method, ImmutableSet.copyOf(overridden));
-          // Check for invalid @override metadata.
-          if (overridden.isEmpty() && node.getObsoleteMetadata().isOverride()) {
-            typeError(node.getName(), ResolverErrorCode.INVALID_OVERRIDE_METADATA);
-          }
-          // Check that override is valid.
-          for (Element superElement : overridden) {
-            if (!(method.isStatic() && superElement.getModifiers().isStatic())) {
-              if (canOverride(node.getName(), method.getModifiers(), superElement)
-                  && !superElement.getModifiers().isStatic()) {
-                switch (superElement.getKind()) {
-                  case METHOD:
-                    checkOverride(node.getName(), method, superElement);
-                    break;
-
-                  case FIELD:
-                    typeError(node.getName(), TypeErrorCode.SUPERTYPE_HAS_FIELD, superElement.getName(),
-                        superElement.getEnclosingElement().getName());
-                    break;
-
-                  default:
-                    typeError(node, TypeErrorCode.INTERNAL_ERROR, superElement);
-                    break;
-                }
-              }
-            }
-          }
-        }
-        return null;
-      }
-
-      /**
-       * Report a compile-time error if a static member tries to override an instance member
-       * @returns true if no compile-time error was reported
-       */
-      private boolean canOverride(HasSourceInfo errorTarget, Modifiers modifiers,
-          Element superElement) {
-        if (!superElement.getModifiers().isStatic() && modifiers.isStatic()) {
-          onError(errorTarget, ResolverErrorCode.CANNOT_OVERRIDE_INSTANCE_MEMBER,
-                          superElement.getName(), superElement.getEnclosingElement().getName());
-          return false;
-        } else if (superElement.getModifiers().isStatic() && !modifiers.isStatic()) {
-            onError(errorTarget, TypeErrorCode.OVERRIDING_STATIC_MEMBER,
-                superElement.getName(), superElement.getEnclosingElement().getName());
-          // Although a warning, override is allowed anyway
-          return true;
-        }
-        return true;
-      }
-
-      /**
-       * Report a static type error if member cannot override superElement, that
-       * is, they are not assignable.
-       */
-      private void checkOverride(HasSourceInfo errorTarget, Element member, Element superElement) {
-        String name = member.getName();
-        Type superMember = typeAsMemberOf(superElement, currentClass);
-        if (member.getKind() == ElementKind.METHOD && superElement.getKind() == ElementKind.METHOD) {
-          MethodElement method = (MethodElement) member;
-          MethodElement superMethod = (MethodElement) superElement;
-          if (hasLegalMethodOverrideSignature(errorTarget, method, superMethod)) {
-            if (!types.isSubtype(member.getType(), superMember)) {
-              typeError(errorTarget,
-                        TypeErrorCode.CANNOT_OVERRIDE_METHOD_NOT_SUBTYPE,
-                        name,
-                        superElement.getEnclosingElement().getName(),
-                        member.getType(),
-                        superMember);
-            }
-          }
-        } else {
-          if (ElementKind.of(member) == ElementKind.FIELD
-              && ElementKind.of(superElement) == ElementKind.FIELD) {
-            FieldElement field = (FieldElement) member;
-            FieldElement superField = (FieldElement) superElement;
-            //
-            MethodElement fGetter = field.getGetter();
-            MethodElement sGetter = superField.getGetter();
-            if (fGetter != null && sGetter != null) {
-              checkOverride(errorTarget, fGetter, sGetter);
-            } else if (fGetter != null && sGetter == null || fGetter == null && sGetter != null) {
-            } else {
-              if (!types.isAssignable(superMember, member.getType())) {
-                typeError(errorTarget, TypeErrorCode.CANNOT_OVERRIDE_TYPED_MEMBER, name,
-                    superElement.getEnclosingElement().getName(), member.getType(), superMember);
-                return;
-              }
-            }
-            //
-            MethodElement fSetter = field.getSetter();
-            MethodElement sSetter = superField.getSetter();
-            if (fSetter != null && sSetter != null) {
-              checkOverride(errorTarget, fSetter, sSetter);
-            } else if (fSetter != null && sSetter == null || fSetter == null && sSetter != null) {
-            } else {
-              if (!types.isAssignable(superMember, member.getType())) {
-                typeError(errorTarget, TypeErrorCode.CANNOT_OVERRIDE_TYPED_MEMBER, name,
-                    superElement.getEnclosingElement().getName(), member.getType(), superMember);
-                return;
-              }
-            }
-            return;
-          }
-          if (!types.isAssignable(superMember, member.getType())) {
-            typeError(errorTarget, TypeErrorCode.CANNOT_OVERRIDE_TYPED_MEMBER, name,
-                superElement.getEnclosingElement().getName(), member.getType(), superMember);
-          }
-        }
-      }
-
-      /**
-       * @return <code>true</code> if given "method" has signature compatible with "superMethod".
-       */
-      private boolean hasLegalMethodOverrideSignature(HasSourceInfo errorTarget,
-                                                      MethodElement method,
-                                                      MethodElement superMethod) {
-        // Prepare parameters.
-        List<VariableElement> parameters = method.getParameters();
-        List<VariableElement> superParameters = superMethod.getParameters();
-        // Number of required parameters should be same.
-        {
-          int numRequired = Elements.getNumberOfRequiredParameters(method);
-          int superNumRequired = Elements.getNumberOfRequiredParameters(superMethod);
-          if (numRequired != superNumRequired) {
-            onError(errorTarget,
-                    ResolverErrorCode.CANNOT_OVERRIDE_METHOD_NUM_REQUIRED_PARAMS,
-                    getMethodSignature(superMethod),
-                    superMethod.getEnclosingElement().getName());
-            return false;
-          }
-        }
-        // "method" should have at least same number of optional positional parameters as "superMethod"
-        {
-          LinkedHashMap<VariableElement, DartExpression> defMethod = getParametersDefaultsOptional(parameters);
-          LinkedHashMap<VariableElement, DartExpression> defSuper = getParametersDefaultsOptional(superParameters);
-          if (defMethod.size() < defSuper.size()) {
-            onError(errorTarget,
-                    ResolverErrorCode.CANNOT_OVERRIDE_METHOD_OPTIONAL_PARAMS,
-                    getMethodSignature(superMethod),
-                    superMethod.getEnclosingElement().getName());
-            return false;
-          }
-          Iterator<Entry<VariableElement, DartExpression>> defMethodIter = defMethod.entrySet().iterator();
-          Iterator<Entry<VariableElement, DartExpression>> defSuperIter = defSuper.entrySet().iterator();
-          while (defSuperIter.hasNext()) {
-            Entry<VariableElement, DartExpression> methodEntry = defMethodIter.next();
-            Entry<VariableElement, DartExpression> superEntry = defSuperIter.next();
-            DartExpression methodValue = methodEntry.getValue();
-            DartExpression superValue = superEntry.getValue();
-            if (superValue != null
-                && !Objects.equal(ObjectUtils.toString(methodValue),
-                    ObjectUtils.toString(superValue))) {
-              onError(methodEntry.getKey().getSourceInfo(),
-                  TypeErrorCode.CANNOT_OVERRIDE_METHOD_DEFAULT_VALUE, method.getName(),
-                  superValue);
-            }
-          }
-        }
-        // "method" should have at least all named parameters of "superMethod".
-        {
-          Map<String, VariableElement> methodNames = getParametersNamed(parameters);
-          Map<String, VariableElement> superNames = getParametersNamed(superParameters);
-          if (!methodNames.keySet().containsAll(superNames.keySet())) {
-            onError(errorTarget, ResolverErrorCode.CANNOT_OVERRIDE_METHOD_NAMED_PARAMS, method.getName());
-            return false;
-          }
-          Map<String, DartExpression> methodDefs = getParametersDefaultsNamed(parameters);
-          Map<String, DartExpression> superDefs = getParametersDefaultsNamed(superParameters);
-          for (Entry<String, DartExpression> entry : superDefs.entrySet()) {
-            String name = entry.getKey();
-            DartExpression defValue = methodDefs.get(name);
-            DartExpression superDefValue = superDefs.get(name);
-            if (superDefValue != null
-                && !Objects.equal(ObjectUtils.toString(defValue),
-                    ObjectUtils.toString(superDefValue))) {
-              onError(methodNames.get(name).getSourceInfo(),
-                  TypeErrorCode.CANNOT_OVERRIDE_METHOD_DEFAULT_VALUE, method.getName(),
-                  superDefValue);
-            }
-          }
-        }
-//        List<VariableElement> named = getNamedParameters(parameters);
-//        List<VariableElement> superNamed = getNamedParameters(superParameters);
-//        Iterator<VariableElement> namedIterator = named.iterator();
-//        Iterator<VariableElement> superNamedIterator = superNamed.iterator();
-//        while (superNamedIterator.hasNext()) {
-//          VariableElement superParameter = superNamedIterator.next();
-//          if (namedIterator.hasNext()) {
-//            VariableElement parameter = namedIterator.next();
-//            if (Objects.equal(parameter.getName(), superParameter.getName())) {
-//              DartExpression superDefValue = superParameter.getDefaultValue();
-//              DartExpression defValue = parameter.getDefaultValue();
-//              if (superDefValue != null
-//                  && !Objects.equal(ObjectUtils.toString(defValue),
-//                      ObjectUtils.toString(superDefValue))) {
-//                onError(parameter.getSourceInfo(),
-//                    TypeErrorCode.CANNOT_OVERRIDE_METHOD_DEFAULT_VALUE, method.getName(),
-//                    superDefValue);
-//              }
-//              continue;
-//            }
-//          }
-//          onError(errorTarget, ResolverErrorCode.CANNOT_OVERRIDE_METHOD_NAMED_PARAMS, method.getName());
-//          return false;
-//        }
-        return true;
-      }
-
-      private String getMethodSignature(MethodElement method) {
-        StringBuilder builder = new StringBuilder();
-        builder.append(method.getName());
-        builder.append("(");
-        boolean inOptional = false;
-        boolean inNamed = false;
-        List<VariableElement> superParameters = method.getParameters();
-        int parameterCount = superParameters.size();
-        for (int i = 0; i < parameterCount; i++) {
-          if (i > 0) {
-            builder.append(", ");
-          }
-          VariableElement parameter = superParameters.get(i);
-          if (!inOptional && parameter.isOptional()) {
-            builder.append("[");
-            inOptional = true;
-          }
-          if (!inNamed && parameter.isNamed()) {
-            builder.append("{");
-            inNamed = true;
-          }
-          builder.append(parameter.getType().toString());
-        }
-        if (inOptional) {
-          builder.append("]");
-        }
-        if (inNamed) {
-          builder.append("}");
-        }
-        builder.append(")");
-        String methodSignature = builder.toString();
-        return methodSignature;
-      }
-
-      private LinkedHashMap<VariableElement, DartExpression> getParametersDefaultsOptional(List<VariableElement> parameters) {
-        LinkedHashMap<VariableElement, DartExpression> defaults = Maps.newLinkedHashMap();
-        for (VariableElement parameter : parameters) {
-          if (parameter.isOptional()) {
-            defaults.put(parameter, parameter.getDefaultValue());
-          }
-        }
-        return defaults;
-      }
-
-      private Map<String, VariableElement> getParametersNamed(List<VariableElement> parameters) {
-        Map<String, VariableElement> namedParameters = Maps.newHashMap();
-        for (VariableElement parameter : parameters) {
-          if (parameter.isNamed()) {
-            namedParameters.put(parameter.getName(), parameter);
-          }
-        }
-        return namedParameters;
-      }
-
-      private Map<String, DartExpression> getParametersDefaultsNamed(List<VariableElement> parameters) {
-        Map<String, DartExpression> defaults = Maps.newHashMap();
-        for (VariableElement parameter : parameters) {
-          if (parameter.isNamed()) {
-            defaults.put(parameter.getName(), parameter.getDefaultValue());
-          }
-        }
-        return defaults;
-      }
-    }
-  }
-
-  private static boolean isExplicitlySpecifiedType(Type type) {
-    return type != null && TypeKind.of(type) != TypeKind.DYNAMIC
-        && !TypeQuality.isInferred(type);
-  }
-
-  /**
-   * @return the {@link TypeQuality} of given {@link DartExpression}.
-   */
-  public static TypeQuality getTypeQuality(DartExpression expr) {
-    if (expr != null) {
-      if (expr instanceof DartIdentifier) {
-        Type varType = expr.getType();
-        if (varType != null) {
-          TypeQuality varTypeQuality = varType.getQuality();
-          if (varTypeQuality == TypeQuality.EXACT) {
-            varTypeQuality = TypeQuality.INFERRED_EXACT;
-          }
-          return varTypeQuality;
-        }
-      }
-      if (expr instanceof DartLiteral) {
-        return TypeQuality.INFERRED_EXACT;
-      }
-      if (expr instanceof DartUnaryExpression) {
-        DartUnaryExpression unary = (DartUnaryExpression) expr;
-        if (hasTypeBoolIntDouble(unary.getArg())) {
-          return TypeQuality.INFERRED_EXACT;
-        }
-        return TypeQuality.INFERRED;
-      }
-      if (expr instanceof DartBinaryExpression) {
-        DartBinaryExpression binary = (DartBinaryExpression) expr;
-        if (hasTypeBoolIntDouble(binary.getArg1()) && hasTypeBoolIntDouble(binary.getArg2())) {
-          return TypeQuality.INFERRED_EXACT;
-        }
-        return TypeQuality.INFERRED;
-      }
-      if (expr instanceof DartNewExpression) {
-        DartNewExpression newExpression = (DartNewExpression) expr;
-        ConstructorElement constructorElement = newExpression.getElement();
-        if (constructorElement != null && !constructorElement.getModifiers().isFactory()) {
-          return TypeQuality.INFERRED_EXACT;
-        }
-        return TypeQuality.INFERRED;
-      }
-    }
-    return TypeQuality.INFERRED;
-  }
-
-  private static boolean hasTypeBoolIntDouble(DartExpression expr) {
-    Type type = expr.getType();
-    return isCoreType(type, "bool") || isCoreType(type, "int") || isCoreType(type, "double");
-  }
-
-  private static boolean isCoreType(Type type, String name) {
-    return type != null
-        && Elements.isCoreLibrarySource(type.getElement().getSourceInfo().getSource())
-        && type.getElement().getName().equals(name);
-  }
-
-  /**
-   * Sometimes inferred type is too generic - such as "Object" or "Collection", so there are no
-   * reason to reports problems.
-   */
-  private static boolean isTooGenericInferredType(Type type) {
-    if (TypeQuality.of(type) == TypeQuality.INFERRED) {
-      String typeName = type.getElement().getName();
-      if ("Object".equals(typeName) || "Collection".equals(typeName)) {
-        return true;
-      }
-    }
-    return false;
-  }
-}
diff --git a/compiler/java/com/google/dart/compiler/type/TypeKind.java b/compiler/java/com/google/dart/compiler/type/TypeKind.java
deleted file mode 100644
index 8564dbb..0000000
--- a/compiler/java/com/google/dart/compiler/type/TypeKind.java
+++ /dev/null
@@ -1,27 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.type;
-
-/**
- * Kinds of types. Use kinds instead of instanceof for maximum flexibility
- * and sharing of similar implementation classes.
- */
-public enum TypeKind {
-  DYNAMIC,
-  FUNCTION,
-  FUNCTION_ALIAS,
-  INTERFACE,
-  NONE,
-  VOID,
-  VARIABLE;
-
-  public static TypeKind of(Type type) {
-    if (type == null) {
-      return NONE;
-    } else {
-      return type.getKind();
-    }
-  }
-}
diff --git a/compiler/java/com/google/dart/compiler/type/TypeQuality.java b/compiler/java/com/google/dart/compiler/type/TypeQuality.java
deleted file mode 100644
index 04ff2a6..0000000
--- a/compiler/java/com/google/dart/compiler/type/TypeQuality.java
+++ /dev/null
@@ -1,36 +0,0 @@
-// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.type;
-
-import com.google.dart.compiler.resolver.Element;
-
-/**
- * Quality of the {@link Type}.
- */
-public enum TypeQuality {
-  /**
-   * {@link Element} was declared with this {@link Type}.
-   */
-  EXACT,
-  /**
-   * {@link Element} was not declared with this {@link Type}, but we can prove that we can treat it
-   * as if it was declared with this {@link Type}.
-   */
-  INFERRED_EXACT,
-  /**
-   * {@link Element} was not declared this {@link Type}, but we have some reasons to think that it
-   * has such {@link Type}, or one of its subtypes.
-   */
-  INFERRED;
-
-  public static TypeQuality of(Type type) {
-    return type.getQuality();
-  }
-
-  public static boolean isInferred(Type type) {
-    return type.getQuality() != EXACT;
-  }
-
-}
diff --git a/compiler/java/com/google/dart/compiler/type/TypeVariable.java b/compiler/java/com/google/dart/compiler/type/TypeVariable.java
deleted file mode 100644
index b3b98b4..0000000
--- a/compiler/java/com/google/dart/compiler/type/TypeVariable.java
+++ /dev/null
@@ -1,34 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.type;
-
-import com.google.dart.compiler.resolver.TypeVariableElement;
-
-/**
- * Represents a type variable, that is the type parameters of a class
- * or interface type. For example, in {@code class Array<E> { ... }},
- * E is a type variable.
- *
- * <p>Each class/interface should have its own unique type variables,
- * one for each type parameter. A class/interface with type parameters
- * is said to be parameterized or generic.
- *
- * <p>Non-static members, constructors, and factories of generic
- * class/interface can refer to type variables of the current class
- * (not of supertypes).
- *
- * <p>When using a generic type, also known as an application or
- * instantiation of the type, the actual type arguments should be
- * substituted for the type variables in the class declaration.
- *
- * <p>For example, given a box, {@code class Box<T> { T value; }}, the
- * type of the expression {@code new Box<String>().value} is
- * {@code String} because we must substitute {@code String} for the
- * the type variable {@code T}.
- */
-public interface TypeVariable extends Type {
-  // Work around JDK 6 bug. Should @Override getElement().
-  TypeVariableElement getTypeVariableElement();
-}
diff --git a/compiler/java/com/google/dart/compiler/type/TypeVariableImplementation.java b/compiler/java/com/google/dart/compiler/type/TypeVariableImplementation.java
deleted file mode 100644
index 6df862b..0000000
--- a/compiler/java/com/google/dart/compiler/type/TypeVariableImplementation.java
+++ /dev/null
@@ -1,74 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.type;
-
-import com.google.dart.compiler.resolver.Element;
-import com.google.dart.compiler.resolver.TypeVariableElement;
-
-import java.util.Iterator;
-import java.util.List;
-
-/**
- * Default implementation of {@link TypeVariable}.
- */
-class TypeVariableImplementation extends AbstractType implements TypeVariable {
-  private final TypeVariableElement element;
-
-  public TypeVariableImplementation(TypeVariableElement element) {
-    this.element = element;
-  }
-
-  @Override
-  public TypeVariableElement getElement() {
-    return element;
-  }
-
-  @Override
-  public TypeVariableElement getTypeVariableElement() {
-    return getElement();
-  }
-
-  @Override
-  public String toString() {
-    Element owner = element.getDeclaringElement();
-    if (owner == null) {
-      return element.getName();
-    } else {
-      return owner.getName() + "." + element.getName();
-    }
-  }
-
-  @Override
-  public Type subst(List<Type> arguments, List<Type> parameters) {
-    Iterator<? extends Type> itA = arguments.iterator();
-    Iterator<? extends Type> itP = parameters.iterator();
-    while (itA.hasNext() && itP.hasNext()) {
-      Type argument = itA.next();
-      Type parameter = itP.next();
-      if (equals(parameter)) {
-        return argument;
-      }
-    }
-
-    // O(1) check to assert arguments and parameters are of same size.
-    assert itA.hasNext() == itP.hasNext() :
-      "arguments: " + arguments + " parameters: " + parameters;
-    return this;
-  }
-
-  @Override
-  public boolean equals(Object obj) {
-    if (obj instanceof TypeVariable) {
-      TypeVariable other = (TypeVariable) obj;
-      return element.equals(other.getElement());
-    }
-    return false;
-  }
-
-  @Override
-  public TypeKind getKind() {
-    return TypeKind.VARIABLE;
-  }
-}
diff --git a/compiler/java/com/google/dart/compiler/type/Types.java b/compiler/java/com/google/dart/compiler/type/Types.java
deleted file mode 100644
index 8e83daf..0000000
--- a/compiler/java/com/google/dart/compiler/type/Types.java
+++ /dev/null
@@ -1,817 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.type;
-
-import com.google.common.annotations.VisibleForTesting;
-import com.google.common.base.Function;
-import com.google.common.base.Predicate;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.Iterables;
-import com.google.common.collect.Lists;
-import com.google.common.collect.MapMaker;
-import com.google.common.collect.Maps;
-import com.google.common.collect.Sets;
-import com.google.dart.compiler.ast.DartNewExpression;
-import com.google.dart.compiler.ast.DartNode;
-import com.google.dart.compiler.ast.DartPropertyAccess;
-import com.google.dart.compiler.ast.DartTypeNode;
-import com.google.dart.compiler.resolver.ClassElement;
-import com.google.dart.compiler.resolver.CoreTypeProvider;
-import com.google.dart.compiler.resolver.Element;
-import com.google.dart.compiler.resolver.FunctionAliasElement;
-import com.google.dart.compiler.resolver.ResolutionErrorListener;
-import com.google.dart.compiler.resolver.TypeVariableElement;
-import com.google.dart.compiler.resolver.VariableElement;
-import com.google.dart.compiler.type.InterfaceType.Member;
-
-import java.lang.reflect.InvocationHandler;
-import java.lang.reflect.Method;
-import java.lang.reflect.Proxy;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.LinkedHashMap;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
-
-/**
- * Utility class for types.
- */
-public class Types {
-  private static Map<Type, Map<TypeQuality, Type>> inferredTypes = new MapMaker().weakKeys().makeMap();
-  private final CoreTypeProvider typeProvider;
-
-  private Types(CoreTypeProvider typeProvider) { // Prevent subclassing.
-    this.typeProvider = typeProvider;
-  }
-
-  public Type leastUpperBound(Type t, Type s) {
-    if (isSubtype(t, s)) {
-      return s;
-    } else if (isSubtype(s, t)) {
-      return t;
-    } else {
-      List<InterfaceType> tTypes = getSuperTypes(t);
-      List<InterfaceType> sTypes = getSuperTypes(s);
-      for (InterfaceType tType : tTypes) {
-        if (sTypes.contains(tType)) {
-          return tType;
-        }
-      }
-      return typeProvider.getObjectType();
-    }
-  }
-
-  public Type intersection(Type t, Type s) {
-    return intersection(ImmutableList.of(t, s));
-  }
-    
-  public static TypeQuality getIntersectionQuality(Type t, Type s) {
-    return getIntersectionQuality(ImmutableList.of(t, s));
-  }
-  
-  public static TypeQuality getIntersectionQuality(List<Type> types) {
-    Type singleType = null;
-    for (Type type : types) {
-      if (singleType == null) {
-        singleType = type;
-      } else if (singleType != type) {
-        return TypeQuality.INFERRED;
-      }
-    }
-    return TypeQuality.INFERRED_EXACT;
-  }
-    
-  public Type intersection(List<Type> types) {
-    // exclude 'dynamic' type
-    {
-      List<Type> newTypes = Lists.newArrayList();
-      for (Type type : types) {
-        if (TypeKind.of(type) != TypeKind.DYNAMIC) {
-          newTypes.add(type);
-        }
-      }
-      types = newTypes;
-    }
-    // no types, so Dynamic
-    if (types.isEmpty()) {
-      return typeProvider.getDynamicType();
-    }
-    // prepare all super types
-    List<List<InterfaceType>> superTypesLists = Lists.newArrayList();
-    List<Map<InterfaceType, InterfaceType>> superTypesMaps = Lists.newArrayList();
-    for (Type type : types) {
-      List<InterfaceType> superTypes = getSuperTypes(type);
-      superTypesLists.add(superTypes);
-      Map<InterfaceType, InterfaceType> superTypesMap = Maps.newHashMap();
-      for (InterfaceType superType : superTypes) {
-        superTypesMap.put(superType.asRawType(), superType);
-      }
-      superTypesMaps.add(superTypesMap);
-    }
-    // find intersection of super types
-    LinkedList<InterfaceType> interTypes = Lists.newLinkedList();
-    if (superTypesLists.size() > 0) {
-      for (InterfaceType superType : superTypesLists.get(0)) {
-        boolean inAll = true;
-        for (Map<InterfaceType, InterfaceType> otherTypesMap : superTypesMaps) {
-          InterfaceType superTypeRaw = superType.asRawType();
-          InterfaceType otherType = otherTypesMap.get(superTypeRaw);
-          // no such raw type, exclude from intersection
-          if (otherType == null) {
-            inAll = false;
-            break;
-          }
-          // if not raw, choose type arguments
-          if (!superType.getArguments().isEmpty()) {
-            InterfaceType t0 = superType;
-            InterfaceType t1 = otherType;
-            // if two-way sub-type, then has Dynamic(s), choose with least number
-            if (isSubtype(t0, t1) && isSubtype(t1, t0)) {
-              int dynamics0 = getDynamicArgumentsCount(t0);
-              int dynamics1 = getDynamicArgumentsCount(t1);
-              if (dynamics0 < dynamics1) {
-                superType = t0;
-              } else {
-                superType = t1;
-              }
-              continue;
-            }
-            // use super-type of t0 and t1
-            if (isSubtype(t0, t1)) {
-              superType = t1;
-            }
-            if (isSubtype(t1, t0)) {
-              superType = t0;
-            }
-          }
-        }
-        if (inAll && !interTypes.contains(superType)) {
-          interTypes.add(superType);
-        }
-      }
-    }
-    // try to remove sub-types already covered by existing types
-    for (Iterator<InterfaceType> i = interTypes.descendingIterator(); i.hasNext();) {
-      InterfaceType subType = i.next();
-      boolean hasSuperType = false;
-      for (InterfaceType superType : interTypes) {
-        if (superType != subType && isSubtype(superType, subType)) {
-          hasSuperType = true;
-          break;
-        }
-      }
-      if (hasSuperType) {
-        i.remove();
-      }
-    }
-    // use single type
-    if (interTypes.size() == 0) {
-      return typeProvider.getObjectType();
-    }
-    if (interTypes.size() == 1) {
-      return interTypes.get(0);
-    }
-    // create union
-    return unionTypes(interTypes);
-  }
-
-  /**
-   * @return the {@link InterfaceType} which is union of given ones.
-   */
-  public InterfaceType unionTypes(List<InterfaceType> types) {
-    return new InterfaceTypeUnionImplementation(types);
-  }
-
-  /**
-   * @return the number of <code>Dynamic</code> type arguments in given {@link InterfaceType}.
-   */
-  private static int getDynamicArgumentsCount(InterfaceType t) {
-    return Iterables.size(Iterables.filter(t.getArguments(), new Predicate<Type>() {
-      public boolean apply(Type arg) {
-        return TypeKind.of(arg) == TypeKind.DYNAMIC;
-      }
-    }));
-  }
-
-  /**
-   * @return list of the super-types (if class type given) or super-interfaces (if interface type
-   *         given) from most specific to least specific.
-   */
-  private static List<InterfaceType> getSuperTypes(Type type) {
-    List<InterfaceType> types = Lists.newArrayList();
-    if (type instanceof InterfaceType) {
-      InterfaceType interfaceType = (InterfaceType) type;
-      types.add(interfaceType);
-      for (InterfaceType intf : interfaceType.getElement().getInterfaces()) {
-        intf = asSupertype(interfaceType, intf);
-        types.addAll(getSuperTypes(intf));
-      }
-      for (InterfaceType mixin : interfaceType.getElement().getMixins()) {
-        mixin = asSupertype(interfaceType, mixin);
-        types.add(mixin);
-      }
-      if (!interfaceType.getElement().isInterface()) {
-        InterfaceType superClass = interfaceType.getElement().getSupertype();
-        superClass= asSupertype(interfaceType, superClass);
-        types.addAll(getSuperTypes(superClass));
-      }
-    }
-    return types;
-  }
-
-  /**
-   * Return an interface type representing the given interface, function or
-   * variable type.
-   * @return An interface type or null if the argument is neither an interface
-   *         function or variable type.
-   */
-  public InterfaceType getInterfaceType(Type type) {
-    switch (TypeKind.of(type)) {
-      case VARIABLE: {
-        TypeVariableElement element = ((TypeVariable) type).getTypeVariableElement();
-        if (element.getBound() == null) {
-          return typeProvider.getObjectType();
-        } else {
-          return getInterfaceType(element.getBound());
-        }
-      }
-      case FUNCTION:
-      case FUNCTION_ALIAS:
-        return typeProvider.getFunctionType();
-      case INTERFACE:
-        return (InterfaceType) type;
-      case DYNAMIC:
-      case NONE:
-      case VOID:
-      default:
-        return null;
-    }
-  }
-
-  /**
-   * Returns true if t is a subtype of s.
-   */
-  public boolean isSubtype(Type t, Type s) {
-    if (t.getKind().equals(TypeKind.DYNAMIC)) {
-      return true;
-    }
-    switch (s.getKind()) {
-      case DYNAMIC:
-        return true;
-
-      case INTERFACE:
-        return isSubtypeOfInterface(t, (InterfaceType) s);
-
-      case FUNCTION_ALIAS:
-        return isSubtypeOfAlias(t, (FunctionAliasType) s);
-
-      case FUNCTION:
-        switch (t.getKind()) {
-          case FUNCTION_ALIAS:
-            return isSubtypeOfFunction(asFunctionType((FunctionAliasType) t), (FunctionType) s);
-
-          case FUNCTION:
-            return isSubtypeOfFunction((FunctionType) t, (FunctionType) s);
-
-          default:
-            return false;
-        }
-
-      case VARIABLE:
-        return isSubtypeOfTypeVariable(t, (TypeVariable) s);
-
-      case VOID:
-        return t.equals(s);
-
-      default:
-        throw new AssertionError(s.getKind());
-    }
-  }
-
-  static FunctionType asFunctionType(FunctionAliasType alias) {
-    FunctionAliasElement element = alias.getElement();
-    FunctionType type =
-        (FunctionType) element.getFunctionType().subst(alias.getArguments(),
-                                                       element.getTypeParameters());
-    return type;
-  }
-
-  private boolean isSubtypeOfAlias(Type t, FunctionAliasType s) {
-    if (isSubtypeOfInterface(t, s)) {
-      return true;
-    }
-    if (t.getKind() == TypeKind.VARIABLE) {
-      Type bound = ((TypeVariable) t).getTypeVariableElement().getBound();
-      if (bound != null) {
-        return isSubtype(bound, s);
-      }
-      return true;
-    }
-    if (t.getKind() == TypeKind.FUNCTION_ALIAS) {
-      return isSubtypeOfFunction(asFunctionType((FunctionAliasType) t), asFunctionType(s));
-    }
-    // class has method call()
-    if (t.getKind() == TypeKind.INTERFACE) {
-      InterfaceType ti = (InterfaceType) t;
-      Member callMember = ti.lookupMember("call");
-      return callMember != null && isSubtype(callMember.getType(), asFunctionType(s));
-    }
-    return false;
-  }
-
-  private boolean isSubtypeOfTypeVariable(Type t, TypeVariable sv) {
-    // May be same type variable.
-    if (sv.equals(t)) {
-      return true;
-    }
-    // May be "T extends S".
-    if (t.getKind() == TypeKind.VARIABLE) {
-      TypeVariable tv = (TypeVariable) t;
-      Type tBound = tv.getTypeVariableElement().getBound();
-      if (tBound != null && tBound.getKind() == TypeKind.VARIABLE) {
-        // Prevent cycle.
-        if (tBound.equals(t)) {
-          return false;
-        }
-        // Check bound.
-        return isSubtype(tBound, sv);
-      }
-    }
-    // May be concrete InterfaceType.
-    if (t.getKind() == TypeKind.INTERFACE) {
-      InterfaceType ti = (InterfaceType) t;
-      Type sBound = sv.getTypeVariableElement().getBound();
-      if (sBound == null) {
-        return true;
-      }
-      // Prevent cycle.
-      if (sBound.equals(sv)) {
-        return false;
-      }
-      if (sBound.getKind() == TypeKind.INTERFACE) {
-        return isSubtype(ti, sBound);
-      }
-    }
-    // no
-    return false;
-  }
-
-  private boolean isSubtypeOfInterface(Type t, InterfaceType s) {
-    // Special handling for union.
-    if (t instanceof InterfaceTypeUnion) {
-      InterfaceTypeUnion tUnion = (InterfaceTypeUnion) t;
-      for (InterfaceType unionPart : tUnion.getTypes()) {
-        if (isSubtype(unionPart, s)) {
-          return true;
-        }
-      }
-      return false;
-    }
-
-    // class "t" implements call() and "s" is Function
-    if (TypeKind.of(t) == TypeKind.INTERFACE && typeProvider != null
-        && s == typeProvider.getFunctionType()) {
-      InterfaceType ti = (InterfaceType) t;
-      if (ti.lookupMember("call") != null) {
-        return true;
-      }
-    }
-
-    // Try to cast "t" to "s".
-    final Type sup = asInstanceOf(t, s.getElement());
-    if (TypeKind.of(sup) == TypeKind.INTERFACE) {
-      InterfaceType ti = (InterfaceType) sup;
-      assert ti.getElement().equals(s.getElement());
-      if (ti.isRaw() || s.isRaw()) {
-        return true;
-      }
-      // Type arguments are covariant.
-      return areSubtypes(ti.getArguments().iterator(), s.getArguments().iterator());
-    }
-    return false;
-  }
-
-  /**
-   * Implement the Dart function subtype rule. Unlike the classic arrow rule (return type is
-   * covariant, and parameter types are contravariant), in Dart they must just be assignable.
-   */
-  private boolean isSubtypeOfFunction(FunctionType t, FunctionType s) {
-    if (s.getKind() == TypeKind.DYNAMIC || t.getKind() == TypeKind.DYNAMIC) {
-      return true;
-    }
-    // Classic: return type is covariant; Dart: assignable.
-    if (!isAssignable(t.getReturnType(), s.getReturnType())) {
-      // A function that returns a value can be used as a function where you ignore the value.
-      if (!s.getReturnType().equals(typeProvider.getVoidType())) {
-        return false;
-      }
-    }
-    Type tRest = t.getRest();
-    Type sRest = s.getRest();
-    if ((tRest == null) != (sRest == null)) {
-      return false;
-    }
-    if (tRest != null) {
-      // Classic: parameter types are contravariant; Dart: assignable.
-      if (!isAssignable(sRest, tRest)) {
-        return false;
-      }
-    }
-
-    {
-      Map<String, Type> sOpti = s.getOptionalParameterTypes();
-      Map<String, Type> tOpti = t.getOptionalParameterTypes();
-      if (tOpti.size() < sOpti.size()) {
-        return false;
-      }
-      Iterator<Entry<String, Type>> tList = tOpti.entrySet().iterator();
-      Iterator<Entry<String, Type>> sList = sOpti.entrySet().iterator();
-      while (sList.hasNext()) {
-        if (!tList.hasNext()) {
-          return false;
-        }
-        Entry<String, Type> sEntry = sList.next();
-        Entry<String, Type> tEntry = tList.next();
-        if (!isAssignable(tEntry.getValue(), sEntry.getValue())) {
-          return false;
-        }
-      }
-    }
-    
-    Map<String, Type> tNamed = t.getNamedParameterTypes();
-    Map<String, Type> sNamed = s.getNamedParameterTypes();
-    if (tNamed.isEmpty() && !sNamed.isEmpty()) {
-      return false;
-    }
-
-    // T's named parameters must be in the same order and assignable to S's but
-    // maybe a superset.
-    if (!sNamed.isEmpty()) {
-      LinkedHashMap<String,Type> tMap = (LinkedHashMap<String, Type>)(tNamed);
-      LinkedHashMap<String,Type> sMap = (LinkedHashMap<String, Type>)(sNamed);
-      if (!tMap.keySet().containsAll(sMap.keySet())) {
-        return false;
-      }
-      for (Entry<String, Type> entry : sMap.entrySet()) {
-        String name = entry.getKey();
-        Type sType = sMap.get(name);
-        Type tType = tMap.get(name);
-        if (!isAssignable(tType, sType)) {
-          return false;
-        }
-      }
-//      Iterator<Entry<String, Type>> tList = tMap.entrySet().iterator();
-//      Iterator<Entry<String, Type>> sList = sMap.entrySet().iterator();
-//      // t named parameters must start with the named parameters of s
-//      while (sList.hasNext()) {
-//        if (!tList.hasNext()) {
-//          return false;
-//        }
-//        Entry<String, Type> sEntry = sList.next();
-//        Entry<String, Type> tEntry = tList.next();
-//        if (!sEntry.getKey().equals(tEntry.getKey())) {
-//          return false;
-//        }
-//        // Classic: parameter types are contravariant; Dart: assignable.
-//        if (!isAssignable(tEntry.getValue(), sEntry.getValue())) {
-//          return false;
-//        }
-//      }
-    }
-
-    // Classic: parameter types are contravariant; Dart: assignable.
-    return areAssignable(s.getParameterTypes().iterator(), t.getParameterTypes().iterator());
-  }
-
-  private boolean areSubtypes(Iterator<? extends Type> t, Iterator<? extends Type> s) {
-    while (t.hasNext() && s.hasNext()) {
-      if (!isSubtype(t.next(), s.next())) {
-        return false;
-      }
-    }
-
-    // O(1) check to assert t and s are of same size.
-    return t.hasNext() == s.hasNext();
-  }
-
-  private boolean areAssignable(Iterator<? extends Type> t, Iterator<? extends Type> s) {
-    while (t.hasNext() && s.hasNext()) {
-      if (!isAssignable(t.next(), s.next())) {
-        return false;
-      }
-    }
-
-    // O(1) check to assert t and s are of same size.
-    return t.hasNext() == s.hasNext();
-  }
-
-  /**
-   * Returns true if s is assignable to t.
-   */
-  public boolean isAssignable(Type t, Type s) {
-    t.getClass(); // Quick null check.
-    s.getClass(); // Quick null check.
-    return isSubtype(t, s) || isSubtype(s, t);
-  }
-
-  /**
-   * Translates the given type into an instantiation of the given
-   * element. This is done by walking the supertype hierarchy and
-   * substituting in the appropriate type arguments.
-   *
-   * <p>For example, if {@code GrowableArray<T>} is a subtype of
-   * {@code Array<T>}, then
-   * {@code asInstanceOf("GrowableArray<String>", "Array")} would
-   * return {@code Array<String>}
-   *
-   * @return null if t is not a subtype of element
-   */
-  @VisibleForTesting
-  public InterfaceType asInstanceOf(Type t, ClassElement element) {
-    return checkedAsInstanceOf(t, element, new HashSet<TypeVariable>(), new HashSet<Type>());
-  }
-
-  private InterfaceType checkedAsInstanceOf(Type t, ClassElement element,
-      Set<TypeVariable> variablesReferenced, Set<Type> checkedTypes) {
-    // check for recursion
-    if (checkedTypes.contains(t)) {
-      return null;
-    }
-    checkedTypes.add(t);
-    // check current Type
-    switch (TypeKind.of(t)) {
-      case FUNCTION_ALIAS:
-      case INTERFACE: {
-        if (t.getElement().equals(element)) {
-          return (InterfaceType) t;
-        }
-        InterfaceType ti = (InterfaceType) t;
-        ClassElement tElement = ti.getElement();
-        InterfaceType supertype = tElement.getSupertype();
-        // super type
-        if (supertype != null) {
-          InterfaceType result = checkedAsInstanceOf(asSupertype(ti, supertype), element,
-                                                     variablesReferenced, checkedTypes);
-          if (result != null) {
-            return result;
-          }
-        }
-        // interfaces
-        for (InterfaceType intf : tElement.getInterfaces()) {
-          InterfaceType result = checkedAsInstanceOf(asSupertype(ti, intf), element,
-                                                     variablesReferenced, checkedTypes);
-          if (result != null) {
-            return result;
-          }
-        }
-        // mixins
-        for (InterfaceType mixin : tElement.getMixins()) {
-          if (mixin.getElement().equals(element)) {
-            return asSupertype(ti, mixin);
-          }
-        }
-        // no
-        return null;
-      }
-      case FUNCTION: {
-        Element e = t.getElement();
-        switch (e.getKind()) {
-          case CLASS:
-            // e should be the interface Function in the core library. See the
-            // documentation comment on FunctionType.
-            InterfaceType ti = (InterfaceType) e.getType();
-            return checkedAsInstanceOf(ti, element, variablesReferenced, checkedTypes);
-          default:
-            return null;
-        }
-      }
-      case VARIABLE: {
-        TypeVariable v = (TypeVariable) t;
-        Type bound = v.getTypeVariableElement().getBound();
-        // Check for previously encountered variables to avoid getting stuck in an infinite loop.
-        if (variablesReferenced.contains(v)) {
-          if (bound instanceof InterfaceType) {
-            return (InterfaceType) bound;
-          }
-          return typeProvider.getObjectType();
-        }
-        variablesReferenced.add(v);
-        return checkedAsInstanceOf(bound, element, variablesReferenced, checkedTypes);
-      }
-      default:
-        return null;
-    }
-  }
-
-  private static InterfaceType asSupertype(InterfaceType type, InterfaceType supertype) {
-    if (supertype == null) {
-      return null;
-    }
-    if (type.isRaw()) {
-      return supertype.asRawType();
-    }
-    List<Type> arguments = type.getArguments();
-    List<Type> parameters = type.getElement().getTypeParameters();
-    return supertype.subst(arguments, parameters);
-  }
-
-  static void printTypesOn(StringBuilder sb, List<Type> types,
-                           String start, String end) {
-    sb.append(start);
-    boolean first = true;
-    for (Type argument : types) {
-      if (!first) {
-        sb.append(", ");
-      }
-      sb.append(argument);
-      first = false;
-    }
-    sb.append(end);
-  }
-
-  public static List<Type> subst(List<Type> types,
-                                 List<Type> arguments, List<Type> parameters) {
-    ArrayList<Type> result = new ArrayList<Type>(types.size());
-    for (Type type : types) {
-      result.add(type.subst(arguments, parameters));
-    }
-    return result;
-  }
-
-  public static FunctionType makeFunctionType(ResolutionErrorListener listener,
-                                              ClassElement element,
-                                              List<VariableElement> parameters,
-                                              Type returnType) {
-    List<Type> parameterTypes = new ArrayList<Type>(parameters.size());
-    Map<String, Type> optionalParameterTypes = null;
-    Map<String, Type> namedParameterTypes = null;
-    Type restParameter = null;
-    for (VariableElement parameter : parameters) {
-      Type type = parameter.getType();
-      // TODO(scheglov) one we will make optional parameter not named,
-      // check isOptional() before isNamed() 
-      if (parameter.isNamed()) {
-        if (namedParameterTypes == null) {
-          namedParameterTypes = new LinkedHashMap<String, Type>();
-        }
-        namedParameterTypes.put(parameter.getName(), type);
-      } else if (parameter.isOptional()) {
-        if (optionalParameterTypes == null) {
-          optionalParameterTypes = new LinkedHashMap<String, Type>();
-        }
-        optionalParameterTypes.put(parameter.getName(), type);
-      } else {
-        parameterTypes.add(type);
-      }
-    }
-    return FunctionTypeImplementation.of(element, parameterTypes, optionalParameterTypes,
-        namedParameterTypes, restParameter, returnType);
-  }
-
-  public static Types getInstance(CoreTypeProvider typeProvider) {
-    return new Types(typeProvider);
-  }
-
-  public static InterfaceType interfaceType(ClassElement element, List<Type> arguments) {
-    return new InterfaceTypeImplementation(element, arguments);
-  }
-
-  public static FunctionAliasType functionAliasType(FunctionAliasElement element,
-      List<TypeVariable> typeVariables) {
-    return new FunctionAliasTypeImplementation(element,
-        Collections.<Type>unmodifiableList(typeVariables));
-  }
-
-  public static TypeVariable typeVariable(TypeVariableElement element) {
-    return new TypeVariableImplementation(element);
-  }
-
-  public static DynamicType newDynamicType() {
-    return new DynamicTypeImplementation();
-  }
-
-  public static InterfaceType ensureInterface(Type type) {
-    TypeKind kind = TypeKind.of(type);
-    switch (kind) {
-      case INTERFACE:
-        return (InterfaceType) type;
-      case NONE:
-      case DYNAMIC:
-        return null;
-      default:
-        throw new AssertionError("unexpected kind " + kind);
-    }
-  }
-
-  public static Type newVoidType() {
-    return new VoidType();
-  }
-
-  /**
-   * Returns the type node corresponding to the instantiated class or interface.
-   */
-  public static DartTypeNode constructorTypeNode(DartNewExpression node) {
-    DartNode constructor = node.getConstructor();
-    if (constructor instanceof DartPropertyAccess) {
-      return (DartTypeNode) ((DartPropertyAccess) constructor).getQualifier();
-    } else {
-      return (DartTypeNode) constructor;
-    }
-  }
-
-  /**
-   * Returns the interface type being instantiated by the given node.
-   */
-  public static InterfaceType constructorType(DartNewExpression node) {
-    DartTypeNode typeNode = constructorTypeNode(node);
-    return (InterfaceType) typeNode.getType();
-  }
-
-  /**
-   * @return the wrapper of the given {@link Type} with {@link TypeQuality#INFERRED}.
-   */
-  public static Type makeInferred(Type type) {
-    return makeInferred(type, TypeQuality.INFERRED);
-  }
-  
-  /**
-   * @return the wrapper of the given {@link Type} with {@link TypeQuality#INFERRED_EXACT}.
-   */
-  public static Type makeInferredExact(Type type) {
-    return makeInferred(type, TypeQuality.INFERRED_EXACT);
-  }
-
-  /**
-   * @return the wrapper of the given {@link Type} with given {@link TypeQuality}.
-   */
-  public static Type makeInferred(Type type, TypeQuality quality) {
-    if (type == null) {
-      return null;
-    }
-    if (type.getQuality().ordinal() > quality.ordinal()) {
-      return type;
-    }
-    if (quality == TypeQuality.EXACT) {
-      return type;
-    }
-    Set<Class<?>> interfaceSet = getAllImplementedInterfaces(type.getClass());
-    if (!interfaceSet.isEmpty()) {
-      Class<?>[] interfaces = interfaceSet.toArray(new Class[interfaceSet.size()]);
-      return makeInferred(type, interfaces, quality);
-    }
-    return type;
-  }
-
-  private static Type makeInferred(final Type type, Class<?>[] interfaces, final TypeQuality quality) {
-    Map<TypeQuality, Type> inferredMap = inferredTypes.get(type);
-    if (inferredMap == null) {
-      inferredMap = new MapMaker().weakValues().makeMap();
-      inferredTypes.put(type, inferredMap);
-    }
-    Type inferred = inferredMap.get(quality);
-    if (inferred == null) {
-      inferred = (Type) Proxy.newProxyInstance(type.getClass().getClassLoader(),
-          interfaces, new InvocationHandler() {
-            @Override
-            @SuppressWarnings("unchecked")
-            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
-              if (args == null && method.getName().equals("getQuality")) {
-                return quality;
-              }
-              if (type instanceof FunctionType) {
-                if (args == null && method.getName().equals("getParameterTypes")) {
-                  List<Type> originalTypes = (List<Type>) method.invoke(type, args);
-                  return Lists.transform(originalTypes, new Function<Type, Type>() {
-                    public Type apply(Type input) {
-                      return makeInferred(input, quality);
-                    }
-                  });
-                }
-              }
-              return method.invoke(type, args);
-            }
-          });
-      inferredMap.put(quality, inferred);
-    }
-    return inferred;
-  }
-  
-  /**
-   * @return all interfaces implemented by given {@link Class}.
-   */
-  private static Set<Class<?>> getAllImplementedInterfaces(Class<?> c) {
-    Set<Class<?>> result = Sets.newHashSet();
-    for (Class<?> intf : c.getInterfaces()) {
-      result.add(intf);
-      result.addAll(getAllImplementedInterfaces(intf));
-    }
-    return result;
-  }
-}
diff --git a/compiler/java/com/google/dart/compiler/type/VoidType.java b/compiler/java/com/google/dart/compiler/type/VoidType.java
deleted file mode 100644
index 2e089bd..0000000
--- a/compiler/java/com/google/dart/compiler/type/VoidType.java
+++ /dev/null
@@ -1,46 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.type;
-
-import com.google.dart.compiler.resolver.Element;
-import com.google.dart.compiler.resolver.Elements;
-
-import java.util.List;
-
-/**
- * Implementation of "void". There is no public interface for this class as Type already exposes
- * all the functionality needed.
- */
-class VoidType extends AbstractType {
-  @Override
-  public Type subst(List<Type> arguments, List<Type> parameters) {
-    return this;
-  }
-
-  @Override
-  public TypeKind getKind() {
-    return TypeKind.VOID;
-  }
-
-  @Override
-  public Element getElement() {
-    return Elements.voidElement();
-  }
-
-  @Override
-  public String toString() {
-    return "void";
-  }
-
-  @Override
-  public boolean equals(Object other) {
-    return other instanceof VoidType;
-  }
-
-  @Override
-  public int hashCode() {
-    return VoidType.class.hashCode();
-  }
-}
diff --git a/compiler/java/com/google/dart/compiler/util/AbstractTextOutput.java b/compiler/java/com/google/dart/compiler/util/AbstractTextOutput.java
deleted file mode 100644
index 9c8d2b1..0000000
--- a/compiler/java/com/google/dart/compiler/util/AbstractTextOutput.java
+++ /dev/null
@@ -1,132 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.util;
-
-import java.io.PrintWriter;
-import java.util.Arrays;
-
-/**
- * An abstract base type to build TextOutput implementations.
- */
-public abstract class AbstractTextOutput implements TextOutput {
-  private final boolean compact;
-  private int identLevel = 0;
-  private int indentGranularity = 2;
-  private char[][] indents = new char[][] {new char[0]};
-  private boolean justNewlined;
-  private PrintWriter out;
-  private int position = 0;
-  private int line = 0;
-  private int column = 0;
-
-  protected AbstractTextOutput(boolean compact) {
-    this.compact = compact;
-  }
-
-  public int getPosition() {
-    return position;
-  }
-
-  public int getLine() {
-    return line;
-  }
-
-  public int getColumn() {
-    return column;
-  }
-
-  public void indentIn() {
-    ++identLevel;
-    if (identLevel >= indents.length) {
-      // Cache a new level of indentation string.
-      //
-      char[] newIndentLevel = new char[identLevel * indentGranularity];
-      Arrays.fill(newIndentLevel, ' ');
-      char[][] newIndents = new char[indents.length + 1][];
-      System.arraycopy(indents, 0, newIndents, 0, indents.length);
-      newIndents[identLevel] = newIndentLevel;
-      indents = newIndents;
-    }
-  }
-
-  public void indentOut() {
-    --identLevel;
-  }
-
-  public void newline() {
-    out.print('\n');
-    position++;
-    line++;
-    column = 0;
-    justNewlined = true;
-  }
-
-  public void newlineOpt() {
-    if (!compact) {
-      newline();
-    }
-  }
-
-  public void print(char c) {
-    maybeIndent();
-    out.print(c);
-    position++;
-    column++;
-    justNewlined = false;
-  }
-
-  public void print(char[] s) {
-    maybeIndent();
-    printAndCount(s);
-    justNewlined = false;
-  }
-
-  public void print(String s) {
-    maybeIndent();
-    printAndCount(s.toCharArray());
-    justNewlined = false;
-  }
-
-  // Why don't the "Opt" methods update "justNewLined"?
-  public void printOpt(char c) {
-    if (!compact) {
-      maybeIndent();
-      out.print(c);
-      position += 1;
-      column++;
-    }
-  }
-
-  public void printOpt(char[] s) {
-    if (!compact) {
-      maybeIndent();
-      printAndCount(s);
-    }
-  }
-
-  public void printOpt(String s) {
-    if (!compact) {
-      maybeIndent();
-      printAndCount(s.toCharArray());
-    }
-  }
-
-  protected void setPrintWriter(PrintWriter out) {
-    this.out = out;
-  }
-
-  private void maybeIndent() {
-    if (justNewlined && !compact) {
-      printAndCount(indents[identLevel]);
-      justNewlined = false;
-    }
-  }
-
-  private void printAndCount(char[] chars) {
-    position += chars.length;
-    column += chars.length;
-    out.print(chars);
-  }
-}
diff --git a/compiler/java/com/google/dart/compiler/util/DartSourceString.java b/compiler/java/com/google/dart/compiler/util/DartSourceString.java
deleted file mode 100644
index 407d18b..0000000
--- a/compiler/java/com/google/dart/compiler/util/DartSourceString.java
+++ /dev/null
@@ -1,87 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.util;
-
-import com.google.dart.compiler.DartSource;
-import com.google.dart.compiler.LibrarySource;
-
-import java.io.Reader;
-import java.io.StringReader;
-import java.net.URI;
-import java.net.URISyntaxException;
-
-/**
- * Instances of the class <code>DartSourceString</code> represent a source
- * composed from a string rather than an external file.
- */
-public class DartSourceString implements DartSource {
-  /**
-   * The name of the source being represented.
-   */
-  private String name;
-
-  /**
-   * The source being represented.
-   */
-  private String source;
-
-  /**
-   * Initialize a new Dart source to have the given content.
-   * 
-   * @param source the source being represented
-   */
-  public DartSourceString(String name, String source) {
-    this.name = name;
-    this.source = source;
-  }
-
-  @Override
-  public boolean exists() {
-    return true;
-  }
-
-  @Override
-  public long getLastModified() {
-    return 0;
-  }
-
-  @Override
-  public LibrarySource getLibrary() {
-    return null;
-  }
-
-  @Override
-  public String getName() {
-    return name;
-  }
-
-  @Override
-  public String getRelativePath() {
-    return name;
-  }
-
-  @Override
-  public Reader getSourceReader() {
-    return new StringReader(source);
-  }
-
-  @Override
-  public String getUniqueIdentifier() {
-    try {
-      return new URI(null, null, getName(), null).normalize().toString();
-    } catch (URISyntaxException e) {
-      throw new IllegalArgumentException(e);
-    }
-  }
-
-  @Override
-  public URI getUri() {
-    try {
-      return new URI(null, null, getName(), null, null).normalize();
-    } catch (URISyntaxException e) {
-      throw new IllegalArgumentException(e);
-    }
-  }
-}
diff --git a/compiler/java/com/google/dart/compiler/util/DefaultTextOutput.java b/compiler/java/com/google/dart/compiler/util/DefaultTextOutput.java
deleted file mode 100644
index 2a064ff..0000000
--- a/compiler/java/com/google/dart/compiler/util/DefaultTextOutput.java
+++ /dev/null
@@ -1,32 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.util;
-
-import java.io.PrintWriter;
-import java.io.StringWriter;
-
-/**
- * Adapts {@link TextOutput} to an internal text buffer.
- */
-public class DefaultTextOutput extends AbstractTextOutput {
-
-  private final StringWriter sw = new StringWriter();
-  private final PrintWriter out;
-
-  public DefaultTextOutput(boolean compact) {
-    super(compact);
-    setPrintWriter(out = new PrintWriter(sw));
-  }
-
-  @Override
-  public String toString() {
-    out.flush();
-    if (sw != null) {
-      return sw.toString();
-    } else {
-      return super.toString();
-    }
-  }
-}
diff --git a/compiler/java/com/google/dart/compiler/util/Hack.java b/compiler/java/com/google/dart/compiler/util/Hack.java
deleted file mode 100644
index 642f416..0000000
--- a/compiler/java/com/google/dart/compiler/util/Hack.java
+++ /dev/null
@@ -1,16 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.util;
-
-/**
- * Utility to hack around untypable (or yet to be) code.
- */
-public class Hack {
-  public static <T> T cast(Object o) {
-    @SuppressWarnings("unchecked")
-    T t = (T) o;
-    return t;
-  }
-}
diff --git a/compiler/java/com/google/dart/compiler/util/Lists.java b/compiler/java/com/google/dart/compiler/util/Lists.java
deleted file mode 100644
index 5d7f6dd..0000000
--- a/compiler/java/com/google/dart/compiler/util/Lists.java
+++ /dev/null
@@ -1,296 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.util;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.List;
-
-/**
- * Utility methods for operating on memory-efficient lists. All lists of size 0
- * or 1 are assumed to be immutable. All lists of size greater than 1 are
- * assumed to be mutable.
- */
-public class Lists {
-
-  private static final Class<?> MULTI_LIST_CLASS = ArrayList.class;
-  private static final Class<?> SINGLETON_LIST_CLASS = Collections.singletonList(null).getClass();
-
-  public static <T> List<T> add(List<T> list, int index, T toAdd) {
-    switch (list.size()) {
-      case 0:
-        // Empty -> Singleton
-        if (index != 0) {
-          throw newIndexOutOfBounds(list, index);
-        }
-        return Collections.singletonList(toAdd);
-      case 1: {
-        // Singleton -> ArrayList
-        List<T> result = new ArrayList<T>(2);
-        switch (index) {
-          case 0:
-            result.add(toAdd);
-            result.add(list.get(0));
-            return result;
-          case 1:
-            result.add(list.get(0));
-            result.add(toAdd);
-            return result;
-          default:
-            throw newIndexOutOfBounds(list, index);
-        }
-      }
-      default:
-        // ArrayList
-        list.add(index, toAdd);
-        return list;
-    }
-  }
-
-  public static <T> List<T> add(List<T> list, T toAdd) {
-    switch (list.size()) {
-      case 0:
-        // Empty -> Singleton
-        return Collections.singletonList(toAdd);
-      case 1: {
-        // Singleton -> ArrayList
-        List<T> result = new ArrayList<T>(2);
-        result.add(list.get(0));
-        result.add(toAdd);
-        return result;
-      }
-      default:
-        // ArrayList
-        list.add(toAdd);
-        return list;
-    }
-  }
-
-  public static <T> List<T> addAll(List<T> list, int index, List<T> toAdd) {
-    switch (toAdd.size()) {
-      case 0:
-        // No-op.
-        return list;
-      case 1:
-        // Add one element.
-        return add(list, index, toAdd.get(0));
-      default:
-        // True list merge, result >= 2.
-        switch (list.size()) {
-          case 0:
-            if (index != 0) {
-              throw newIndexOutOfBounds(list, index);
-            }
-            return new ArrayList<T>(toAdd);
-          case 1: {
-            List<T> result = new ArrayList<T>(1 + toAdd.size());
-            switch (index) {
-              case 0:
-                result.addAll(toAdd);
-                result.add(list.get(0));
-                return result;
-              case 1:
-                result.add(list.get(0));
-                result.addAll(toAdd);
-                return result;
-              default:
-                throw newIndexOutOfBounds(list, index);
-            }
-          }
-          default:
-            list.addAll(index, toAdd);
-            return list;
-        }
-    }
-  }
-
-  public static <T> List<T> addAll(List<T> list, List<T> toAdd) {
-    switch (toAdd.size()) {
-      case 0:
-        // No-op.
-        return list;
-      case 1:
-        // Add one element.
-        return add(list, toAdd.get(0));
-      default:
-        // True list merge, result >= 2.
-        switch (list.size()) {
-          case 0:
-            return new ArrayList<T>(toAdd);
-          case 1: {
-            List<T> result = new ArrayList<T>(1 + toAdd.size());
-            result.add(list.get(0));
-            result.addAll(toAdd);
-            return result;
-          }
-          default:
-            list.addAll(toAdd);
-            return list;
-        }
-    }
-  }
-
-  public static <T> List<T> addAll(List<T> list, T... toAdd) {
-    switch (toAdd.length) {
-      case 0:
-        // No-op.
-        return list;
-      case 1:
-        // Add one element.
-        return add(list, toAdd[0]);
-      default:
-        // True list merge, result >= 2.
-        switch (list.size()) {
-          case 0:
-            return new ArrayList<T>(Arrays.asList(toAdd));
-          case 1: {
-            List<T> result = new ArrayList<T>(1 + toAdd.length);
-            result.add(list.get(0));
-            result.addAll(Arrays.asList(toAdd));
-            return result;
-          }
-          default:
-            list.addAll(Arrays.asList(toAdd));
-            return list;
-        }
-    }
-  }
-
-  public static <T> List<T> create() {
-    return Collections.emptyList();
-  }
-
-  public static <T> List<T> create(Collection<T> collection) {
-    switch (collection.size()) {
-      case 0:
-        return create();
-      default:
-        return new ArrayList<T>(collection);
-    }
-  }
-
-  public static <T> List<T> create(List<T> list) {
-    switch (list.size()) {
-      case 0:
-        return create();
-      case 1:
-        return create(list.get(0));
-      default:
-        return new ArrayList<T>(list);
-    }
-  }
-
-  public static <T> List<T> create(T item) {
-    return Collections.singletonList(item);
-  }
-
-  public static <T> List<T> create(T... items) {
-    switch (items.length) {
-      case 0:
-        return create();
-      case 1:
-        return create(items[0]);
-      default:
-        return new ArrayList<T>(Arrays.asList(items));
-    }
-  }
-
-  public static <T> List<T> normalize(List<T> list) {
-    switch (list.size()) {
-      case 0:
-        return create();
-      case 1: {
-        if (list.getClass() == SINGLETON_LIST_CLASS) {
-          return list;
-        }
-        return create(list.get(0));
-      }
-      default:
-        if (list.getClass() == MULTI_LIST_CLASS) {
-          return list;
-        }
-        return new ArrayList<T>(list);
-    }
-  }
-
-  public static <T> List<T> normalizeUnmodifiable(List<T> list) {
-    if (list.size() < 2) {
-      return normalize(list);
-    } else {
-      List<T> copy = new ArrayList<T>(list.size());
-      Collections.copy(copy, list);
-      return copy;
-    }
-  }
-
-  public static <T> List<T> remove(List<T> list, int toRemove) {
-    switch (list.size()) {
-      case 0:
-        // Empty
-        throw newIndexOutOfBounds(list, toRemove);
-      case 1:
-        // Singleton -> Empty
-        if (toRemove == 0) {
-          return Collections.emptyList();
-        } else {
-          throw newIndexOutOfBounds(list, toRemove);
-        }
-      case 2:
-        // ArrayList -> Singleton
-        switch (toRemove) {
-          case 0:
-            return Collections.singletonList(list.get(1));
-          case 1:
-            return Collections.singletonList(list.get(0));
-          default:
-            throw newIndexOutOfBounds(list, toRemove);
-        }
-      default:
-        // ArrayList
-        list.remove(toRemove);
-        return list;
-    }
-  }
-
-  public static <T> List<T> set(List<T> list, int index, T e) {
-    switch (list.size()) {
-      case 0:
-        // Empty
-        throw newIndexOutOfBounds(list, index);
-      case 1:
-        // Singleton
-        if (index == 0) {
-          return Collections.singletonList(e);
-        } else {
-          throw newIndexOutOfBounds(list, index);
-        }
-      default:
-        // ArrayList
-        list.set(index, e);
-        return list;
-    }
-  }
-
-  public static <T extends Comparable<? super T>> List<T> sort(List<T> list) {
-    if (list.size() > 1) {
-      Collections.sort(list);
-    }
-    return list;
-  }
-
-  public static <T> List<T> sort(List<T> list, Comparator<? super T> sort) {
-    if (list.size() > 1) {
-      Collections.sort(list, sort);
-    }
-    return list;
-  }
-
-  private static <T> IndexOutOfBoundsException newIndexOutOfBounds(List<T> list, int index) {
-    return new IndexOutOfBoundsException("Index: " + index + ", Size: " + list.size());
-  }
-}
diff --git a/compiler/java/com/google/dart/compiler/util/Maps.java b/compiler/java/com/google/dart/compiler/util/Maps.java
deleted file mode 100644
index 89ea29f..0000000
--- a/compiler/java/com/google/dart/compiler/util/Maps.java
+++ /dev/null
@@ -1,160 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.util;
-
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.LinkedHashMap;
-
-/**
- * Utility methods for operating on memory-efficient maps. All maps of size 0 or
- * 1 are assumed to be immutable. All maps of size greater than 1 are assumed to
- * be mutable.
- */
-public class Maps {
-
-  private static final Class<?> MULTI_MAP_CLASS = HashMap.class;
-  private static final Class<?> SINGLETON_MAP_CLASS =
-      Collections.singletonMap(null, null).getClass();
-
-  public static <K, V> Map<K, V> create() {
-    return Collections.emptyMap();
-  }
-
-  public static <K, V> Map<K, V> create(K key, V value) {
-    return Collections.singletonMap(key, value);
-  }
-
-  public static <K, V> Map<K, V> normalize(Map<K, V> map) {
-    switch (map.size()) {
-      case 0:
-        return create();
-      case 1: {
-        if (map.getClass() == SINGLETON_MAP_CLASS) {
-          return map;
-        }
-        K key = map.keySet().iterator().next();
-        return create(key, map.get(key));
-      }
-      default:
-        if (map.getClass() == MULTI_MAP_CLASS) {
-          return map;
-        }
-        return new HashMap<K, V>(map);
-    }
-  }
-
-  public static <K, V> Map<K, V> normalizeUnmodifiable(Map<K, V> map) {
-    if (map.size() < 2) {
-      return normalize(map);
-    } else {
-      // TODO: implement an UnmodifiableHashMap?
-      return Collections.unmodifiableMap(normalize(map));
-    }
-  }
-
-  public static <K, V> Map<K, V> put(Map<K, V> map, K key, V value) {
-    switch (map.size()) {
-      case 0:
-        // Empty -> Singleton
-        return Collections.singletonMap(key, value);
-      case 1: {
-        if (map.containsKey(key)) {
-          return create(key, value);
-        }
-        // Singleton -> HashMap
-        Map<K, V> result = new HashMap<K, V>();
-        result.put(map.keySet().iterator().next(), map.values().iterator().next());
-        result.put(key, value);
-        return result;
-      }
-      default:
-        // HashMap
-        map.put(key, value);
-        return map;
-    }
-  }
-
-  public static <K, V> Map<K, V> putAll(Map<K, V> map, Map<K, V> toAdd) {
-    switch (toAdd.size()) {
-      case 0:
-        // No-op.
-        return map;
-      case 1: {
-        // Add one element.
-        K key = toAdd.keySet().iterator().next();
-        return put(map, key, toAdd.get(key));
-      }
-      default:
-        // True list merge, result >= 2.
-        switch (map.size()) {
-          case 0:
-            return new HashMap<K, V>(toAdd);
-          case 1: {
-            HashMap<K, V> result = new HashMap<K, V>();
-            K key = map.keySet().iterator().next();
-            result.put(key, map.get(key));
-            result.putAll(toAdd);
-            return result;
-          }
-          default:
-            map.putAll(toAdd);
-            return map;
-        }
-    }
-  }
-
-  /**
-   * A variation of the put method which uses a LinkedHashMap.
-   */
-  public static <K, V> Map<K, V> putOrdered(Map<K, V> map, K key, V value) {
-    switch (map.size()) {
-      case 0:
-        // Empty -> Singleton
-        return Collections.singletonMap(key, value);
-      case 1: {
-        if (map.containsKey(key)) {
-          return create(key, value);
-        }
-        // Singleton -> LinkedHashMap
-        Map<K, V> result = new LinkedHashMap<K, V>();
-        result.put(map.keySet().iterator().next(), map.values().iterator().next());
-        result.put(key, value);
-        return result;
-      }
-      default:
-        // LinkedHashMap
-        map.put(key, value);
-        return map;
-    }
-  }
-
-  public static <K, V> Map<K, V> remove(Map<K, V> map, K key) {
-    switch (map.size()) {
-      case 0:
-        // Empty
-        return map;
-      case 1:
-        // Singleton -> Empty
-        if (map.containsKey(key)) {
-          return create();
-        }
-        return map;
-      case 2:
-        // HashMap -> Singleton
-        if (map.containsKey(key)) {
-          map.remove(key);
-          key = map.keySet().iterator().next();
-          return create(key, map.get(key));
-        }
-        return map;
-      default:
-        // IdentityHashMap
-        map.remove(key);
-        return map;
-    }
-  }
-}
diff --git a/compiler/java/com/google/dart/compiler/util/Paths.java b/compiler/java/com/google/dart/compiler/util/Paths.java
deleted file mode 100644
index ee42826..0000000
--- a/compiler/java/com/google/dart/compiler/util/Paths.java
+++ /dev/null
@@ -1,105 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.util;
-
-import java.io.File;
-import java.net.URI;
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Utility methods for obtaining relative paths from files and translating
- * relative paths into files.
- */
-public class Paths {
-
-  /**
-   * Answer the relative path from baseFile to relFile
-   * 
-   * @param baseFile the base file (not <code>null</code>) from which the
-   *          desired path starts
-   * @param relFile the file referenced by the desired relative path (not
-   *          <code>null</code>)
-   * @return a relative path (not <code>null</code>)
-   */
-  public static String relativePathFor(File baseFile, File relFile) {
-    String baseFilePath = baseFile.getPath().replace(File.separatorChar, '/');
-    String relFilePath = relFile.getPath().replace(File.separatorChar, '/');
-    int baseFilePathLen = baseFilePath.length();
-    int relFilePathLen = relFilePath.length();
-
-    // Check for empty cases
-    if (baseFilePathLen == 0 && relFilePathLen == 0) {
-      return relFilePath;
-    }
-
-    // Find the common path elements
-    int index = 0;
-    while (index < baseFilePathLen - 1 && index < relFilePathLen - 1) {
-      if (baseFilePath.charAt(index) != relFilePath.charAt(index)) {
-        break;
-      }
-      index++;
-    }
-    while (index >= 0
-        && (baseFilePath.charAt(index) != '/' || relFilePath.charAt(index) != '/')) {
-      index--;
-    }
-    int commonStart = index;
-
-    // Build a path up from the base file
-    StringBuilder relPath = new StringBuilder(baseFilePathLen + relFilePathLen
-        - commonStart * 2);
-    index = commonStart + 1;
-    while (true) {
-      index = baseFilePath.indexOf('/', index);
-      if (index == -1) {
-        break;
-      }
-      relPath.append("../");
-      index++;
-    }
-    relPath.append(relFilePath.substring(commonStart + 1));
-    return relPath.toString();
-  }
-
-  /**
-   * Answer the file relative to the specified file
-   * 
-   * @param baseFile the base file (not <code>null</code>)
-   * @param relPath the path to the desired file relative to baseFile
-   * @return the file (not <code>null</code>)
-   */
-  public static File relativePathToFile(File baseFile, String relPath) {
-    if (relPath.startsWith("/")) {
-      return new File(relPath);
-    }
-    File parentFile = baseFile.getParentFile();
-    String name;
-    if (parentFile == null) {
-      name = ".";
-    } else {
-      name = parentFile.getPath().replace(File.separatorChar, '/');
-    }
-    name = URI.create(name + "/" + relPath).normalize().getPath();
-    return new File(name);
-  }
-
-  /**
-   * Given a collection of paths, return a collection of files
-   * 
-   * @param a collection of paths to various files (not <code>null</code>,
-   *          contains no <code>null</code>s)
-   * @return a collection of files (not <code>null</code>, contains no
-   *         <code>null</code>s)
-   */
-  public static List<File> toFiles(List<String> filePaths) {
-    List<File> files = new ArrayList<File>();
-    for (String path : filePaths) {
-      files.add(new File(path));
-    }
-    return files;
-  }
-}
diff --git a/compiler/java/com/google/dart/compiler/util/StringInterner.java b/compiler/java/com/google/dart/compiler/util/StringInterner.java
deleted file mode 100644
index e33118e..0000000
--- a/compiler/java/com/google/dart/compiler/util/StringInterner.java
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright (c) 2013, the Dart project authors.
- * 
- * Licensed under the Eclipse Public License v1.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.eclipse.org/legal/epl-v10.html
- * 
- * 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.dart.compiler.util;
-
-import com.google.common.collect.Interner;
-import com.google.common.collect.Interners;
-
-public class StringInterner {
-  private static Interner<String> INTERNER = Interners.newStrongInterner();
-  
-  public static String intern(String s) {
-    if (s == null) {
-      return null;
-    }
-    s = new String(s);
-    return INTERNER.intern(s);
-//    return s;
-  }
-}
diff --git a/compiler/java/com/google/dart/compiler/util/TextOutput.java b/compiler/java/com/google/dart/compiler/util/TextOutput.java
deleted file mode 100644
index 99a465b..0000000
--- a/compiler/java/com/google/dart/compiler/util/TextOutput.java
+++ /dev/null
@@ -1,37 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.util;
-
-/**
- * Interface used for printing text output.
- */
-public interface TextOutput {
-
-  int getPosition();
-
-  int getLine();
-
-  int getColumn();
-
-  void indentIn();
-
-  void indentOut();
-
-  void newline();
-
-  void newlineOpt();
-
-  void print(char c);
-
-  void print(char[] s);
-
-  void print(String s);
-
-  void printOpt(char c);
-
-  void printOpt(char[] s);
-
-  void printOpt(String s);
-}
diff --git a/compiler/java/com/google/dart/compiler/util/apache/ArrayUtils.java b/compiler/java/com/google/dart/compiler/util/apache/ArrayUtils.java
deleted file mode 100644
index e123549..0000000
--- a/compiler/java/com/google/dart/compiler/util/apache/ArrayUtils.java
+++ /dev/null
@@ -1,5799 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-/*
- * 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 com.google.dart.compiler.util.apache;
-
-import com.google.dart.compiler.util.apache.mutable.MutableInt;
-
-import java.lang.reflect.Array;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-
-/**
- * <p>Operations on arrays, primitive arrays (like {@code int[]}) and
- * primitive wrapper arrays (like {@code Integer[]}).</p>
- *
- * <p>This class tries to handle {@code null} input gracefully.
- * An exception will not be thrown for a {@code null}
- * array input. However, an Object array that contains a {@code null}
- * element may throw an exception. Each method documents its behaviour.</p>
- * <p>
- * NOTICE: This file is modified copy of its original Apache library.
- * It was moved to the different package, and changed to reduce number of dependencies.
- *
- * <p>#ThreadSafe#</p>
- * @since 2.0
- * @version $Id: ArrayUtils.java 1154216 2011-08-05 13:57:16Z mbenson $
- */
-public class ArrayUtils {
-
-    /**
-     * An empty immutable {@code Object} array.
-     */
-    public static final Object[] EMPTY_OBJECT_ARRAY = new Object[0];
-    /**
-     * An empty immutable {@code Class} array.
-     */
-    public static final Class<?>[] EMPTY_CLASS_ARRAY = new Class[0];
-    /**
-     * An empty immutable {@code String} array.
-     */
-    public static final String[] EMPTY_STRING_ARRAY = new String[0];
-    /**
-     * An empty immutable {@code long} array.
-     */
-    public static final long[] EMPTY_LONG_ARRAY = new long[0];
-    /**
-     * An empty immutable {@code Long} array.
-     */
-    public static final Long[] EMPTY_LONG_OBJECT_ARRAY = new Long[0];
-    /**
-     * An empty immutable {@code int} array.
-     */
-    public static final int[] EMPTY_INT_ARRAY = new int[0];
-    /**
-     * An empty immutable {@code Integer} array.
-     */
-    public static final Integer[] EMPTY_INTEGER_OBJECT_ARRAY = new Integer[0];
-    /**
-     * An empty immutable {@code short} array.
-     */
-    public static final short[] EMPTY_SHORT_ARRAY = new short[0];
-    /**
-     * An empty immutable {@code Short} array.
-     */
-    public static final Short[] EMPTY_SHORT_OBJECT_ARRAY = new Short[0];
-    /**
-     * An empty immutable {@code byte} array.
-     */
-    public static final byte[] EMPTY_BYTE_ARRAY = new byte[0];
-    /**
-     * An empty immutable {@code Byte} array.
-     */
-    public static final Byte[] EMPTY_BYTE_OBJECT_ARRAY = new Byte[0];
-    /**
-     * An empty immutable {@code double} array.
-     */
-    public static final double[] EMPTY_DOUBLE_ARRAY = new double[0];
-    /**
-     * An empty immutable {@code Double} array.
-     */
-    public static final Double[] EMPTY_DOUBLE_OBJECT_ARRAY = new Double[0];
-    /**
-     * An empty immutable {@code float} array.
-     */
-    public static final float[] EMPTY_FLOAT_ARRAY = new float[0];
-    /**
-     * An empty immutable {@code Float} array.
-     */
-    public static final Float[] EMPTY_FLOAT_OBJECT_ARRAY = new Float[0];
-    /**
-     * An empty immutable {@code boolean} array.
-     */
-    public static final boolean[] EMPTY_BOOLEAN_ARRAY = new boolean[0];
-    /**
-     * An empty immutable {@code Boolean} array.
-     */
-    public static final Boolean[] EMPTY_BOOLEAN_OBJECT_ARRAY = new Boolean[0];
-    /**
-     * An empty immutable {@code char} array.
-     */
-    public static final char[] EMPTY_CHAR_ARRAY = new char[0];
-    /**
-     * An empty immutable {@code Character} array.
-     */
-    public static final Character[] EMPTY_CHARACTER_OBJECT_ARRAY = new Character[0];
-
-    /**
-     * The index value when an element is not found in a list or array: {@code -1}.
-     * This value is returned by methods in this class and can also be used in comparisons with values returned by
-     * various method from {@link java.util.List}.
-     */
-    public static final int INDEX_NOT_FOUND = -1;
-
-    /**
-     * <p>ArrayUtils instances should NOT be constructed in standard programming.
-     * Instead, the class should be used as <code>ArrayUtils.clone(new int[] {2})</code>.</p>
-     *
-     * <p>This constructor is public to permit tools that require a JavaBean instance
-     * to operate.</p>
-     */
-    public ArrayUtils() {
-      super();
-    }
-
-
-    // NOTE: Cannot use {@code} to enclose text which includes {}, but <code></code> is OK
-
-
-    // Basic methods handling multi-dimensional arrays
-    //-----------------------------------------------------------------------
-//    /**
-//     * <p>Outputs an array as a String, treating {@code null} as an empty array.</p>
-//     *
-//     * <p>Multi-dimensional arrays are handled correctly, including
-//     * multi-dimensional primitive arrays.</p>
-//     *
-//     * <p>The format is that of Java source code, for example <code>{a,b}</code>.</p>
-//     *
-//     * @param array  the array to get a toString for, may be {@code null}
-//     * @return a String representation of the array, '{}' if null array input
-//     */
-//    public static String toString(Object array) {
-//        return toString(array, "{}");
-//    }
-//
-//    /**
-//     * <p>Outputs an array as a String handling {@code null}s.</p>
-//     *
-//     * <p>Multi-dimensional arrays are handled correctly, including
-//     * multi-dimensional primitive arrays.</p>
-//     *
-//     * <p>The format is that of Java source code, for example <code>{a,b}</code>.</p>
-//     *
-//     * @param array  the array to get a toString for, may be {@code null}
-//     * @param stringIfNull  the String to return if the array is {@code null}
-//     * @return a String representation of the array
-//     */
-//    public static String toString(Object array, String stringIfNull) {
-//        if (array == null) {
-//            return stringIfNull;
-//        }
-//        return new ToStringBuilder(array, ToStringStyle.SIMPLE_STYLE).append(array).toString();
-//    }
-//
-//    /**
-//     * <p>Get a hash code for an array handling multi-dimensional arrays correctly.</p>
-//     *
-//     * <p>Multi-dimensional primitive arrays are also handled correctly by this method.</p>
-//     *
-//     * @param array  the array to get a hash code for, {@code null} returns zero
-//     * @return a hash code for the array
-//     */
-//    public static int hashCode(Object array) {
-//        return new HashCodeBuilder().append(array).toHashCode();
-//    }
-//
-//    /**
-//     * <p>Compares two arrays, using equals(), handling multi-dimensional arrays
-//     * correctly.</p>
-//     *
-//     * <p>Multi-dimensional primitive arrays are also handled correctly by this method.</p>
-//     *
-//     * @param array1  the left hand array to compare, may be {@code null}
-//     * @param array2  the right hand array to compare, may be {@code null}
-//     * @return {@code true} if the arrays are equal
-//     */
-//    public static boolean isEquals(Object array1, Object array2) {
-//        return new EqualsBuilder().append(array1, array2).isEquals();
-//    }
-
-    // To map
-    //-----------------------------------------------------------------------
-    /**
-     * <p>Converts the given array into a {@link java.util.Map}. Each element of the array
-     * must be either a {@link java.util.Map.Entry} or an Array, containing at least two
-     * elements, where the first element is used as key and the second as
-     * value.</p>
-     *
-     * <p>This method can be used to initialize:</p>
-     * <pre>
-     * // Create a Map mapping colors.
-     * Map colorMap = MapUtils.toMap(new String[][] {{
-     *     {"RED", "#FF0000"},
-     *     {"GREEN", "#00FF00"},
-     *     {"BLUE", "#0000FF"}});
-     * </pre>
-     *
-     * <p>This method returns {@code null} for a {@code null} input array.</p>
-     *
-     * @param array  an array whose elements are either a {@link java.util.Map.Entry} or
-     *  an Array containing at least two elements, may be {@code null}
-     * @return a {@code Map} that was created from the array
-     * @throws IllegalArgumentException  if one element of this Array is
-     *  itself an Array containing less then two elements
-     * @throws IllegalArgumentException  if the array contains elements other
-     *  than {@link java.util.Map.Entry} and an Array
-     */
-    public static Map<Object, Object> toMap(Object[] array) {
-        if (array == null) {
-            return null;
-        }
-        final Map<Object, Object> map = new HashMap<Object, Object>((int) (array.length * 1.5));
-        for (int i = 0; i < array.length; i++) {
-            Object object = array[i];
-            if (object instanceof Map.Entry<?, ?>) {
-                Map.Entry<?,?> entry = (Map.Entry<?,?>) object;
-                map.put(entry.getKey(), entry.getValue());
-            } else if (object instanceof Object[]) {
-                Object[] entry = (Object[]) object;
-                if (entry.length < 2) {
-                    throw new IllegalArgumentException("Array element " + i + ", '"
-                        + object
-                        + "', has a length less than 2");
-                }
-                map.put(entry[0], entry[1]);
-            } else {
-                throw new IllegalArgumentException("Array element " + i + ", '"
-                        + object
-                        + "', is neither of type Map.Entry nor an Array");
-            }
-        }
-        return map;
-    }
-
-    // Generic array
-    //-----------------------------------------------------------------------
-    /**
-     * <p>Create a type-safe generic array.</p>
-     *
-     * <p>The Java language does not allow an array to be created from a generic type:</p>
-     *
-     * <pre>
-    public static &lt;T&gt; T[] createAnArray(int size) {
-        return new T[size]; // compiler error here
-    }
-    public static &lt;T&gt; T[] createAnArray(int size) {
-        return (T[])new Object[size]; // ClassCastException at runtime
-    }
-     * </pre>
-     *
-     * <p>Therefore new arrays of generic types can be created with this method.
-     * For example, an array of Strings can be created:</p>
-     *
-     * <pre>
-    String[] array = ArrayUtils.toArray("1", "2");
-    String[] emptyArray = ArrayUtils.&lt;String&gt;toArray();
-     * </pre>
-     *
-     * <p>The method is typically used in scenarios, where the caller itself uses generic types
-     * that have to be combined into an array.</p>
-     *
-     * <p>Note, this method makes only sense to provide arguments of the same type so that the
-     * compiler can deduce the type of the array itself. While it is possible to select the
-     * type explicitly like in
-     * <code>Number[] array = ArrayUtils.&lt;Number&gt;toArray(Integer.valueOf(42), Double.valueOf(Math.PI))</code>,
-     * there is no real advantage when compared to
-     * <code>new Number[] {Integer.valueOf(42), Double.valueOf(Math.PI)}</code>.</p>
-     *
-     * @param  <T>   the array's element type
-     * @param  items  the varargs array items, null allowed
-     * @return the array, not null unless a null array is passed in
-     * @since  3.0
-     */
-    public static <T> T[] toArray(final T... items) {
-        return items;
-    }
-
-    // Clone
-    //-----------------------------------------------------------------------
-    /**
-     * <p>Shallow clones an array returning a typecast result and handling
-     * {@code null}.</p>
-     *
-     * <p>The objects in the array are not cloned, thus there is no special
-     * handling for multi-dimensional arrays.</p>
-     *
-     * <p>This method returns {@code null} for a {@code null} input array.</p>
-     *
-     * @param <T> the component type of the array
-     * @param array  the array to shallow clone, may be {@code null}
-     * @return the cloned array, {@code null} if {@code null} input
-     */
-    public static <T> T[] clone(T[] array) {
-        if (array == null) {
-            return null;
-        }
-        return array.clone();
-    }
-
-    /**
-     * <p>Clones an array returning a typecast result and handling
-     * {@code null}.</p>
-     *
-     * <p>This method returns {@code null} for a {@code null} input array.</p>
-     *
-     * @param array  the array to clone, may be {@code null}
-     * @return the cloned array, {@code null} if {@code null} input
-     */
-    public static long[] clone(long[] array) {
-        if (array == null) {
-            return null;
-        }
-        return array.clone();
-    }
-
-    /**
-     * <p>Clones an array returning a typecast result and handling
-     * {@code null}.</p>
-     *
-     * <p>This method returns {@code null} for a {@code null} input array.</p>
-     *
-     * @param array  the array to clone, may be {@code null}
-     * @return the cloned array, {@code null} if {@code null} input
-     */
-    public static int[] clone(int[] array) {
-        if (array == null) {
-            return null;
-        }
-        return array.clone();
-    }
-
-    /**
-     * <p>Clones an array returning a typecast result and handling
-     * {@code null}.</p>
-     *
-     * <p>This method returns {@code null} for a {@code null} input array.</p>
-     *
-     * @param array  the array to clone, may be {@code null}
-     * @return the cloned array, {@code null} if {@code null} input
-     */
-    public static short[] clone(short[] array) {
-        if (array == null) {
-            return null;
-        }
-        return array.clone();
-    }
-
-    /**
-     * <p>Clones an array returning a typecast result and handling
-     * {@code null}.</p>
-     *
-     * <p>This method returns {@code null} for a {@code null} input array.</p>
-     *
-     * @param array  the array to clone, may be {@code null}
-     * @return the cloned array, {@code null} if {@code null} input
-     */
-    public static char[] clone(char[] array) {
-        if (array == null) {
-            return null;
-        }
-        return array.clone();
-    }
-
-    /**
-     * <p>Clones an array returning a typecast result and handling
-     * {@code null}.</p>
-     *
-     * <p>This method returns {@code null} for a {@code null} input array.</p>
-     *
-     * @param array  the array to clone, may be {@code null}
-     * @return the cloned array, {@code null} if {@code null} input
-     */
-    public static byte[] clone(byte[] array) {
-        if (array == null) {
-            return null;
-        }
-        return array.clone();
-    }
-
-    /**
-     * <p>Clones an array returning a typecast result and handling
-     * {@code null}.</p>
-     *
-     * <p>This method returns {@code null} for a {@code null} input array.</p>
-     *
-     * @param array  the array to clone, may be {@code null}
-     * @return the cloned array, {@code null} if {@code null} input
-     */
-    public static double[] clone(double[] array) {
-        if (array == null) {
-            return null;
-        }
-        return array.clone();
-    }
-
-    /**
-     * <p>Clones an array returning a typecast result and handling
-     * {@code null}.</p>
-     *
-     * <p>This method returns {@code null} for a {@code null} input array.</p>
-     *
-     * @param array  the array to clone, may be {@code null}
-     * @return the cloned array, {@code null} if {@code null} input
-     */
-    public static float[] clone(float[] array) {
-        if (array == null) {
-            return null;
-        }
-        return array.clone();
-    }
-
-    /**
-     * <p>Clones an array returning a typecast result and handling
-     * {@code null}.</p>
-     *
-     * <p>This method returns {@code null} for a {@code null} input array.</p>
-     *
-     * @param array  the array to clone, may be {@code null}
-     * @return the cloned array, {@code null} if {@code null} input
-     */
-    public static boolean[] clone(boolean[] array) {
-        if (array == null) {
-            return null;
-        }
-        return array.clone();
-    }
-
-    // nullToEmpty
-    //-----------------------------------------------------------------------
-    /**
-     * <p>Defensive programming technique to change a {@code null}
-     * reference to an empty one.</p>
-     *
-     * <p>This method returns an empty array for a {@code null} input array.</p>
-     *
-     * <p>As a memory optimizing technique an empty array passed in will be overridden with
-     * the empty {@code public static} references in this class.</p>
-     *
-     * @param array  the array to check for {@code null} or empty
-     * @return the same array, {@code public static} empty array if {@code null} or empty input
-     * @since 2.5
-     */
-    public static Object[] nullToEmpty(Object[] array) {
-        if (array == null || array.length == 0) {
-            return EMPTY_OBJECT_ARRAY;
-        }
-        return array;
-    }
-
-    /**
-     * <p>Defensive programming technique to change a {@code null}
-     * reference to an empty one.</p>
-     *
-     * <p>This method returns an empty array for a {@code null} input array.</p>
-     *
-     * <p>As a memory optimizing technique an empty array passed in will be overridden with
-     * the empty {@code public static} references in this class.</p>
-     *
-     * @param array  the array to check for {@code null} or empty
-     * @return the same array, {@code public static} empty array if {@code null} or empty input
-     * @since 2.5
-     */
-    public static String[] nullToEmpty(String[] array) {
-        if (array == null || array.length == 0) {
-            return EMPTY_STRING_ARRAY;
-        }
-        return array;
-    }
-
-    /**
-     * <p>Defensive programming technique to change a {@code null}
-     * reference to an empty one.</p>
-     *
-     * <p>This method returns an empty array for a {@code null} input array.</p>
-     *
-     * <p>As a memory optimizing technique an empty array passed in will be overridden with
-     * the empty {@code public static} references in this class.</p>
-     *
-     * @param array  the array to check for {@code null} or empty
-     * @return the same array, {@code public static} empty array if {@code null} or empty input
-     * @since 2.5
-     */
-    public static long[] nullToEmpty(long[] array) {
-        if (array == null || array.length == 0) {
-            return EMPTY_LONG_ARRAY;
-        }
-        return array;
-    }
-
-    /**
-     * <p>Defensive programming technique to change a {@code null}
-     * reference to an empty one.</p>
-     *
-     * <p>This method returns an empty array for a {@code null} input array.</p>
-     *
-     * <p>As a memory optimizing technique an empty array passed in will be overridden with
-     * the empty {@code public static} references in this class.</p>
-     *
-     * @param array  the array to check for {@code null} or empty
-     * @return the same array, {@code public static} empty array if {@code null} or empty input
-     * @since 2.5
-     */
-    public static int[] nullToEmpty(int[] array) {
-        if (array == null || array.length == 0) {
-            return EMPTY_INT_ARRAY;
-        }
-        return array;
-    }
-
-    /**
-     * <p>Defensive programming technique to change a {@code null}
-     * reference to an empty one.</p>
-     *
-     * <p>This method returns an empty array for a {@code null} input array.</p>
-     *
-     * <p>As a memory optimizing technique an empty array passed in will be overridden with
-     * the empty {@code public static} references in this class.</p>
-     *
-     * @param array  the array to check for {@code null} or empty
-     * @return the same array, {@code public static} empty array if {@code null} or empty input
-     * @since 2.5
-     */
-    public static short[] nullToEmpty(short[] array) {
-        if (array == null || array.length == 0) {
-            return EMPTY_SHORT_ARRAY;
-        }
-        return array;
-    }
-
-    /**
-     * <p>Defensive programming technique to change a {@code null}
-     * reference to an empty one.</p>
-     *
-     * <p>This method returns an empty array for a {@code null} input array.</p>
-     *
-     * <p>As a memory optimizing technique an empty array passed in will be overridden with
-     * the empty {@code public static} references in this class.</p>
-     *
-     * @param array  the array to check for {@code null} or empty
-     * @return the same array, {@code public static} empty array if {@code null} or empty input
-     * @since 2.5
-     */
-    public static char[] nullToEmpty(char[] array) {
-        if (array == null || array.length == 0) {
-            return EMPTY_CHAR_ARRAY;
-        }
-        return array;
-    }
-
-    /**
-     * <p>Defensive programming technique to change a {@code null}
-     * reference to an empty one.</p>
-     *
-     * <p>This method returns an empty array for a {@code null} input array.</p>
-     *
-     * <p>As a memory optimizing technique an empty array passed in will be overridden with
-     * the empty {@code public static} references in this class.</p>
-     *
-     * @param array  the array to check for {@code null} or empty
-     * @return the same array, {@code public static} empty array if {@code null} or empty input
-     * @since 2.5
-     */
-    public static byte[] nullToEmpty(byte[] array) {
-        if (array == null || array.length == 0) {
-            return EMPTY_BYTE_ARRAY;
-        }
-        return array;
-    }
-
-    /**
-     * <p>Defensive programming technique to change a {@code null}
-     * reference to an empty one.</p>
-     *
-     * <p>This method returns an empty array for a {@code null} input array.</p>
-     *
-     * <p>As a memory optimizing technique an empty array passed in will be overridden with
-     * the empty {@code public static} references in this class.</p>
-     *
-     * @param array  the array to check for {@code null} or empty
-     * @return the same array, {@code public static} empty array if {@code null} or empty input
-     * @since 2.5
-     */
-    public static double[] nullToEmpty(double[] array) {
-        if (array == null || array.length == 0) {
-            return EMPTY_DOUBLE_ARRAY;
-        }
-        return array;
-    }
-
-    /**
-     * <p>Defensive programming technique to change a {@code null}
-     * reference to an empty one.</p>
-     *
-     * <p>This method returns an empty array for a {@code null} input array.</p>
-     *
-     * <p>As a memory optimizing technique an empty array passed in will be overridden with
-     * the empty {@code public static} references in this class.</p>
-     *
-     * @param array  the array to check for {@code null} or empty
-     * @return the same array, {@code public static} empty array if {@code null} or empty input
-     * @since 2.5
-     */
-    public static float[] nullToEmpty(float[] array) {
-        if (array == null || array.length == 0) {
-            return EMPTY_FLOAT_ARRAY;
-        }
-        return array;
-    }
-
-    /**
-     * <p>Defensive programming technique to change a {@code null}
-     * reference to an empty one.</p>
-     *
-     * <p>This method returns an empty array for a {@code null} input array.</p>
-     *
-     * <p>As a memory optimizing technique an empty array passed in will be overridden with
-     * the empty {@code public static} references in this class.</p>
-     *
-     * @param array  the array to check for {@code null} or empty
-     * @return the same array, {@code public static} empty array if {@code null} or empty input
-     * @since 2.5
-     */
-    public static boolean[] nullToEmpty(boolean[] array) {
-        if (array == null || array.length == 0) {
-            return EMPTY_BOOLEAN_ARRAY;
-        }
-        return array;
-    }
-
-    /**
-     * <p>Defensive programming technique to change a {@code null}
-     * reference to an empty one.</p>
-     *
-     * <p>This method returns an empty array for a {@code null} input array.</p>
-     *
-     * <p>As a memory optimizing technique an empty array passed in will be overridden with
-     * the empty {@code public static} references in this class.</p>
-     *
-     * @param array  the array to check for {@code null} or empty
-     * @return the same array, {@code public static} empty array if {@code null} or empty input
-     * @since 2.5
-     */
-    public static Long[] nullToEmpty(Long[] array) {
-        if (array == null || array.length == 0) {
-            return EMPTY_LONG_OBJECT_ARRAY;
-        }
-        return array;
-    }
-
-    /**
-     * <p>Defensive programming technique to change a {@code null}
-     * reference to an empty one.</p>
-     *
-     * <p>This method returns an empty array for a {@code null} input array.</p>
-     *
-     * <p>As a memory optimizing technique an empty array passed in will be overridden with
-     * the empty {@code public static} references in this class.</p>
-     *
-     * @param array  the array to check for {@code null} or empty
-     * @return the same array, {@code public static} empty array if {@code null} or empty input
-     * @since 2.5
-     */
-    public static Integer[] nullToEmpty(Integer[] array) {
-        if (array == null || array.length == 0) {
-            return EMPTY_INTEGER_OBJECT_ARRAY;
-        }
-        return array;
-    }
-
-    /**
-     * <p>Defensive programming technique to change a {@code null}
-     * reference to an empty one.</p>
-     *
-     * <p>This method returns an empty array for a {@code null} input array.</p>
-     *
-     * <p>As a memory optimizing technique an empty array passed in will be overridden with
-     * the empty {@code public static} references in this class.</p>
-     *
-     * @param array  the array to check for {@code null} or empty
-     * @return the same array, {@code public static} empty array if {@code null} or empty input
-     * @since 2.5
-     */
-    public static Short[] nullToEmpty(Short[] array) {
-        if (array == null || array.length == 0) {
-            return EMPTY_SHORT_OBJECT_ARRAY;
-        }
-        return array;
-    }
-
-    /**
-     * <p>Defensive programming technique to change a {@code null}
-     * reference to an empty one.</p>
-     *
-     * <p>This method returns an empty array for a {@code null} input array.</p>
-     *
-     * <p>As a memory optimizing technique an empty array passed in will be overridden with
-     * the empty {@code public static} references in this class.</p>
-     *
-     * @param array  the array to check for {@code null} or empty
-     * @return the same array, {@code public static} empty array if {@code null} or empty input
-     * @since 2.5
-     */
-    public static Character[] nullToEmpty(Character[] array) {
-        if (array == null || array.length == 0) {
-            return EMPTY_CHARACTER_OBJECT_ARRAY;
-        }
-        return array;
-    }
-
-    /**
-     * <p>Defensive programming technique to change a {@code null}
-     * reference to an empty one.</p>
-     *
-     * <p>This method returns an empty array for a {@code null} input array.</p>
-     *
-     * <p>As a memory optimizing technique an empty array passed in will be overridden with
-     * the empty {@code public static} references in this class.</p>
-     *
-     * @param array  the array to check for {@code null} or empty
-     * @return the same array, {@code public static} empty array if {@code null} or empty input
-     * @since 2.5
-     */
-    public static Byte[] nullToEmpty(Byte[] array) {
-        if (array == null || array.length == 0) {
-            return EMPTY_BYTE_OBJECT_ARRAY;
-        }
-        return array;
-    }
-
-    /**
-     * <p>Defensive programming technique to change a {@code null}
-     * reference to an empty one.</p>
-     *
-     * <p>This method returns an empty array for a {@code null} input array.</p>
-     *
-     * <p>As a memory optimizing technique an empty array passed in will be overridden with
-     * the empty {@code public static} references in this class.</p>
-     *
-     * @param array  the array to check for {@code null} or empty
-     * @return the same array, {@code public static} empty array if {@code null} or empty input
-     * @since 2.5
-     */
-    public static Double[] nullToEmpty(Double[] array) {
-        if (array == null || array.length == 0) {
-            return EMPTY_DOUBLE_OBJECT_ARRAY;
-        }
-        return array;
-    }
-
-    /**
-     * <p>Defensive programming technique to change a {@code null}
-     * reference to an empty one.</p>
-     *
-     * <p>This method returns an empty array for a {@code null} input array.</p>
-     *
-     * <p>As a memory optimizing technique an empty array passed in will be overridden with
-     * the empty {@code public static} references in this class.</p>
-     *
-     * @param array  the array to check for {@code null} or empty
-     * @return the same array, {@code public static} empty array if {@code null} or empty input
-     * @since 2.5
-     */
-    public static Float[] nullToEmpty(Float[] array) {
-        if (array == null || array.length == 0) {
-            return EMPTY_FLOAT_OBJECT_ARRAY;
-        }
-        return array;
-    }
-
-    /**
-     * <p>Defensive programming technique to change a {@code null}
-     * reference to an empty one.</p>
-     *
-     * <p>This method returns an empty array for a {@code null} input array.</p>
-     *
-     * <p>As a memory optimizing technique an empty array passed in will be overridden with
-     * the empty {@code public static} references in this class.</p>
-     *
-     * @param array  the array to check for {@code null} or empty
-     * @return the same array, {@code public static} empty array if {@code null} or empty input
-     * @since 2.5
-     */
-    public static Boolean[] nullToEmpty(Boolean[] array) {
-        if (array == null || array.length == 0) {
-            return EMPTY_BOOLEAN_OBJECT_ARRAY;
-        }
-        return array;
-    }
-
-    // Subarrays
-    //-----------------------------------------------------------------------
-    /**
-     * <p>Produces a new array containing the elements between
-     * the start and end indices.</p>
-     *
-     * <p>The start index is inclusive, the end index exclusive.
-     * Null array input produces null output.</p>
-     *
-     * <p>The component type of the subarray is always the same as
-     * that of the input array. Thus, if the input is an array of type
-     * {@code Date}, the following usage is envisaged:</p>
-     *
-     * <pre>
-     * Date[] someDates = (Date[])ArrayUtils.subarray(allDates, 2, 5);
-     * </pre>
-     *
-     * @param <T> the component type of the array
-     * @param array  the array
-     * @param startIndexInclusive  the starting index. Undervalue (&lt;0)
-     *      is promoted to 0, overvalue (&gt;array.length) results
-     *      in an empty array.
-     * @param endIndexExclusive  elements up to endIndex-1 are present in the
-     *      returned subarray. Undervalue (&lt; startIndex) produces
-     *      empty array, overvalue (&gt;array.length) is demoted to
-     *      array length.
-     * @return a new array containing the elements between
-     *      the start and end indices.
-     * @since 2.1
-     */
-    public static <T> T[] subarray(T[] array, int startIndexInclusive, int endIndexExclusive) {
-        if (array == null) {
-            return null;
-        }
-        if (startIndexInclusive < 0) {
-            startIndexInclusive = 0;
-        }
-        if (endIndexExclusive > array.length) {
-            endIndexExclusive = array.length;
-        }
-        int newSize = endIndexExclusive - startIndexInclusive;
-        Class<?> type = array.getClass().getComponentType();
-        if (newSize <= 0) {
-            @SuppressWarnings("unchecked") // OK, because array is of type T
-            final T[] emptyArray = (T[]) Array.newInstance(type, 0);
-            return emptyArray;
-        }
-        @SuppressWarnings("unchecked") // OK, because array is of type T
-        T[] subarray = (T[]) Array.newInstance(type, newSize);
-        System.arraycopy(array, startIndexInclusive, subarray, 0, newSize);
-        return subarray;
-    }
-
-    /**
-     * <p>Produces a new {@code long} array containing the elements
-     * between the start and end indices.</p>
-     *
-     * <p>The start index is inclusive, the end index exclusive.
-     * Null array input produces null output.</p>
-     *
-     * @param array  the array
-     * @param startIndexInclusive  the starting index. Undervalue (&lt;0)
-     *      is promoted to 0, overvalue (&gt;array.length) results
-     *      in an empty array.
-     * @param endIndexExclusive  elements up to endIndex-1 are present in the
-     *      returned subarray. Undervalue (&lt; startIndex) produces
-     *      empty array, overvalue (&gt;array.length) is demoted to
-     *      array length.
-     * @return a new array containing the elements between
-     *      the start and end indices.
-     * @since 2.1
-     */
-    public static long[] subarray(long[] array, int startIndexInclusive, int endIndexExclusive) {
-        if (array == null) {
-            return null;
-        }
-        if (startIndexInclusive < 0) {
-            startIndexInclusive = 0;
-        }
-        if (endIndexExclusive > array.length) {
-            endIndexExclusive = array.length;
-        }
-        int newSize = endIndexExclusive - startIndexInclusive;
-        if (newSize <= 0) {
-            return EMPTY_LONG_ARRAY;
-        }
-
-        long[] subarray = new long[newSize];
-        System.arraycopy(array, startIndexInclusive, subarray, 0, newSize);
-        return subarray;
-    }
-
-    /**
-     * <p>Produces a new {@code int} array containing the elements
-     * between the start and end indices.</p>
-     *
-     * <p>The start index is inclusive, the end index exclusive.
-     * Null array input produces null output.</p>
-     *
-     * @param array  the array
-     * @param startIndexInclusive  the starting index. Undervalue (&lt;0)
-     *      is promoted to 0, overvalue (&gt;array.length) results
-     *      in an empty array.
-     * @param endIndexExclusive  elements up to endIndex-1 are present in the
-     *      returned subarray. Undervalue (&lt; startIndex) produces
-     *      empty array, overvalue (&gt;array.length) is demoted to
-     *      array length.
-     * @return a new array containing the elements between
-     *      the start and end indices.
-     * @since 2.1
-     */
-    public static int[] subarray(int[] array, int startIndexInclusive, int endIndexExclusive) {
-        if (array == null) {
-            return null;
-        }
-        if (startIndexInclusive < 0) {
-            startIndexInclusive = 0;
-        }
-        if (endIndexExclusive > array.length) {
-            endIndexExclusive = array.length;
-        }
-        int newSize = endIndexExclusive - startIndexInclusive;
-        if (newSize <= 0) {
-            return EMPTY_INT_ARRAY;
-        }
-
-        int[] subarray = new int[newSize];
-        System.arraycopy(array, startIndexInclusive, subarray, 0, newSize);
-        return subarray;
-    }
-
-    /**
-     * <p>Produces a new {@code short} array containing the elements
-     * between the start and end indices.</p>
-     *
-     * <p>The start index is inclusive, the end index exclusive.
-     * Null array input produces null output.</p>
-     *
-     * @param array  the array
-     * @param startIndexInclusive  the starting index. Undervalue (&lt;0)
-     *      is promoted to 0, overvalue (&gt;array.length) results
-     *      in an empty array.
-     * @param endIndexExclusive  elements up to endIndex-1 are present in the
-     *      returned subarray. Undervalue (&lt; startIndex) produces
-     *      empty array, overvalue (&gt;array.length) is demoted to
-     *      array length.
-     * @return a new array containing the elements between
-     *      the start and end indices.
-     * @since 2.1
-     */
-    public static short[] subarray(short[] array, int startIndexInclusive, int endIndexExclusive) {
-        if (array == null) {
-            return null;
-        }
-        if (startIndexInclusive < 0) {
-            startIndexInclusive = 0;
-        }
-        if (endIndexExclusive > array.length) {
-            endIndexExclusive = array.length;
-        }
-        int newSize = endIndexExclusive - startIndexInclusive;
-        if (newSize <= 0) {
-            return EMPTY_SHORT_ARRAY;
-        }
-
-        short[] subarray = new short[newSize];
-        System.arraycopy(array, startIndexInclusive, subarray, 0, newSize);
-        return subarray;
-    }
-
-    /**
-     * <p>Produces a new {@code char} array containing the elements
-     * between the start and end indices.</p>
-     *
-     * <p>The start index is inclusive, the end index exclusive.
-     * Null array input produces null output.</p>
-     *
-     * @param array  the array
-     * @param startIndexInclusive  the starting index. Undervalue (&lt;0)
-     *      is promoted to 0, overvalue (&gt;array.length) results
-     *      in an empty array.
-     * @param endIndexExclusive  elements up to endIndex-1 are present in the
-     *      returned subarray. Undervalue (&lt; startIndex) produces
-     *      empty array, overvalue (&gt;array.length) is demoted to
-     *      array length.
-     * @return a new array containing the elements between
-     *      the start and end indices.
-     * @since 2.1
-     */
-    public static char[] subarray(char[] array, int startIndexInclusive, int endIndexExclusive) {
-        if (array == null) {
-            return null;
-        }
-        if (startIndexInclusive < 0) {
-            startIndexInclusive = 0;
-        }
-        if (endIndexExclusive > array.length) {
-            endIndexExclusive = array.length;
-        }
-        int newSize = endIndexExclusive - startIndexInclusive;
-        if (newSize <= 0) {
-            return EMPTY_CHAR_ARRAY;
-        }
-
-        char[] subarray = new char[newSize];
-        System.arraycopy(array, startIndexInclusive, subarray, 0, newSize);
-        return subarray;
-    }
-
-    /**
-     * <p>Produces a new {@code byte} array containing the elements
-     * between the start and end indices.</p>
-     *
-     * <p>The start index is inclusive, the end index exclusive.
-     * Null array input produces null output.</p>
-     *
-     * @param array  the array
-     * @param startIndexInclusive  the starting index. Undervalue (&lt;0)
-     *      is promoted to 0, overvalue (&gt;array.length) results
-     *      in an empty array.
-     * @param endIndexExclusive  elements up to endIndex-1 are present in the
-     *      returned subarray. Undervalue (&lt; startIndex) produces
-     *      empty array, overvalue (&gt;array.length) is demoted to
-     *      array length.
-     * @return a new array containing the elements between
-     *      the start and end indices.
-     * @since 2.1
-     */
-    public static byte[] subarray(byte[] array, int startIndexInclusive, int endIndexExclusive) {
-        if (array == null) {
-            return null;
-        }
-        if (startIndexInclusive < 0) {
-            startIndexInclusive = 0;
-        }
-        if (endIndexExclusive > array.length) {
-            endIndexExclusive = array.length;
-        }
-        int newSize = endIndexExclusive - startIndexInclusive;
-        if (newSize <= 0) {
-            return EMPTY_BYTE_ARRAY;
-        }
-
-        byte[] subarray = new byte[newSize];
-        System.arraycopy(array, startIndexInclusive, subarray, 0, newSize);
-        return subarray;
-    }
-
-    /**
-     * <p>Produces a new {@code double} array containing the elements
-     * between the start and end indices.</p>
-     *
-     * <p>The start index is inclusive, the end index exclusive.
-     * Null array input produces null output.</p>
-     *
-     * @param array  the array
-     * @param startIndexInclusive  the starting index. Undervalue (&lt;0)
-     *      is promoted to 0, overvalue (&gt;array.length) results
-     *      in an empty array.
-     * @param endIndexExclusive  elements up to endIndex-1 are present in the
-     *      returned subarray. Undervalue (&lt; startIndex) produces
-     *      empty array, overvalue (&gt;array.length) is demoted to
-     *      array length.
-     * @return a new array containing the elements between
-     *      the start and end indices.
-     * @since 2.1
-     */
-    public static double[] subarray(double[] array, int startIndexInclusive, int endIndexExclusive) {
-        if (array == null) {
-            return null;
-        }
-        if (startIndexInclusive < 0) {
-            startIndexInclusive = 0;
-        }
-        if (endIndexExclusive > array.length) {
-            endIndexExclusive = array.length;
-        }
-        int newSize = endIndexExclusive - startIndexInclusive;
-        if (newSize <= 0) {
-            return EMPTY_DOUBLE_ARRAY;
-        }
-
-        double[] subarray = new double[newSize];
-        System.arraycopy(array, startIndexInclusive, subarray, 0, newSize);
-        return subarray;
-    }
-
-    /**
-     * <p>Produces a new {@code float} array containing the elements
-     * between the start and end indices.</p>
-     *
-     * <p>The start index is inclusive, the end index exclusive.
-     * Null array input produces null output.</p>
-     *
-     * @param array  the array
-     * @param startIndexInclusive  the starting index. Undervalue (&lt;0)
-     *      is promoted to 0, overvalue (&gt;array.length) results
-     *      in an empty array.
-     * @param endIndexExclusive  elements up to endIndex-1 are present in the
-     *      returned subarray. Undervalue (&lt; startIndex) produces
-     *      empty array, overvalue (&gt;array.length) is demoted to
-     *      array length.
-     * @return a new array containing the elements between
-     *      the start and end indices.
-     * @since 2.1
-     */
-    public static float[] subarray(float[] array, int startIndexInclusive, int endIndexExclusive) {
-        if (array == null) {
-            return null;
-        }
-        if (startIndexInclusive < 0) {
-            startIndexInclusive = 0;
-        }
-        if (endIndexExclusive > array.length) {
-            endIndexExclusive = array.length;
-        }
-        int newSize = endIndexExclusive - startIndexInclusive;
-        if (newSize <= 0) {
-            return EMPTY_FLOAT_ARRAY;
-        }
-
-        float[] subarray = new float[newSize];
-        System.arraycopy(array, startIndexInclusive, subarray, 0, newSize);
-        return subarray;
-    }
-
-    /**
-     * <p>Produces a new {@code boolean} array containing the elements
-     * between the start and end indices.</p>
-     *
-     * <p>The start index is inclusive, the end index exclusive.
-     * Null array input produces null output.</p>
-     *
-     * @param array  the array
-     * @param startIndexInclusive  the starting index. Undervalue (&lt;0)
-     *      is promoted to 0, overvalue (&gt;array.length) results
-     *      in an empty array.
-     * @param endIndexExclusive  elements up to endIndex-1 are present in the
-     *      returned subarray. Undervalue (&lt; startIndex) produces
-     *      empty array, overvalue (&gt;array.length) is demoted to
-     *      array length.
-     * @return a new array containing the elements between
-     *      the start and end indices.
-     * @since 2.1
-     */
-    public static boolean[] subarray(boolean[] array, int startIndexInclusive, int endIndexExclusive) {
-        if (array == null) {
-            return null;
-        }
-        if (startIndexInclusive < 0) {
-            startIndexInclusive = 0;
-        }
-        if (endIndexExclusive > array.length) {
-            endIndexExclusive = array.length;
-        }
-        int newSize = endIndexExclusive - startIndexInclusive;
-        if (newSize <= 0) {
-            return EMPTY_BOOLEAN_ARRAY;
-        }
-
-        boolean[] subarray = new boolean[newSize];
-        System.arraycopy(array, startIndexInclusive, subarray, 0, newSize);
-        return subarray;
-    }
-
-    // Is same length
-    //-----------------------------------------------------------------------
-    /**
-     * <p>Checks whether two arrays are the same length, treating
-     * {@code null} arrays as length {@code 0}.
-     *
-     * <p>Any multi-dimensional aspects of the arrays are ignored.</p>
-     *
-     * @param array1 the first array, may be {@code null}
-     * @param array2 the second array, may be {@code null}
-     * @return {@code true} if length of arrays matches, treating
-     *  {@code null} as an empty array
-     */
-    public static boolean isSameLength(Object[] array1, Object[] array2) {
-        if ((array1 == null && array2 != null && array2.length > 0) ||
-            (array2 == null && array1 != null && array1.length > 0) ||
-            (array1 != null && array2 != null && array1.length != array2.length)) {
-                return false;
-        }
-        return true;
-    }
-
-    /**
-     * <p>Checks whether two arrays are the same length, treating
-     * {@code null} arrays as length {@code 0}.</p>
-     *
-     * @param array1 the first array, may be {@code null}
-     * @param array2 the second array, may be {@code null}
-     * @return {@code true} if length of arrays matches, treating
-     *  {@code null} as an empty array
-     */
-    public static boolean isSameLength(long[] array1, long[] array2) {
-        if ((array1 == null && array2 != null && array2.length > 0) ||
-            (array2 == null && array1 != null && array1.length > 0) ||
-            (array1 != null && array2 != null && array1.length != array2.length)) {
-                return false;
-        }
-        return true;
-    }
-
-    /**
-     * <p>Checks whether two arrays are the same length, treating
-     * {@code null} arrays as length {@code 0}.</p>
-     *
-     * @param array1 the first array, may be {@code null}
-     * @param array2 the second array, may be {@code null}
-     * @return {@code true} if length of arrays matches, treating
-     *  {@code null} as an empty array
-     */
-    public static boolean isSameLength(int[] array1, int[] array2) {
-        if ((array1 == null && array2 != null && array2.length > 0) ||
-            (array2 == null && array1 != null && array1.length > 0) ||
-            (array1 != null && array2 != null && array1.length != array2.length)) {
-                return false;
-        }
-        return true;
-    }
-
-    /**
-     * <p>Checks whether two arrays are the same length, treating
-     * {@code null} arrays as length {@code 0}.</p>
-     *
-     * @param array1 the first array, may be {@code null}
-     * @param array2 the second array, may be {@code null}
-     * @return {@code true} if length of arrays matches, treating
-     *  {@code null} as an empty array
-     */
-    public static boolean isSameLength(short[] array1, short[] array2) {
-        if ((array1 == null && array2 != null && array2.length > 0) ||
-            (array2 == null && array1 != null && array1.length > 0) ||
-            (array1 != null && array2 != null && array1.length != array2.length)) {
-                return false;
-        }
-        return true;
-    }
-
-    /**
-     * <p>Checks whether two arrays are the same length, treating
-     * {@code null} arrays as length {@code 0}.</p>
-     *
-     * @param array1 the first array, may be {@code null}
-     * @param array2 the second array, may be {@code null}
-     * @return {@code true} if length of arrays matches, treating
-     *  {@code null} as an empty array
-     */
-    public static boolean isSameLength(char[] array1, char[] array2) {
-        if ((array1 == null && array2 != null && array2.length > 0) ||
-            (array2 == null && array1 != null && array1.length > 0) ||
-            (array1 != null && array2 != null && array1.length != array2.length)) {
-                return false;
-        }
-        return true;
-    }
-
-    /**
-     * <p>Checks whether two arrays are the same length, treating
-     * {@code null} arrays as length {@code 0}.</p>
-     *
-     * @param array1 the first array, may be {@code null}
-     * @param array2 the second array, may be {@code null}
-     * @return {@code true} if length of arrays matches, treating
-     *  {@code null} as an empty array
-     */
-    public static boolean isSameLength(byte[] array1, byte[] array2) {
-        if ((array1 == null && array2 != null && array2.length > 0) ||
-            (array2 == null && array1 != null && array1.length > 0) ||
-            (array1 != null && array2 != null && array1.length != array2.length)) {
-                return false;
-        }
-        return true;
-    }
-
-    /**
-     * <p>Checks whether two arrays are the same length, treating
-     * {@code null} arrays as length {@code 0}.</p>
-     *
-     * @param array1 the first array, may be {@code null}
-     * @param array2 the second array, may be {@code null}
-     * @return {@code true} if length of arrays matches, treating
-     *  {@code null} as an empty array
-     */
-    public static boolean isSameLength(double[] array1, double[] array2) {
-        if ((array1 == null && array2 != null && array2.length > 0) ||
-            (array2 == null && array1 != null && array1.length > 0) ||
-            (array1 != null && array2 != null && array1.length != array2.length)) {
-                return false;
-        }
-        return true;
-    }
-
-    /**
-     * <p>Checks whether two arrays are the same length, treating
-     * {@code null} arrays as length {@code 0}.</p>
-     *
-     * @param array1 the first array, may be {@code null}
-     * @param array2 the second array, may be {@code null}
-     * @return {@code true} if length of arrays matches, treating
-     *  {@code null} as an empty array
-     */
-    public static boolean isSameLength(float[] array1, float[] array2) {
-        if ((array1 == null && array2 != null && array2.length > 0) ||
-            (array2 == null && array1 != null && array1.length > 0) ||
-            (array1 != null && array2 != null && array1.length != array2.length)) {
-                return false;
-        }
-        return true;
-    }
-
-    /**
-     * <p>Checks whether two arrays are the same length, treating
-     * {@code null} arrays as length {@code 0}.</p>
-     *
-     * @param array1 the first array, may be {@code null}
-     * @param array2 the second array, may be {@code null}
-     * @return {@code true} if length of arrays matches, treating
-     *  {@code null} as an empty array
-     */
-    public static boolean isSameLength(boolean[] array1, boolean[] array2) {
-        if ((array1 == null && array2 != null && array2.length > 0) ||
-            (array2 == null && array1 != null && array1.length > 0) ||
-            (array1 != null && array2 != null && array1.length != array2.length)) {
-                return false;
-        }
-        return true;
-    }
-
-    //-----------------------------------------------------------------------
-    /**
-     * <p>Returns the length of the specified array.
-     * This method can deal with {@code Object} arrays and with primitive arrays.</p>
-     *
-     * <p>If the input array is {@code null}, {@code 0} is returned.</p>
-     *
-     * <pre>
-     * ArrayUtils.getLength(null)            = 0
-     * ArrayUtils.getLength([])              = 0
-     * ArrayUtils.getLength([null])          = 1
-     * ArrayUtils.getLength([true, false])   = 2
-     * ArrayUtils.getLength([1, 2, 3])       = 3
-     * ArrayUtils.getLength(["a", "b", "c"]) = 3
-     * </pre>
-     *
-     * @param array  the array to retrieve the length from, may be null
-     * @return The length of the array, or {@code 0} if the array is {@code null}
-     * @throws IllegalArgumentException if the object arguement is not an array.
-     * @since 2.1
-     */
-    public static int getLength(Object array) {
-        if (array == null) {
-            return 0;
-        }
-        return Array.getLength(array);
-    }
-
-    /**
-     * <p>Checks whether two arrays are the same type taking into account
-     * multi-dimensional arrays.</p>
-     *
-     * @param array1 the first array, must not be {@code null}
-     * @param array2 the second array, must not be {@code null}
-     * @return {@code true} if type of arrays matches
-     * @throws IllegalArgumentException if either array is {@code null}
-     */
-    public static boolean isSameType(Object array1, Object array2) {
-        if (array1 == null || array2 == null) {
-            throw new IllegalArgumentException("The Array must not be null");
-        }
-        return array1.getClass().getName().equals(array2.getClass().getName());
-    }
-
-    // Reverse
-    //-----------------------------------------------------------------------
-    /**
-     * <p>Reverses the order of the given array.</p>
-     *
-     * <p>There is no special handling for multi-dimensional arrays.</p>
-     *
-     * <p>This method does nothing for a {@code null} input array.</p>
-     *
-     * @param array  the array to reverse, may be {@code null}
-     */
-    public static void reverse(Object[] array) {
-        if (array == null) {
-            return;
-        }
-        int i = 0;
-        int j = array.length - 1;
-        Object tmp;
-        while (j > i) {
-            tmp = array[j];
-            array[j] = array[i];
-            array[i] = tmp;
-            j--;
-            i++;
-        }
-    }
-
-    /**
-     * <p>Reverses the order of the given array.</p>
-     *
-     * <p>This method does nothing for a {@code null} input array.</p>
-     *
-     * @param array  the array to reverse, may be {@code null}
-     */
-    public static void reverse(long[] array) {
-        if (array == null) {
-            return;
-        }
-        int i = 0;
-        int j = array.length - 1;
-        long tmp;
-        while (j > i) {
-            tmp = array[j];
-            array[j] = array[i];
-            array[i] = tmp;
-            j--;
-            i++;
-        }
-    }
-
-    /**
-     * <p>Reverses the order of the given array.</p>
-     *
-     * <p>This method does nothing for a {@code null} input array.</p>
-     *
-     * @param array  the array to reverse, may be {@code null}
-     */
-    public static void reverse(int[] array) {
-        if (array == null) {
-            return;
-        }
-        int i = 0;
-        int j = array.length - 1;
-        int tmp;
-        while (j > i) {
-            tmp = array[j];
-            array[j] = array[i];
-            array[i] = tmp;
-            j--;
-            i++;
-        }
-    }
-
-    /**
-     * <p>Reverses the order of the given array.</p>
-     *
-     * <p>This method does nothing for a {@code null} input array.</p>
-     *
-     * @param array  the array to reverse, may be {@code null}
-     */
-    public static void reverse(short[] array) {
-        if (array == null) {
-            return;
-        }
-        int i = 0;
-        int j = array.length - 1;
-        short tmp;
-        while (j > i) {
-            tmp = array[j];
-            array[j] = array[i];
-            array[i] = tmp;
-            j--;
-            i++;
-        }
-    }
-
-    /**
-     * <p>Reverses the order of the given array.</p>
-     *
-     * <p>This method does nothing for a {@code null} input array.</p>
-     *
-     * @param array  the array to reverse, may be {@code null}
-     */
-    public static void reverse(char[] array) {
-        if (array == null) {
-            return;
-        }
-        int i = 0;
-        int j = array.length - 1;
-        char tmp;
-        while (j > i) {
-            tmp = array[j];
-            array[j] = array[i];
-            array[i] = tmp;
-            j--;
-            i++;
-        }
-    }
-
-    /**
-     * <p>Reverses the order of the given array.</p>
-     *
-     * <p>This method does nothing for a {@code null} input array.</p>
-     *
-     * @param array  the array to reverse, may be {@code null}
-     */
-    public static void reverse(byte[] array) {
-        if (array == null) {
-            return;
-        }
-        int i = 0;
-        int j = array.length - 1;
-        byte tmp;
-        while (j > i) {
-            tmp = array[j];
-            array[j] = array[i];
-            array[i] = tmp;
-            j--;
-            i++;
-        }
-    }
-
-    /**
-     * <p>Reverses the order of the given array.</p>
-     *
-     * <p>This method does nothing for a {@code null} input array.</p>
-     *
-     * @param array  the array to reverse, may be {@code null}
-     */
-    public static void reverse(double[] array) {
-        if (array == null) {
-            return;
-        }
-        int i = 0;
-        int j = array.length - 1;
-        double tmp;
-        while (j > i) {
-            tmp = array[j];
-            array[j] = array[i];
-            array[i] = tmp;
-            j--;
-            i++;
-        }
-    }
-
-    /**
-     * <p>Reverses the order of the given array.</p>
-     *
-     * <p>This method does nothing for a {@code null} input array.</p>
-     *
-     * @param array  the array to reverse, may be {@code null}
-     */
-    public static void reverse(float[] array) {
-        if (array == null) {
-            return;
-        }
-        int i = 0;
-        int j = array.length - 1;
-        float tmp;
-        while (j > i) {
-            tmp = array[j];
-            array[j] = array[i];
-            array[i] = tmp;
-            j--;
-            i++;
-        }
-    }
-
-    /**
-     * <p>Reverses the order of the given array.</p>
-     *
-     * <p>This method does nothing for a {@code null} input array.</p>
-     *
-     * @param array  the array to reverse, may be {@code null}
-     */
-    public static void reverse(boolean[] array) {
-        if (array == null) {
-            return;
-        }
-        int i = 0;
-        int j = array.length - 1;
-        boolean tmp;
-        while (j > i) {
-            tmp = array[j];
-            array[j] = array[i];
-            array[i] = tmp;
-            j--;
-            i++;
-        }
-    }
-
-    // IndexOf search
-    // ----------------------------------------------------------------------
-
-    // Object IndexOf
-    //-----------------------------------------------------------------------
-    /**
-     * <p>Finds the index of the given object in the array.</p>
-     *
-     * <p>This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.</p>
-     *
-     * @param array  the array to search through for the object, may be {@code null}
-     * @param objectToFind  the object to find, may be {@code null}
-     * @return the index of the object within the array,
-     *  {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
-     */
-    public static int indexOf(Object[] array, Object objectToFind) {
-        return indexOf(array, objectToFind, 0);
-    }
-
-    /**
-     * <p>Finds the index of the given object in the array starting at the given index.</p>
-     *
-     * <p>This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.</p>
-     *
-     * <p>A negative startIndex is treated as zero. A startIndex larger than the array
-     * length will return {@link #INDEX_NOT_FOUND} ({@code -1}).</p>
-     *
-     * @param array  the array to search through for the object, may be {@code null}
-     * @param objectToFind  the object to find, may be {@code null}
-     * @param startIndex  the index to start searching at
-     * @return the index of the object within the array starting at the index,
-     *  {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
-     */
-    public static int indexOf(Object[] array, Object objectToFind, int startIndex) {
-        if (array == null) {
-            return INDEX_NOT_FOUND;
-        }
-        if (startIndex < 0) {
-            startIndex = 0;
-        }
-        if (objectToFind == null) {
-            for (int i = startIndex; i < array.length; i++) {
-                if (array[i] == null) {
-                    return i;
-                }
-            }
-        } else if (array.getClass().getComponentType().isInstance(objectToFind)) {
-            for (int i = startIndex; i < array.length; i++) {
-                if (objectToFind.equals(array[i])) {
-                    return i;
-                }
-            }
-        }
-        return INDEX_NOT_FOUND;
-    }
-
-    /**
-     * <p>Finds the last index of the given object within the array.</p>
-     *
-     * <p>This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.</p>
-     *
-     * @param array  the array to travers backwords looking for the object, may be {@code null}
-     * @param objectToFind  the object to find, may be {@code null}
-     * @return the last index of the object within the array,
-     *  {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
-     */
-    public static int lastIndexOf(Object[] array, Object objectToFind) {
-        return lastIndexOf(array, objectToFind, Integer.MAX_VALUE);
-    }
-
-    /**
-     * <p>Finds the last index of the given object in the array starting at the given index.</p>
-     *
-     * <p>This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.</p>
-     *
-     * <p>A negative startIndex will return {@link #INDEX_NOT_FOUND} ({@code -1}). A startIndex larger than
-     * the array length will search from the end of the array.</p>
-     *
-     * @param array  the array to traverse for looking for the object, may be {@code null}
-     * @param objectToFind  the object to find, may be {@code null}
-     * @param startIndex  the start index to travers backwards from
-     * @return the last index of the object within the array,
-     *  {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
-     */
-    public static int lastIndexOf(Object[] array, Object objectToFind, int startIndex) {
-        if (array == null) {
-            return INDEX_NOT_FOUND;
-        }
-        if (startIndex < 0) {
-            return INDEX_NOT_FOUND;
-        } else if (startIndex >= array.length) {
-            startIndex = array.length - 1;
-        }
-        if (objectToFind == null) {
-            for (int i = startIndex; i >= 0; i--) {
-                if (array[i] == null) {
-                    return i;
-                }
-            }
-        } else if (array.getClass().getComponentType().isInstance(objectToFind)) {
-            for (int i = startIndex; i >= 0; i--) {
-                if (objectToFind.equals(array[i])) {
-                    return i;
-                }
-            }
-        }
-        return INDEX_NOT_FOUND;
-    }
-
-    /**
-     * <p>Checks if the object is in the given array.</p>
-     *
-     * <p>The method returns {@code false} if a {@code null} array is passed in.</p>
-     *
-     * @param array  the array to search through
-     * @param objectToFind  the object to find
-     * @return {@code true} if the array contains the object
-     */
-    public static boolean contains(Object[] array, Object objectToFind) {
-        return indexOf(array, objectToFind) != INDEX_NOT_FOUND;
-    }
-
-    // long IndexOf
-    //-----------------------------------------------------------------------
-    /**
-     * <p>Finds the index of the given value in the array.</p>
-     *
-     * <p>This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.</p>
-     *
-     * @param array  the array to search through for the object, may be {@code null}
-     * @param valueToFind  the value to find
-     * @return the index of the value within the array,
-     *  {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
-     */
-    public static int indexOf(long[] array, long valueToFind) {
-        return indexOf(array, valueToFind, 0);
-    }
-
-    /**
-     * <p>Finds the index of the given value in the array starting at the given index.</p>
-     *
-     * <p>This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.</p>
-     *
-     * <p>A negative startIndex is treated as zero. A startIndex larger than the array
-     * length will return {@link #INDEX_NOT_FOUND} ({@code -1}).</p>
-     *
-     * @param array  the array to search through for the object, may be {@code null}
-     * @param valueToFind  the value to find
-     * @param startIndex  the index to start searching at
-     * @return the index of the value within the array,
-     *  {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
-     */
-    public static int indexOf(long[] array, long valueToFind, int startIndex) {
-        if (array == null) {
-            return INDEX_NOT_FOUND;
-        }
-        if (startIndex < 0) {
-            startIndex = 0;
-        }
-        for (int i = startIndex; i < array.length; i++) {
-            if (valueToFind == array[i]) {
-                return i;
-            }
-        }
-        return INDEX_NOT_FOUND;
-    }
-
-    /**
-     * <p>Finds the last index of the given value within the array.</p>
-     *
-     * <p>This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.</p>
-     *
-     * @param array  the array to travers backwords looking for the object, may be {@code null}
-     * @param valueToFind  the object to find
-     * @return the last index of the value within the array,
-     *  {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
-     */
-    public static int lastIndexOf(long[] array, long valueToFind) {
-        return lastIndexOf(array, valueToFind, Integer.MAX_VALUE);
-    }
-
-    /**
-     * <p>Finds the last index of the given value in the array starting at the given index.</p>
-     *
-     * <p>This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.</p>
-     *
-     * <p>A negative startIndex will return {@link #INDEX_NOT_FOUND} ({@code -1}). A startIndex larger than the
-     * array length will search from the end of the array.</p>
-     *
-     * @param array  the array to traverse for looking for the object, may be {@code null}
-     * @param valueToFind  the value to find
-     * @param startIndex  the start index to travers backwards from
-     * @return the last index of the value within the array,
-     *  {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
-     */
-    public static int lastIndexOf(long[] array, long valueToFind, int startIndex) {
-        if (array == null) {
-            return INDEX_NOT_FOUND;
-        }
-        if (startIndex < 0) {
-            return INDEX_NOT_FOUND;
-        } else if (startIndex >= array.length) {
-            startIndex = array.length - 1;
-        }
-        for (int i = startIndex; i >= 0; i--) {
-            if (valueToFind == array[i]) {
-                return i;
-            }
-        }
-        return INDEX_NOT_FOUND;
-    }
-
-    /**
-     * <p>Checks if the value is in the given array.</p>
-     *
-     * <p>The method returns {@code false} if a {@code null} array is passed in.</p>
-     *
-     * @param array  the array to search through
-     * @param valueToFind  the value to find
-     * @return {@code true} if the array contains the object
-     */
-    public static boolean contains(long[] array, long valueToFind) {
-        return indexOf(array, valueToFind) != INDEX_NOT_FOUND;
-    }
-
-    // int IndexOf
-    //-----------------------------------------------------------------------
-    /**
-     * <p>Finds the index of the given value in the array.</p>
-     *
-     * <p>This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.</p>
-     *
-     * @param array  the array to search through for the object, may be {@code null}
-     * @param valueToFind  the value to find
-     * @return the index of the value within the array,
-     *  {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
-     */
-    public static int indexOf(int[] array, int valueToFind) {
-        return indexOf(array, valueToFind, 0);
-    }
-
-    /**
-     * <p>Finds the index of the given value in the array starting at the given index.</p>
-     *
-     * <p>This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.</p>
-     *
-     * <p>A negative startIndex is treated as zero. A startIndex larger than the array
-     * length will return {@link #INDEX_NOT_FOUND} ({@code -1}).</p>
-     *
-     * @param array  the array to search through for the object, may be {@code null}
-     * @param valueToFind  the value to find
-     * @param startIndex  the index to start searching at
-     * @return the index of the value within the array,
-     *  {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
-     */
-    public static int indexOf(int[] array, int valueToFind, int startIndex) {
-        if (array == null) {
-            return INDEX_NOT_FOUND;
-        }
-        if (startIndex < 0) {
-            startIndex = 0;
-        }
-        for (int i = startIndex; i < array.length; i++) {
-            if (valueToFind == array[i]) {
-                return i;
-            }
-        }
-        return INDEX_NOT_FOUND;
-    }
-
-    /**
-     * <p>Finds the last index of the given value within the array.</p>
-     *
-     * <p>This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.</p>
-     *
-     * @param array  the array to travers backwords looking for the object, may be {@code null}
-     * @param valueToFind  the object to find
-     * @return the last index of the value within the array,
-     *  {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
-     */
-    public static int lastIndexOf(int[] array, int valueToFind) {
-        return lastIndexOf(array, valueToFind, Integer.MAX_VALUE);
-    }
-
-    /**
-     * <p>Finds the last index of the given value in the array starting at the given index.</p>
-     *
-     * <p>This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.</p>
-     *
-     * <p>A negative startIndex will return {@link #INDEX_NOT_FOUND} ({@code -1}). A startIndex larger than the
-     * array length will search from the end of the array.</p>
-     *
-     * @param array  the array to traverse for looking for the object, may be {@code null}
-     * @param valueToFind  the value to find
-     * @param startIndex  the start index to travers backwards from
-     * @return the last index of the value within the array,
-     *  {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
-     */
-    public static int lastIndexOf(int[] array, int valueToFind, int startIndex) {
-        if (array == null) {
-            return INDEX_NOT_FOUND;
-        }
-        if (startIndex < 0) {
-            return INDEX_NOT_FOUND;
-        } else if (startIndex >= array.length) {
-            startIndex = array.length - 1;
-        }
-        for (int i = startIndex; i >= 0; i--) {
-            if (valueToFind == array[i]) {
-                return i;
-            }
-        }
-        return INDEX_NOT_FOUND;
-    }
-
-    /**
-     * <p>Checks if the value is in the given array.</p>
-     *
-     * <p>The method returns {@code false} if a {@code null} array is passed in.</p>
-     *
-     * @param array  the array to search through
-     * @param valueToFind  the value to find
-     * @return {@code true} if the array contains the object
-     */
-    public static boolean contains(int[] array, int valueToFind) {
-        return indexOf(array, valueToFind) != INDEX_NOT_FOUND;
-    }
-
-    // short IndexOf
-    //-----------------------------------------------------------------------
-    /**
-     * <p>Finds the index of the given value in the array.</p>
-     *
-     * <p>This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.</p>
-     *
-     * @param array  the array to search through for the object, may be {@code null}
-     * @param valueToFind  the value to find
-     * @return the index of the value within the array,
-     *  {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
-     */
-    public static int indexOf(short[] array, short valueToFind) {
-        return indexOf(array, valueToFind, 0);
-    }
-
-    /**
-     * <p>Finds the index of the given value in the array starting at the given index.</p>
-     *
-     * <p>This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.</p>
-     *
-     * <p>A negative startIndex is treated as zero. A startIndex larger than the array
-     * length will return {@link #INDEX_NOT_FOUND} ({@code -1}).</p>
-     *
-     * @param array  the array to search through for the object, may be {@code null}
-     * @param valueToFind  the value to find
-     * @param startIndex  the index to start searching at
-     * @return the index of the value within the array,
-     *  {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
-     */
-    public static int indexOf(short[] array, short valueToFind, int startIndex) {
-        if (array == null) {
-            return INDEX_NOT_FOUND;
-        }
-        if (startIndex < 0) {
-            startIndex = 0;
-        }
-        for (int i = startIndex; i < array.length; i++) {
-            if (valueToFind == array[i]) {
-                return i;
-            }
-        }
-        return INDEX_NOT_FOUND;
-    }
-
-    /**
-     * <p>Finds the last index of the given value within the array.</p>
-     *
-     * <p>This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.</p>
-     *
-     * @param array  the array to travers backwords looking for the object, may be {@code null}
-     * @param valueToFind  the object to find
-     * @return the last index of the value within the array,
-     *  {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
-     */
-    public static int lastIndexOf(short[] array, short valueToFind) {
-        return lastIndexOf(array, valueToFind, Integer.MAX_VALUE);
-    }
-
-    /**
-     * <p>Finds the last index of the given value in the array starting at the given index.</p>
-     *
-     * <p>This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.</p>
-     *
-     * <p>A negative startIndex will return {@link #INDEX_NOT_FOUND} ({@code -1}). A startIndex larger than the
-     * array length will search from the end of the array.</p>
-     *
-     * @param array  the array to traverse for looking for the object, may be {@code null}
-     * @param valueToFind  the value to find
-     * @param startIndex  the start index to travers backwards from
-     * @return the last index of the value within the array,
-     *  {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
-     */
-    public static int lastIndexOf(short[] array, short valueToFind, int startIndex) {
-        if (array == null) {
-            return INDEX_NOT_FOUND;
-        }
-        if (startIndex < 0) {
-            return INDEX_NOT_FOUND;
-        } else if (startIndex >= array.length) {
-            startIndex = array.length - 1;
-        }
-        for (int i = startIndex; i >= 0; i--) {
-            if (valueToFind == array[i]) {
-                return i;
-            }
-        }
-        return INDEX_NOT_FOUND;
-    }
-
-    /**
-     * <p>Checks if the value is in the given array.</p>
-     *
-     * <p>The method returns {@code false} if a {@code null} array is passed in.</p>
-     *
-     * @param array  the array to search through
-     * @param valueToFind  the value to find
-     * @return {@code true} if the array contains the object
-     */
-    public static boolean contains(short[] array, short valueToFind) {
-        return indexOf(array, valueToFind) != INDEX_NOT_FOUND;
-    }
-
-    // char IndexOf
-    //-----------------------------------------------------------------------
-    /**
-     * <p>Finds the index of the given value in the array.</p>
-     *
-     * <p>This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.</p>
-     *
-     * @param array  the array to search through for the object, may be {@code null}
-     * @param valueToFind  the value to find
-     * @return the index of the value within the array,
-     *  {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
-     * @since 2.1
-     */
-    public static int indexOf(char[] array, char valueToFind) {
-        return indexOf(array, valueToFind, 0);
-    }
-
-    /**
-     * <p>Finds the index of the given value in the array starting at the given index.</p>
-     *
-     * <p>This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.</p>
-     *
-     * <p>A negative startIndex is treated as zero. A startIndex larger than the array
-     * length will return {@link #INDEX_NOT_FOUND} ({@code -1}).</p>
-     *
-     * @param array  the array to search through for the object, may be {@code null}
-     * @param valueToFind  the value to find
-     * @param startIndex  the index to start searching at
-     * @return the index of the value within the array,
-     *  {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
-     * @since 2.1
-     */
-    public static int indexOf(char[] array, char valueToFind, int startIndex) {
-        if (array == null) {
-            return INDEX_NOT_FOUND;
-        }
-        if (startIndex < 0) {
-            startIndex = 0;
-        }
-        for (int i = startIndex; i < array.length; i++) {
-            if (valueToFind == array[i]) {
-                return i;
-            }
-        }
-        return INDEX_NOT_FOUND;
-    }
-
-    /**
-     * <p>Finds the last index of the given value within the array.</p>
-     *
-     * <p>This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.</p>
-     *
-     * @param array  the array to travers backwords looking for the object, may be {@code null}
-     * @param valueToFind  the object to find
-     * @return the last index of the value within the array,
-     *  {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
-     * @since 2.1
-     */
-    public static int lastIndexOf(char[] array, char valueToFind) {
-        return lastIndexOf(array, valueToFind, Integer.MAX_VALUE);
-    }
-
-    /**
-     * <p>Finds the last index of the given value in the array starting at the given index.</p>
-     *
-     * <p>This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.</p>
-     *
-     * <p>A negative startIndex will return {@link #INDEX_NOT_FOUND} ({@code -1}). A startIndex larger than the
-     * array length will search from the end of the array.</p>
-     *
-     * @param array  the array to traverse for looking for the object, may be {@code null}
-     * @param valueToFind  the value to find
-     * @param startIndex  the start index to travers backwards from
-     * @return the last index of the value within the array,
-     *  {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
-     * @since 2.1
-     */
-    public static int lastIndexOf(char[] array, char valueToFind, int startIndex) {
-        if (array == null) {
-            return INDEX_NOT_FOUND;
-        }
-        if (startIndex < 0) {
-            return INDEX_NOT_FOUND;
-        } else if (startIndex >= array.length) {
-            startIndex = array.length - 1;
-        }
-        for (int i = startIndex; i >= 0; i--) {
-            if (valueToFind == array[i]) {
-                return i;
-            }
-        }
-        return INDEX_NOT_FOUND;
-    }
-
-    /**
-     * <p>Checks if the value is in the given array.</p>
-     *
-     * <p>The method returns {@code false} if a {@code null} array is passed in.</p>
-     *
-     * @param array  the array to search through
-     * @param valueToFind  the value to find
-     * @return {@code true} if the array contains the object
-     * @since 2.1
-     */
-    public static boolean contains(char[] array, char valueToFind) {
-        return indexOf(array, valueToFind) != INDEX_NOT_FOUND;
-    }
-
-    // byte IndexOf
-    //-----------------------------------------------------------------------
-    /**
-     * <p>Finds the index of the given value in the array.</p>
-     *
-     * <p>This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.</p>
-     *
-     * @param array  the array to search through for the object, may be {@code null}
-     * @param valueToFind  the value to find
-     * @return the index of the value within the array,
-     *  {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
-     */
-    public static int indexOf(byte[] array, byte valueToFind) {
-        return indexOf(array, valueToFind, 0);
-    }
-
-    /**
-     * <p>Finds the index of the given value in the array starting at the given index.</p>
-     *
-     * <p>This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.</p>
-     *
-     * <p>A negative startIndex is treated as zero. A startIndex larger than the array
-     * length will return {@link #INDEX_NOT_FOUND} ({@code -1}).</p>
-     *
-     * @param array  the array to search through for the object, may be {@code null}
-     * @param valueToFind  the value to find
-     * @param startIndex  the index to start searching at
-     * @return the index of the value within the array,
-     *  {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
-     */
-    public static int indexOf(byte[] array, byte valueToFind, int startIndex) {
-        if (array == null) {
-            return INDEX_NOT_FOUND;
-        }
-        if (startIndex < 0) {
-            startIndex = 0;
-        }
-        for (int i = startIndex; i < array.length; i++) {
-            if (valueToFind == array[i]) {
-                return i;
-            }
-        }
-        return INDEX_NOT_FOUND;
-    }
-
-    /**
-     * <p>Finds the last index of the given value within the array.</p>
-     *
-     * <p>This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.</p>
-     *
-     * @param array  the array to travers backwords looking for the object, may be {@code null}
-     * @param valueToFind  the object to find
-     * @return the last index of the value within the array,
-     *  {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
-     */
-    public static int lastIndexOf(byte[] array, byte valueToFind) {
-        return lastIndexOf(array, valueToFind, Integer.MAX_VALUE);
-    }
-
-    /**
-     * <p>Finds the last index of the given value in the array starting at the given index.</p>
-     *
-     * <p>This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.</p>
-     *
-     * <p>A negative startIndex will return {@link #INDEX_NOT_FOUND} ({@code -1}). A startIndex larger than the
-     * array length will search from the end of the array.</p>
-     *
-     * @param array  the array to traverse for looking for the object, may be {@code null}
-     * @param valueToFind  the value to find
-     * @param startIndex  the start index to travers backwards from
-     * @return the last index of the value within the array,
-     *  {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
-     */
-    public static int lastIndexOf(byte[] array, byte valueToFind, int startIndex) {
-        if (array == null) {
-            return INDEX_NOT_FOUND;
-        }
-        if (startIndex < 0) {
-            return INDEX_NOT_FOUND;
-        } else if (startIndex >= array.length) {
-            startIndex = array.length - 1;
-        }
-        for (int i = startIndex; i >= 0; i--) {
-            if (valueToFind == array[i]) {
-                return i;
-            }
-        }
-        return INDEX_NOT_FOUND;
-    }
-
-    /**
-     * <p>Checks if the value is in the given array.</p>
-     *
-     * <p>The method returns {@code false} if a {@code null} array is passed in.</p>
-     *
-     * @param array  the array to search through
-     * @param valueToFind  the value to find
-     * @return {@code true} if the array contains the object
-     */
-    public static boolean contains(byte[] array, byte valueToFind) {
-        return indexOf(array, valueToFind) != INDEX_NOT_FOUND;
-    }
-
-    // double IndexOf
-    //-----------------------------------------------------------------------
-    /**
-     * <p>Finds the index of the given value in the array.</p>
-     *
-     * <p>This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.</p>
-     *
-     * @param array  the array to search through for the object, may be {@code null}
-     * @param valueToFind  the value to find
-     * @return the index of the value within the array,
-     *  {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
-     */
-    public static int indexOf(double[] array, double valueToFind) {
-        return indexOf(array, valueToFind, 0);
-    }
-
-    /**
-     * <p>Finds the index of the given value within a given tolerance in the array.
-     * This method will return the index of the first value which falls between the region
-     * defined by valueToFind - tolerance and valueToFind + tolerance.</p>
-     *
-     * <p>This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.</p>
-     *
-     * @param array  the array to search through for the object, may be {@code null}
-     * @param valueToFind  the value to find
-     * @param tolerance tolerance of the search
-     * @return the index of the value within the array,
-     *  {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
-     */
-    public static int indexOf(double[] array, double valueToFind, double tolerance) {
-        return indexOf(array, valueToFind, 0, tolerance);
-    }
-
-    /**
-     * <p>Finds the index of the given value in the array starting at the given index.</p>
-     *
-     * <p>This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.</p>
-     *
-     * <p>A negative startIndex is treated as zero. A startIndex larger than the array
-     * length will return {@link #INDEX_NOT_FOUND} ({@code -1}).</p>
-     *
-     * @param array  the array to search through for the object, may be {@code null}
-     * @param valueToFind  the value to find
-     * @param startIndex  the index to start searching at
-     * @return the index of the value within the array,
-     *  {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
-     */
-    public static int indexOf(double[] array, double valueToFind, int startIndex) {
-        if (ArrayUtils.isEmpty(array)) {
-            return INDEX_NOT_FOUND;
-        }
-        if (startIndex < 0) {
-            startIndex = 0;
-        }
-        for (int i = startIndex; i < array.length; i++) {
-            if (valueToFind == array[i]) {
-                return i;
-            }
-        }
-        return INDEX_NOT_FOUND;
-    }
-
-    /**
-     * <p>Finds the index of the given value in the array starting at the given index.
-     * This method will return the index of the first value which falls between the region
-     * defined by valueToFind - tolerance and valueToFind + tolerance.</p>
-     *
-     * <p>This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.</p>
-     *
-     * <p>A negative startIndex is treated as zero. A startIndex larger than the array
-     * length will return {@link #INDEX_NOT_FOUND} ({@code -1}).</p>
-     *
-     * @param array  the array to search through for the object, may be {@code null}
-     * @param valueToFind  the value to find
-     * @param startIndex  the index to start searching at
-     * @param tolerance tolerance of the search
-     * @return the index of the value within the array,
-     *  {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
-     */
-    public static int indexOf(double[] array, double valueToFind, int startIndex, double tolerance) {
-        if (ArrayUtils.isEmpty(array)) {
-            return INDEX_NOT_FOUND;
-        }
-        if (startIndex < 0) {
-            startIndex = 0;
-        }
-        double min = valueToFind - tolerance;
-        double max = valueToFind + tolerance;
-        for (int i = startIndex; i < array.length; i++) {
-            if (array[i] >= min && array[i] <= max) {
-                return i;
-            }
-        }
-        return INDEX_NOT_FOUND;
-    }
-
-    /**
-     * <p>Finds the last index of the given value within the array.</p>
-     *
-     * <p>This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.</p>
-     *
-     * @param array  the array to travers backwords looking for the object, may be {@code null}
-     * @param valueToFind  the object to find
-     * @return the last index of the value within the array,
-     *  {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
-     */
-    public static int lastIndexOf(double[] array, double valueToFind) {
-        return lastIndexOf(array, valueToFind, Integer.MAX_VALUE);
-    }
-
-    /**
-     * <p>Finds the last index of the given value within a given tolerance in the array.
-     * This method will return the index of the last value which falls between the region
-     * defined by valueToFind - tolerance and valueToFind + tolerance.</p>
-     *
-     * <p>This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.</p>
-     *
-     * @param array  the array to search through for the object, may be {@code null}
-     * @param valueToFind  the value to find
-     * @param tolerance tolerance of the search
-     * @return the index of the value within the array,
-     *  {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
-     */
-    public static int lastIndexOf(double[] array, double valueToFind, double tolerance) {
-        return lastIndexOf(array, valueToFind, Integer.MAX_VALUE, tolerance);
-    }
-
-    /**
-     * <p>Finds the last index of the given value in the array starting at the given index.</p>
-     *
-     * <p>This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.</p>
-     *
-     * <p>A negative startIndex will return {@link #INDEX_NOT_FOUND} ({@code -1}). A startIndex larger than the
-     * array length will search from the end of the array.</p>
-     *
-     * @param array  the array to traverse for looking for the object, may be {@code null}
-     * @param valueToFind  the value to find
-     * @param startIndex  the start index to travers backwards from
-     * @return the last index of the value within the array,
-     *  {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
-     */
-    public static int lastIndexOf(double[] array, double valueToFind, int startIndex) {
-        if (ArrayUtils.isEmpty(array)) {
-            return INDEX_NOT_FOUND;
-        }
-        if (startIndex < 0) {
-            return INDEX_NOT_FOUND;
-        } else if (startIndex >= array.length) {
-            startIndex = array.length - 1;
-        }
-        for (int i = startIndex; i >= 0; i--) {
-            if (valueToFind == array[i]) {
-                return i;
-            }
-        }
-        return INDEX_NOT_FOUND;
-    }
-
-    /**
-     * <p>Finds the last index of the given value in the array starting at the given index.
-     * This method will return the index of the last value which falls between the region
-     * defined by valueToFind - tolerance and valueToFind + tolerance.</p>
-     *
-     * <p>This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.</p>
-     *
-     * <p>A negative startIndex will return {@link #INDEX_NOT_FOUND} ({@code -1}). A startIndex larger than the
-     * array length will search from the end of the array.</p>
-     *
-     * @param array  the array to traverse for looking for the object, may be {@code null}
-     * @param valueToFind  the value to find
-     * @param startIndex  the start index to travers backwards from
-     * @param tolerance  search for value within plus/minus this amount
-     * @return the last index of the value within the array,
-     *  {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
-     */
-    public static int lastIndexOf(double[] array, double valueToFind, int startIndex, double tolerance) {
-        if (ArrayUtils.isEmpty(array)) {
-            return INDEX_NOT_FOUND;
-        }
-        if (startIndex < 0) {
-            return INDEX_NOT_FOUND;
-        } else if (startIndex >= array.length) {
-            startIndex = array.length - 1;
-        }
-        double min = valueToFind - tolerance;
-        double max = valueToFind + tolerance;
-        for (int i = startIndex; i >= 0; i--) {
-            if (array[i] >= min && array[i] <= max) {
-                return i;
-            }
-        }
-        return INDEX_NOT_FOUND;
-    }
-
-    /**
-     * <p>Checks if the value is in the given array.</p>
-     *
-     * <p>The method returns {@code false} if a {@code null} array is passed in.</p>
-     *
-     * @param array  the array to search through
-     * @param valueToFind  the value to find
-     * @return {@code true} if the array contains the object
-     */
-    public static boolean contains(double[] array, double valueToFind) {
-        return indexOf(array, valueToFind) != INDEX_NOT_FOUND;
-    }
-
-    /**
-     * <p>Checks if a value falling within the given tolerance is in the
-     * given array.  If the array contains a value within the inclusive range
-     * defined by (value - tolerance) to (value + tolerance).</p>
-     *
-     * <p>The method returns {@code false} if a {@code null} array
-     * is passed in.</p>
-     *
-     * @param array  the array to search
-     * @param valueToFind  the value to find
-     * @param tolerance  the array contains the tolerance of the search
-     * @return true if value falling within tolerance is in array
-     */
-    public static boolean contains(double[] array, double valueToFind, double tolerance) {
-        return indexOf(array, valueToFind, 0, tolerance) != INDEX_NOT_FOUND;
-    }
-
-    // float IndexOf
-    //-----------------------------------------------------------------------
-    /**
-     * <p>Finds the index of the given value in the array.</p>
-     *
-     * <p>This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.</p>
-     *
-     * @param array  the array to search through for the object, may be {@code null}
-     * @param valueToFind  the value to find
-     * @return the index of the value within the array,
-     *  {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
-     */
-    public static int indexOf(float[] array, float valueToFind) {
-        return indexOf(array, valueToFind, 0);
-    }
-
-    /**
-     * <p>Finds the index of the given value in the array starting at the given index.</p>
-     *
-     * <p>This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.</p>
-     *
-     * <p>A negative startIndex is treated as zero. A startIndex larger than the array
-     * length will return {@link #INDEX_NOT_FOUND} ({@code -1}).</p>
-     *
-     * @param array  the array to search through for the object, may be {@code null}
-     * @param valueToFind  the value to find
-     * @param startIndex  the index to start searching at
-     * @return the index of the value within the array,
-     *  {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
-     */
-    public static int indexOf(float[] array, float valueToFind, int startIndex) {
-        if (ArrayUtils.isEmpty(array)) {
-            return INDEX_NOT_FOUND;
-        }
-        if (startIndex < 0) {
-            startIndex = 0;
-        }
-        for (int i = startIndex; i < array.length; i++) {
-            if (valueToFind == array[i]) {
-                return i;
-            }
-        }
-        return INDEX_NOT_FOUND;
-    }
-
-    /**
-     * <p>Finds the last index of the given value within the array.</p>
-     *
-     * <p>This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.</p>
-     *
-     * @param array  the array to travers backwords looking for the object, may be {@code null}
-     * @param valueToFind  the object to find
-     * @return the last index of the value within the array,
-     *  {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
-     */
-    public static int lastIndexOf(float[] array, float valueToFind) {
-        return lastIndexOf(array, valueToFind, Integer.MAX_VALUE);
-    }
-
-    /**
-     * <p>Finds the last index of the given value in the array starting at the given index.</p>
-     *
-     * <p>This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.</p>
-     *
-     * <p>A negative startIndex will return {@link #INDEX_NOT_FOUND} ({@code -1}). A startIndex larger than the
-     * array length will search from the end of the array.</p>
-     *
-     * @param array  the array to traverse for looking for the object, may be {@code null}
-     * @param valueToFind  the value to find
-     * @param startIndex  the start index to travers backwards from
-     * @return the last index of the value within the array,
-     *  {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
-     */
-    public static int lastIndexOf(float[] array, float valueToFind, int startIndex) {
-        if (ArrayUtils.isEmpty(array)) {
-            return INDEX_NOT_FOUND;
-        }
-        if (startIndex < 0) {
-            return INDEX_NOT_FOUND;
-        } else if (startIndex >= array.length) {
-            startIndex = array.length - 1;
-        }
-        for (int i = startIndex; i >= 0; i--) {
-            if (valueToFind == array[i]) {
-                return i;
-            }
-        }
-        return INDEX_NOT_FOUND;
-    }
-
-    /**
-     * <p>Checks if the value is in the given array.</p>
-     *
-     * <p>The method returns {@code false} if a {@code null} array is passed in.</p>
-     *
-     * @param array  the array to search through
-     * @param valueToFind  the value to find
-     * @return {@code true} if the array contains the object
-     */
-    public static boolean contains(float[] array, float valueToFind) {
-        return indexOf(array, valueToFind) != INDEX_NOT_FOUND;
-    }
-
-    // boolean IndexOf
-    //-----------------------------------------------------------------------
-    /**
-     * <p>Finds the index of the given value in the array.</p>
-     *
-     * <p>This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.</p>
-     *
-     * @param array  the array to search through for the object, may be {@code null}
-     * @param valueToFind  the value to find
-     * @return the index of the value within the array,
-     *  {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
-     */
-    public static int indexOf(boolean[] array, boolean valueToFind) {
-        return indexOf(array, valueToFind, 0);
-    }
-
-    /**
-     * <p>Finds the index of the given value in the array starting at the given index.</p>
-     *
-     * <p>This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.</p>
-     *
-     * <p>A negative startIndex is treated as zero. A startIndex larger than the array
-     * length will return {@link #INDEX_NOT_FOUND} ({@code -1}).</p>
-     *
-     * @param array  the array to search through for the object, may be {@code null}
-     * @param valueToFind  the value to find
-     * @param startIndex  the index to start searching at
-     * @return the index of the value within the array,
-     *  {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null}
-     *  array input
-     */
-    public static int indexOf(boolean[] array, boolean valueToFind, int startIndex) {
-        if (ArrayUtils.isEmpty(array)) {
-            return INDEX_NOT_FOUND;
-        }
-        if (startIndex < 0) {
-            startIndex = 0;
-        }
-        for (int i = startIndex; i < array.length; i++) {
-            if (valueToFind == array[i]) {
-                return i;
-            }
-        }
-        return INDEX_NOT_FOUND;
-    }
-
-    /**
-     * <p>Finds the last index of the given value within the array.</p>
-     *
-     * <p>This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) if
-     * {@code null} array input.</p>
-     *
-     * @param array  the array to travers backwords looking for the object, may be {@code null}
-     * @param valueToFind  the object to find
-     * @return the last index of the value within the array,
-     *  {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
-     */
-    public static int lastIndexOf(boolean[] array, boolean valueToFind) {
-        return lastIndexOf(array, valueToFind, Integer.MAX_VALUE);
-    }
-
-    /**
-     * <p>Finds the last index of the given value in the array starting at the given index.</p>
-     *
-     * <p>This method returns {@link #INDEX_NOT_FOUND} ({@code -1}) for a {@code null} input array.</p>
-     *
-     * <p>A negative startIndex will return {@link #INDEX_NOT_FOUND} ({@code -1}). A startIndex larger than
-     * the array length will search from the end of the array.</p>
-     *
-     * @param array  the array to traverse for looking for the object, may be {@code null}
-     * @param valueToFind  the value to find
-     * @param startIndex  the start index to travers backwards from
-     * @return the last index of the value within the array,
-     *  {@link #INDEX_NOT_FOUND} ({@code -1}) if not found or {@code null} array input
-     */
-    public static int lastIndexOf(boolean[] array, boolean valueToFind, int startIndex) {
-        if (ArrayUtils.isEmpty(array)) {
-            return INDEX_NOT_FOUND;
-        }
-        if (startIndex < 0) {
-            return INDEX_NOT_FOUND;
-        } else if (startIndex >= array.length) {
-            startIndex = array.length - 1;
-        }
-        for (int i = startIndex; i >= 0; i--) {
-            if (valueToFind == array[i]) {
-                return i;
-            }
-        }
-        return INDEX_NOT_FOUND;
-    }
-
-    /**
-     * <p>Checks if the value is in the given array.</p>
-     *
-     * <p>The method returns {@code false} if a {@code null} array is passed in.</p>
-     *
-     * @param array  the array to search through
-     * @param valueToFind  the value to find
-     * @return {@code true} if the array contains the object
-     */
-    public static boolean contains(boolean[] array, boolean valueToFind) {
-        return indexOf(array, valueToFind) != INDEX_NOT_FOUND;
-    }
-
-    // Primitive/Object array converters
-    // ----------------------------------------------------------------------
-
-    // Character array converters
-    // ----------------------------------------------------------------------
-    /**
-     * <p>Converts an array of object Characters to primitives.</p>
-     *
-     * <p>This method returns {@code null} for a {@code null} input array.</p>
-     *
-     * @param array  a {@code Character} array, may be {@code null}
-     * @return a {@code char} array, {@code null} if null array input
-     * @throws NullPointerException if array content is {@code null}
-     */
-    public static char[] toPrimitive(Character[] array) {
-        if (array == null) {
-            return null;
-        } else if (array.length == 0) {
-            return EMPTY_CHAR_ARRAY;
-        }
-        final char[] result = new char[array.length];
-        for (int i = 0; i < array.length; i++) {
-            result[i] = array[i].charValue();
-        }
-        return result;
-    }
-
-    /**
-     * <p>Converts an array of object Character to primitives handling {@code null}.</p>
-     *
-     * <p>This method returns {@code null} for a {@code null} input array.</p>
-     *
-     * @param array  a {@code Character} array, may be {@code null}
-     * @param valueForNull  the value to insert if {@code null} found
-     * @return a {@code char} array, {@code null} if null array input
-     */
-    public static char[] toPrimitive(Character[] array, char valueForNull) {
-        if (array == null) {
-            return null;
-        } else if (array.length == 0) {
-            return EMPTY_CHAR_ARRAY;
-        }
-        final char[] result = new char[array.length];
-        for (int i = 0; i < array.length; i++) {
-            Character b = array[i];
-            result[i] = (b == null ? valueForNull : b.charValue());
-        }
-        return result;
-    }
-
-    /**
-     * <p>Converts an array of primitive chars to objects.</p>
-     *
-     * <p>This method returns {@code null} for a {@code null} input array.</p>
-     *
-     * @param array a {@code char} array
-     * @return a {@code Character} array, {@code null} if null array input
-     */
-    public static Character[] toObject(char[] array) {
-        if (array == null) {
-            return null;
-        } else if (array.length == 0) {
-            return EMPTY_CHARACTER_OBJECT_ARRAY;
-        }
-        final Character[] result = new Character[array.length];
-        for (int i = 0; i < array.length; i++) {
-            result[i] = Character.valueOf(array[i]);
-        }
-        return result;
-     }
-
-    // Long array converters
-    // ----------------------------------------------------------------------
-    /**
-     * <p>Converts an array of object Longs to primitives.</p>
-     *
-     * <p>This method returns {@code null} for a {@code null} input array.</p>
-     *
-     * @param array  a {@code Long} array, may be {@code null}
-     * @return a {@code long} array, {@code null} if null array input
-     * @throws NullPointerException if array content is {@code null}
-     */
-    public static long[] toPrimitive(Long[] array) {
-        if (array == null) {
-            return null;
-        } else if (array.length == 0) {
-            return EMPTY_LONG_ARRAY;
-        }
-        final long[] result = new long[array.length];
-        for (int i = 0; i < array.length; i++) {
-            result[i] = array[i].longValue();
-        }
-        return result;
-    }
-
-    /**
-     * <p>Converts an array of object Long to primitives handling {@code null}.</p>
-     *
-     * <p>This method returns {@code null} for a {@code null} input array.</p>
-     *
-     * @param array  a {@code Long} array, may be {@code null}
-     * @param valueForNull  the value to insert if {@code null} found
-     * @return a {@code long} array, {@code null} if null array input
-     */
-    public static long[] toPrimitive(Long[] array, long valueForNull) {
-        if (array == null) {
-            return null;
-        } else if (array.length == 0) {
-            return EMPTY_LONG_ARRAY;
-        }
-        final long[] result = new long[array.length];
-        for (int i = 0; i < array.length; i++) {
-            Long b = array[i];
-            result[i] = (b == null ? valueForNull : b.longValue());
-        }
-        return result;
-    }
-
-    /**
-     * <p>Converts an array of primitive longs to objects.</p>
-     *
-     * <p>This method returns {@code null} for a {@code null} input array.</p>
-     *
-     * @param array  a {@code long} array
-     * @return a {@code Long} array, {@code null} if null array input
-     */
-    public static Long[] toObject(long[] array) {
-        if (array == null) {
-            return null;
-        } else if (array.length == 0) {
-            return EMPTY_LONG_OBJECT_ARRAY;
-        }
-        final Long[] result = new Long[array.length];
-        for (int i = 0; i < array.length; i++) {
-            result[i] = Long.valueOf(array[i]);
-        }
-        return result;
-    }
-
-    // Int array converters
-    // ----------------------------------------------------------------------
-    /**
-     * <p>Converts an array of object Integers to primitives.</p>
-     *
-     * <p>This method returns {@code null} for a {@code null} input array.</p>
-     *
-     * @param array  a {@code Integer} array, may be {@code null}
-     * @return an {@code int} array, {@code null} if null array input
-     * @throws NullPointerException if array content is {@code null}
-     */
-    public static int[] toPrimitive(Integer[] array) {
-        if (array == null) {
-            return null;
-        } else if (array.length == 0) {
-            return EMPTY_INT_ARRAY;
-        }
-        final int[] result = new int[array.length];
-        for (int i = 0; i < array.length; i++) {
-            result[i] = array[i].intValue();
-        }
-        return result;
-    }
-
-    /**
-     * <p>Converts an array of object Integer to primitives handling {@code null}.</p>
-     *
-     * <p>This method returns {@code null} for a {@code null} input array.</p>
-     *
-     * @param array  a {@code Integer} array, may be {@code null}
-     * @param valueForNull  the value to insert if {@code null} found
-     * @return an {@code int} array, {@code null} if null array input
-     */
-    public static int[] toPrimitive(Integer[] array, int valueForNull) {
-        if (array == null) {
-            return null;
-        } else if (array.length == 0) {
-            return EMPTY_INT_ARRAY;
-        }
-        final int[] result = new int[array.length];
-        for (int i = 0; i < array.length; i++) {
-            Integer b = array[i];
-            result[i] = (b == null ? valueForNull : b.intValue());
-        }
-        return result;
-    }
-
-    /**
-     * <p>Converts an array of primitive ints to objects.</p>
-     *
-     * <p>This method returns {@code null} for a {@code null} input array.</p>
-     *
-     * @param array  an {@code int} array
-     * @return an {@code Integer} array, {@code null} if null array input
-     */
-    public static Integer[] toObject(int[] array) {
-        if (array == null) {
-            return null;
-        } else if (array.length == 0) {
-            return EMPTY_INTEGER_OBJECT_ARRAY;
-        }
-        final Integer[] result = new Integer[array.length];
-        for (int i = 0; i < array.length; i++) {
-            result[i] = Integer.valueOf(array[i]);
-        }
-        return result;
-    }
-
-    // Short array converters
-    // ----------------------------------------------------------------------
-    /**
-     * <p>Converts an array of object Shorts to primitives.</p>
-     *
-     * <p>This method returns {@code null} for a {@code null} input array.</p>
-     *
-     * @param array  a {@code Short} array, may be {@code null}
-     * @return a {@code byte} array, {@code null} if null array input
-     * @throws NullPointerException if array content is {@code null}
-     */
-    public static short[] toPrimitive(Short[] array) {
-        if (array == null) {
-            return null;
-        } else if (array.length == 0) {
-            return EMPTY_SHORT_ARRAY;
-        }
-        final short[] result = new short[array.length];
-        for (int i = 0; i < array.length; i++) {
-            result[i] = array[i].shortValue();
-        }
-        return result;
-    }
-
-    /**
-     * <p>Converts an array of object Short to primitives handling {@code null}.</p>
-     *
-     * <p>This method returns {@code null} for a {@code null} input array.</p>
-     *
-     * @param array  a {@code Short} array, may be {@code null}
-     * @param valueForNull  the value to insert if {@code null} found
-     * @return a {@code byte} array, {@code null} if null array input
-     */
-    public static short[] toPrimitive(Short[] array, short valueForNull) {
-        if (array == null) {
-            return null;
-        } else if (array.length == 0) {
-            return EMPTY_SHORT_ARRAY;
-        }
-        final short[] result = new short[array.length];
-        for (int i = 0; i < array.length; i++) {
-            Short b = array[i];
-            result[i] = (b == null ? valueForNull : b.shortValue());
-        }
-        return result;
-    }
-
-    /**
-     * <p>Converts an array of primitive shorts to objects.</p>
-     *
-     * <p>This method returns {@code null} for a {@code null} input array.</p>
-     *
-     * @param array  a {@code short} array
-     * @return a {@code Short} array, {@code null} if null array input
-     */
-    public static Short[] toObject(short[] array) {
-        if (array == null) {
-            return null;
-        } else if (array.length == 0) {
-            return EMPTY_SHORT_OBJECT_ARRAY;
-        }
-        final Short[] result = new Short[array.length];
-        for (int i = 0; i < array.length; i++) {
-            result[i] = Short.valueOf(array[i]);
-        }
-        return result;
-    }
-
-    // Byte array converters
-    // ----------------------------------------------------------------------
-    /**
-     * <p>Converts an array of object Bytes to primitives.</p>
-     *
-     * <p>This method returns {@code null} for a {@code null} input array.</p>
-     *
-     * @param array  a {@code Byte} array, may be {@code null}
-     * @return a {@code byte} array, {@code null} if null array input
-     * @throws NullPointerException if array content is {@code null}
-     */
-    public static byte[] toPrimitive(Byte[] array) {
-        if (array == null) {
-            return null;
-        } else if (array.length == 0) {
-            return EMPTY_BYTE_ARRAY;
-        }
-        final byte[] result = new byte[array.length];
-        for (int i = 0; i < array.length; i++) {
-            result[i] = array[i].byteValue();
-        }
-        return result;
-    }
-
-    /**
-     * <p>Converts an array of object Bytes to primitives handling {@code null}.</p>
-     *
-     * <p>This method returns {@code null} for a {@code null} input array.</p>
-     *
-     * @param array  a {@code Byte} array, may be {@code null}
-     * @param valueForNull  the value to insert if {@code null} found
-     * @return a {@code byte} array, {@code null} if null array input
-     */
-    public static byte[] toPrimitive(Byte[] array, byte valueForNull) {
-        if (array == null) {
-            return null;
-        } else if (array.length == 0) {
-            return EMPTY_BYTE_ARRAY;
-        }
-        final byte[] result = new byte[array.length];
-        for (int i = 0; i < array.length; i++) {
-            Byte b = array[i];
-            result[i] = (b == null ? valueForNull : b.byteValue());
-        }
-        return result;
-    }
-
-    /**
-     * <p>Converts an array of primitive bytes to objects.</p>
-     *
-     * <p>This method returns {@code null} for a {@code null} input array.</p>
-     *
-     * @param array  a {@code byte} array
-     * @return a {@code Byte} array, {@code null} if null array input
-     */
-    public static Byte[] toObject(byte[] array) {
-        if (array == null) {
-            return null;
-        } else if (array.length == 0) {
-            return EMPTY_BYTE_OBJECT_ARRAY;
-        }
-        final Byte[] result = new Byte[array.length];
-        for (int i = 0; i < array.length; i++) {
-            result[i] = Byte.valueOf(array[i]);
-        }
-        return result;
-    }
-
-    // Double array converters
-    // ----------------------------------------------------------------------
-    /**
-     * <p>Converts an array of object Doubles to primitives.</p>
-     *
-     * <p>This method returns {@code null} for a {@code null} input array.</p>
-     *
-     * @param array  a {@code Double} array, may be {@code null}
-     * @return a {@code double} array, {@code null} if null array input
-     * @throws NullPointerException if array content is {@code null}
-     */
-    public static double[] toPrimitive(Double[] array) {
-        if (array == null) {
-            return null;
-        } else if (array.length == 0) {
-            return EMPTY_DOUBLE_ARRAY;
-        }
-        final double[] result = new double[array.length];
-        for (int i = 0; i < array.length; i++) {
-            result[i] = array[i].doubleValue();
-        }
-        return result;
-    }
-
-    /**
-     * <p>Converts an array of object Doubles to primitives handling {@code null}.</p>
-     *
-     * <p>This method returns {@code null} for a {@code null} input array.</p>
-     *
-     * @param array  a {@code Double} array, may be {@code null}
-     * @param valueForNull  the value to insert if {@code null} found
-     * @return a {@code double} array, {@code null} if null array input
-     */
-    public static double[] toPrimitive(Double[] array, double valueForNull) {
-        if (array == null) {
-            return null;
-        } else if (array.length == 0) {
-            return EMPTY_DOUBLE_ARRAY;
-        }
-        final double[] result = new double[array.length];
-        for (int i = 0; i < array.length; i++) {
-            Double b = array[i];
-            result[i] = (b == null ? valueForNull : b.doubleValue());
-        }
-        return result;
-    }
-
-    /**
-     * <p>Converts an array of primitive doubles to objects.</p>
-     *
-     * <p>This method returns {@code null} for a {@code null} input array.</p>
-     *
-     * @param array  a {@code double} array
-     * @return a {@code Double} array, {@code null} if null array input
-     */
-    public static Double[] toObject(double[] array) {
-        if (array == null) {
-            return null;
-        } else if (array.length == 0) {
-            return EMPTY_DOUBLE_OBJECT_ARRAY;
-        }
-        final Double[] result = new Double[array.length];
-        for (int i = 0; i < array.length; i++) {
-            result[i] = Double.valueOf(array[i]);
-        }
-        return result;
-    }
-
-    //   Float array converters
-    // ----------------------------------------------------------------------
-    /**
-     * <p>Converts an array of object Floats to primitives.</p>
-     *
-     * <p>This method returns {@code null} for a {@code null} input array.</p>
-     *
-     * @param array  a {@code Float} array, may be {@code null}
-     * @return a {@code float} array, {@code null} if null array input
-     * @throws NullPointerException if array content is {@code null}
-     */
-    public static float[] toPrimitive(Float[] array) {
-        if (array == null) {
-            return null;
-        } else if (array.length == 0) {
-            return EMPTY_FLOAT_ARRAY;
-        }
-        final float[] result = new float[array.length];
-        for (int i = 0; i < array.length; i++) {
-            result[i] = array[i].floatValue();
-        }
-        return result;
-    }
-
-    /**
-     * <p>Converts an array of object Floats to primitives handling {@code null}.</p>
-     *
-     * <p>This method returns {@code null} for a {@code null} input array.</p>
-     *
-     * @param array  a {@code Float} array, may be {@code null}
-     * @param valueForNull  the value to insert if {@code null} found
-     * @return a {@code float} array, {@code null} if null array input
-     */
-    public static float[] toPrimitive(Float[] array, float valueForNull) {
-        if (array == null) {
-            return null;
-        } else if (array.length == 0) {
-            return EMPTY_FLOAT_ARRAY;
-        }
-        final float[] result = new float[array.length];
-        for (int i = 0; i < array.length; i++) {
-            Float b = array[i];
-            result[i] = (b == null ? valueForNull : b.floatValue());
-        }
-        return result;
-    }
-
-    /**
-     * <p>Converts an array of primitive floats to objects.</p>
-     *
-     * <p>This method returns {@code null} for a {@code null} input array.</p>
-     *
-     * @param array  a {@code float} array
-     * @return a {@code Float} array, {@code null} if null array input
-     */
-    public static Float[] toObject(float[] array) {
-        if (array == null) {
-            return null;
-        } else if (array.length == 0) {
-            return EMPTY_FLOAT_OBJECT_ARRAY;
-        }
-        final Float[] result = new Float[array.length];
-        for (int i = 0; i < array.length; i++) {
-            result[i] = Float.valueOf(array[i]);
-        }
-        return result;
-    }
-
-    // Boolean array converters
-    // ----------------------------------------------------------------------
-    /**
-     * <p>Converts an array of object Booleans to primitives.</p>
-     *
-     * <p>This method returns {@code null} for a {@code null} input array.</p>
-     *
-     * @param array  a {@code Boolean} array, may be {@code null}
-     * @return a {@code boolean} array, {@code null} if null array input
-     * @throws NullPointerException if array content is {@code null}
-     */
-    public static boolean[] toPrimitive(Boolean[] array) {
-        if (array == null) {
-            return null;
-        } else if (array.length == 0) {
-            return EMPTY_BOOLEAN_ARRAY;
-        }
-        final boolean[] result = new boolean[array.length];
-        for (int i = 0; i < array.length; i++) {
-            result[i] = array[i].booleanValue();
-        }
-        return result;
-    }
-
-    /**
-     * <p>Converts an array of object Booleans to primitives handling {@code null}.</p>
-     *
-     * <p>This method returns {@code null} for a {@code null} input array.</p>
-     *
-     * @param array  a {@code Boolean} array, may be {@code null}
-     * @param valueForNull  the value to insert if {@code null} found
-     * @return a {@code boolean} array, {@code null} if null array input
-     */
-    public static boolean[] toPrimitive(Boolean[] array, boolean valueForNull) {
-        if (array == null) {
-            return null;
-        } else if (array.length == 0) {
-            return EMPTY_BOOLEAN_ARRAY;
-        }
-        final boolean[] result = new boolean[array.length];
-        for (int i = 0; i < array.length; i++) {
-            Boolean b = array[i];
-            result[i] = (b == null ? valueForNull : b.booleanValue());
-        }
-        return result;
-    }
-
-    /**
-     * <p>Converts an array of primitive booleans to objects.</p>
-     *
-     * <p>This method returns {@code null} for a {@code null} input array.</p>
-     *
-     * @param array  a {@code boolean} array
-     * @return a {@code Boolean} array, {@code null} if null array input
-     */
-    public static Boolean[] toObject(boolean[] array) {
-        if (array == null) {
-            return null;
-        } else if (array.length == 0) {
-            return EMPTY_BOOLEAN_OBJECT_ARRAY;
-        }
-        final Boolean[] result = new Boolean[array.length];
-        for (int i = 0; i < array.length; i++) {
-            result[i] = (array[i] ? Boolean.TRUE : Boolean.FALSE);
-        }
-        return result;
-    }
-
-    // ----------------------------------------------------------------------
-    /**
-     * <p>Checks if an array of Objects is empty or {@code null}.</p>
-     *
-     * @param array  the array to test
-     * @return {@code true} if the array is empty or {@code null}
-     * @since 2.1
-     */
-    public static boolean isEmpty(Object[] array) {
-        return array == null || array.length == 0;
-    }
-
-    /**
-     * <p>Checks if an array of primitive longs is empty or {@code null}.</p>
-     *
-     * @param array  the array to test
-     * @return {@code true} if the array is empty or {@code null}
-     * @since 2.1
-     */
-    public static boolean isEmpty(long[] array) {
-        return array == null || array.length == 0;
-    }
-
-    /**
-     * <p>Checks if an array of primitive ints is empty or {@code null}.</p>
-     *
-     * @param array  the array to test
-     * @return {@code true} if the array is empty or {@code null}
-     * @since 2.1
-     */
-    public static boolean isEmpty(int[] array) {
-        return array == null || array.length == 0;
-    }
-
-    /**
-     * <p>Checks if an array of primitive shorts is empty or {@code null}.</p>
-     *
-     * @param array  the array to test
-     * @return {@code true} if the array is empty or {@code null}
-     * @since 2.1
-     */
-    public static boolean isEmpty(short[] array) {
-        return array == null || array.length == 0;
-    }
-
-    /**
-     * <p>Checks if an array of primitive chars is empty or {@code null}.</p>
-     *
-     * @param array  the array to test
-     * @return {@code true} if the array is empty or {@code null}
-     * @since 2.1
-     */
-    public static boolean isEmpty(char[] array) {
-        return array == null || array.length == 0;
-    }
-
-    /**
-     * <p>Checks if an array of primitive bytes is empty or {@code null}.</p>
-     *
-     * @param array  the array to test
-     * @return {@code true} if the array is empty or {@code null}
-     * @since 2.1
-     */
-    public static boolean isEmpty(byte[] array) {
-        return array == null || array.length == 0;
-    }
-
-    /**
-     * <p>Checks if an array of primitive doubles is empty or {@code null}.</p>
-     *
-     * @param array  the array to test
-     * @return {@code true} if the array is empty or {@code null}
-     * @since 2.1
-     */
-    public static boolean isEmpty(double[] array) {
-        return array == null || array.length == 0;
-    }
-
-    /**
-     * <p>Checks if an array of primitive floats is empty or {@code null}.</p>
-     *
-     * @param array  the array to test
-     * @return {@code true} if the array is empty or {@code null}
-     * @since 2.1
-     */
-    public static boolean isEmpty(float[] array) {
-        return array == null || array.length == 0;
-    }
-
-    /**
-     * <p>Checks if an array of primitive booleans is empty or {@code null}.</p>
-     *
-     * @param array  the array to test
-     * @return {@code true} if the array is empty or {@code null}
-     * @since 2.1
-     */
-    public static boolean isEmpty(boolean[] array) {
-        return array == null || array.length == 0;
-    }
-
-    // ----------------------------------------------------------------------
-    /**
-     * <p>Checks if an array of Objects is not empty or not {@code null}.</p>
-     *
-     * @param <T> the component type of the array
-     * @param array  the array to test
-     * @return {@code true} if the array is not empty or not {@code null}
-     * @since 2.5
-     */
-     public static <T> boolean isNotEmpty(T[] array) {
-         return (array != null && array.length != 0);
-     }
-
-    /**
-     * <p>Checks if an array of primitive longs is not empty or not {@code null}.</p>
-     *
-     * @param array  the array to test
-     * @return {@code true} if the array is not empty or not {@code null}
-     * @since 2.5
-     */
-    public static boolean isNotEmpty(long[] array) {
-        return (array != null && array.length != 0);
-    }
-
-    /**
-     * <p>Checks if an array of primitive ints is not empty or not {@code null}.</p>
-     *
-     * @param array  the array to test
-     * @return {@code true} if the array is not empty or not {@code null}
-     * @since 2.5
-     */
-    public static boolean isNotEmpty(int[] array) {
-        return (array != null && array.length != 0);
-    }
-
-    /**
-     * <p>Checks if an array of primitive shorts is not empty or not {@code null}.</p>
-     *
-     * @param array  the array to test
-     * @return {@code true} if the array is not empty or not {@code null}
-     * @since 2.5
-     */
-    public static boolean isNotEmpty(short[] array) {
-        return (array != null && array.length != 0);
-    }
-
-    /**
-     * <p>Checks if an array of primitive chars is not empty or not {@code null}.</p>
-     *
-     * @param array  the array to test
-     * @return {@code true} if the array is not empty or not {@code null}
-     * @since 2.5
-     */
-    public static boolean isNotEmpty(char[] array) {
-        return (array != null && array.length != 0);
-    }
-
-    /**
-     * <p>Checks if an array of primitive bytes is not empty or not {@code null}.</p>
-     *
-     * @param array  the array to test
-     * @return {@code true} if the array is not empty or not {@code null}
-     * @since 2.5
-     */
-    public static boolean isNotEmpty(byte[] array) {
-        return (array != null && array.length != 0);
-    }
-
-    /**
-     * <p>Checks if an array of primitive doubles is not empty or not {@code null}.</p>
-     *
-     * @param array  the array to test
-     * @return {@code true} if the array is not empty or not {@code null}
-     * @since 2.5
-     */
-    public static boolean isNotEmpty(double[] array) {
-        return (array != null && array.length != 0);
-    }
-
-    /**
-     * <p>Checks if an array of primitive floats is not empty or not {@code null}.</p>
-     *
-     * @param array  the array to test
-     * @return {@code true} if the array is not empty or not {@code null}
-     * @since 2.5
-     */
-    public static boolean isNotEmpty(float[] array) {
-        return (array != null && array.length != 0);
-    }
-
-    /**
-     * <p>Checks if an array of primitive booleans is not empty or not {@code null}.</p>
-     *
-     * @param array  the array to test
-     * @return {@code true} if the array is not empty or not {@code null}
-     * @since 2.5
-     */
-    public static boolean isNotEmpty(boolean[] array) {
-        return (array != null && array.length != 0);
-    }
-
-    /**
-     * <p>Adds all the elements of the given arrays into a new array.</p>
-     * <p>The new array contains all of the element of {@code array1} followed
-     * by all of the elements {@code array2}. When an array is returned, it is always
-     * a new array.</p>
-     *
-     * <pre>
-     * ArrayUtils.addAll(null, null)     = null
-     * ArrayUtils.addAll(array1, null)   = cloned copy of array1
-     * ArrayUtils.addAll(null, array2)   = cloned copy of array2
-     * ArrayUtils.addAll([], [])         = []
-     * ArrayUtils.addAll([null], [null]) = [null, null]
-     * ArrayUtils.addAll(["a", "b", "c"], ["1", "2", "3"]) = ["a", "b", "c", "1", "2", "3"]
-     * </pre>
-     *
-     * @param <T> the component type of the array
-     * @param array1  the first array whose elements are added to the new array, may be {@code null}
-     * @param array2  the second array whose elements are added to the new array, may be {@code null}
-     * @return The new array, {@code null} if both arrays are {@code null}.
-     *      The type of the new array is the type of the first array,
-     *      unless the first array is null, in which case the type is the same as the second array.
-     * @since 2.1
-     * @throws IllegalArgumentException if the array types are incompatible
-     */
-    public static <T> T[] addAll(T[] array1, T... array2) {
-        if (array1 == null) {
-            return clone(array2);
-        } else if (array2 == null) {
-            return clone(array1);
-        }
-        final Class<?> type1 = array1.getClass().getComponentType();
-        @SuppressWarnings("unchecked") // OK, because array is of type T
-        T[] joinedArray = (T[]) Array.newInstance(type1, array1.length + array2.length);
-        System.arraycopy(array1, 0, joinedArray, 0, array1.length);
-        try {
-            System.arraycopy(array2, 0, joinedArray, array1.length, array2.length);
-        } catch (ArrayStoreException ase) {
-            // Check if problem was due to incompatible types
-            /*
-             * We do this here, rather than before the copy because:
-             * - it would be a wasted check most of the time
-             * - safer, in case check turns out to be too strict
-             */
-            final Class<?> type2 = array2.getClass().getComponentType();
-            if (!type1.isAssignableFrom(type2)){
-                throw new IllegalArgumentException("Cannot store "+type2.getName()+" in an array of "
-                        +type1.getName(), ase);
-            }
-            throw ase; // No, so rethrow original
-        }
-        return joinedArray;
-    }
-
-    /**
-     * <p>Adds all the elements of the given arrays into a new array.</p>
-     * <p>The new array contains all of the element of {@code array1} followed
-     * by all of the elements {@code array2}. When an array is returned, it is always
-     * a new array.</p>
-     *
-     * <pre>
-     * ArrayUtils.addAll(array1, null)   = cloned copy of array1
-     * ArrayUtils.addAll(null, array2)   = cloned copy of array2
-     * ArrayUtils.addAll([], [])         = []
-     * </pre>
-     *
-     * @param array1  the first array whose elements are added to the new array.
-     * @param array2  the second array whose elements are added to the new array.
-     * @return The new boolean[] array.
-     * @since 2.1
-     */
-    public static boolean[] addAll(boolean[] array1, boolean... array2) {
-        if (array1 == null) {
-            return clone(array2);
-        } else if (array2 == null) {
-            return clone(array1);
-        }
-        boolean[] joinedArray = new boolean[array1.length + array2.length];
-        System.arraycopy(array1, 0, joinedArray, 0, array1.length);
-        System.arraycopy(array2, 0, joinedArray, array1.length, array2.length);
-        return joinedArray;
-    }
-
-    /**
-     * <p>Adds all the elements of the given arrays into a new array.</p>
-     * <p>The new array contains all of the element of {@code array1} followed
-     * by all of the elements {@code array2}. When an array is returned, it is always
-     * a new array.</p>
-     *
-     * <pre>
-     * ArrayUtils.addAll(array1, null)   = cloned copy of array1
-     * ArrayUtils.addAll(null, array2)   = cloned copy of array2
-     * ArrayUtils.addAll([], [])         = []
-     * </pre>
-     *
-     * @param array1  the first array whose elements are added to the new array.
-     * @param array2  the second array whose elements are added to the new array.
-     * @return The new char[] array.
-     * @since 2.1
-     */
-    public static char[] addAll(char[] array1, char... array2) {
-        if (array1 == null) {
-            return clone(array2);
-        } else if (array2 == null) {
-            return clone(array1);
-        }
-        char[] joinedArray = new char[array1.length + array2.length];
-        System.arraycopy(array1, 0, joinedArray, 0, array1.length);
-        System.arraycopy(array2, 0, joinedArray, array1.length, array2.length);
-        return joinedArray;
-    }
-
-    /**
-     * <p>Adds all the elements of the given arrays into a new array.</p>
-     * <p>The new array contains all of the element of {@code array1} followed
-     * by all of the elements {@code array2}. When an array is returned, it is always
-     * a new array.</p>
-     *
-     * <pre>
-     * ArrayUtils.addAll(array1, null)   = cloned copy of array1
-     * ArrayUtils.addAll(null, array2)   = cloned copy of array2
-     * ArrayUtils.addAll([], [])         = []
-     * </pre>
-     *
-     * @param array1  the first array whose elements are added to the new array.
-     * @param array2  the second array whose elements are added to the new array.
-     * @return The new byte[] array.
-     * @since 2.1
-     */
-    public static byte[] addAll(byte[] array1, byte... array2) {
-        if (array1 == null) {
-            return clone(array2);
-        } else if (array2 == null) {
-            return clone(array1);
-        }
-        byte[] joinedArray = new byte[array1.length + array2.length];
-        System.arraycopy(array1, 0, joinedArray, 0, array1.length);
-        System.arraycopy(array2, 0, joinedArray, array1.length, array2.length);
-        return joinedArray;
-    }
-
-    /**
-     * <p>Adds all the elements of the given arrays into a new array.</p>
-     * <p>The new array contains all of the element of {@code array1} followed
-     * by all of the elements {@code array2}. When an array is returned, it is always
-     * a new array.</p>
-     *
-     * <pre>
-     * ArrayUtils.addAll(array1, null)   = cloned copy of array1
-     * ArrayUtils.addAll(null, array2)   = cloned copy of array2
-     * ArrayUtils.addAll([], [])         = []
-     * </pre>
-     *
-     * @param array1  the first array whose elements are added to the new array.
-     * @param array2  the second array whose elements are added to the new array.
-     * @return The new short[] array.
-     * @since 2.1
-     */
-    public static short[] addAll(short[] array1, short... array2) {
-        if (array1 == null) {
-            return clone(array2);
-        } else if (array2 == null) {
-            return clone(array1);
-        }
-        short[] joinedArray = new short[array1.length + array2.length];
-        System.arraycopy(array1, 0, joinedArray, 0, array1.length);
-        System.arraycopy(array2, 0, joinedArray, array1.length, array2.length);
-        return joinedArray;
-    }
-
-    /**
-     * <p>Adds all the elements of the given arrays into a new array.</p>
-     * <p>The new array contains all of the element of {@code array1} followed
-     * by all of the elements {@code array2}. When an array is returned, it is always
-     * a new array.</p>
-     *
-     * <pre>
-     * ArrayUtils.addAll(array1, null)   = cloned copy of array1
-     * ArrayUtils.addAll(null, array2)   = cloned copy of array2
-     * ArrayUtils.addAll([], [])         = []
-     * </pre>
-     *
-     * @param array1  the first array whose elements are added to the new array.
-     * @param array2  the second array whose elements are added to the new array.
-     * @return The new int[] array.
-     * @since 2.1
-     */
-    public static int[] addAll(int[] array1, int... array2) {
-        if (array1 == null) {
-            return clone(array2);
-        } else if (array2 == null) {
-            return clone(array1);
-        }
-        int[] joinedArray = new int[array1.length + array2.length];
-        System.arraycopy(array1, 0, joinedArray, 0, array1.length);
-        System.arraycopy(array2, 0, joinedArray, array1.length, array2.length);
-        return joinedArray;
-    }
-
-    /**
-     * <p>Adds all the elements of the given arrays into a new array.</p>
-     * <p>The new array contains all of the element of {@code array1} followed
-     * by all of the elements {@code array2}. When an array is returned, it is always
-     * a new array.</p>
-     *
-     * <pre>
-     * ArrayUtils.addAll(array1, null)   = cloned copy of array1
-     * ArrayUtils.addAll(null, array2)   = cloned copy of array2
-     * ArrayUtils.addAll([], [])         = []
-     * </pre>
-     *
-     * @param array1  the first array whose elements are added to the new array.
-     * @param array2  the second array whose elements are added to the new array.
-     * @return The new long[] array.
-     * @since 2.1
-     */
-    public static long[] addAll(long[] array1, long... array2) {
-        if (array1 == null) {
-            return clone(array2);
-        } else if (array2 == null) {
-            return clone(array1);
-        }
-        long[] joinedArray = new long[array1.length + array2.length];
-        System.arraycopy(array1, 0, joinedArray, 0, array1.length);
-        System.arraycopy(array2, 0, joinedArray, array1.length, array2.length);
-        return joinedArray;
-    }
-
-    /**
-     * <p>Adds all the elements of the given arrays into a new array.</p>
-     * <p>The new array contains all of the element of {@code array1} followed
-     * by all of the elements {@code array2}. When an array is returned, it is always
-     * a new array.</p>
-     *
-     * <pre>
-     * ArrayUtils.addAll(array1, null)   = cloned copy of array1
-     * ArrayUtils.addAll(null, array2)   = cloned copy of array2
-     * ArrayUtils.addAll([], [])         = []
-     * </pre>
-     *
-     * @param array1  the first array whose elements are added to the new array.
-     * @param array2  the second array whose elements are added to the new array.
-     * @return The new float[] array.
-     * @since 2.1
-     */
-    public static float[] addAll(float[] array1, float... array2) {
-        if (array1 == null) {
-            return clone(array2);
-        } else if (array2 == null) {
-            return clone(array1);
-        }
-        float[] joinedArray = new float[array1.length + array2.length];
-        System.arraycopy(array1, 0, joinedArray, 0, array1.length);
-        System.arraycopy(array2, 0, joinedArray, array1.length, array2.length);
-        return joinedArray;
-    }
-
-    /**
-     * <p>Adds all the elements of the given arrays into a new array.</p>
-     * <p>The new array contains all of the element of {@code array1} followed
-     * by all of the elements {@code array2}. When an array is returned, it is always
-     * a new array.</p>
-     *
-     * <pre>
-     * ArrayUtils.addAll(array1, null)   = cloned copy of array1
-     * ArrayUtils.addAll(null, array2)   = cloned copy of array2
-     * ArrayUtils.addAll([], [])         = []
-     * </pre>
-     *
-     * @param array1  the first array whose elements are added to the new array.
-     * @param array2  the second array whose elements are added to the new array.
-     * @return The new double[] array.
-     * @since 2.1
-     */
-    public static double[] addAll(double[] array1, double... array2) {
-        if (array1 == null) {
-            return clone(array2);
-        } else if (array2 == null) {
-            return clone(array1);
-        }
-        double[] joinedArray = new double[array1.length + array2.length];
-        System.arraycopy(array1, 0, joinedArray, 0, array1.length);
-        System.arraycopy(array2, 0, joinedArray, array1.length, array2.length);
-        return joinedArray;
-    }
-
-    /**
-     * <p>Copies the given array and adds the given element at the end of the new array.</p>
-     *
-     * <p>The new array contains the same elements of the input
-     * array plus the given element in the last position. The component type of
-     * the new array is the same as that of the input array.</p>
-     *
-     * <p>If the input array is {@code null}, a new one element array is returned
-     *  whose component type is the same as the element, unless the element itself is null,
-     *  in which case the return type is Object[]</p>
-     *
-     * <pre>
-     * ArrayUtils.add(null, null)      = [null]
-     * ArrayUtils.add(null, "a")       = ["a"]
-     * ArrayUtils.add(["a"], null)     = ["a", null]
-     * ArrayUtils.add(["a"], "b")      = ["a", "b"]
-     * ArrayUtils.add(["a", "b"], "c") = ["a", "b", "c"]
-     * </pre>
-     *
-     * @param <T> the component type of the array
-     * @param array  the array to "add" the element to, may be {@code null}
-     * @param element  the object to add, may be {@code null}
-     * @return A new array containing the existing elements plus the new element
-     * The returned array type will be that of the input array (unless null),
-     * in which case it will have the same type as the element.
-     * If both are null, an IllegalArgumentException is thrown
-     * @since 2.1
-     * @throws IllegalArgumentException if both arguments are null
-     */
-    public static <T> T[] add(T[] array, T element) {
-        Class<?> type;
-        if (array != null){
-            type = array.getClass();
-        } else if (element != null) {
-            type = element.getClass();
-        } else {
-            throw new IllegalArgumentException("Arguments cannot both be null");
-        }
-        @SuppressWarnings("unchecked") // type must be T
-        T[] newArray = (T[]) copyArrayGrow1(array, type);
-        newArray[newArray.length - 1] = element;
-        return newArray;
-    }
-
-    /**
-     * <p>Copies the given array and adds the given element at the end of the new array.</p>
-     *
-     * <p>The new array contains the same elements of the input
-     * array plus the given element in the last position. The component type of
-     * the new array is the same as that of the input array.</p>
-     *
-     * <p>If the input array is {@code null}, a new one element array is returned
-     *  whose component type is the same as the element.</p>
-     *
-     * <pre>
-     * ArrayUtils.add(null, true)          = [true]
-     * ArrayUtils.add([true], false)       = [true, false]
-     * ArrayUtils.add([true, false], true) = [true, false, true]
-     * </pre>
-     *
-     * @param array  the array to copy and add the element to, may be {@code null}
-     * @param element  the object to add at the last index of the new array
-     * @return A new array containing the existing elements plus the new element
-     * @since 2.1
-     */
-    public static boolean[] add(boolean[] array, boolean element) {
-        boolean[] newArray = (boolean[])copyArrayGrow1(array, Boolean.TYPE);
-        newArray[newArray.length - 1] = element;
-        return newArray;
-    }
-
-    /**
-     * <p>Copies the given array and adds the given element at the end of the new array.</p>
-     *
-     * <p>The new array contains the same elements of the input
-     * array plus the given element in the last position. The component type of
-     * the new array is the same as that of the input array.</p>
-     *
-     * <p>If the input array is {@code null}, a new one element array is returned
-     *  whose component type is the same as the element.</p>
-     *
-     * <pre>
-     * ArrayUtils.add(null, 0)   = [0]
-     * ArrayUtils.add([1], 0)    = [1, 0]
-     * ArrayUtils.add([1, 0], 1) = [1, 0, 1]
-     * </pre>
-     *
-     * @param array  the array to copy and add the element to, may be {@code null}
-     * @param element  the object to add at the last index of the new array
-     * @return A new array containing the existing elements plus the new element
-     * @since 2.1
-     */
-    public static byte[] add(byte[] array, byte element) {
-        byte[] newArray = (byte[])copyArrayGrow1(array, Byte.TYPE);
-        newArray[newArray.length - 1] = element;
-        return newArray;
-    }
-
-    /**
-     * <p>Copies the given array and adds the given element at the end of the new array.</p>
-     *
-     * <p>The new array contains the same elements of the input
-     * array plus the given element in the last position. The component type of
-     * the new array is the same as that of the input array.</p>
-     *
-     * <p>If the input array is {@code null}, a new one element array is returned
-     *  whose component type is the same as the element.</p>
-     *
-     * <pre>
-     * ArrayUtils.add(null, '0')       = ['0']
-     * ArrayUtils.add(['1'], '0')      = ['1', '0']
-     * ArrayUtils.add(['1', '0'], '1') = ['1', '0', '1']
-     * </pre>
-     *
-     * @param array  the array to copy and add the element to, may be {@code null}
-     * @param element  the object to add at the last index of the new array
-     * @return A new array containing the existing elements plus the new element
-     * @since 2.1
-     */
-    public static char[] add(char[] array, char element) {
-        char[] newArray = (char[])copyArrayGrow1(array, Character.TYPE);
-        newArray[newArray.length - 1] = element;
-        return newArray;
-    }
-
-    /**
-     * <p>Copies the given array and adds the given element at the end of the new array.</p>
-     *
-     * <p>The new array contains the same elements of the input
-     * array plus the given element in the last position. The component type of
-     * the new array is the same as that of the input array.</p>
-     *
-     * <p>If the input array is {@code null}, a new one element array is returned
-     *  whose component type is the same as the element.</p>
-     *
-     * <pre>
-     * ArrayUtils.add(null, 0)   = [0]
-     * ArrayUtils.add([1], 0)    = [1, 0]
-     * ArrayUtils.add([1, 0], 1) = [1, 0, 1]
-     * </pre>
-     *
-     * @param array  the array to copy and add the element to, may be {@code null}
-     * @param element  the object to add at the last index of the new array
-     * @return A new array containing the existing elements plus the new element
-     * @since 2.1
-     */
-    public static double[] add(double[] array, double element) {
-        double[] newArray = (double[])copyArrayGrow1(array, Double.TYPE);
-        newArray[newArray.length - 1] = element;
-        return newArray;
-    }
-
-    /**
-     * <p>Copies the given array and adds the given element at the end of the new array.</p>
-     *
-     * <p>The new array contains the same elements of the input
-     * array plus the given element in the last position. The component type of
-     * the new array is the same as that of the input array.</p>
-     *
-     * <p>If the input array is {@code null}, a new one element array is returned
-     *  whose component type is the same as the element.</p>
-     *
-     * <pre>
-     * ArrayUtils.add(null, 0)   = [0]
-     * ArrayUtils.add([1], 0)    = [1, 0]
-     * ArrayUtils.add([1, 0], 1) = [1, 0, 1]
-     * </pre>
-     *
-     * @param array  the array to copy and add the element to, may be {@code null}
-     * @param element  the object to add at the last index of the new array
-     * @return A new array containing the existing elements plus the new element
-     * @since 2.1
-     */
-    public static float[] add(float[] array, float element) {
-        float[] newArray = (float[])copyArrayGrow1(array, Float.TYPE);
-        newArray[newArray.length - 1] = element;
-        return newArray;
-    }
-
-    /**
-     * <p>Copies the given array and adds the given element at the end of the new array.</p>
-     *
-     * <p>The new array contains the same elements of the input
-     * array plus the given element in the last position. The component type of
-     * the new array is the same as that of the input array.</p>
-     *
-     * <p>If the input array is {@code null}, a new one element array is returned
-     *  whose component type is the same as the element.</p>
-     *
-     * <pre>
-     * ArrayUtils.add(null, 0)   = [0]
-     * ArrayUtils.add([1], 0)    = [1, 0]
-     * ArrayUtils.add([1, 0], 1) = [1, 0, 1]
-     * </pre>
-     *
-     * @param array  the array to copy and add the element to, may be {@code null}
-     * @param element  the object to add at the last index of the new array
-     * @return A new array containing the existing elements plus the new element
-     * @since 2.1
-     */
-    public static int[] add(int[] array, int element) {
-        int[] newArray = (int[])copyArrayGrow1(array, Integer.TYPE);
-        newArray[newArray.length - 1] = element;
-        return newArray;
-    }
-
-    /**
-     * <p>Copies the given array and adds the given element at the end of the new array.</p>
-     *
-     * <p>The new array contains the same elements of the input
-     * array plus the given element in the last position. The component type of
-     * the new array is the same as that of the input array.</p>
-     *
-     * <p>If the input array is {@code null}, a new one element array is returned
-     *  whose component type is the same as the element.</p>
-     *
-     * <pre>
-     * ArrayUtils.add(null, 0)   = [0]
-     * ArrayUtils.add([1], 0)    = [1, 0]
-     * ArrayUtils.add([1, 0], 1) = [1, 0, 1]
-     * </pre>
-     *
-     * @param array  the array to copy and add the element to, may be {@code null}
-     * @param element  the object to add at the last index of the new array
-     * @return A new array containing the existing elements plus the new element
-     * @since 2.1
-     */
-    public static long[] add(long[] array, long element) {
-        long[] newArray = (long[])copyArrayGrow1(array, Long.TYPE);
-        newArray[newArray.length - 1] = element;
-        return newArray;
-    }
-
-    /**
-     * <p>Copies the given array and adds the given element at the end of the new array.</p>
-     *
-     * <p>The new array contains the same elements of the input
-     * array plus the given element in the last position. The component type of
-     * the new array is the same as that of the input array.</p>
-     *
-     * <p>If the input array is {@code null}, a new one element array is returned
-     *  whose component type is the same as the element.</p>
-     *
-     * <pre>
-     * ArrayUtils.add(null, 0)   = [0]
-     * ArrayUtils.add([1], 0)    = [1, 0]
-     * ArrayUtils.add([1, 0], 1) = [1, 0, 1]
-     * </pre>
-     *
-     * @param array  the array to copy and add the element to, may be {@code null}
-     * @param element  the object to add at the last index of the new array
-     * @return A new array containing the existing elements plus the new element
-     * @since 2.1
-     */
-    public static short[] add(short[] array, short element) {
-        short[] newArray = (short[])copyArrayGrow1(array, Short.TYPE);
-        newArray[newArray.length - 1] = element;
-        return newArray;
-    }
-
-    /**
-     * Returns a copy of the given array of size 1 greater than the argument.
-     * The last value of the array is left to the default value.
-     *
-     * @param array The array to copy, must not be {@code null}.
-     * @param newArrayComponentType If {@code array} is {@code null}, create a
-     * size 1 array of this type.
-     * @return A new copy of the array of size 1 greater than the input.
-     */
-    private static Object copyArrayGrow1(Object array, Class<?> newArrayComponentType) {
-        if (array != null) {
-            int arrayLength = Array.getLength(array);
-            Object newArray = Array.newInstance(array.getClass().getComponentType(), arrayLength + 1);
-            System.arraycopy(array, 0, newArray, 0, arrayLength);
-            return newArray;
-        }
-        return Array.newInstance(newArrayComponentType, 1);
-    }
-
-    /**
-     * <p>Inserts the specified element at the specified position in the array.
-     * Shifts the element currently at that position (if any) and any subsequent
-     * elements to the right (adds one to their indices).</p>
-     *
-     * <p>This method returns a new array with the same elements of the input
-     * array plus the given element on the specified position. The component
-     * type of the returned array is always the same as that of the input
-     * array.</p>
-     *
-     * <p>If the input array is {@code null}, a new one element array is returned
-     *  whose component type is the same as the element.</p>
-     *
-     * <pre>
-     * ArrayUtils.add(null, 0, null)      = [null]
-     * ArrayUtils.add(null, 0, "a")       = ["a"]
-     * ArrayUtils.add(["a"], 1, null)     = ["a", null]
-     * ArrayUtils.add(["a"], 1, "b")      = ["a", "b"]
-     * ArrayUtils.add(["a", "b"], 3, "c") = ["a", "b", "c"]
-     * </pre>
-     *
-     * @param <T> the component type of the array
-     * @param array  the array to add the element to, may be {@code null}
-     * @param index  the position of the new object
-     * @param element  the object to add
-     * @return A new array containing the existing elements and the new element
-     * @throws IndexOutOfBoundsException if the index is out of range
-     * (index < 0 || index > array.length).
-     * @throws IllegalArgumentException if both array and element are null
-     */
-    public static <T> T[] add(T[] array, int index, T element) {
-        Class<?> clss = null;
-        if (array != null) {
-            clss = array.getClass().getComponentType();
-        } else if (element != null) {
-            clss = element.getClass();
-        } else {
-            throw new IllegalArgumentException("Array and element cannot both be null");
-        }
-        @SuppressWarnings("unchecked") // the add method creates an array of type clss, which is type T
-        final T[] newArray = (T[]) add(array, index, element, clss);
-        return newArray;
-    }
-
-    /**
-     * <p>Inserts the specified element at the specified position in the array.
-     * Shifts the element currently at that position (if any) and any subsequent
-     * elements to the right (adds one to their indices).</p>
-     *
-     * <p>This method returns a new array with the same elements of the input
-     * array plus the given element on the specified position. The component
-     * type of the returned array is always the same as that of the input
-     * array.</p>
-     *
-     * <p>If the input array is {@code null}, a new one element array is returned
-     *  whose component type is the same as the element.</p>
-     *
-     * <pre>
-     * ArrayUtils.add(null, 0, true)          = [true]
-     * ArrayUtils.add([true], 0, false)       = [false, true]
-     * ArrayUtils.add([false], 1, true)       = [false, true]
-     * ArrayUtils.add([true, false], 1, true) = [true, true, false]
-     * </pre>
-     *
-     * @param array  the array to add the element to, may be {@code null}
-     * @param index  the position of the new object
-     * @param element  the object to add
-     * @return A new array containing the existing elements and the new element
-     * @throws IndexOutOfBoundsException if the index is out of range
-     * (index < 0 || index > array.length).
-     */
-    public static boolean[] add(boolean[] array, int index, boolean element) {
-        return (boolean[]) add(array, index, Boolean.valueOf(element), Boolean.TYPE);
-    }
-
-    /**
-     * <p>Inserts the specified element at the specified position in the array.
-     * Shifts the element currently at that position (if any) and any subsequent
-     * elements to the right (adds one to their indices).</p>
-     *
-     * <p>This method returns a new array with the same elements of the input
-     * array plus the given element on the specified position. The component
-     * type of the returned array is always the same as that of the input
-     * array.</p>
-     *
-     * <p>If the input array is {@code null}, a new one element array is returned
-     *  whose component type is the same as the element.</p>
-     *
-     * <pre>
-     * ArrayUtils.add(null, 0, 'a')            = ['a']
-     * ArrayUtils.add(['a'], 0, 'b')           = ['b', 'a']
-     * ArrayUtils.add(['a', 'b'], 0, 'c')      = ['c', 'a', 'b']
-     * ArrayUtils.add(['a', 'b'], 1, 'k')      = ['a', 'k', 'b']
-     * ArrayUtils.add(['a', 'b', 'c'], 1, 't') = ['a', 't', 'b', 'c']
-     * </pre>
-     *
-     * @param array  the array to add the element to, may be {@code null}
-     * @param index  the position of the new object
-     * @param element  the object to add
-     * @return A new array containing the existing elements and the new element
-     * @throws IndexOutOfBoundsException if the index is out of range
-     * (index < 0 || index > array.length).
-     */
-    public static char[] add(char[] array, int index, char element) {
-        return (char[]) add(array, index, Character.valueOf(element), Character.TYPE);
-    }
-
-    /**
-     * <p>Inserts the specified element at the specified position in the array.
-     * Shifts the element currently at that position (if any) and any subsequent
-     * elements to the right (adds one to their indices).</p>
-     *
-     * <p>This method returns a new array with the same elements of the input
-     * array plus the given element on the specified position. The component
-     * type of the returned array is always the same as that of the input
-     * array.</p>
-     *
-     * <p>If the input array is {@code null}, a new one element array is returned
-     *  whose component type is the same as the element.</p>
-     *
-     * <pre>
-     * ArrayUtils.add([1], 0, 2)         = [2, 1]
-     * ArrayUtils.add([2, 6], 2, 3)      = [2, 6, 3]
-     * ArrayUtils.add([2, 6], 0, 1)      = [1, 2, 6]
-     * ArrayUtils.add([2, 6, 3], 2, 1)   = [2, 6, 1, 3]
-     * </pre>
-     *
-     * @param array  the array to add the element to, may be {@code null}
-     * @param index  the position of the new object
-     * @param element  the object to add
-     * @return A new array containing the existing elements and the new element
-     * @throws IndexOutOfBoundsException if the index is out of range
-     * (index < 0 || index > array.length).
-     */
-    public static byte[] add(byte[] array, int index, byte element) {
-        return (byte[]) add(array, index, Byte.valueOf(element), Byte.TYPE);
-    }
-
-    /**
-     * <p>Inserts the specified element at the specified position in the array.
-     * Shifts the element currently at that position (if any) and any subsequent
-     * elements to the right (adds one to their indices).</p>
-     *
-     * <p>This method returns a new array with the same elements of the input
-     * array plus the given element on the specified position. The component
-     * type of the returned array is always the same as that of the input
-     * array.</p>
-     *
-     * <p>If the input array is {@code null}, a new one element array is returned
-     *  whose component type is the same as the element.</p>
-     *
-     * <pre>
-     * ArrayUtils.add([1], 0, 2)         = [2, 1]
-     * ArrayUtils.add([2, 6], 2, 10)     = [2, 6, 10]
-     * ArrayUtils.add([2, 6], 0, -4)     = [-4, 2, 6]
-     * ArrayUtils.add([2, 6, 3], 2, 1)   = [2, 6, 1, 3]
-     * </pre>
-     *
-     * @param array  the array to add the element to, may be {@code null}
-     * @param index  the position of the new object
-     * @param element  the object to add
-     * @return A new array containing the existing elements and the new element
-     * @throws IndexOutOfBoundsException if the index is out of range
-     * (index < 0 || index > array.length).
-     */
-    public static short[] add(short[] array, int index, short element) {
-        return (short[]) add(array, index, Short.valueOf(element), Short.TYPE);
-    }
-
-    /**
-     * <p>Inserts the specified element at the specified position in the array.
-     * Shifts the element currently at that position (if any) and any subsequent
-     * elements to the right (adds one to their indices).</p>
-     *
-     * <p>This method returns a new array with the same elements of the input
-     * array plus the given element on the specified position. The component
-     * type of the returned array is always the same as that of the input
-     * array.</p>
-     *
-     * <p>If the input array is {@code null}, a new one element array is returned
-     *  whose component type is the same as the element.</p>
-     *
-     * <pre>
-     * ArrayUtils.add([1], 0, 2)         = [2, 1]
-     * ArrayUtils.add([2, 6], 2, 10)     = [2, 6, 10]
-     * ArrayUtils.add([2, 6], 0, -4)     = [-4, 2, 6]
-     * ArrayUtils.add([2, 6, 3], 2, 1)   = [2, 6, 1, 3]
-     * </pre>
-     *
-     * @param array  the array to add the element to, may be {@code null}
-     * @param index  the position of the new object
-     * @param element  the object to add
-     * @return A new array containing the existing elements and the new element
-     * @throws IndexOutOfBoundsException if the index is out of range
-     * (index < 0 || index > array.length).
-     */
-    public static int[] add(int[] array, int index, int element) {
-        return (int[]) add(array, index, Integer.valueOf(element), Integer.TYPE);
-    }
-
-    /**
-     * <p>Inserts the specified element at the specified position in the array.
-     * Shifts the element currently at that position (if any) and any subsequent
-     * elements to the right (adds one to their indices).</p>
-     *
-     * <p>This method returns a new array with the same elements of the input
-     * array plus the given element on the specified position. The component
-     * type of the returned array is always the same as that of the input
-     * array.</p>
-     *
-     * <p>If the input array is {@code null}, a new one element array is returned
-     *  whose component type is the same as the element.</p>
-     *
-     * <pre>
-     * ArrayUtils.add([1L], 0, 2L)           = [2L, 1L]
-     * ArrayUtils.add([2L, 6L], 2, 10L)      = [2L, 6L, 10L]
-     * ArrayUtils.add([2L, 6L], 0, -4L)      = [-4L, 2L, 6L]
-     * ArrayUtils.add([2L, 6L, 3L], 2, 1L)   = [2L, 6L, 1L, 3L]
-     * </pre>
-     *
-     * @param array  the array to add the element to, may be {@code null}
-     * @param index  the position of the new object
-     * @param element  the object to add
-     * @return A new array containing the existing elements and the new element
-     * @throws IndexOutOfBoundsException if the index is out of range
-     * (index < 0 || index > array.length).
-     */
-    public static long[] add(long[] array, int index, long element) {
-        return (long[]) add(array, index, Long.valueOf(element), Long.TYPE);
-    }
-
-    /**
-     * <p>Inserts the specified element at the specified position in the array.
-     * Shifts the element currently at that position (if any) and any subsequent
-     * elements to the right (adds one to their indices).</p>
-     *
-     * <p>This method returns a new array with the same elements of the input
-     * array plus the given element on the specified position. The component
-     * type of the returned array is always the same as that of the input
-     * array.</p>
-     *
-     * <p>If the input array is {@code null}, a new one element array is returned
-     *  whose component type is the same as the element.</p>
-     *
-     * <pre>
-     * ArrayUtils.add([1.1f], 0, 2.2f)               = [2.2f, 1.1f]
-     * ArrayUtils.add([2.3f, 6.4f], 2, 10.5f)        = [2.3f, 6.4f, 10.5f]
-     * ArrayUtils.add([2.6f, 6.7f], 0, -4.8f)        = [-4.8f, 2.6f, 6.7f]
-     * ArrayUtils.add([2.9f, 6.0f, 0.3f], 2, 1.0f)   = [2.9f, 6.0f, 1.0f, 0.3f]
-     * </pre>
-     *
-     * @param array  the array to add the element to, may be {@code null}
-     * @param index  the position of the new object
-     * @param element  the object to add
-     * @return A new array containing the existing elements and the new element
-     * @throws IndexOutOfBoundsException if the index is out of range
-     * (index < 0 || index > array.length).
-     */
-    public static float[] add(float[] array, int index, float element) {
-        return (float[]) add(array, index, Float.valueOf(element), Float.TYPE);
-    }
-
-    /**
-     * <p>Inserts the specified element at the specified position in the array.
-     * Shifts the element currently at that position (if any) and any subsequent
-     * elements to the right (adds one to their indices).</p>
-     *
-     * <p>This method returns a new array with the same elements of the input
-     * array plus the given element on the specified position. The component
-     * type of the returned array is always the same as that of the input
-     * array.</p>
-     *
-     * <p>If the input array is {@code null}, a new one element array is returned
-     *  whose component type is the same as the element.</p>
-     *
-     * <pre>
-     * ArrayUtils.add([1.1], 0, 2.2)              = [2.2, 1.1]
-     * ArrayUtils.add([2.3, 6.4], 2, 10.5)        = [2.3, 6.4, 10.5]
-     * ArrayUtils.add([2.6, 6.7], 0, -4.8)        = [-4.8, 2.6, 6.7]
-     * ArrayUtils.add([2.9, 6.0, 0.3], 2, 1.0)    = [2.9, 6.0, 1.0, 0.3]
-     * </pre>
-     *
-     * @param array  the array to add the element to, may be {@code null}
-     * @param index  the position of the new object
-     * @param element  the object to add
-     * @return A new array containing the existing elements and the new element
-     * @throws IndexOutOfBoundsException if the index is out of range
-     * (index < 0 || index > array.length).
-     */
-    public static double[] add(double[] array, int index, double element) {
-        return (double[]) add(array, index, Double.valueOf(element), Double.TYPE);
-    }
-
-    /**
-     * Underlying implementation of add(array, index, element) methods.
-     * The last parameter is the class, which may not equal element.getClass
-     * for primitives.
-     *
-     * @param array  the array to add the element to, may be {@code null}
-     * @param index  the position of the new object
-     * @param element  the object to add
-     * @param clss the type of the element being added
-     * @return A new array containing the existing elements and the new element
-     */
-    private static Object add(Object array, int index, Object element, Class<?> clss) {
-        if (array == null) {
-            if (index != 0) {
-                throw new IndexOutOfBoundsException("Index: " + index + ", Length: 0");
-            }
-            Object joinedArray = Array.newInstance(clss, 1);
-            Array.set(joinedArray, 0, element);
-            return joinedArray;
-        }
-        int length = Array.getLength(array);
-        if (index > length || index < 0) {
-            throw new IndexOutOfBoundsException("Index: " + index + ", Length: " + length);
-        }
-        Object result = Array.newInstance(clss, length + 1);
-        System.arraycopy(array, 0, result, 0, index);
-        Array.set(result, index, element);
-        if (index < length) {
-            System.arraycopy(array, index, result, index + 1, length - index);
-        }
-        return result;
-    }
-
-    /**
-     * <p>Removes the element at the specified position from the specified array.
-     * All subsequent elements are shifted to the left (subtracts one from
-     * their indices).</p>
-     *
-     * <p>This method returns a new array with the same elements of the input
-     * array except the element on the specified position. The component
-     * type of the returned array is always the same as that of the input
-     * array.</p>
-     *
-     * <p>If the input array is {@code null}, an IndexOutOfBoundsException
-     * will be thrown, because in that case no valid index can be specified.</p>
-     *
-     * <pre>
-     * ArrayUtils.remove(["a"], 0)           = []
-     * ArrayUtils.remove(["a", "b"], 0)      = ["b"]
-     * ArrayUtils.remove(["a", "b"], 1)      = ["a"]
-     * ArrayUtils.remove(["a", "b", "c"], 1) = ["a", "c"]
-     * </pre>
-     *
-     * @param <T> the component type of the array
-     * @param array  the array to remove the element from, may not be {@code null}
-     * @param index  the position of the element to be removed
-     * @return A new array containing the existing elements except the element
-     *         at the specified position.
-     * @throws IndexOutOfBoundsException if the index is out of range
-     * (index < 0 || index >= array.length), or if the array is {@code null}.
-     * @since 2.1
-     */
-    @SuppressWarnings("unchecked") // remove() always creates an array of the same type as its input
-    public static <T> T[] remove(T[] array, int index) {
-        return (T[]) remove((Object) array, index);
-    }
-
-    /**
-     * <p>Removes the first occurrence of the specified element from the
-     * specified array. All subsequent elements are shifted to the left
-     * (subtracts one from their indices). If the array doesn't contains
-     * such an element, no elements are removed from the array.</p>
-     *
-     * <p>This method returns a new array with the same elements of the input
-     * array except the first occurrence of the specified element. The component
-     * type of the returned array is always the same as that of the input
-     * array.</p>
-     *
-     * <pre>
-     * ArrayUtils.removeElement(null, "a")            = null
-     * ArrayUtils.removeElement([], "a")              = []
-     * ArrayUtils.removeElement(["a"], "b")           = ["a"]
-     * ArrayUtils.removeElement(["a", "b"], "a")      = ["b"]
-     * ArrayUtils.removeElement(["a", "b", "a"], "a") = ["b", "a"]
-     * </pre>
-     *
-     * @param <T> the component type of the array
-     * @param array  the array to remove the element from, may be {@code null}
-     * @param element  the element to be removed
-     * @return A new array containing the existing elements except the first
-     *         occurrence of the specified element.
-     * @since 2.1
-     */
-    public static <T> T[] removeElement(T[] array, Object element) {
-        int index = indexOf(array, element);
-        if (index == INDEX_NOT_FOUND) {
-            return clone(array);
-        }
-        return remove(array, index);
-    }
-
-    /**
-     * <p>Removes the element at the specified position from the specified array.
-     * All subsequent elements are shifted to the left (subtracts one from
-     * their indices).</p>
-     *
-     * <p>This method returns a new array with the same elements of the input
-     * array except the element on the specified position. The component
-     * type of the returned array is always the same as that of the input
-     * array.</p>
-     *
-     * <p>If the input array is {@code null}, an IndexOutOfBoundsException
-     * will be thrown, because in that case no valid index can be specified.</p>
-     *
-     * <pre>
-     * ArrayUtils.remove([true], 0)              = []
-     * ArrayUtils.remove([true, false], 0)       = [false]
-     * ArrayUtils.remove([true, false], 1)       = [true]
-     * ArrayUtils.remove([true, true, false], 1) = [true, false]
-     * </pre>
-     *
-     * @param array  the array to remove the element from, may not be {@code null}
-     * @param index  the position of the element to be removed
-     * @return A new array containing the existing elements except the element
-     *         at the specified position.
-     * @throws IndexOutOfBoundsException if the index is out of range
-     * (index < 0 || index >= array.length), or if the array is {@code null}.
-     * @since 2.1
-     */
-    public static boolean[] remove(boolean[] array, int index) {
-        return (boolean[]) remove((Object) array, index);
-    }
-
-    /**
-     * <p>Removes the first occurrence of the specified element from the
-     * specified array. All subsequent elements are shifted to the left
-     * (subtracts one from their indices). If the array doesn't contains
-     * such an element, no elements are removed from the array.</p>
-     *
-     * <p>This method returns a new array with the same elements of the input
-     * array except the first occurrence of the specified element. The component
-     * type of the returned array is always the same as that of the input
-     * array.</p>
-     *
-     * <pre>
-     * ArrayUtils.removeElement(null, true)                = null
-     * ArrayUtils.removeElement([], true)                  = []
-     * ArrayUtils.removeElement([true], false)             = [true]
-     * ArrayUtils.removeElement([true, false], false)      = [true]
-     * ArrayUtils.removeElement([true, false, true], true) = [false, true]
-     * </pre>
-     *
-     * @param array  the array to remove the element from, may be {@code null}
-     * @param element  the element to be removed
-     * @return A new array containing the existing elements except the first
-     *         occurrence of the specified element.
-     * @since 2.1
-     */
-    public static boolean[] removeElement(boolean[] array, boolean element) {
-        int index = indexOf(array, element);
-        if (index == INDEX_NOT_FOUND) {
-            return clone(array);
-        }
-        return remove(array, index);
-    }
-
-    /**
-     * <p>Removes the element at the specified position from the specified array.
-     * All subsequent elements are shifted to the left (subtracts one from
-     * their indices).</p>
-     *
-     * <p>This method returns a new array with the same elements of the input
-     * array except the element on the specified position. The component
-     * type of the returned array is always the same as that of the input
-     * array.</p>
-     *
-     * <p>If the input array is {@code null}, an IndexOutOfBoundsException
-     * will be thrown, because in that case no valid index can be specified.</p>
-     *
-     * <pre>
-     * ArrayUtils.remove([1], 0)          = []
-     * ArrayUtils.remove([1, 0], 0)       = [0]
-     * ArrayUtils.remove([1, 0], 1)       = [1]
-     * ArrayUtils.remove([1, 0, 1], 1)    = [1, 1]
-     * </pre>
-     *
-     * @param array  the array to remove the element from, may not be {@code null}
-     * @param index  the position of the element to be removed
-     * @return A new array containing the existing elements except the element
-     *         at the specified position.
-     * @throws IndexOutOfBoundsException if the index is out of range
-     * (index < 0 || index >= array.length), or if the array is {@code null}.
-     * @since 2.1
-     */
-    public static byte[] remove(byte[] array, int index) {
-        return (byte[]) remove((Object) array, index);
-    }
-
-    /**
-     * <p>Removes the first occurrence of the specified element from the
-     * specified array. All subsequent elements are shifted to the left
-     * (subtracts one from their indices). If the array doesn't contains
-     * such an element, no elements are removed from the array.</p>
-     *
-     * <p>This method returns a new array with the same elements of the input
-     * array except the first occurrence of the specified element. The component
-     * type of the returned array is always the same as that of the input
-     * array.</p>
-     *
-     * <pre>
-     * ArrayUtils.removeElement(null, 1)        = null
-     * ArrayUtils.removeElement([], 1)          = []
-     * ArrayUtils.removeElement([1], 0)         = [1]
-     * ArrayUtils.removeElement([1, 0], 0)      = [1]
-     * ArrayUtils.removeElement([1, 0, 1], 1)   = [0, 1]
-     * </pre>
-     *
-     * @param array  the array to remove the element from, may be {@code null}
-     * @param element  the element to be removed
-     * @return A new array containing the existing elements except the first
-     *         occurrence of the specified element.
-     * @since 2.1
-     */
-    public static byte[] removeElement(byte[] array, byte element) {
-        int index = indexOf(array, element);
-        if (index == INDEX_NOT_FOUND) {
-            return clone(array);
-        }
-        return remove(array, index);
-    }
-
-    /**
-     * <p>Removes the element at the specified position from the specified array.
-     * All subsequent elements are shifted to the left (subtracts one from
-     * their indices).</p>
-     *
-     * <p>This method returns a new array with the same elements of the input
-     * array except the element on the specified position. The component
-     * type of the returned array is always the same as that of the input
-     * array.</p>
-     *
-     * <p>If the input array is {@code null}, an IndexOutOfBoundsException
-     * will be thrown, because in that case no valid index can be specified.</p>
-     *
-     * <pre>
-     * ArrayUtils.remove(['a'], 0)           = []
-     * ArrayUtils.remove(['a', 'b'], 0)      = ['b']
-     * ArrayUtils.remove(['a', 'b'], 1)      = ['a']
-     * ArrayUtils.remove(['a', 'b', 'c'], 1) = ['a', 'c']
-     * </pre>
-     *
-     * @param array  the array to remove the element from, may not be {@code null}
-     * @param index  the position of the element to be removed
-     * @return A new array containing the existing elements except the element
-     *         at the specified position.
-     * @throws IndexOutOfBoundsException if the index is out of range
-     * (index < 0 || index >= array.length), or if the array is {@code null}.
-     * @since 2.1
-     */
-    public static char[] remove(char[] array, int index) {
-        return (char[]) remove((Object) array, index);
-    }
-
-    /**
-     * <p>Removes the first occurrence of the specified element from the
-     * specified array. All subsequent elements are shifted to the left
-     * (subtracts one from their indices). If the array doesn't contains
-     * such an element, no elements are removed from the array.</p>
-     *
-     * <p>This method returns a new array with the same elements of the input
-     * array except the first occurrence of the specified element. The component
-     * type of the returned array is always the same as that of the input
-     * array.</p>
-     *
-     * <pre>
-     * ArrayUtils.removeElement(null, 'a')            = null
-     * ArrayUtils.removeElement([], 'a')              = []
-     * ArrayUtils.removeElement(['a'], 'b')           = ['a']
-     * ArrayUtils.removeElement(['a', 'b'], 'a')      = ['b']
-     * ArrayUtils.removeElement(['a', 'b', 'a'], 'a') = ['b', 'a']
-     * </pre>
-     *
-     * @param array  the array to remove the element from, may be {@code null}
-     * @param element  the element to be removed
-     * @return A new array containing the existing elements except the first
-     *         occurrence of the specified element.
-     * @since 2.1
-     */
-    public static char[] removeElement(char[] array, char element) {
-        int index = indexOf(array, element);
-        if (index == INDEX_NOT_FOUND) {
-            return clone(array);
-        }
-        return remove(array, index);
-    }
-
-    /**
-     * <p>Removes the element at the specified position from the specified array.
-     * All subsequent elements are shifted to the left (subtracts one from
-     * their indices).</p>
-     *
-     * <p>This method returns a new array with the same elements of the input
-     * array except the element on the specified position. The component
-     * type of the returned array is always the same as that of the input
-     * array.</p>
-     *
-     * <p>If the input array is {@code null}, an IndexOutOfBoundsException
-     * will be thrown, because in that case no valid index can be specified.</p>
-     *
-     * <pre>
-     * ArrayUtils.remove([1.1], 0)           = []
-     * ArrayUtils.remove([2.5, 6.0], 0)      = [6.0]
-     * ArrayUtils.remove([2.5, 6.0], 1)      = [2.5]
-     * ArrayUtils.remove([2.5, 6.0, 3.8], 1) = [2.5, 3.8]
-     * </pre>
-     *
-     * @param array  the array to remove the element from, may not be {@code null}
-     * @param index  the position of the element to be removed
-     * @return A new array containing the existing elements except the element
-     *         at the specified position.
-     * @throws IndexOutOfBoundsException if the index is out of range
-     * (index < 0 || index >= array.length), or if the array is {@code null}.
-     * @since 2.1
-     */
-    public static double[] remove(double[] array, int index) {
-        return (double[]) remove((Object) array, index);
-    }
-
-    /**
-     * <p>Removes the first occurrence of the specified element from the
-     * specified array. All subsequent elements are shifted to the left
-     * (subtracts one from their indices). If the array doesn't contains
-     * such an element, no elements are removed from the array.</p>
-     *
-     * <p>This method returns a new array with the same elements of the input
-     * array except the first occurrence of the specified element. The component
-     * type of the returned array is always the same as that of the input
-     * array.</p>
-     *
-     * <pre>
-     * ArrayUtils.removeElement(null, 1.1)            = null
-     * ArrayUtils.removeElement([], 1.1)              = []
-     * ArrayUtils.removeElement([1.1], 1.2)           = [1.1]
-     * ArrayUtils.removeElement([1.1, 2.3], 1.1)      = [2.3]
-     * ArrayUtils.removeElement([1.1, 2.3, 1.1], 1.1) = [2.3, 1.1]
-     * </pre>
-     *
-     * @param array  the array to remove the element from, may be {@code null}
-     * @param element  the element to be removed
-     * @return A new array containing the existing elements except the first
-     *         occurrence of the specified element.
-     * @since 2.1
-     */
-    public static double[] removeElement(double[] array, double element) {
-        int index = indexOf(array, element);
-        if (index == INDEX_NOT_FOUND) {
-            return clone(array);
-        }
-        return remove(array, index);
-    }
-
-    /**
-     * <p>Removes the element at the specified position from the specified array.
-     * All subsequent elements are shifted to the left (subtracts one from
-     * their indices).</p>
-     *
-     * <p>This method returns a new array with the same elements of the input
-     * array except the element on the specified position. The component
-     * type of the returned array is always the same as that of the input
-     * array.</p>
-     *
-     * <p>If the input array is {@code null}, an IndexOutOfBoundsException
-     * will be thrown, because in that case no valid index can be specified.</p>
-     *
-     * <pre>
-     * ArrayUtils.remove([1.1], 0)           = []
-     * ArrayUtils.remove([2.5, 6.0], 0)      = [6.0]
-     * ArrayUtils.remove([2.5, 6.0], 1)      = [2.5]
-     * ArrayUtils.remove([2.5, 6.0, 3.8], 1) = [2.5, 3.8]
-     * </pre>
-     *
-     * @param array  the array to remove the element from, may not be {@code null}
-     * @param index  the position of the element to be removed
-     * @return A new array containing the existing elements except the element
-     *         at the specified position.
-     * @throws IndexOutOfBoundsException if the index is out of range
-     * (index < 0 || index >= array.length), or if the array is {@code null}.
-     * @since 2.1
-     */
-    public static float[] remove(float[] array, int index) {
-        return (float[]) remove((Object) array, index);
-    }
-
-    /**
-     * <p>Removes the first occurrence of the specified element from the
-     * specified array. All subsequent elements are shifted to the left
-     * (subtracts one from their indices). If the array doesn't contains
-     * such an element, no elements are removed from the array.</p>
-     *
-     * <p>This method returns a new array with the same elements of the input
-     * array except the first occurrence of the specified element. The component
-     * type of the returned array is always the same as that of the input
-     * array.</p>
-     *
-     * <pre>
-     * ArrayUtils.removeElement(null, 1.1)            = null
-     * ArrayUtils.removeElement([], 1.1)              = []
-     * ArrayUtils.removeElement([1.1], 1.2)           = [1.1]
-     * ArrayUtils.removeElement([1.1, 2.3], 1.1)      = [2.3]
-     * ArrayUtils.removeElement([1.1, 2.3, 1.1], 1.1) = [2.3, 1.1]
-     * </pre>
-     *
-     * @param array  the array to remove the element from, may be {@code null}
-     * @param element  the element to be removed
-     * @return A new array containing the existing elements except the first
-     *         occurrence of the specified element.
-     * @since 2.1
-     */
-    public static float[] removeElement(float[] array, float element) {
-        int index = indexOf(array, element);
-        if (index == INDEX_NOT_FOUND) {
-            return clone(array);
-        }
-        return remove(array, index);
-    }
-
-    /**
-     * <p>Removes the element at the specified position from the specified array.
-     * All subsequent elements are shifted to the left (subtracts one from
-     * their indices).</p>
-     *
-     * <p>This method returns a new array with the same elements of the input
-     * array except the element on the specified position. The component
-     * type of the returned array is always the same as that of the input
-     * array.</p>
-     *
-     * <p>If the input array is {@code null}, an IndexOutOfBoundsException
-     * will be thrown, because in that case no valid index can be specified.</p>
-     *
-     * <pre>
-     * ArrayUtils.remove([1], 0)         = []
-     * ArrayUtils.remove([2, 6], 0)      = [6]
-     * ArrayUtils.remove([2, 6], 1)      = [2]
-     * ArrayUtils.remove([2, 6, 3], 1)   = [2, 3]
-     * </pre>
-     *
-     * @param array  the array to remove the element from, may not be {@code null}
-     * @param index  the position of the element to be removed
-     * @return A new array containing the existing elements except the element
-     *         at the specified position.
-     * @throws IndexOutOfBoundsException if the index is out of range
-     * (index < 0 || index >= array.length), or if the array is {@code null}.
-     * @since 2.1
-     */
-    public static int[] remove(int[] array, int index) {
-        return (int[]) remove((Object) array, index);
-    }
-
-    /**
-     * <p>Removes the first occurrence of the specified element from the
-     * specified array. All subsequent elements are shifted to the left
-     * (subtracts one from their indices). If the array doesn't contains
-     * such an element, no elements are removed from the array.</p>
-     *
-     * <p>This method returns a new array with the same elements of the input
-     * array except the first occurrence of the specified element. The component
-     * type of the returned array is always the same as that of the input
-     * array.</p>
-     *
-     * <pre>
-     * ArrayUtils.removeElement(null, 1)      = null
-     * ArrayUtils.removeElement([], 1)        = []
-     * ArrayUtils.removeElement([1], 2)       = [1]
-     * ArrayUtils.removeElement([1, 3], 1)    = [3]
-     * ArrayUtils.removeElement([1, 3, 1], 1) = [3, 1]
-     * </pre>
-     *
-     * @param array  the array to remove the element from, may be {@code null}
-     * @param element  the element to be removed
-     * @return A new array containing the existing elements except the first
-     *         occurrence of the specified element.
-     * @since 2.1
-     */
-    public static int[] removeElement(int[] array, int element) {
-        int index = indexOf(array, element);
-        if (index == INDEX_NOT_FOUND) {
-            return clone(array);
-        }
-        return remove(array, index);
-    }
-
-    /**
-     * <p>Removes the element at the specified position from the specified array.
-     * All subsequent elements are shifted to the left (subtracts one from
-     * their indices).</p>
-     *
-     * <p>This method returns a new array with the same elements of the input
-     * array except the element on the specified position. The component
-     * type of the returned array is always the same as that of the input
-     * array.</p>
-     *
-     * <p>If the input array is {@code null}, an IndexOutOfBoundsException
-     * will be thrown, because in that case no valid index can be specified.</p>
-     *
-     * <pre>
-     * ArrayUtils.remove([1], 0)         = []
-     * ArrayUtils.remove([2, 6], 0)      = [6]
-     * ArrayUtils.remove([2, 6], 1)      = [2]
-     * ArrayUtils.remove([2, 6, 3], 1)   = [2, 3]
-     * </pre>
-     *
-     * @param array  the array to remove the element from, may not be {@code null}
-     * @param index  the position of the element to be removed
-     * @return A new array containing the existing elements except the element
-     *         at the specified position.
-     * @throws IndexOutOfBoundsException if the index is out of range
-     * (index < 0 || index >= array.length), or if the array is {@code null}.
-     * @since 2.1
-     */
-    public static long[] remove(long[] array, int index) {
-        return (long[]) remove((Object) array, index);
-    }
-
-    /**
-     * <p>Removes the first occurrence of the specified element from the
-     * specified array. All subsequent elements are shifted to the left
-     * (subtracts one from their indices). If the array doesn't contains
-     * such an element, no elements are removed from the array.</p>
-     *
-     * <p>This method returns a new array with the same elements of the input
-     * array except the first occurrence of the specified element. The component
-     * type of the returned array is always the same as that of the input
-     * array.</p>
-     *
-     * <pre>
-     * ArrayUtils.removeElement(null, 1)      = null
-     * ArrayUtils.removeElement([], 1)        = []
-     * ArrayUtils.removeElement([1], 2)       = [1]
-     * ArrayUtils.removeElement([1, 3], 1)    = [3]
-     * ArrayUtils.removeElement([1, 3, 1], 1) = [3, 1]
-     * </pre>
-     *
-     * @param array  the array to remove the element from, may be {@code null}
-     * @param element  the element to be removed
-     * @return A new array containing the existing elements except the first
-     *         occurrence of the specified element.
-     * @since 2.1
-     */
-    public static long[] removeElement(long[] array, long element) {
-        int index = indexOf(array, element);
-        if (index == INDEX_NOT_FOUND) {
-            return clone(array);
-        }
-        return remove(array, index);
-    }
-
-    /**
-     * <p>Removes the element at the specified position from the specified array.
-     * All subsequent elements are shifted to the left (subtracts one from
-     * their indices).</p>
-     *
-     * <p>This method returns a new array with the same elements of the input
-     * array except the element on the specified position. The component
-     * type of the returned array is always the same as that of the input
-     * array.</p>
-     *
-     * <p>If the input array is {@code null}, an IndexOutOfBoundsException
-     * will be thrown, because in that case no valid index can be specified.</p>
-     *
-     * <pre>
-     * ArrayUtils.remove([1], 0)         = []
-     * ArrayUtils.remove([2, 6], 0)      = [6]
-     * ArrayUtils.remove([2, 6], 1)      = [2]
-     * ArrayUtils.remove([2, 6, 3], 1)   = [2, 3]
-     * </pre>
-     *
-     * @param array  the array to remove the element from, may not be {@code null}
-     * @param index  the position of the element to be removed
-     * @return A new array containing the existing elements except the element
-     *         at the specified position.
-     * @throws IndexOutOfBoundsException if the index is out of range
-     * (index < 0 || index >= array.length), or if the array is {@code null}.
-     * @since 2.1
-     */
-    public static short[] remove(short[] array, int index) {
-        return (short[]) remove((Object) array, index);
-    }
-
-    /**
-     * <p>Removes the first occurrence of the specified element from the
-     * specified array. All subsequent elements are shifted to the left
-     * (subtracts one from their indices). If the array doesn't contains
-     * such an element, no elements are removed from the array.</p>
-     *
-     * <p>This method returns a new array with the same elements of the input
-     * array except the first occurrence of the specified element. The component
-     * type of the returned array is always the same as that of the input
-     * array.</p>
-     *
-     * <pre>
-     * ArrayUtils.removeElement(null, 1)      = null
-     * ArrayUtils.removeElement([], 1)        = []
-     * ArrayUtils.removeElement([1], 2)       = [1]
-     * ArrayUtils.removeElement([1, 3], 1)    = [3]
-     * ArrayUtils.removeElement([1, 3, 1], 1) = [3, 1]
-     * </pre>
-     *
-     * @param array  the array to remove the element from, may be {@code null}
-     * @param element  the element to be removed
-     * @return A new array containing the existing elements except the first
-     *         occurrence of the specified element.
-     * @since 2.1
-     */
-    public static short[] removeElement(short[] array, short element) {
-        int index = indexOf(array, element);
-        if (index == INDEX_NOT_FOUND) {
-            return clone(array);
-        }
-        return remove(array, index);
-    }
-
-    /**
-     * <p>Removes the element at the specified position from the specified array.
-     * All subsequent elements are shifted to the left (subtracts one from
-     * their indices).</p>
-     *
-     * <p>This method returns a new array with the same elements of the input
-     * array except the element on the specified position. The component
-     * type of the returned array is always the same as that of the input
-     * array.</p>
-     *
-     * <p>If the input array is {@code null}, an IndexOutOfBoundsException
-     * will be thrown, because in that case no valid index can be specified.</p>
-     *
-     * @param array  the array to remove the element from, may not be {@code null}
-     * @param index  the position of the element to be removed
-     * @return A new array containing the existing elements except the element
-     *         at the specified position.
-     * @throws IndexOutOfBoundsException if the index is out of range
-     * (index < 0 || index >= array.length), or if the array is {@code null}.
-     * @since 2.1
-     */
-    private static Object remove(Object array, int index) {
-        int length = getLength(array);
-        if (index < 0 || index >= length) {
-            throw new IndexOutOfBoundsException("Index: " + index + ", Length: " + length);
-        }
-
-        Object result = Array.newInstance(array.getClass().getComponentType(), length - 1);
-        System.arraycopy(array, 0, result, 0, index);
-        if (index < length - 1) {
-            System.arraycopy(array, index + 1, result, index, length - index - 1);
-        }
-
-        return result;
-    }
-
-    /**
-     * <p>Removes the elements at the specified positions from the specified array.
-     * All remaining elements are shifted to the left.</p>
-     *
-     * <p>This method returns a new array with the same elements of the input
-     * array except those at the specified positions. The component
-     * type of the returned array is always the same as that of the input
-     * array.</p>
-     *
-     * <p>If the input array is {@code null}, an IndexOutOfBoundsException
-     * will be thrown, because in that case no valid index can be specified.</p>
-     *
-     * <pre>
-     * ArrayUtils.removeAll(["a", "b", "c"], 0, 2) = ["b"]
-     * ArrayUtils.removeAll(["a", "b", "c"], 1, 2) = ["a"]
-     * </pre>
-     *
-     * @param <T> the component type of the array
-     * @param array   the array to remove the element from, may not be {@code null}
-     * @param indices the positions of the elements to be removed
-     * @return A new array containing the existing elements except those
-     *         at the specified positions.
-     * @throws IndexOutOfBoundsException if any index is out of range
-     * (index < 0 || index >= array.length), or if the array is {@code null}.
-     * @since 3.0.1
-     */
-    @SuppressWarnings("unchecked")
-    // removeAll() always creates an array of the same type as its input
-    public static <T> T[] removeAll(T[] array, int... indices) {
-        return (T[]) removeAll((Object) array, clone(indices));
-    }
-
-    /**
-     * <p>Removes occurrences of specified elements, in specified quantities,
-     * from the specified array. All subsequent elements are shifted left.
-     * For any element-to-be-removed specified in greater quantities than
-     * contained in the original array, no change occurs beyond the
-     * removal of the existing matching items.</p>
-     *
-     * <p>This method returns a new array with the same elements of the input
-     * array except for the earliest-encountered occurrences of the specified
-     * elements. The component type of the returned array is always the same
-     * as that of the input array.</p>
-     *
-     * <pre>
-     * ArrayUtils.removeElements(null, "a", "b")            = null
-     * ArrayUtils.removeElements([], "a", "b")              = []
-     * ArrayUtils.removeElements(["a"], "b", "c")           = ["a"]
-     * ArrayUtils.removeElements(["a", "b"], "a", "c")      = ["b"]
-     * ArrayUtils.removeElements(["a", "b", "a"], "a")      = ["b", "a"]
-     * ArrayUtils.removeElements(["a", "b", "a"], "a", "a") = ["b"]
-     * </pre>
-     *
-     * @param <T> the component type of the array
-     * @param array  the array to remove the element from, may be {@code null}
-     * @param values the elements to be removed
-     * @return A new array containing the existing elements except the
-     *         earliest-encountered occurrences of the specified elements.
-     * @since 3.0.1
-     */
-    public static <T> T[] removeElements(T[] array, T... values) {
-        if (isEmpty(array) || isEmpty(values)) {
-            return clone(array);
-        }
-        HashMap<T, MutableInt> occurrences = new HashMap<T, MutableInt>(values.length);
-        for (T v : values) {
-            MutableInt count = occurrences.get(v);
-            if (count == null) {
-                occurrences.put(v, new MutableInt(1));
-            } else {
-                count.increment();
-            }
-        }
-        HashSet<Integer> toRemove = new HashSet<Integer>();
-        for (Map.Entry<T, MutableInt> e : occurrences.entrySet()) {
-            T v = e.getKey();
-            int found = 0;
-            for (int i = 0, ct = e.getValue().intValue(); i < ct; i++) {
-                found = indexOf(array, v, found);
-                if (found < 0) {
-                    break;
-                }
-                toRemove.add(found++);
-            }
-        }
-        return removeAll(array, extractIndices(toRemove));
-    }
-
-    /**
-     * <p>Removes the elements at the specified positions from the specified array.
-     * All remaining elements are shifted to the left.</p>
-     *
-     * <p>This method returns a new array with the same elements of the input
-     * array except those at the specified positions. The component
-     * type of the returned array is always the same as that of the input
-     * array.</p>
-     *
-     * <p>If the input array is {@code null}, an IndexOutOfBoundsException
-     * will be thrown, because in that case no valid index can be specified.</p>
-     *
-     * <pre>
-     * ArrayUtils.removeAll([1], 0)             = []
-     * ArrayUtils.removeAll([2, 6], 0)          = [6]
-     * ArrayUtils.removeAll([2, 6], 0, 1)       = []
-     * ArrayUtils.removeAll([2, 6, 3], 1, 2)    = [2]
-     * ArrayUtils.removeAll([2, 6, 3], 0, 2)    = [6]
-     * ArrayUtils.removeAll([2, 6, 3], 0, 1, 2) = []
-     * </pre>
-     *
-     * @param array   the array to remove the element from, may not be {@code null}
-     * @param indices the positions of the elements to be removed
-     * @return A new array containing the existing elements except those
-     *         at the specified positions.
-     * @throws IndexOutOfBoundsException if any index is out of range
-     * (index < 0 || index >= array.length), or if the array is {@code null}.
-     * @since 3.0.1
-     */
-    public static byte[] removeAll(byte[] array, int... indices) {
-        return (byte[]) removeAll((Object) array, clone(indices));
-    }
-
-    /**
-     * <p>Removes occurrences of specified elements, in specified quantities,
-     * from the specified array. All subsequent elements are shifted left.
-     * For any element-to-be-removed specified in greater quantities than
-     * contained in the original array, no change occurs beyond the
-     * removal of the existing matching items.</p>
-     *
-     * <p>This method returns a new array with the same elements of the input
-     * array except for the earliest-encountered occurrences of the specified
-     * elements. The component type of the returned array is always the same
-     * as that of the input array.</p>
-     *
-     * <pre>
-     * ArrayUtils.removeElements(null, 1, 2)      = null
-     * ArrayUtils.removeElements([], 1, 2)        = []
-     * ArrayUtils.removeElements([1], 2, 3)       = [1]
-     * ArrayUtils.removeElements([1, 3], 1, 2)    = [3]
-     * ArrayUtils.removeElements([1, 3, 1], 1)    = [3, 1]
-     * ArrayUtils.removeElements([1, 3, 1], 1, 1) = [3]
-     * </pre>
-     *
-     * @param array  the array to remove the element from, may be {@code null}
-     * @param values the elements to be removed
-     * @return A new array containing the existing elements except the
-     *         earliest-encountered occurrences of the specified elements.
-     * @since 3.0.1
-     */
-    public static byte[] removeElements(byte[] array, byte... values) {
-        if (isEmpty(array) || isEmpty(values)) {
-            return clone(array);
-        }
-        HashMap<Byte, MutableInt> occurrences = new HashMap<Byte, MutableInt>(values.length);
-        for (byte v : values) {
-            Byte boxed = Byte.valueOf(v);
-            MutableInt count = occurrences.get(boxed);
-            if (count == null) {
-                occurrences.put(boxed, new MutableInt(1));
-            } else {
-                count.increment();
-            }
-        }
-        HashSet<Integer> toRemove = new HashSet<Integer>();
-        for (Map.Entry<Byte, MutableInt> e : occurrences.entrySet()) {
-            Byte v = e.getKey();
-            int found = 0;
-            for (int i = 0, ct = e.getValue().intValue(); i < ct; i++) {
-                found = indexOf(array, v.byteValue(), found);
-                if (found < 0) {
-                    break;
-                }
-                toRemove.add(found++);
-            }
-        }
-        return removeAll(array, extractIndices(toRemove));
-    }
-
-    /**
-     * <p>Removes the elements at the specified positions from the specified array.
-     * All remaining elements are shifted to the left.</p>
-     *
-     * <p>This method returns a new array with the same elements of the input
-     * array except those at the specified positions. The component
-     * type of the returned array is always the same as that of the input
-     * array.</p>
-     *
-     * <p>If the input array is {@code null}, an IndexOutOfBoundsException
-     * will be thrown, because in that case no valid index can be specified.</p>
-     *
-     * <pre>
-     * ArrayUtils.removeAll([1], 0)             = []
-     * ArrayUtils.removeAll([2, 6], 0)          = [6]
-     * ArrayUtils.removeAll([2, 6], 0, 1)       = []
-     * ArrayUtils.removeAll([2, 6, 3], 1, 2)    = [2]
-     * ArrayUtils.removeAll([2, 6, 3], 0, 2)    = [6]
-     * ArrayUtils.removeAll([2, 6, 3], 0, 1, 2) = []
-     * </pre>
-     *
-     * @param array   the array to remove the element from, may not be {@code null}
-     * @param indices the positions of the elements to be removed
-     * @return A new array containing the existing elements except those
-     *         at the specified positions.
-     * @throws IndexOutOfBoundsException if any index is out of range
-     * (index < 0 || index >= array.length), or if the array is {@code null}.
-     * @since 3.0.1
-     */
-    public static short[] removeAll(short[] array, int... indices) {
-        return (short[]) removeAll((Object) array, clone(indices));
-    }
-
-    /**
-     * <p>Removes occurrences of specified elements, in specified quantities,
-     * from the specified array. All subsequent elements are shifted left.
-     * For any element-to-be-removed specified in greater quantities than
-     * contained in the original array, no change occurs beyond the
-     * removal of the existing matching items.</p>
-     *
-     * <p>This method returns a new array with the same elements of the input
-     * array except for the earliest-encountered occurrences of the specified
-     * elements. The component type of the returned array is always the same
-     * as that of the input array.</p>
-     *
-     * <pre>
-     * ArrayUtils.removeElements(null, 1, 2)      = null
-     * ArrayUtils.removeElements([], 1, 2)        = []
-     * ArrayUtils.removeElements([1], 2, 3)       = [1]
-     * ArrayUtils.removeElements([1, 3], 1, 2)    = [3]
-     * ArrayUtils.removeElements([1, 3, 1], 1)    = [3, 1]
-     * ArrayUtils.removeElements([1, 3, 1], 1, 1) = [3]
-     * </pre>
-     *
-     * @param array  the array to remove the element from, may be {@code null}
-     * @param values the elements to be removed
-     * @return A new array containing the existing elements except the
-     *         earliest-encountered occurrences of the specified elements.
-     * @since 3.0.1
-     */
-    public static short[] removeElements(short[] array, short... values) {
-        if (isEmpty(array) || isEmpty(values)) {
-            return clone(array);
-        }
-        HashMap<Short, MutableInt> occurrences = new HashMap<Short, MutableInt>(values.length);
-        for (short v : values) {
-            Short boxed = Short.valueOf(v);
-            MutableInt count = occurrences.get(boxed);
-            if (count == null) {
-                occurrences.put(boxed, new MutableInt(1));
-            } else {
-                count.increment();
-            }
-        }
-        HashSet<Integer> toRemove = new HashSet<Integer>();
-        for (Map.Entry<Short, MutableInt> e : occurrences.entrySet()) {
-            Short v = e.getKey();
-            int found = 0;
-            for (int i = 0, ct = e.getValue().intValue(); i < ct; i++) {
-                found = indexOf(array, v.shortValue(), found);
-                if (found < 0) {
-                    break;
-                }
-                toRemove.add(found++);
-            }
-        }
-        return removeAll(array, extractIndices(toRemove));
-    }
-
-    /**
-     * <p>Removes the elements at the specified positions from the specified array.
-     * All remaining elements are shifted to the left.</p>
-     *
-     * <p>This method returns a new array with the same elements of the input
-     * array except those at the specified positions. The component
-     * type of the returned array is always the same as that of the input
-     * array.</p>
-     *
-     * <p>If the input array is {@code null}, an IndexOutOfBoundsException
-     * will be thrown, because in that case no valid index can be specified.</p>
-     *
-     * <pre>
-     * ArrayUtils.removeAll([1], 0)             = []
-     * ArrayUtils.removeAll([2, 6], 0)          = [6]
-     * ArrayUtils.removeAll([2, 6], 0, 1)       = []
-     * ArrayUtils.removeAll([2, 6, 3], 1, 2)    = [2]
-     * ArrayUtils.removeAll([2, 6, 3], 0, 2)    = [6]
-     * ArrayUtils.removeAll([2, 6, 3], 0, 1, 2) = []
-     * </pre>
-     *
-     * @param array   the array to remove the element from, may not be {@code null}
-     * @param indices the positions of the elements to be removed
-     * @return A new array containing the existing elements except those
-     *         at the specified positions.
-     * @throws IndexOutOfBoundsException if any index is out of range
-     * (index < 0 || index >= array.length), or if the array is {@code null}.
-     * @since 3.0.1
-     */
-    public static int[] removeAll(int[] array, int... indices) {
-        return (int[]) removeAll((Object) array, clone(indices));
-    }
-
-    /**
-     * <p>Removes occurrences of specified elements, in specified quantities,
-     * from the specified array. All subsequent elements are shifted left.
-     * For any element-to-be-removed specified in greater quantities than
-     * contained in the original array, no change occurs beyond the
-     * removal of the existing matching items.</p>
-     *
-     * <p>This method returns a new array with the same elements of the input
-     * array except for the earliest-encountered occurrences of the specified
-     * elements. The component type of the returned array is always the same
-     * as that of the input array.</p>
-     *
-     * <pre>
-     * ArrayUtils.removeElements(null, 1, 2)      = null
-     * ArrayUtils.removeElements([], 1, 2)        = []
-     * ArrayUtils.removeElements([1], 2, 3)       = [1]
-     * ArrayUtils.removeElements([1, 3], 1, 2)    = [3]
-     * ArrayUtils.removeElements([1, 3, 1], 1)    = [3, 1]
-     * ArrayUtils.removeElements([1, 3, 1], 1, 1) = [3]
-     * </pre>
-     *
-     * @param array  the array to remove the element from, may be {@code null}
-     * @param values the elements to be removed
-     * @return A new array containing the existing elements except the
-     *         earliest-encountered occurrences of the specified elements.
-     * @since 3.0.1
-     */
-    public static int[] removeElements(int[] array, int... values) {
-        if (isEmpty(array) || isEmpty(values)) {
-            return clone(array);
-        }
-        HashMap<Integer, MutableInt> occurrences = new HashMap<Integer, MutableInt>(values.length);
-        for (int v : values) {
-            Integer boxed = Integer.valueOf(v);
-            MutableInt count = occurrences.get(boxed);
-            if (count == null) {
-                occurrences.put(boxed, new MutableInt(1));
-            } else {
-                count.increment();
-            }
-        }
-        HashSet<Integer> toRemove = new HashSet<Integer>();
-        for (Map.Entry<Integer, MutableInt> e : occurrences.entrySet()) {
-            Integer v = e.getKey();
-            int found = 0;
-            for (int i = 0, ct = e.getValue().intValue(); i < ct; i++) {
-                found = indexOf(array, v.intValue(), found);
-                if (found < 0) {
-                    break;
-                }
-                toRemove.add(found++);
-            }
-        }
-        return removeAll(array, extractIndices(toRemove));
-    }
-
-    /**
-     * <p>Removes the elements at the specified positions from the specified array.
-     * All remaining elements are shifted to the left.</p>
-     *
-     * <p>This method returns a new array with the same elements of the input
-     * array except those at the specified positions. The component
-     * type of the returned array is always the same as that of the input
-     * array.</p>
-     *
-     * <p>If the input array is {@code null}, an IndexOutOfBoundsException
-     * will be thrown, because in that case no valid index can be specified.</p>
-     *
-     * <pre>
-     * ArrayUtils.removeAll([1], 0)             = []
-     * ArrayUtils.removeAll([2, 6], 0)          = [6]
-     * ArrayUtils.removeAll([2, 6], 0, 1)       = []
-     * ArrayUtils.removeAll([2, 6, 3], 1, 2)    = [2]
-     * ArrayUtils.removeAll([2, 6, 3], 0, 2)    = [6]
-     * ArrayUtils.removeAll([2, 6, 3], 0, 1, 2) = []
-     * </pre>
-     *
-     * @param array   the array to remove the element from, may not be {@code null}
-     * @param indices the positions of the elements to be removed
-     * @return A new array containing the existing elements except those
-     *         at the specified positions.
-     * @throws IndexOutOfBoundsException if any index is out of range
-     * (index < 0 || index >= array.length), or if the array is {@code null}.
-     * @since 3.0.1
-     */
-    public static char[] removeAll(char[] array, int... indices) {
-        return (char[]) removeAll((Object) array, clone(indices));
-    }
-
-    /**
-     * <p>Removes occurrences of specified elements, in specified quantities,
-     * from the specified array. All subsequent elements are shifted left.
-     * For any element-to-be-removed specified in greater quantities than
-     * contained in the original array, no change occurs beyond the
-     * removal of the existing matching items.</p>
-     *
-     * <p>This method returns a new array with the same elements of the input
-     * array except for the earliest-encountered occurrences of the specified
-     * elements. The component type of the returned array is always the same
-     * as that of the input array.</p>
-     *
-     * <pre>
-     * ArrayUtils.removeElements(null, 1, 2)      = null
-     * ArrayUtils.removeElements([], 1, 2)        = []
-     * ArrayUtils.removeElements([1], 2, 3)       = [1]
-     * ArrayUtils.removeElements([1, 3], 1, 2)    = [3]
-     * ArrayUtils.removeElements([1, 3, 1], 1)    = [3, 1]
-     * ArrayUtils.removeElements([1, 3, 1], 1, 1) = [3]
-     * </pre>
-     *
-     * @param array  the array to remove the element from, may be {@code null}
-     * @param values the elements to be removed
-     * @return A new array containing the existing elements except the
-     *         earliest-encountered occurrences of the specified elements.
-     * @since 3.0.1
-     */
-    public static char[] removeElements(char[] array, char... values) {
-        if (isEmpty(array) || isEmpty(values)) {
-            return clone(array);
-        }
-        HashMap<Character, MutableInt> occurrences = new HashMap<Character, MutableInt>(values.length);
-        for (char v : values) {
-            Character boxed = Character.valueOf(v);
-            MutableInt count = occurrences.get(boxed);
-            if (count == null) {
-                occurrences.put(boxed, new MutableInt(1));
-            } else {
-                count.increment();
-            }
-        }
-        HashSet<Integer> toRemove = new HashSet<Integer>();
-        for (Map.Entry<Character, MutableInt> e : occurrences.entrySet()) {
-            Character v = e.getKey();
-            int found = 0;
-            for (int i = 0, ct = e.getValue().intValue(); i < ct; i++) {
-                found = indexOf(array, v.charValue(), found);
-                if (found < 0) {
-                    break;
-                }
-                toRemove.add(found++);
-            }
-        }
-        return removeAll(array, extractIndices(toRemove));
-    }
-
-    /**
-     * <p>Removes the elements at the specified positions from the specified array.
-     * All remaining elements are shifted to the left.</p>
-     *
-     * <p>This method returns a new array with the same elements of the input
-     * array except those at the specified positions. The component
-     * type of the returned array is always the same as that of the input
-     * array.</p>
-     *
-     * <p>If the input array is {@code null}, an IndexOutOfBoundsException
-     * will be thrown, because in that case no valid index can be specified.</p>
-     *
-     * <pre>
-     * ArrayUtils.removeAll([1], 0)             = []
-     * ArrayUtils.removeAll([2, 6], 0)          = [6]
-     * ArrayUtils.removeAll([2, 6], 0, 1)       = []
-     * ArrayUtils.removeAll([2, 6, 3], 1, 2)    = [2]
-     * ArrayUtils.removeAll([2, 6, 3], 0, 2)    = [6]
-     * ArrayUtils.removeAll([2, 6, 3], 0, 1, 2) = []
-     * </pre>
-     *
-     * @param array   the array to remove the element from, may not be {@code null}
-     * @param indices the positions of the elements to be removed
-     * @return A new array containing the existing elements except those
-     *         at the specified positions.
-     * @throws IndexOutOfBoundsException if any index is out of range
-     * (index < 0 || index >= array.length), or if the array is {@code null}.
-     * @since 3.0.1
-     */
-    public static long[] removeAll(long[] array, int... indices) {
-        return (long[]) removeAll((Object) array, clone(indices));
-    }
-
-    /**
-     * <p>Removes occurrences of specified elements, in specified quantities,
-     * from the specified array. All subsequent elements are shifted left.
-     * For any element-to-be-removed specified in greater quantities than
-     * contained in the original array, no change occurs beyond the
-     * removal of the existing matching items.</p>
-     *
-     * <p>This method returns a new array with the same elements of the input
-     * array except for the earliest-encountered occurrences of the specified
-     * elements. The component type of the returned array is always the same
-     * as that of the input array.</p>
-     *
-     * <pre>
-     * ArrayUtils.removeElements(null, 1, 2)      = null
-     * ArrayUtils.removeElements([], 1, 2)        = []
-     * ArrayUtils.removeElements([1], 2, 3)       = [1]
-     * ArrayUtils.removeElements([1, 3], 1, 2)    = [3]
-     * ArrayUtils.removeElements([1, 3, 1], 1)    = [3, 1]
-     * ArrayUtils.removeElements([1, 3, 1], 1, 1) = [3]
-     * </pre>
-     *
-     * @param array  the array to remove the element from, may be {@code null}
-     * @param values the elements to be removed
-     * @return A new array containing the existing elements except the
-     *         earliest-encountered occurrences of the specified elements.
-     * @since 3.0.1
-     */
-    public static long[] removeElements(long[] array, long... values) {
-        if (isEmpty(array) || isEmpty(values)) {
-            return clone(array);
-        }
-        HashMap<Long, MutableInt> occurrences = new HashMap<Long, MutableInt>(values.length);
-        for (long v : values) {
-            Long boxed = Long.valueOf(v);
-            MutableInt count = occurrences.get(boxed);
-            if (count == null) {
-                occurrences.put(boxed, new MutableInt(1));
-            } else {
-                count.increment();
-            }
-        }
-        HashSet<Integer> toRemove = new HashSet<Integer>();
-        for (Map.Entry<Long, MutableInt> e : occurrences.entrySet()) {
-            Long v = e.getKey();
-            int found = 0;
-            for (int i = 0, ct = e.getValue().intValue(); i < ct; i++) {
-                found = indexOf(array, v.longValue(), found);
-                if (found < 0) {
-                    break;
-                }
-                toRemove.add(found++);
-            }
-        }
-        return removeAll(array, extractIndices(toRemove));
-    }
-
-    /**
-     * <p>Removes the elements at the specified positions from the specified array.
-     * All remaining elements are shifted to the left.</p>
-     *
-     * <p>This method returns a new array with the same elements of the input
-     * array except those at the specified positions. The component
-     * type of the returned array is always the same as that of the input
-     * array.</p>
-     *
-     * <p>If the input array is {@code null}, an IndexOutOfBoundsException
-     * will be thrown, because in that case no valid index can be specified.</p>
-     *
-     * <pre>
-     * ArrayUtils.removeAll([1], 0)             = []
-     * ArrayUtils.removeAll([2, 6], 0)          = [6]
-     * ArrayUtils.removeAll([2, 6], 0, 1)       = []
-     * ArrayUtils.removeAll([2, 6, 3], 1, 2)    = [2]
-     * ArrayUtils.removeAll([2, 6, 3], 0, 2)    = [6]
-     * ArrayUtils.removeAll([2, 6, 3], 0, 1, 2) = []
-     * </pre>
-     *
-     * @param array   the array to remove the element from, may not be {@code null}
-     * @param indices the positions of the elements to be removed
-     * @return A new array containing the existing elements except those
-     *         at the specified positions.
-     * @throws IndexOutOfBoundsException if any index is out of range
-     * (index < 0 || index >= array.length), or if the array is {@code null}.
-     * @since 3.0.1
-     */
-    public static float[] removeAll(float[] array, int... indices) {
-        return (float[]) removeAll((Object) array, clone(indices));
-    }
-
-    /**
-     * <p>Removes occurrences of specified elements, in specified quantities,
-     * from the specified array. All subsequent elements are shifted left.
-     * For any element-to-be-removed specified in greater quantities than
-     * contained in the original array, no change occurs beyond the
-     * removal of the existing matching items.</p>
-     *
-     * <p>This method returns a new array with the same elements of the input
-     * array except for the earliest-encountered occurrences of the specified
-     * elements. The component type of the returned array is always the same
-     * as that of the input array.</p>
-     *
-     * <pre>
-     * ArrayUtils.removeElements(null, 1, 2)      = null
-     * ArrayUtils.removeElements([], 1, 2)        = []
-     * ArrayUtils.removeElements([1], 2, 3)       = [1]
-     * ArrayUtils.removeElements([1, 3], 1, 2)    = [3]
-     * ArrayUtils.removeElements([1, 3, 1], 1)    = [3, 1]
-     * ArrayUtils.removeElements([1, 3, 1], 1, 1) = [3]
-     * </pre>
-     *
-     * @param array  the array to remove the element from, may be {@code null}
-     * @param values the elements to be removed
-     * @return A new array containing the existing elements except the
-     *         earliest-encountered occurrences of the specified elements.
-     * @since 3.0.1
-     */
-    public static float[] removeElements(float[] array, float... values) {
-        if (isEmpty(array) || isEmpty(values)) {
-            return clone(array);
-        }
-        HashMap<Float, MutableInt> occurrences = new HashMap<Float, MutableInt>(values.length);
-        for (float v : values) {
-            Float boxed = Float.valueOf(v);
-            MutableInt count = occurrences.get(boxed);
-            if (count == null) {
-                occurrences.put(boxed, new MutableInt(1));
-            } else {
-                count.increment();
-            }
-        }
-        HashSet<Integer> toRemove = new HashSet<Integer>();
-        for (Map.Entry<Float, MutableInt> e : occurrences.entrySet()) {
-            Float v = e.getKey();
-            int found = 0;
-            for (int i = 0, ct = e.getValue().intValue(); i < ct; i++) {
-                found = indexOf(array, v.floatValue(), found);
-                if (found < 0) {
-                    break;
-                }
-                toRemove.add(found++);
-            }
-        }
-        return removeAll(array, extractIndices(toRemove));
-    }
-
-    /**
-     * <p>Removes the elements at the specified positions from the specified array.
-     * All remaining elements are shifted to the left.</p>
-     *
-     * <p>This method returns a new array with the same elements of the input
-     * array except those at the specified positions. The component
-     * type of the returned array is always the same as that of the input
-     * array.</p>
-     *
-     * <p>If the input array is {@code null}, an IndexOutOfBoundsException
-     * will be thrown, because in that case no valid index can be specified.</p>
-     *
-     * <pre>
-     * ArrayUtils.removeAll([1], 0)             = []
-     * ArrayUtils.removeAll([2, 6], 0)          = [6]
-     * ArrayUtils.removeAll([2, 6], 0, 1)       = []
-     * ArrayUtils.removeAll([2, 6, 3], 1, 2)    = [2]
-     * ArrayUtils.removeAll([2, 6, 3], 0, 2)    = [6]
-     * ArrayUtils.removeAll([2, 6, 3], 0, 1, 2) = []
-     * </pre>
-     *
-     * @param array   the array to remove the element from, may not be {@code null}
-     * @param indices the positions of the elements to be removed
-     * @return A new array containing the existing elements except those
-     *         at the specified positions.
-     * @throws IndexOutOfBoundsException if any index is out of range
-     * (index < 0 || index >= array.length), or if the array is {@code null}.
-     * @since 3.0.1
-     */
-    public static double[] removeAll(double[] array, int... indices) {
-        return (double[]) removeAll((Object) array, clone(indices));
-    }
-
-    /**
-     * <p>Removes occurrences of specified elements, in specified quantities,
-     * from the specified array. All subsequent elements are shifted left.
-     * For any element-to-be-removed specified in greater quantities than
-     * contained in the original array, no change occurs beyond the
-     * removal of the existing matching items.</p>
-     *
-     * <p>This method returns a new array with the same elements of the input
-     * array except for the earliest-encountered occurrences of the specified
-     * elements. The component type of the returned array is always the same
-     * as that of the input array.</p>
-     *
-     * <pre>
-     * ArrayUtils.removeElements(null, 1, 2)      = null
-     * ArrayUtils.removeElements([], 1, 2)        = []
-     * ArrayUtils.removeElements([1], 2, 3)       = [1]
-     * ArrayUtils.removeElements([1, 3], 1, 2)    = [3]
-     * ArrayUtils.removeElements([1, 3, 1], 1)    = [3, 1]
-     * ArrayUtils.removeElements([1, 3, 1], 1, 1) = [3]
-     * </pre>
-     *
-     * @param array  the array to remove the element from, may be {@code null}
-     * @param values the elements to be removed
-     * @return A new array containing the existing elements except the
-     *         earliest-encountered occurrences of the specified elements.
-     * @since 3.0.1
-     */
-    public static double[] removeElements(double[] array, double... values) {
-        if (isEmpty(array) || isEmpty(values)) {
-            return clone(array);
-        }
-        HashMap<Double, MutableInt> occurrences = new HashMap<Double, MutableInt>(values.length);
-        for (double v : values) {
-            Double boxed = Double.valueOf(v);
-            MutableInt count = occurrences.get(boxed);
-            if (count == null) {
-                occurrences.put(boxed, new MutableInt(1));
-            } else {
-                count.increment();
-            }
-        }
-        HashSet<Integer> toRemove = new HashSet<Integer>();
-        for (Map.Entry<Double, MutableInt> e : occurrences.entrySet()) {
-            Double v = e.getKey();
-            int found = 0;
-            for (int i = 0, ct = e.getValue().intValue(); i < ct; i++) {
-                found = indexOf(array, v.doubleValue(), found);
-                if (found < 0) {
-                    break;
-                }
-                toRemove.add(found++);
-            }
-        }
-        return removeAll(array, extractIndices(toRemove));
-    }
-
-    /**
-     * <p>Removes the elements at the specified positions from the specified array.
-     * All remaining elements are shifted to the left.</p>
-     *
-     * <p>This method returns a new array with the same elements of the input
-     * array except those at the specified positions. The component
-     * type of the returned array is always the same as that of the input
-     * array.</p>
-     *
-     * <p>If the input array is {@code null}, an IndexOutOfBoundsException
-     * will be thrown, because in that case no valid index can be specified.</p>
-     *
-     * <pre>
-     * ArrayUtils.removeAll([true, false, true], 0, 2) = [false]
-     * ArrayUtils.removeAll([true, false, true], 1, 2) = [true]
-     * </pre>
-     *
-     * @param array   the array to remove the element from, may not be {@code null}
-     * @param indices the positions of the elements to be removed
-     * @return A new array containing the existing elements except those
-     *         at the specified positions.
-     * @throws IndexOutOfBoundsException if any index is out of range
-     * (index < 0 || index >= array.length), or if the array is {@code null}.
-     * @since 3.0.1
-     */
-    public static boolean[] removeAll(boolean[] array, int... indices) {
-        return (boolean[]) removeAll((Object) array, clone(indices));
-    }
-
-    /**
-     * <p>Removes occurrences of specified elements, in specified quantities,
-     * from the specified array. All subsequent elements are shifted left.
-     * For any element-to-be-removed specified in greater quantities than
-     * contained in the original array, no change occurs beyond the
-     * removal of the existing matching items.</p>
-     *
-     * <p>This method returns a new array with the same elements of the input
-     * array except for the earliest-encountered occurrences of the specified
-     * elements. The component type of the returned array is always the same
-     * as that of the input array.</p>
-     *
-     * <pre>
-     * ArrayUtils.removeElements(null, true, false)               = null
-     * ArrayUtils.removeElements([], true, false)                 = []
-     * ArrayUtils.removeElements([true], false, false)            = [true]
-     * ArrayUtils.removeElements([true, false], true, true)       = [false]
-     * ArrayUtils.removeElements([true, false, true], true)       = [false, true]
-     * ArrayUtils.removeElements([true, false, true], true, true) = [false]
-     * </pre>
-     *
-     * @param array  the array to remove the element from, may be {@code null}
-     * @param values the elements to be removed
-     * @return A new array containing the existing elements except the
-     *         earliest-encountered occurrences of the specified elements.
-     * @since 3.0.1
-     */
-    public static boolean[] removeElements(boolean[] array, boolean... values) {
-        if (isEmpty(array) || isEmpty(values)) {
-            return clone(array);
-        }
-        HashMap<Boolean, MutableInt> occurrences = new HashMap<Boolean, MutableInt>(values.length);
-        for (boolean v : values) {
-            Boolean boxed = Boolean.valueOf(v);
-            MutableInt count = occurrences.get(boxed);
-            if (count == null) {
-                occurrences.put(boxed, new MutableInt(1));
-            } else {
-                count.increment();
-            }
-        }
-        HashSet<Integer> toRemove = new HashSet<Integer>();
-        for (Map.Entry<Boolean, MutableInt> e : occurrences.entrySet()) {
-            Boolean v = e.getKey();
-            int found = 0;
-            for (int i = 0, ct = e.getValue().intValue(); i < ct; i++) {
-                found = indexOf(array, v.booleanValue(), found);
-                if (found < 0) {
-                    break;
-                }
-                toRemove.add(found++);
-            }
-        }
-        return removeAll(array, extractIndices(toRemove));
-    }
-
-    /**
-     * Removes multiple array elements specified by index.
-     * @param array source
-     * @param indices to remove, WILL BE SORTED--so only clones of user-owned arrays!
-     * @return new array of same type minus elements specified by unique values of {@code indices}
-     * @since 3.0.1
-     */
-    private static Object removeAll(Object array, int... indices) {
-        int length = getLength(array);
-        int diff = 0;
-
-        if (isNotEmpty(indices)) {
-            Arrays.sort(indices);
-
-            int i = indices.length;
-            int prevIndex = length;
-            while (--i >= 0) {
-                int index = indices[i];
-                if (index < 0 || index >= length) {
-                    throw new IndexOutOfBoundsException("Index: " + index + ", Length: " + length);
-                }
-                if (index >= prevIndex) {
-                    continue;
-                }
-                diff++;
-                prevIndex = index;
-            }
-        }
-        Object result = Array.newInstance(array.getClass().getComponentType(), length - diff);
-        if (diff < length) {
-            int end = length;
-            int dest = length - diff;
-            for (int i = indices.length - 1; i >= 0; i--) {
-                int index = indices[i];
-                if (end - index > 1) {
-                    int cp = end - index - 1;
-                    dest -= cp;
-                    System.arraycopy(array, index + 1, result, dest, cp);
-                }
-                end = index;
-            }
-            if (end > 0) {
-                System.arraycopy(array, 0, result, 0, end);
-            }
-        }
-        return result;
-    }
-
-    /**
-     * Extract a set of Integer indices into an int[].
-     * @param coll {@code HashSet} of {@code Integer}
-     * @return int[]
-     * @since 3.0.1
-     */
-    private static int[] extractIndices(HashSet<Integer> coll) {
-        int[] result = new int[coll.size()];
-        int i = 0;
-        for (Integer index : coll) {
-            result[i++] = index.intValue();
-        }
-        return result;
-    }
-}
diff --git a/compiler/java/com/google/dart/compiler/util/apache/CharSequenceUtils.java b/compiler/java/com/google/dart/compiler/util/apache/CharSequenceUtils.java
deleted file mode 100644
index 88a266e..0000000
--- a/compiler/java/com/google/dart/compiler/util/apache/CharSequenceUtils.java
+++ /dev/null
@@ -1,204 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-/*
- * 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 com.google.dart.compiler.util.apache;
-
-/**
- * <p>Operations on {@link java.lang.CharSequence} that are
- * {@code null} safe.</p>
- * <p>
- * NOTICE: This file is modified copy of its original Apache library.
- * It was moved to the different package, and changed to reduce number of dependencies.
- *
- * @see java.lang.CharSequence
- * @since 3.0
- * @version $Id: CharSequenceUtils.java 1199894 2011-11-09 17:53:59Z ggregory $
- */
-public class CharSequenceUtils {
-
-    /**
-     * <p>{@code CharSequenceUtils} instances should NOT be constructed in
-     * standard programming. </p>
-     *
-     * <p>This constructor is public to permit tools that require a JavaBean
-     * instance to operate.</p>
-     */
-    public CharSequenceUtils() {
-        super();
-    }
-
-    //-----------------------------------------------------------------------
-    /**
-     * <p>Returns a new {@code CharSequence} that is a subsequence of this
-     * sequence starting with the {@code char} value at the specified index.</p>
-     *
-     * <p>This provides the {@code CharSequence} equivalent to {@link String#substring(int)}.
-     * The length (in {@code char}) of the returned sequence is {@code length() - start},
-     * so if {@code start == end} then an empty sequence is returned.</p>
-     *
-     * @param cs  the specified subsequence, null returns null
-     * @param start  the start index, inclusive, valid
-     * @return a new subsequence, may be null
-     * @throws IndexOutOfBoundsException if {@code start} is negative or if 
-     *  {@code start} is greater than {@code length()}
-     */
-    public static CharSequence subSequence(CharSequence cs, int start) {
-        return cs == null ? null : cs.subSequence(start, cs.length());
-    }
-
-    //-----------------------------------------------------------------------
-    /**
-     * <p>Finds the first index in the {@code CharSequence} that matches the
-     * specified character.</p>
-     *
-     * @param cs  the {@code CharSequence} to be processed, not null
-     * @param searchChar  the char to be searched for
-     * @param start  the start index, negative starts at the string start
-     * @return the index where the search char was found, -1 if not found
-     */
-    static int indexOf(CharSequence cs, int searchChar, int start) {
-        if (cs instanceof String) {
-            return ((String) cs).indexOf(searchChar, start);
-        } else {
-            int sz = cs.length();
-            if (start < 0) {
-                start = 0;
-            }
-            for (int i = start; i < sz; i++) {
-                if (cs.charAt(i) == searchChar) {
-                    return i;
-                }
-            }
-            return -1;
-        }
-    }
-
-    /**
-     * Used by the indexOf(CharSequence methods) as a green implementation of indexOf.
-     *
-     * @param cs the {@code CharSequence} to be processed
-     * @param searchChar the {@code CharSequence} to be searched for
-     * @param start the start index
-     * @return the index where the search sequence was found
-     */
-    static int indexOf(CharSequence cs, CharSequence searchChar, int start) {
-        return cs.toString().indexOf(searchChar.toString(), start);
-//        if (cs instanceof String && searchChar instanceof String) {
-//            // TODO: Do we assume searchChar is usually relatively small;
-//            //       If so then calling toString() on it is better than reverting to
-//            //       the green implementation in the else block
-//            return ((String) cs).indexOf((String) searchChar, start);
-//        } else {
-//            // TODO: Implement rather than convert to String
-//            return cs.toString().indexOf(searchChar.toString(), start);
-//        }
-    }
-
-    /**
-     * <p>Finds the last index in the {@code CharSequence} that matches the
-     * specified character.</p>
-     *
-     * @param cs  the {@code CharSequence} to be processed
-     * @param searchChar  the char to be searched for
-     * @param start  the start index, negative returns -1, beyond length starts at end
-     * @return the index where the search char was found, -1 if not found
-     */
-    static int lastIndexOf(CharSequence cs, int searchChar, int start) {
-        if (cs instanceof String) {
-            return ((String) cs).lastIndexOf(searchChar, start);
-        } else {
-            int sz = cs.length();
-            if (start < 0) {
-                return -1;
-            }
-            if (start >= sz) {
-                start = sz - 1;
-            }
-            for (int i = start; i >= 0; --i) {
-                if (cs.charAt(i) == searchChar) {
-                    return i;
-                }
-            }
-            return -1;
-        }
-    }
-
-    /**
-     * Used by the lastIndexOf(CharSequence methods) as a green implementation of lastIndexOf
-     *
-     * @param cs the {@code CharSequence} to be processed
-     * @param searchChar the {@code CharSequence} to be searched for
-     * @param start the start index
-     * @return the index where the search sequence was found
-     */
-    static int lastIndexOf(CharSequence cs, CharSequence searchChar, int start) {
-        return cs.toString().lastIndexOf(searchChar.toString(), start);
-//        if (cs instanceof String && searchChar instanceof String) {
-//            // TODO: Do we assume searchChar is usually relatively small;
-//            //       If so then calling toString() on it is better than reverting to
-//            //       the green implementation in the else block
-//            return ((String) cs).lastIndexOf((String) searchChar, start);
-//        } else {
-//            // TODO: Implement rather than convert to String
-//            return cs.toString().lastIndexOf(searchChar.toString(), start);
-//        }
-    }
-
-    /**
-     * Green implementation of toCharArray.
-     *
-     * @param cs the {@code CharSequence} to be processed
-     * @return the resulting char array
-     */
-    static char[] toCharArray(CharSequence cs) {
-        if (cs instanceof String) {
-            return ((String) cs).toCharArray();
-        } else {
-            int sz = cs.length();
-            char[] array = new char[cs.length()];
-            for (int i = 0; i < sz; i++) {
-                array[i] = cs.charAt(i);
-            }
-            return array;
-        }
-    }
-
-    /**
-     * Green implementation of regionMatches.
-     *
-     * @param cs the {@code CharSequence} to be processed
-     * @param ignoreCase whether or not to be case insensitive
-     * @param thisStart the index to start on the {@code cs} CharSequence
-     * @param substring the {@code CharSequence} to be looked for
-     * @param start the index to start on the {@code substring} CharSequence
-     * @param length character length of the region
-     * @return whether the region matched
-     */
-    static boolean regionMatches(CharSequence cs, boolean ignoreCase, int thisStart,
-            CharSequence substring, int start, int length)    {
-        if (cs instanceof String && substring instanceof String) {
-            return ((String) cs).regionMatches(ignoreCase, thisStart, (String) substring, start, length);
-        } else {
-            // TODO: Implement rather than convert to String
-            return cs.toString().regionMatches(ignoreCase, thisStart, substring.toString(), start, length);
-        }
-    }
-
-}
diff --git a/compiler/java/com/google/dart/compiler/util/apache/CharUtils.java b/compiler/java/com/google/dart/compiler/util/apache/CharUtils.java
deleted file mode 100644
index 4e8ca5e..0000000
--- a/compiler/java/com/google/dart/compiler/util/apache/CharUtils.java
+++ /dev/null
@@ -1,546 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-/*
- * 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 com.google.dart.compiler.util.apache;
-
-/**
- * <p>Operations on char primitives and Character objects.</p>
- *
- * <p>This class tries to handle {@code null} input gracefully.
- * An exception will not be thrown for a {@code null} input.
- * Each method documents its behaviour in more detail.</p>
- * <p>
- * NOTICE: This file is modified copy of its original Apache library.
- * It was moved to the different package, and changed to reduce number of dependencies.
- * 
- * <p>#ThreadSafe#</p>
- * @since 2.1
- * @version $Id: CharUtils.java 1158279 2011-08-16 14:06:45Z ggregory $
- */
-public class CharUtils {
-    
-    private static final String[] CHAR_STRING_ARRAY = new String[128];
-    
-    /**
-     * {@code \u000a} linefeed LF ('\n').
-     * 
-     * @see <a href="http://java.sun.com/docs/books/jls/third_edition/html/lexical.html#101089">JLF: Escape Sequences
-     *      for Character and String Literals</a>
-     * @since 2.2
-     */
-    public static final char LF = '\n';
-
-    /**
-     * {@code \u000d} carriage return CR ('\r').
-     * 
-     * @see <a href="http://java.sun.com/docs/books/jls/third_edition/html/lexical.html#101089">JLF: Escape Sequences
-     *      for Character and String Literals</a>
-     * @since 2.2
-     */
-    public static final char CR = '\r';
-    
-
-    static {
-        for (char c = 0; c < CHAR_STRING_ARRAY.length; c++) {
-            CHAR_STRING_ARRAY[c] = String.valueOf(c);
-        }
-    }
-
-    /**
-     * <p>{@code CharUtils} instances should NOT be constructed in standard programming.
-     * Instead, the class should be used as {@code CharUtils.toString('c');}.</p>
-     *
-     * <p>This constructor is public to permit tools that require a JavaBean instance
-     * to operate.</p>
-     */
-    public CharUtils() {
-      super();
-    }
-
-    //-----------------------------------------------------------------------
-    /**
-     * <p>Converts the character to a Character.</p>
-     * 
-     * <p>For ASCII 7 bit characters, this uses a cache that will return the
-     * same Character object each time.</p>
-     *
-     * <pre>
-     *   CharUtils.toCharacterObject(' ')  = ' '
-     *   CharUtils.toCharacterObject('A')  = 'A'
-     * </pre>
-     *
-     * @deprecated Java 5 introduced {@link Character#valueOf(char)} which caches chars 0 through 127.
-     * @param ch  the character to convert
-     * @return a Character of the specified character
-     */
-    @Deprecated
-    public static Character toCharacterObject(char ch) {
-        return Character.valueOf(ch);
-    }
-    
-    /**
-     * <p>Converts the String to a Character using the first character, returning
-     * null for empty Strings.</p>
-     * 
-     * <p>For ASCII 7 bit characters, this uses a cache that will return the
-     * same Character object each time.</p>
-     * 
-     * <pre>
-     *   CharUtils.toCharacterObject(null) = null
-     *   CharUtils.toCharacterObject("")   = null
-     *   CharUtils.toCharacterObject("A")  = 'A'
-     *   CharUtils.toCharacterObject("BA") = 'B'
-     * </pre>
-     *
-     * @param str  the character to convert
-     * @return the Character value of the first letter of the String
-     */
-    public static Character toCharacterObject(String str) {
-        if (StringUtils.isEmpty(str)) {
-            return null;
-        }
-        return Character.valueOf(str.charAt(0));
-    }
-    
-    //-----------------------------------------------------------------------
-    /**
-     * <p>Converts the Character to a char throwing an exception for {@code null}.</p>
-     * 
-     * <pre>
-     *   CharUtils.toChar(' ')  = ' '
-     *   CharUtils.toChar('A')  = 'A'
-     *   CharUtils.toChar(null) throws IllegalArgumentException
-     * </pre>
-     *
-     * @param ch  the character to convert
-     * @return the char value of the Character
-     * @throws IllegalArgumentException if the Character is null
-     */
-    public static char toChar(Character ch) {
-        if (ch == null) {
-            throw new IllegalArgumentException("The Character must not be null");
-        }
-        return ch.charValue();
-    }
-    
-    /**
-     * <p>Converts the Character to a char handling {@code null}.</p>
-     * 
-     * <pre>
-     *   CharUtils.toChar(null, 'X') = 'X'
-     *   CharUtils.toChar(' ', 'X')  = ' '
-     *   CharUtils.toChar('A', 'X')  = 'A'
-     * </pre>
-     *
-     * @param ch  the character to convert
-     * @param defaultValue  the value to use if the  Character is null
-     * @return the char value of the Character or the default if null
-     */
-    public static char toChar(Character ch, char defaultValue) {
-        if (ch == null) {
-            return defaultValue;
-        }
-        return ch.charValue();
-    }
-    
-    //-----------------------------------------------------------------------
-    /**
-     * <p>Converts the String to a char using the first character, throwing
-     * an exception on empty Strings.</p>
-     * 
-     * <pre>
-     *   CharUtils.toChar("A")  = 'A'
-     *   CharUtils.toChar("BA") = 'B'
-     *   CharUtils.toChar(null) throws IllegalArgumentException
-     *   CharUtils.toChar("")   throws IllegalArgumentException
-     * </pre>
-     *
-     * @param str  the character to convert
-     * @return the char value of the first letter of the String
-     * @throws IllegalArgumentException if the String is empty
-     */
-    public static char toChar(String str) {
-        if (StringUtils.isEmpty(str)) {
-            throw new IllegalArgumentException("The String must not be empty");
-        }
-        return str.charAt(0);
-    }
-    
-    /**
-     * <p>Converts the String to a char using the first character, defaulting
-     * the value on empty Strings.</p>
-     * 
-     * <pre>
-     *   CharUtils.toChar(null, 'X') = 'X'
-     *   CharUtils.toChar("", 'X')   = 'X'
-     *   CharUtils.toChar("A", 'X')  = 'A'
-     *   CharUtils.toChar("BA", 'X') = 'B'
-     * </pre>
-     *
-     * @param str  the character to convert
-     * @param defaultValue  the value to use if the  Character is null
-     * @return the char value of the first letter of the String or the default if null
-     */
-    public static char toChar(String str, char defaultValue) {
-        if (StringUtils.isEmpty(str)) {
-            return defaultValue;
-        }
-        return str.charAt(0);
-    }
-    
-    //-----------------------------------------------------------------------
-    /**
-     * <p>Converts the character to the Integer it represents, throwing an
-     * exception if the character is not numeric.</p>
-     * 
-     * <p>This method coverts the char '1' to the int 1 and so on.</p>
-     *
-     * <pre>
-     *   CharUtils.toIntValue('3')  = 3
-     *   CharUtils.toIntValue('A')  throws IllegalArgumentException
-     * </pre>
-     *
-     * @param ch  the character to convert
-     * @return the int value of the character
-     * @throws IllegalArgumentException if the character is not ASCII numeric
-     */
-    public static int toIntValue(char ch) {
-        if (isAsciiNumeric(ch) == false) {
-            throw new IllegalArgumentException("The character " + ch + " is not in the range '0' - '9'");
-        }
-        return ch - 48;
-    }
-    
-    /**
-     * <p>Converts the character to the Integer it represents, throwing an
-     * exception if the character is not numeric.</p>
-     * 
-     * <p>This method coverts the char '1' to the int 1 and so on.</p>
-     *
-     * <pre>
-     *   CharUtils.toIntValue('3', -1)  = 3
-     *   CharUtils.toIntValue('A', -1)  = -1
-     * </pre>
-     *
-     * @param ch  the character to convert
-     * @param defaultValue  the default value to use if the character is not numeric
-     * @return the int value of the character
-     */
-    public static int toIntValue(char ch, int defaultValue) {
-        if (isAsciiNumeric(ch) == false) {
-            return defaultValue;
-        }
-        return ch - 48;
-    }
-    
-    /**
-     * <p>Converts the character to the Integer it represents, throwing an
-     * exception if the character is not numeric.</p>
-     * 
-     * <p>This method coverts the char '1' to the int 1 and so on.</p>
-     *
-     * <pre>
-     *   CharUtils.toIntValue('3')  = 3
-     *   CharUtils.toIntValue(null) throws IllegalArgumentException
-     *   CharUtils.toIntValue('A')  throws IllegalArgumentException
-     * </pre>
-     *
-     * @param ch  the character to convert, not null
-     * @return the int value of the character
-     * @throws IllegalArgumentException if the Character is not ASCII numeric or is null
-     */
-    public static int toIntValue(Character ch) {
-        if (ch == null) {
-            throw new IllegalArgumentException("The character must not be null");
-        }
-        return toIntValue(ch.charValue());
-    }
-    
-    /**
-     * <p>Converts the character to the Integer it represents, throwing an
-     * exception if the character is not numeric.</p>
-     * 
-     * <p>This method coverts the char '1' to the int 1 and so on.</p>
-     *
-     * <pre>
-     *   CharUtils.toIntValue(null, -1) = -1
-     *   CharUtils.toIntValue('3', -1)  = 3
-     *   CharUtils.toIntValue('A', -1)  = -1
-     * </pre>
-     *
-     * @param ch  the character to convert
-     * @param defaultValue  the default value to use if the character is not numeric
-     * @return the int value of the character
-     */
-    public static int toIntValue(Character ch, int defaultValue) {
-        if (ch == null) {
-            return defaultValue;
-        }
-        return toIntValue(ch.charValue(), defaultValue);
-    }
-    
-    //-----------------------------------------------------------------------
-    /**
-     * <p>Converts the character to a String that contains the one character.</p>
-     * 
-     * <p>For ASCII 7 bit characters, this uses a cache that will return the
-     * same String object each time.</p>
-     *
-     * <pre>
-     *   CharUtils.toString(' ')  = " "
-     *   CharUtils.toString('A')  = "A"
-     * </pre>
-     *
-     * @param ch  the character to convert
-     * @return a String containing the one specified character
-     */
-    public static String toString(char ch) {
-        if (ch < 128) {
-            return CHAR_STRING_ARRAY[ch];
-        }
-        return new String(new char[] {ch});
-    }
-    
-    /**
-     * <p>Converts the character to a String that contains the one character.</p>
-     * 
-     * <p>For ASCII 7 bit characters, this uses a cache that will return the
-     * same String object each time.</p>
-     * 
-     * <p>If {@code null} is passed in, {@code null} will be returned.</p>
-     *
-     * <pre>
-     *   CharUtils.toString(null) = null
-     *   CharUtils.toString(' ')  = " "
-     *   CharUtils.toString('A')  = "A"
-     * </pre>
-     *
-     * @param ch  the character to convert
-     * @return a String containing the one specified character
-     */
-    public static String toString(Character ch) {
-        if (ch == null) {
-            return null;
-        }
-        return toString(ch.charValue());
-    }
-    
-    //--------------------------------------------------------------------------
-    /**
-     * <p>Converts the string to the Unicode format '\u0020'.</p>
-     * 
-     * <p>This format is the Java source code format.</p>
-     *
-     * <pre>
-     *   CharUtils.unicodeEscaped(' ') = "\u0020"
-     *   CharUtils.unicodeEscaped('A') = "\u0041"
-     * </pre>
-     * 
-     * @param ch  the character to convert
-     * @return the escaped Unicode string
-     */
-    public static String unicodeEscaped(char ch) {
-        if (ch < 0x10) {
-            return "\\u000" + Integer.toHexString(ch);
-        } else if (ch < 0x100) {
-            return "\\u00" + Integer.toHexString(ch);
-        } else if (ch < 0x1000) {
-            return "\\u0" + Integer.toHexString(ch);
-        }
-        return "\\u" + Integer.toHexString(ch);
-    }
-    
-    /**
-     * <p>Converts the string to the Unicode format '\u0020'.</p>
-     * 
-     * <p>This format is the Java source code format.</p>
-     * 
-     * <p>If {@code null} is passed in, {@code null} will be returned.</p>
-     *
-     * <pre>
-     *   CharUtils.unicodeEscaped(null) = null
-     *   CharUtils.unicodeEscaped(' ')  = "\u0020"
-     *   CharUtils.unicodeEscaped('A')  = "\u0041"
-     * </pre>
-     * 
-     * @param ch  the character to convert, may be null
-     * @return the escaped Unicode string, null if null input
-     */
-    public static String unicodeEscaped(Character ch) {
-        if (ch == null) {
-            return null;
-        }
-        return unicodeEscaped(ch.charValue());
-    }
-    
-    //--------------------------------------------------------------------------
-    /**
-     * <p>Checks whether the character is ASCII 7 bit.</p>
-     *
-     * <pre>
-     *   CharUtils.isAscii('a')  = true
-     *   CharUtils.isAscii('A')  = true
-     *   CharUtils.isAscii('3')  = true
-     *   CharUtils.isAscii('-')  = true
-     *   CharUtils.isAscii('\n') = true
-     *   CharUtils.isAscii('&copy;') = false
-     * </pre>
-     * 
-     * @param ch  the character to check
-     * @return true if less than 128
-     */
-    public static boolean isAscii(char ch) {
-        return ch < 128;
-    }
-    
-    /**
-     * <p>Checks whether the character is ASCII 7 bit printable.</p>
-     *
-     * <pre>
-     *   CharUtils.isAsciiPrintable('a')  = true
-     *   CharUtils.isAsciiPrintable('A')  = true
-     *   CharUtils.isAsciiPrintable('3')  = true
-     *   CharUtils.isAsciiPrintable('-')  = true
-     *   CharUtils.isAsciiPrintable('\n') = false
-     *   CharUtils.isAsciiPrintable('&copy;') = false
-     * </pre>
-     * 
-     * @param ch  the character to check
-     * @return true if between 32 and 126 inclusive
-     */
-    public static boolean isAsciiPrintable(char ch) {
-        return ch >= 32 && ch < 127;
-    }
-    
-    /**
-     * <p>Checks whether the character is ASCII 7 bit control.</p>
-     *
-     * <pre>
-     *   CharUtils.isAsciiControl('a')  = false
-     *   CharUtils.isAsciiControl('A')  = false
-     *   CharUtils.isAsciiControl('3')  = false
-     *   CharUtils.isAsciiControl('-')  = false
-     *   CharUtils.isAsciiControl('\n') = true
-     *   CharUtils.isAsciiControl('&copy;') = false
-     * </pre>
-     * 
-     * @param ch  the character to check
-     * @return true if less than 32 or equals 127
-     */
-    public static boolean isAsciiControl(char ch) {
-        return ch < 32 || ch == 127;
-    }
-    
-    /**
-     * <p>Checks whether the character is ASCII 7 bit alphabetic.</p>
-     *
-     * <pre>
-     *   CharUtils.isAsciiAlpha('a')  = true
-     *   CharUtils.isAsciiAlpha('A')  = true
-     *   CharUtils.isAsciiAlpha('3')  = false
-     *   CharUtils.isAsciiAlpha('-')  = false
-     *   CharUtils.isAsciiAlpha('\n') = false
-     *   CharUtils.isAsciiAlpha('&copy;') = false
-     * </pre>
-     * 
-     * @param ch  the character to check
-     * @return true if between 65 and 90 or 97 and 122 inclusive
-     */
-    public static boolean isAsciiAlpha(char ch) {
-        return (ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z');
-    }
-    
-    /**
-     * <p>Checks whether the character is ASCII 7 bit alphabetic upper case.</p>
-     *
-     * <pre>
-     *   CharUtils.isAsciiAlphaUpper('a')  = false
-     *   CharUtils.isAsciiAlphaUpper('A')  = true
-     *   CharUtils.isAsciiAlphaUpper('3')  = false
-     *   CharUtils.isAsciiAlphaUpper('-')  = false
-     *   CharUtils.isAsciiAlphaUpper('\n') = false
-     *   CharUtils.isAsciiAlphaUpper('&copy;') = false
-     * </pre>
-     * 
-     * @param ch  the character to check
-     * @return true if between 65 and 90 inclusive
-     */
-    public static boolean isAsciiAlphaUpper(char ch) {
-        return ch >= 'A' && ch <= 'Z';
-    }
-    
-    /**
-     * <p>Checks whether the character is ASCII 7 bit alphabetic lower case.</p>
-     *
-     * <pre>
-     *   CharUtils.isAsciiAlphaLower('a')  = true
-     *   CharUtils.isAsciiAlphaLower('A')  = false
-     *   CharUtils.isAsciiAlphaLower('3')  = false
-     *   CharUtils.isAsciiAlphaLower('-')  = false
-     *   CharUtils.isAsciiAlphaLower('\n') = false
-     *   CharUtils.isAsciiAlphaLower('&copy;') = false
-     * </pre>
-     * 
-     * @param ch  the character to check
-     * @return true if between 97 and 122 inclusive
-     */
-    public static boolean isAsciiAlphaLower(char ch) {
-        return ch >= 'a' && ch <= 'z';
-    }
-    
-    /**
-     * <p>Checks whether the character is ASCII 7 bit numeric.</p>
-     *
-     * <pre>
-     *   CharUtils.isAsciiNumeric('a')  = false
-     *   CharUtils.isAsciiNumeric('A')  = false
-     *   CharUtils.isAsciiNumeric('3')  = true
-     *   CharUtils.isAsciiNumeric('-')  = false
-     *   CharUtils.isAsciiNumeric('\n') = false
-     *   CharUtils.isAsciiNumeric('&copy;') = false
-     * </pre>
-     * 
-     * @param ch  the character to check
-     * @return true if between 48 and 57 inclusive
-     */
-    public static boolean isAsciiNumeric(char ch) {
-        return ch >= '0' && ch <= '9';
-    }
-    
-    /**
-     * <p>Checks whether the character is ASCII 7 bit numeric.</p>
-     *
-     * <pre>
-     *   CharUtils.isAsciiAlphanumeric('a')  = true
-     *   CharUtils.isAsciiAlphanumeric('A')  = true
-     *   CharUtils.isAsciiAlphanumeric('3')  = true
-     *   CharUtils.isAsciiAlphanumeric('-')  = false
-     *   CharUtils.isAsciiAlphanumeric('\n') = false
-     *   CharUtils.isAsciiAlphanumeric('&copy;') = false
-     * </pre>
-     * 
-     * @param ch  the character to check
-     * @return true if between 48 and 57 or 65 and 90 or 97 and 122 inclusive
-     */
-    public static boolean isAsciiAlphanumeric(char ch) {
-        return (ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z') || (ch >= '0' && ch <= '9');
-    }
-    
-}
diff --git a/compiler/java/com/google/dart/compiler/util/apache/FileUtils.java b/compiler/java/com/google/dart/compiler/util/apache/FileUtils.java
deleted file mode 100644
index 88cb7b1..0000000
--- a/compiler/java/com/google/dart/compiler/util/apache/FileUtils.java
+++ /dev/null
@@ -1,64 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-/*
- * 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 com.google.dart.compiler.util.apache;
-
-import java.io.File;
-import java.net.URL;
-
-/**
- * General file manipulation utilities.
- * * <p>
- * NOTICE: This file is modified copy of its original Apache library.
- * It was moved to the different package, and changed to reduce number of dependencies.
- */
-public class FileUtils {
-  /**
-   * Convert from a <code>URL</code> to a <code>File</code>.
-   * <p>
-   * From version 1.1 this method will decode the URL.
-   * Syntax such as <code>file:///my%20docs/file.txt</code> will be
-   * correctly decoded to <code>/my docs/file.txt</code>. Starting with version
-   * 1.5, this method uses UTF-8 to decode percent-encoded octets to characters.
-   * Additionally, malformed percent-encoded octets are handled leniently by
-   * passing them through literally.
-   *
-   * @param url  the file URL to convert, <code>null</code> returns <code>null</code>
-   * @return the equivalent <code>File</code> object, or <code>null</code>
-   *  if the URL's protocol is not <code>file</code>
-   */
-  public static File toFile(URL url) {
-    if (url == null || !url.getProtocol().equals("file")) {
-      return null;
-    } else {
-      String filename = url.getFile().replace('/', File.separatorChar);
-      int pos = 0;
-      while ((pos = filename.indexOf('%', pos)) >= 0) {
-        if (pos + 2 < filename.length()) {
-          String hexStr = filename.substring(pos + 1, pos + 3);
-          char ch = (char) Integer.parseInt(hexStr, 16);
-          filename = filename.substring(0, pos) + ch + filename.substring(pos + 3);
-        }
-      }
-      return new File(filename);
-    }
-  }
-
-}
diff --git a/compiler/java/com/google/dart/compiler/util/apache/FilenameUtils.java b/compiler/java/com/google/dart/compiler/util/apache/FilenameUtils.java
deleted file mode 100644
index 31288d3..0000000
--- a/compiler/java/com/google/dart/compiler/util/apache/FilenameUtils.java
+++ /dev/null
@@ -1,1405 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-/*
- * 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 com.google.dart.compiler.util.apache;
-
-import java.io.File;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Stack;
-
-/**
- * General filename and filepath manipulation utilities.
- * <p>
- * When dealing with filenames you can hit problems when moving from a Windows
- * based development machine to a Unix based production machine.
- * This class aims to help avoid those problems.
- * <p>
- * <b>NOTE</b>: You may be able to avoid using this class entirely simply by
- * using JDK {@link java.io.File File} objects and the two argument constructor
- * {@link java.io.File#File(java.io.File, java.lang.String) File(File,String)}.
- * <p>
- * Most methods on this class are designed to work the same on both Unix and Windows.
- * Those that don't include 'System', 'Unix' or 'Windows' in their name.
- * <p>
- * Most methods recognise both separators (forward and back), and both
- * sets of prefixes. See the javadoc of each method for details.
- * <p>
- * This class defines six components within a filename
- * (example C:\dev\project\file.txt):
- * <ul>
- * <li>the prefix - C:\</li>
- * <li>the path - dev\project\</li>
- * <li>the full path - C:\dev\project\</li>
- * <li>the name - file.txt</li>
- * <li>the base name - file</li>
- * <li>the extension - txt</li>
- * </ul>
- * Note that this class works best if directory filenames end with a separator.
- * If you omit the last separator, it is impossible to determine if the filename
- * corresponds to a file or a directory. As a result, we have chosen to say
- * it corresponds to a file.
- * <p>
- * This class only supports Unix and Windows style names.
- * Prefixes are matched as follows:
- * <pre>
- * Windows:
- * a\b\c.txt           --> ""          --> relative
- * \a\b\c.txt          --> "\"         --> current drive absolute
- * C:a\b\c.txt         --> "C:"        --> drive relative
- * C:\a\b\c.txt        --> "C:\"       --> absolute
- * \\server\a\b\c.txt  --> "\\server\" --> UNC
- *
- * Unix:
- * a/b/c.txt           --> ""          --> relative
- * /a/b/c.txt          --> "/"         --> absolute
- * ~/a/b/c.txt         --> "~/"        --> current user
- * ~                   --> "~/"        --> current user (slash added)
- * ~user/a/b/c.txt     --> "~user/"    --> named user
- * ~user               --> "~user/"    --> named user (slash added)
- * </pre>
- * Both prefix styles are matched always, irrespective of the machine that you are
- * currently running on.
- * <p>
- * Origin of code: Excalibur, Alexandria, Tomcat, Commons-Utils.
- *
- * @version $Id: FilenameUtils.java 1307462 2012-03-30 15:13:11Z ggregory $
- * @since 1.1
- */
-public class FilenameUtils {
-
-    /**
-     * The extension separator character.
-     * @since 1.4
-     */
-    public static final char EXTENSION_SEPARATOR = '.';
-
-    /**
-     * The extension separator String.
-     * @since 1.4
-     */
-    public static final String EXTENSION_SEPARATOR_STR = Character.toString(EXTENSION_SEPARATOR);
-
-    /**
-     * The Unix separator character.
-     */
-    private static final char UNIX_SEPARATOR = '/';
-
-    /**
-     * The Windows separator character.
-     */
-    private static final char WINDOWS_SEPARATOR = '\\';
-
-    /**
-     * The system separator character.
-     */
-    private static final char SYSTEM_SEPARATOR = File.separatorChar;
-
-    /**
-     * The separator character that is the opposite of the system separator.
-     */
-    private static final char OTHER_SEPARATOR;
-    static {
-        if (isSystemWindows()) {
-            OTHER_SEPARATOR = UNIX_SEPARATOR;
-        } else {
-            OTHER_SEPARATOR = WINDOWS_SEPARATOR;
-        }
-    }
-
-    /**
-     * Instances should NOT be constructed in standard programming.
-     */
-    public FilenameUtils() {
-        super();
-    }
-
-    //-----------------------------------------------------------------------
-    /**
-     * Determines if Windows file system is in use.
-     * 
-     * @return true if the system is Windows
-     */
-    static boolean isSystemWindows() {
-        return SYSTEM_SEPARATOR == WINDOWS_SEPARATOR;
-    }
-
-    //-----------------------------------------------------------------------
-    /**
-     * Checks if the character is a separator.
-     * 
-     * @param ch  the character to check
-     * @return true if it is a separator character
-     */
-    private static boolean isSeparator(char ch) {
-        return ch == UNIX_SEPARATOR || ch == WINDOWS_SEPARATOR;
-    }
-
-    //-----------------------------------------------------------------------
-    /**
-     * Normalizes a path, removing double and single dot path steps.
-     * <p>
-     * This method normalizes a path to a standard format.
-     * The input may contain separators in either Unix or Windows format.
-     * The output will contain separators in the format of the system.
-     * <p>
-     * A trailing slash will be retained.
-     * A double slash will be merged to a single slash (but UNC names are handled).
-     * A single dot path segment will be removed.
-     * A double dot will cause that path segment and the one before to be removed.
-     * If the double dot has no parent path segment to work with, {@code null}
-     * is returned.
-     * <p>
-     * The output will be the same on both Unix and Windows except
-     * for the separator character.
-     * <pre>
-     * /foo//               -->   /foo/
-     * /foo/./              -->   /foo/
-     * /foo/../bar          -->   /bar
-     * /foo/../bar/         -->   /bar/
-     * /foo/../bar/../baz   -->   /baz
-     * //foo//./bar         -->   /foo/bar
-     * /../                 -->   null
-     * ../foo               -->   null
-     * foo/bar/..           -->   foo/
-     * foo/../../bar        -->   null
-     * foo/../bar           -->   bar
-     * //server/foo/../bar  -->   //server/bar
-     * //server/../bar      -->   null
-     * C:\foo\..\bar        -->   C:\bar
-     * C:\..\bar            -->   null
-     * ~/foo/../bar/        -->   ~/bar/
-     * ~/../bar             -->   null
-     * </pre>
-     * (Note the file separator returned will be correct for Windows/Unix)
-     *
-     * @param filename  the filename to normalize, null returns null
-     * @return the normalized filename, or null if invalid
-     */
-    public static String normalize(String filename) {
-        return doNormalize(filename, SYSTEM_SEPARATOR, true);
-    }
-    /**
-     * Normalizes a path, removing double and single dot path steps.
-     * <p>
-     * This method normalizes a path to a standard format.
-     * The input may contain separators in either Unix or Windows format.
-     * The output will contain separators in the format specified.
-     * <p>
-     * A trailing slash will be retained.
-     * A double slash will be merged to a single slash (but UNC names are handled).
-     * A single dot path segment will be removed.
-     * A double dot will cause that path segment and the one before to be removed.
-     * If the double dot has no parent path segment to work with, {@code null}
-     * is returned.
-     * <p>
-     * The output will be the same on both Unix and Windows except
-     * for the separator character.
-     * <pre>
-     * /foo//               -->   /foo/
-     * /foo/./              -->   /foo/
-     * /foo/../bar          -->   /bar
-     * /foo/../bar/         -->   /bar/
-     * /foo/../bar/../baz   -->   /baz
-     * //foo//./bar         -->   /foo/bar
-     * /../                 -->   null
-     * ../foo               -->   null
-     * foo/bar/..           -->   foo/
-     * foo/../../bar        -->   null
-     * foo/../bar           -->   bar
-     * //server/foo/../bar  -->   //server/bar
-     * //server/../bar      -->   null
-     * C:\foo\..\bar        -->   C:\bar
-     * C:\..\bar            -->   null
-     * ~/foo/../bar/        -->   ~/bar/
-     * ~/../bar             -->   null
-     * </pre>
-     * The output will be the same on both Unix and Windows including
-     * the separator character.
-     *
-     * @param filename  the filename to normalize, null returns null
-     * @param unixSeparator {@code true} if a unix separator should
-     * be used or {@code false} if a windows separator should be used.
-     * @return the normalized filename, or null if invalid
-     * @since 2.0
-     */
-    public static String normalize(String filename, boolean unixSeparator) {
-        char separator = unixSeparator ? UNIX_SEPARATOR : WINDOWS_SEPARATOR;
-        return doNormalize(filename, separator, true);
-    }
-
-    //-----------------------------------------------------------------------
-    /**
-     * Normalizes a path, removing double and single dot path steps,
-     * and removing any final directory separator.
-     * <p>
-     * This method normalizes a path to a standard format.
-     * The input may contain separators in either Unix or Windows format.
-     * The output will contain separators in the format of the system.
-     * <p>
-     * A trailing slash will be removed.
-     * A double slash will be merged to a single slash (but UNC names are handled).
-     * A single dot path segment will be removed.
-     * A double dot will cause that path segment and the one before to be removed.
-     * If the double dot has no parent path segment to work with, {@code null}
-     * is returned.
-     * <p>
-     * The output will be the same on both Unix and Windows except
-     * for the separator character.
-     * <pre>
-     * /foo//               -->   /foo
-     * /foo/./              -->   /foo
-     * /foo/../bar          -->   /bar
-     * /foo/../bar/         -->   /bar
-     * /foo/../bar/../baz   -->   /baz
-     * //foo//./bar         -->   /foo/bar
-     * /../                 -->   null
-     * ../foo               -->   null
-     * foo/bar/..           -->   foo
-     * foo/../../bar        -->   null
-     * foo/../bar           -->   bar
-     * //server/foo/../bar  -->   //server/bar
-     * //server/../bar      -->   null
-     * C:\foo\..\bar        -->   C:\bar
-     * C:\..\bar            -->   null
-     * ~/foo/../bar/        -->   ~/bar
-     * ~/../bar             -->   null
-     * </pre>
-     * (Note the file separator returned will be correct for Windows/Unix)
-     *
-     * @param filename  the filename to normalize, null returns null
-     * @return the normalized filename, or null if invalid
-     */
-    public static String normalizeNoEndSeparator(String filename) {
-        return doNormalize(filename, SYSTEM_SEPARATOR, false);
-    }
-
-    /**
-     * Normalizes a path, removing double and single dot path steps,
-     * and removing any final directory separator.
-     * <p>
-     * This method normalizes a path to a standard format.
-     * The input may contain separators in either Unix or Windows format.
-     * The output will contain separators in the format specified.
-     * <p>
-     * A trailing slash will be removed.
-     * A double slash will be merged to a single slash (but UNC names are handled).
-     * A single dot path segment will be removed.
-     * A double dot will cause that path segment and the one before to be removed.
-     * If the double dot has no parent path segment to work with, {@code null}
-     * is returned.
-     * <p>
-     * The output will be the same on both Unix and Windows including
-     * the separator character.
-     * <pre>
-     * /foo//               -->   /foo
-     * /foo/./              -->   /foo
-     * /foo/../bar          -->   /bar
-     * /foo/../bar/         -->   /bar
-     * /foo/../bar/../baz   -->   /baz
-     * //foo//./bar         -->   /foo/bar
-     * /../                 -->   null
-     * ../foo               -->   null
-     * foo/bar/..           -->   foo
-     * foo/../../bar        -->   null
-     * foo/../bar           -->   bar
-     * //server/foo/../bar  -->   //server/bar
-     * //server/../bar      -->   null
-     * C:\foo\..\bar        -->   C:\bar
-     * C:\..\bar            -->   null
-     * ~/foo/../bar/        -->   ~/bar
-     * ~/../bar             -->   null
-     * </pre>
-     *
-     * @param filename  the filename to normalize, null returns null
-     * @param unixSeparator {@code true} if a unix separator should
-     * be used or {@code false} if a windows separtor should be used.
-     * @return the normalized filename, or null if invalid
-     * @since 2.0
-     */
-    public static String normalizeNoEndSeparator(String filename, boolean unixSeparator) {
-         char separator = unixSeparator ? UNIX_SEPARATOR : WINDOWS_SEPARATOR;
-        return doNormalize(filename, separator, false);
-    }
-
-    /**
-     * Internal method to perform the normalization.
-     *
-     * @param filename  the filename
-     * @param separator The separator character to use
-     * @param keepSeparator  true to keep the final separator
-     * @return the normalized filename
-     */
-    private static String doNormalize(String filename, char separator, boolean keepSeparator) {
-        if (filename == null) {
-            return null;
-        }
-        int size = filename.length();
-        if (size == 0) {
-            return filename;
-        }
-        int prefix = getPrefixLength(filename);
-        if (prefix < 0) {
-            return null;
-        }
-        
-        char[] array = new char[size + 2];  // +1 for possible extra slash, +2 for arraycopy
-        filename.getChars(0, filename.length(), array, 0);
-        
-        // fix separators throughout
-        char otherSeparator = separator == SYSTEM_SEPARATOR ? OTHER_SEPARATOR : SYSTEM_SEPARATOR;
-        for (int i = 0; i < array.length; i++) {
-            if (array[i] == otherSeparator) {
-                array[i] = separator;
-            }
-        }
-        
-        // add extra separator on the end to simplify code below
-        boolean lastIsDirectory = true;
-        if (array[size - 1] != separator) {
-            array[size++] = separator;
-            lastIsDirectory = false;
-        }
-        
-        // adjoining slashes
-        for (int i = prefix + 1; i < size; i++) {
-            if (array[i] == separator && array[i - 1] == separator) {
-                System.arraycopy(array, i, array, i - 1, size - i);
-                size--;
-                i--;
-            }
-        }
-        
-        // dot slash
-        for (int i = prefix + 1; i < size; i++) {
-            if (array[i] == separator && array[i - 1] == '.' &&
-                    (i == prefix + 1 || array[i - 2] == separator)) {
-                if (i == size - 1) {
-                    lastIsDirectory = true;
-                }
-                System.arraycopy(array, i + 1, array, i - 1, size - i);
-                size -=2;
-                i--;
-            }
-        }
-        
-        // double dot slash
-        outer:
-        for (int i = prefix + 2; i < size; i++) {
-            if (array[i] == separator && array[i - 1] == '.' && array[i - 2] == '.' &&
-                    (i == prefix + 2 || array[i - 3] == separator)) {
-                if (i == prefix + 2) {
-                    return null;
-                }
-                if (i == size - 1) {
-                    lastIsDirectory = true;
-                }
-                int j;
-                for (j = i - 4 ; j >= prefix; j--) {
-                    if (array[j] == separator) {
-                        // remove b/../ from a/b/../c
-                        System.arraycopy(array, i + 1, array, j + 1, size - i);
-                        size -= i - j;
-                        i = j + 1;
-                        continue outer;
-                    }
-                }
-                // remove a/../ from a/../c
-                System.arraycopy(array, i + 1, array, prefix, size - i);
-                size -= i + 1 - prefix;
-                i = prefix + 1;
-            }
-        }
-        
-        if (size <= 0) {  // should never be less than 0
-            return "";
-        }
-        if (size <= prefix) {  // should never be less than prefix
-            return new String(array, 0, size);
-        }
-        if (lastIsDirectory && keepSeparator) {
-            return new String(array, 0, size);  // keep trailing separator
-        }
-        return new String(array, 0, size - 1);  // lose trailing separator
-    }
-
-    //-----------------------------------------------------------------------
-    /**
-     * Concatenates a filename to a base path using normal command line style rules.
-     * <p>
-     * The effect is equivalent to resultant directory after changing
-     * directory to the first argument, followed by changing directory to
-     * the second argument.
-     * <p>
-     * The first argument is the base path, the second is the path to concatenate.
-     * The returned path is always normalized via {@link #normalize(String)},
-     * thus <code>..</code> is handled.
-     * <p>
-     * If <code>pathToAdd</code> is absolute (has an absolute prefix), then
-     * it will be normalized and returned.
-     * Otherwise, the paths will be joined, normalized and returned.
-     * <p>
-     * The output will be the same on both Unix and Windows except
-     * for the separator character.
-     * <pre>
-     * /foo/ + bar          -->   /foo/bar
-     * /foo + bar           -->   /foo/bar
-     * /foo + /bar          -->   /bar
-     * /foo + C:/bar        -->   C:/bar
-     * /foo + C:bar         -->   C:bar (*)
-     * /foo/a/ + ../bar     -->   foo/bar
-     * /foo/ + ../../bar    -->   null
-     * /foo/ + /bar         -->   /bar
-     * /foo/.. + /bar       -->   /bar
-     * /foo + bar/c.txt     -->   /foo/bar/c.txt
-     * /foo/c.txt + bar     -->   /foo/c.txt/bar (!)
-     * </pre>
-     * (*) Note that the Windows relative drive prefix is unreliable when
-     * used with this method.
-     * (!) Note that the first parameter must be a path. If it ends with a name, then
-     * the name will be built into the concatenated path. If this might be a problem,
-     * use {@link #getFullPath(String)} on the base path argument.
-     *
-     * @param basePath  the base path to attach to, always treated as a path
-     * @param fullFilenameToAdd  the filename (or path) to attach to the base
-     * @return the concatenated path, or null if invalid
-     */
-    public static String concat(String basePath, String fullFilenameToAdd) {
-        int prefix = getPrefixLength(fullFilenameToAdd);
-        if (prefix < 0) {
-            return null;
-        }
-        if (prefix > 0) {
-            return normalize(fullFilenameToAdd);
-        }
-        if (basePath == null) {
-            return null;
-        }
-        int len = basePath.length();
-        if (len == 0) {
-            return normalize(fullFilenameToAdd);
-        }
-        char ch = basePath.charAt(len - 1);
-        if (isSeparator(ch)) {
-            return normalize(basePath + fullFilenameToAdd);
-        } else {
-            return normalize(basePath + '/' + fullFilenameToAdd);
-        }
-    }
-
-    /**
-     * Determines whether the {@code parent} directory contains the {@code child} element (a file or directory).
-     * <p>
-     * The files names are expected to be normalized.
-     * </p>
-     * 
-     * Edge cases:
-     * <ul>
-     * <li>A {@code directory} must not be null: if null, throw IllegalArgumentException</li>
-     * <li>A directory does not contain itself: return false</li>
-     * <li>A null child file is not contained in any parent: return false</li>
-     * </ul>
-     * 
-     * @param canonicalParent
-     *            the file to consider as the parent.
-     * @param canonicalChild
-     *            the file to consider as the child.
-     * @return true is the candidate leaf is under by the specified composite. False otherwise.
-     * @throws IOException
-     *             if an IO error occurs while checking the files.
-     * @since 2.2
-     * @see FileUtils#directoryContains(File, File)
-     */
-    public static boolean directoryContains(final String canonicalParent, final String canonicalChild)
-            throws IOException {
-
-        // Fail fast against NullPointerException
-        if (canonicalParent == null) {
-            throw new IllegalArgumentException("Directory must not be null");
-        }
-
-        if (canonicalChild == null) {
-            return false;
-        }
-
-        if (IOCase.SYSTEM.checkEquals(canonicalParent, canonicalChild)) {
-            return false;
-        }
-
-        return IOCase.SYSTEM.checkStartsWith(canonicalChild, canonicalParent);
-    }
-
-    //-----------------------------------------------------------------------
-    /**
-     * Converts all separators to the Unix separator of forward slash.
-     * 
-     * @param path  the path to be changed, null ignored
-     * @return the updated path
-     */
-    public static String separatorsToUnix(String path) {
-        if (path == null || path.indexOf(WINDOWS_SEPARATOR) == -1) {
-            return path;
-        }
-        return path.replace(WINDOWS_SEPARATOR, UNIX_SEPARATOR);
-    }
-
-    /**
-     * Converts all separators to the Windows separator of backslash.
-     * 
-     * @param path  the path to be changed, null ignored
-     * @return the updated path
-     */
-    public static String separatorsToWindows(String path) {
-        if (path == null || path.indexOf(UNIX_SEPARATOR) == -1) {
-            return path;
-        }
-        return path.replace(UNIX_SEPARATOR, WINDOWS_SEPARATOR);
-    }
-
-    /**
-     * Converts all separators to the system separator.
-     * 
-     * @param path  the path to be changed, null ignored
-     * @return the updated path
-     */
-    public static String separatorsToSystem(String path) {
-        if (path == null) {
-            return null;
-        }
-        if (isSystemWindows()) {
-            return separatorsToWindows(path);
-        } else {
-            return separatorsToUnix(path);
-        }
-    }
-
-    //-----------------------------------------------------------------------
-    /**
-     * Returns the length of the filename prefix, such as <code>C:/</code> or <code>~/</code>.
-     * <p>
-     * This method will handle a file in either Unix or Windows format.
-     * <p>
-     * The prefix length includes the first slash in the full filename
-     * if applicable. Thus, it is possible that the length returned is greater
-     * than the length of the input string.
-     * <pre>
-     * Windows:
-     * a\b\c.txt           --> ""          --> relative
-     * \a\b\c.txt          --> "\"         --> current drive absolute
-     * C:a\b\c.txt         --> "C:"        --> drive relative
-     * C:\a\b\c.txt        --> "C:\"       --> absolute
-     * \\server\a\b\c.txt  --> "\\server\" --> UNC
-     *
-     * Unix:
-     * a/b/c.txt           --> ""          --> relative
-     * /a/b/c.txt          --> "/"         --> absolute
-     * ~/a/b/c.txt         --> "~/"        --> current user
-     * ~                   --> "~/"        --> current user (slash added)
-     * ~user/a/b/c.txt     --> "~user/"    --> named user
-     * ~user               --> "~user/"    --> named user (slash added)
-     * </pre>
-     * <p>
-     * The output will be the same irrespective of the machine that the code is running on.
-     * ie. both Unix and Windows prefixes are matched regardless.
-     *
-     * @param filename  the filename to find the prefix in, null returns -1
-     * @return the length of the prefix, -1 if invalid or null
-     */
-    public static int getPrefixLength(String filename) {
-        if (filename == null) {
-            return -1;
-        }
-        int len = filename.length();
-        if (len == 0) {
-            return 0;
-        }
-        char ch0 = filename.charAt(0);
-        if (ch0 == ':') {
-            return -1;
-        }
-        if (len == 1) {
-            if (ch0 == '~') {
-                return 2;  // return a length greater than the input
-            }
-            return isSeparator(ch0) ? 1 : 0;
-        } else {
-            if (ch0 == '~') {
-                int posUnix = filename.indexOf(UNIX_SEPARATOR, 1);
-                int posWin = filename.indexOf(WINDOWS_SEPARATOR, 1);
-                if (posUnix == -1 && posWin == -1) {
-                    return len + 1;  // return a length greater than the input
-                }
-                posUnix = posUnix == -1 ? posWin : posUnix;
-                posWin = posWin == -1 ? posUnix : posWin;
-                return Math.min(posUnix, posWin) + 1;
-            }
-            char ch1 = filename.charAt(1);
-            if (ch1 == ':') {
-                ch0 = Character.toUpperCase(ch0);
-                if (ch0 >= 'A' && ch0 <= 'Z') {
-                    if (len == 2 || isSeparator(filename.charAt(2)) == false) {
-                        return 2;
-                    }
-                    return 3;
-                }
-                return -1;
-                
-            } else if (isSeparator(ch0) && isSeparator(ch1)) {
-                int posUnix = filename.indexOf(UNIX_SEPARATOR, 2);
-                int posWin = filename.indexOf(WINDOWS_SEPARATOR, 2);
-                if (posUnix == -1 && posWin == -1 || posUnix == 2 || posWin == 2) {
-                    return -1;
-                }
-                posUnix = posUnix == -1 ? posWin : posUnix;
-                posWin = posWin == -1 ? posUnix : posWin;
-                return Math.min(posUnix, posWin) + 1;
-            } else {
-                return isSeparator(ch0) ? 1 : 0;
-            }
-        }
-    }
-
-    /**
-     * Returns the index of the last directory separator character.
-     * <p>
-     * This method will handle a file in either Unix or Windows format.
-     * The position of the last forward or backslash is returned.
-     * <p>
-     * The output will be the same irrespective of the machine that the code is running on.
-     * 
-     * @param filename  the filename to find the last path separator in, null returns -1
-     * @return the index of the last separator character, or -1 if there
-     * is no such character
-     */
-    public static int indexOfLastSeparator(String filename) {
-        if (filename == null) {
-            return -1;
-        }
-        int lastUnixPos = filename.lastIndexOf(UNIX_SEPARATOR);
-        int lastWindowsPos = filename.lastIndexOf(WINDOWS_SEPARATOR);
-        return Math.max(lastUnixPos, lastWindowsPos);
-    }
-
-    /**
-     * Returns the index of the last extension separator character, which is a dot.
-     * <p>
-     * This method also checks that there is no directory separator after the last dot.
-     * To do this it uses {@link #indexOfLastSeparator(String)} which will
-     * handle a file in either Unix or Windows format.
-     * <p>
-     * The output will be the same irrespective of the machine that the code is running on.
-     * 
-     * @param filename  the filename to find the last path separator in, null returns -1
-     * @return the index of the last separator character, or -1 if there
-     * is no such character
-     */
-    public static int indexOfExtension(String filename) {
-        if (filename == null) {
-            return -1;
-        }
-        int extensionPos = filename.lastIndexOf(EXTENSION_SEPARATOR);
-        int lastSeparator = indexOfLastSeparator(filename);
-        return lastSeparator > extensionPos ? -1 : extensionPos;
-    }
-
-    //-----------------------------------------------------------------------
-    /**
-     * Gets the prefix from a full filename, such as <code>C:/</code>
-     * or <code>~/</code>.
-     * <p>
-     * This method will handle a file in either Unix or Windows format.
-     * The prefix includes the first slash in the full filename where applicable.
-     * <pre>
-     * Windows:
-     * a\b\c.txt           --> ""          --> relative
-     * \a\b\c.txt          --> "\"         --> current drive absolute
-     * C:a\b\c.txt         --> "C:"        --> drive relative
-     * C:\a\b\c.txt        --> "C:\"       --> absolute
-     * \\server\a\b\c.txt  --> "\\server\" --> UNC
-     *
-     * Unix:
-     * a/b/c.txt           --> ""          --> relative
-     * /a/b/c.txt          --> "/"         --> absolute
-     * ~/a/b/c.txt         --> "~/"        --> current user
-     * ~                   --> "~/"        --> current user (slash added)
-     * ~user/a/b/c.txt     --> "~user/"    --> named user
-     * ~user               --> "~user/"    --> named user (slash added)
-     * </pre>
-     * <p>
-     * The output will be the same irrespective of the machine that the code is running on.
-     * ie. both Unix and Windows prefixes are matched regardless.
-     *
-     * @param filename  the filename to query, null returns null
-     * @return the prefix of the file, null if invalid
-     */
-    public static String getPrefix(String filename) {
-        if (filename == null) {
-            return null;
-        }
-        int len = getPrefixLength(filename);
-        if (len < 0) {
-            return null;
-        }
-        if (len > filename.length()) {
-            return filename + UNIX_SEPARATOR;  // we know this only happens for unix
-        }
-        return filename.substring(0, len);
-    }
-
-    /**
-     * Gets the path from a full filename, which excludes the prefix.
-     * <p>
-     * This method will handle a file in either Unix or Windows format.
-     * The method is entirely text based, and returns the text before and
-     * including the last forward or backslash.
-     * <pre>
-     * C:\a\b\c.txt --> a\b\
-     * ~/a/b/c.txt  --> a/b/
-     * a.txt        --> ""
-     * a/b/c        --> a/b/
-     * a/b/c/       --> a/b/c/
-     * </pre>
-     * <p>
-     * The output will be the same irrespective of the machine that the code is running on.
-     * <p>
-     * This method drops the prefix from the result.
-     * See {@link #getFullPath(String)} for the method that retains the prefix.
-     *
-     * @param filename  the filename to query, null returns null
-     * @return the path of the file, an empty string if none exists, null if invalid
-     */
-    public static String getPath(String filename) {
-        return doGetPath(filename, 1);
-    }
-
-    /**
-     * Gets the path from a full filename, which excludes the prefix, and
-     * also excluding the final directory separator.
-     * <p>
-     * This method will handle a file in either Unix or Windows format.
-     * The method is entirely text based, and returns the text before the
-     * last forward or backslash.
-     * <pre>
-     * C:\a\b\c.txt --> a\b
-     * ~/a/b/c.txt  --> a/b
-     * a.txt        --> ""
-     * a/b/c        --> a/b
-     * a/b/c/       --> a/b/c
-     * </pre>
-     * <p>
-     * The output will be the same irrespective of the machine that the code is running on.
-     * <p>
-     * This method drops the prefix from the result.
-     * See {@link #getFullPathNoEndSeparator(String)} for the method that retains the prefix.
-     *
-     * @param filename  the filename to query, null returns null
-     * @return the path of the file, an empty string if none exists, null if invalid
-     */
-    public static String getPathNoEndSeparator(String filename) {
-        return doGetPath(filename, 0);
-    }
-
-    /**
-     * Does the work of getting the path.
-     * 
-     * @param filename  the filename
-     * @param separatorAdd  0 to omit the end separator, 1 to return it
-     * @return the path
-     */
-    private static String doGetPath(String filename, int separatorAdd) {
-        if (filename == null) {
-            return null;
-        }
-        int prefix = getPrefixLength(filename);
-        if (prefix < 0) {
-            return null;
-        }
-        int index = indexOfLastSeparator(filename);
-        int endIndex = index+separatorAdd;
-        if (prefix >= filename.length() || index < 0 || prefix >= endIndex) {
-            return "";
-        }
-        return filename.substring(prefix, endIndex);
-    }
-
-    /**
-     * Gets the full path from a full filename, which is the prefix + path.
-     * <p>
-     * This method will handle a file in either Unix or Windows format.
-     * The method is entirely text based, and returns the text before and
-     * including the last forward or backslash.
-     * <pre>
-     * C:\a\b\c.txt --> C:\a\b\
-     * ~/a/b/c.txt  --> ~/a/b/
-     * a.txt        --> ""
-     * a/b/c        --> a/b/
-     * a/b/c/       --> a/b/c/
-     * C:           --> C:
-     * C:\          --> C:\
-     * ~            --> ~/
-     * ~/           --> ~/
-     * ~user        --> ~user/
-     * ~user/       --> ~user/
-     * </pre>
-     * <p>
-     * The output will be the same irrespective of the machine that the code is running on.
-     *
-     * @param filename  the filename to query, null returns null
-     * @return the path of the file, an empty string if none exists, null if invalid
-     */
-    public static String getFullPath(String filename) {
-        return doGetFullPath(filename, true);
-    }
-
-    /**
-     * Gets the full path from a full filename, which is the prefix + path,
-     * and also excluding the final directory separator.
-     * <p>
-     * This method will handle a file in either Unix or Windows format.
-     * The method is entirely text based, and returns the text before the
-     * last forward or backslash.
-     * <pre>
-     * C:\a\b\c.txt --> C:\a\b
-     * ~/a/b/c.txt  --> ~/a/b
-     * a.txt        --> ""
-     * a/b/c        --> a/b
-     * a/b/c/       --> a/b/c
-     * C:           --> C:
-     * C:\          --> C:\
-     * ~            --> ~
-     * ~/           --> ~
-     * ~user        --> ~user
-     * ~user/       --> ~user
-     * </pre>
-     * <p>
-     * The output will be the same irrespective of the machine that the code is running on.
-     *
-     * @param filename  the filename to query, null returns null
-     * @return the path of the file, an empty string if none exists, null if invalid
-     */
-    public static String getFullPathNoEndSeparator(String filename) {
-        return doGetFullPath(filename, false);
-    }
-
-    /**
-     * Does the work of getting the path.
-     * 
-     * @param filename  the filename
-     * @param includeSeparator  true to include the end separator
-     * @return the path
-     */
-    private static String doGetFullPath(String filename, boolean includeSeparator) {
-        if (filename == null) {
-            return null;
-        }
-        int prefix = getPrefixLength(filename);
-        if (prefix < 0) {
-            return null;
-        }
-        if (prefix >= filename.length()) {
-            if (includeSeparator) {
-                return getPrefix(filename);  // add end slash if necessary
-            } else {
-                return filename;
-            }
-        }
-        int index = indexOfLastSeparator(filename);
-        if (index < 0) {
-            return filename.substring(0, prefix);
-        }
-        int end = index + (includeSeparator ?  1 : 0);
-        if (end == 0) {
-            end++;
-        }
-        return filename.substring(0, end);
-    }
-
-    /**
-     * Gets the name minus the path from a full filename.
-     * <p>
-     * This method will handle a file in either Unix or Windows format.
-     * The text after the last forward or backslash is returned.
-     * <pre>
-     * a/b/c.txt --> c.txt
-     * a.txt     --> a.txt
-     * a/b/c     --> c
-     * a/b/c/    --> ""
-     * </pre>
-     * <p>
-     * The output will be the same irrespective of the machine that the code is running on.
-     *
-     * @param filename  the filename to query, null returns null
-     * @return the name of the file without the path, or an empty string if none exists
-     */
-    public static String getName(String filename) {
-        if (filename == null) {
-            return null;
-        }
-        int index = indexOfLastSeparator(filename);
-        return filename.substring(index + 1);
-    }
-
-    /**
-     * Gets the base name, minus the full path and extension, from a full filename.
-     * <p>
-     * This method will handle a file in either Unix or Windows format.
-     * The text after the last forward or backslash and before the last dot is returned.
-     * <pre>
-     * a/b/c.txt --> c
-     * a.txt     --> a
-     * a/b/c     --> c
-     * a/b/c/    --> ""
-     * </pre>
-     * <p>
-     * The output will be the same irrespective of the machine that the code is running on.
-     *
-     * @param filename  the filename to query, null returns null
-     * @return the name of the file without the path, or an empty string if none exists
-     */
-    public static String getBaseName(String filename) {
-        return removeExtension(getName(filename));
-    }
-
-    /**
-     * Gets the extension of a filename.
-     * <p>
-     * This method returns the textual part of the filename after the last dot.
-     * There must be no directory separator after the dot.
-     * <pre>
-     * foo.txt      --> "txt"
-     * a/b/c.jpg    --> "jpg"
-     * a/b.txt/c    --> ""
-     * a/b/c        --> ""
-     * </pre>
-     * <p>
-     * The output will be the same irrespective of the machine that the code is running on.
-     *
-     * @param filename the filename to retrieve the extension of.
-     * @return the extension of the file or an empty string if none exists or {@code null}
-     * if the filename is {@code null}.
-     */
-    public static String getExtension(String filename) {
-        if (filename == null) {
-            return null;
-        }
-        int index = indexOfExtension(filename);
-        if (index == -1) {
-            return "";
-        } else {
-            return filename.substring(index + 1);
-        }
-    }
-
-    //-----------------------------------------------------------------------
-    /**
-     * Removes the extension from a filename.
-     * <p>
-     * This method returns the textual part of the filename before the last dot.
-     * There must be no directory separator after the dot.
-     * <pre>
-     * foo.txt    --> foo
-     * a\b\c.jpg  --> a\b\c
-     * a\b\c      --> a\b\c
-     * a.b\c      --> a.b\c
-     * </pre>
-     * <p>
-     * The output will be the same irrespective of the machine that the code is running on.
-     *
-     * @param filename  the filename to query, null returns null
-     * @return the filename minus the extension
-     */
-    public static String removeExtension(String filename) {
-        if (filename == null) {
-            return null;
-        }
-        int index = indexOfExtension(filename);
-        if (index == -1) {
-            return filename;
-        } else {
-            return filename.substring(0, index);
-        }
-    }
-
-    //-----------------------------------------------------------------------
-    /**
-     * Checks whether two filenames are equal exactly.
-     * <p>
-     * No processing is performed on the filenames other than comparison,
-     * thus this is merely a null-safe case-sensitive equals.
-     *
-     * @param filename1  the first filename to query, may be null
-     * @param filename2  the second filename to query, may be null
-     * @return true if the filenames are equal, null equals null
-     * @see IOCase#SENSITIVE
-     */
-    public static boolean equals(String filename1, String filename2) {
-        return equals(filename1, filename2, false, IOCase.SENSITIVE);
-    }
-
-    /**
-     * Checks whether two filenames are equal using the case rules of the system.
-     * <p>
-     * No processing is performed on the filenames other than comparison.
-     * The check is case-sensitive on Unix and case-insensitive on Windows.
-     *
-     * @param filename1  the first filename to query, may be null
-     * @param filename2  the second filename to query, may be null
-     * @return true if the filenames are equal, null equals null
-     * @see IOCase#SYSTEM
-     */
-    public static boolean equalsOnSystem(String filename1, String filename2) {
-        return equals(filename1, filename2, false, IOCase.SYSTEM);
-    }
-
-    //-----------------------------------------------------------------------
-    /**
-     * Checks whether two filenames are equal after both have been normalized.
-     * <p>
-     * Both filenames are first passed to {@link #normalize(String)}.
-     * The check is then performed in a case-sensitive manner.
-     *
-     * @param filename1  the first filename to query, may be null
-     * @param filename2  the second filename to query, may be null
-     * @return true if the filenames are equal, null equals null
-     * @see IOCase#SENSITIVE
-     */
-    public static boolean equalsNormalized(String filename1, String filename2) {
-        return equals(filename1, filename2, true, IOCase.SENSITIVE);
-    }
-
-    /**
-     * Checks whether two filenames are equal after both have been normalized
-     * and using the case rules of the system.
-     * <p>
-     * Both filenames are first passed to {@link #normalize(String)}.
-     * The check is then performed case-sensitive on Unix and
-     * case-insensitive on Windows.
-     *
-     * @param filename1  the first filename to query, may be null
-     * @param filename2  the second filename to query, may be null
-     * @return true if the filenames are equal, null equals null
-     * @see IOCase#SYSTEM
-     */
-    public static boolean equalsNormalizedOnSystem(String filename1, String filename2) {
-        return equals(filename1, filename2, true, IOCase.SYSTEM);
-    }
-
-    /**
-     * Checks whether two filenames are equal, optionally normalizing and providing
-     * control over the case-sensitivity.
-     *
-     * @param filename1  the first filename to query, may be null
-     * @param filename2  the second filename to query, may be null
-     * @param normalized  whether to normalize the filenames
-     * @param caseSensitivity  what case sensitivity rule to use, null means case-sensitive
-     * @return true if the filenames are equal, null equals null
-     * @since 1.3
-     */
-    public static boolean equals(
-            String filename1, String filename2,
-            boolean normalized, IOCase caseSensitivity) {
-        
-        if (filename1 == null || filename2 == null) {
-            return filename1 == null && filename2 == null;
-        }
-        if (normalized) {
-            filename1 = normalize(filename1);
-            filename2 = normalize(filename2);
-            if (filename1 == null || filename2 == null) {
-                throw new NullPointerException(
-                    "Error normalizing one or both of the file names");
-            }
-        }
-        if (caseSensitivity == null) {
-            caseSensitivity = IOCase.SENSITIVE;
-        }
-        return caseSensitivity.checkEquals(filename1, filename2);
-    }
-
-    //-----------------------------------------------------------------------
-    /**
-     * Checks whether the extension of the filename is that specified.
-     * <p>
-     * This method obtains the extension as the textual part of the filename
-     * after the last dot. There must be no directory separator after the dot.
-     * The extension check is case-sensitive on all platforms.
-     *
-     * @param filename  the filename to query, null returns false
-     * @param extension  the extension to check for, null or empty checks for no extension
-     * @return true if the filename has the specified extension
-     */
-    public static boolean isExtension(String filename, String extension) {
-        if (filename == null) {
-            return false;
-        }
-        if (extension == null || extension.length() == 0) {
-            return indexOfExtension(filename) == -1;
-        }
-        String fileExt = getExtension(filename);
-        return fileExt.equals(extension);
-    }
-
-    /**
-     * Checks whether the extension of the filename is one of those specified.
-     * <p>
-     * This method obtains the extension as the textual part of the filename
-     * after the last dot. There must be no directory separator after the dot.
-     * The extension check is case-sensitive on all platforms.
-     *
-     * @param filename  the filename to query, null returns false
-     * @param extensions  the extensions to check for, null checks for no extension
-     * @return true if the filename is one of the extensions
-     */
-    public static boolean isExtension(String filename, String[] extensions) {
-        if (filename == null) {
-            return false;
-        }
-        if (extensions == null || extensions.length == 0) {
-            return indexOfExtension(filename) == -1;
-        }
-        String fileExt = getExtension(filename);
-        for (String extension : extensions) {
-            if (fileExt.equals(extension)) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    /**
-     * Checks whether the extension of the filename is one of those specified.
-     * <p>
-     * This method obtains the extension as the textual part of the filename
-     * after the last dot. There must be no directory separator after the dot.
-     * The extension check is case-sensitive on all platforms.
-     *
-     * @param filename  the filename to query, null returns false
-     * @param extensions  the extensions to check for, null checks for no extension
-     * @return true if the filename is one of the extensions
-     */
-    public static boolean isExtension(String filename, Collection<String> extensions) {
-        if (filename == null) {
-            return false;
-        }
-        if (extensions == null || extensions.isEmpty()) {
-            return indexOfExtension(filename) == -1;
-        }
-        String fileExt = getExtension(filename);
-        for (String extension : extensions) {
-            if (fileExt.equals(extension)) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    //-----------------------------------------------------------------------
-    /**
-     * Checks a filename to see if it matches the specified wildcard matcher,
-     * always testing case-sensitive.
-     * <p>
-     * The wildcard matcher uses the characters '?' and '*' to represent a
-     * single or multiple (zero or more) wildcard characters.
-     * This is the same as often found on Dos/Unix command lines.
-     * The check is case-sensitive always.
-     * <pre>
-     * wildcardMatch("c.txt", "*.txt")      --> true
-     * wildcardMatch("c.txt", "*.jpg")      --> false
-     * wildcardMatch("a/b/c.txt", "a/b/*")  --> true
-     * wildcardMatch("c.txt", "*.???")      --> true
-     * wildcardMatch("c.txt", "*.????")     --> false
-     * </pre>
-     * N.B. the sequence "*?" does not work properly at present in match strings.
-     * 
-     * @param filename  the filename to match on
-     * @param wildcardMatcher  the wildcard string to match against
-     * @return true if the filename matches the wilcard string
-     * @see IOCase#SENSITIVE
-     */
-    public static boolean wildcardMatch(String filename, String wildcardMatcher) {
-        return wildcardMatch(filename, wildcardMatcher, IOCase.SENSITIVE);
-    }
-
-    /**
-     * Checks a filename to see if it matches the specified wildcard matcher
-     * using the case rules of the system.
-     * <p>
-     * The wildcard matcher uses the characters '?' and '*' to represent a
-     * single or multiple (zero or more) wildcard characters.
-     * This is the same as often found on Dos/Unix command lines.
-     * The check is case-sensitive on Unix and case-insensitive on Windows.
-     * <pre>
-     * wildcardMatch("c.txt", "*.txt")      --> true
-     * wildcardMatch("c.txt", "*.jpg")      --> false
-     * wildcardMatch("a/b/c.txt", "a/b/*")  --> true
-     * wildcardMatch("c.txt", "*.???")      --> true
-     * wildcardMatch("c.txt", "*.????")     --> false
-     * </pre>
-     * N.B. the sequence "*?" does not work properly at present in match strings.
-     * 
-     * @param filename  the filename to match on
-     * @param wildcardMatcher  the wildcard string to match against
-     * @return true if the filename matches the wilcard string
-     * @see IOCase#SYSTEM
-     */
-    public static boolean wildcardMatchOnSystem(String filename, String wildcardMatcher) {
-        return wildcardMatch(filename, wildcardMatcher, IOCase.SYSTEM);
-    }
-
-    /**
-     * Checks a filename to see if it matches the specified wildcard matcher
-     * allowing control over case-sensitivity.
-     * <p>
-     * The wildcard matcher uses the characters '?' and '*' to represent a
-     * single or multiple (zero or more) wildcard characters.
-     * N.B. the sequence "*?" does not work properly at present in match strings.
-     * 
-     * @param filename  the filename to match on
-     * @param wildcardMatcher  the wildcard string to match against
-     * @param caseSensitivity  what case sensitivity rule to use, null means case-sensitive
-     * @return true if the filename matches the wilcard string
-     * @since 1.3
-     */
-    public static boolean wildcardMatch(String filename, String wildcardMatcher, IOCase caseSensitivity) {
-        if (filename == null && wildcardMatcher == null) {
-            return true;
-        }
-        if (filename == null || wildcardMatcher == null) {
-            return false;
-        }
-        if (caseSensitivity == null) {
-            caseSensitivity = IOCase.SENSITIVE;
-        }
-        String[] wcs = splitOnTokens(wildcardMatcher);
-        boolean anyChars = false;
-        int textIdx = 0;
-        int wcsIdx = 0;
-        Stack<int[]> backtrack = new Stack<int[]>();
-        
-        // loop around a backtrack stack, to handle complex * matching
-        do {
-            if (backtrack.size() > 0) {
-                int[] array = backtrack.pop();
-                wcsIdx = array[0];
-                textIdx = array[1];
-                anyChars = true;
-            }
-            
-            // loop whilst tokens and text left to process
-            while (wcsIdx < wcs.length) {
-      
-                if (wcs[wcsIdx].equals("?")) {
-                    // ? so move to next text char
-                    textIdx++;
-                    if (textIdx > filename.length()) {
-                        break;
-                    }
-                    anyChars = false;
-                    
-                } else if (wcs[wcsIdx].equals("*")) {
-                    // set any chars status
-                    anyChars = true;
-                    if (wcsIdx == wcs.length - 1) {
-                        textIdx = filename.length();
-                    }
-                    
-                } else {
-                    // matching text token
-                    if (anyChars) {
-                        // any chars then try to locate text token
-                        textIdx = caseSensitivity.checkIndexOf(filename, textIdx, wcs[wcsIdx]);
-                        if (textIdx == -1) {
-                            // token not found
-                            break;
-                        }
-                        int repeat = caseSensitivity.checkIndexOf(filename, textIdx + 1, wcs[wcsIdx]);
-                        if (repeat >= 0) {
-                            backtrack.push(new int[] {wcsIdx, repeat});
-                        }
-                    } else {
-                        // matching from current position
-                        if (!caseSensitivity.checkRegionMatches(filename, textIdx, wcs[wcsIdx])) {
-                            // couldnt match token
-                            break;
-                        }
-                    }
-      
-                    // matched text token, move text index to end of matched token
-                    textIdx += wcs[wcsIdx].length();
-                    anyChars = false;
-                }
-      
-                wcsIdx++;
-            }
-            
-            // full match
-            if (wcsIdx == wcs.length && textIdx == filename.length()) {
-                return true;
-            }
-            
-        } while (backtrack.size() > 0);
-  
-        return false;
-    }
-
-    /**
-     * Splits a string into a number of tokens.
-     * The text is split by '?' and '*'.
-     * Where multiple '*' occur consecutively they are collapsed into a single '*'.
-     * 
-     * @param text  the text to split
-     * @return the array of tokens, never null
-     */
-    static String[] splitOnTokens(String text) {
-        // used by wildcardMatch
-        // package level so a unit test may run on this
-        
-        if (text.indexOf('?') == -1 && text.indexOf('*') == -1) {
-            return new String[] { text };
-        }
-
-        char[] array = text.toCharArray();
-        ArrayList<String> list = new ArrayList<String>();
-        StringBuilder buffer = new StringBuilder();
-        for (int i = 0; i < array.length; i++) {
-            if (array[i] == '?' || array[i] == '*') {
-                if (buffer.length() != 0) {
-                    list.add(buffer.toString());
-                    buffer.setLength(0);
-                }
-                if (array[i] == '?') {
-                    list.add("?");
-                } else if (list.isEmpty() ||
-                        i > 0 && list.get(list.size() - 1).equals("*") == false) {
-                    list.add("*");
-                }
-            } else {
-                buffer.append(array[i]);
-            }
-        }
-        if (buffer.length() != 0) {
-            list.add(buffer.toString());
-        }
-
-        return list.toArray( new String[ list.size() ] );
-    }
-
-}
diff --git a/compiler/java/com/google/dart/compiler/util/apache/IOCase.java b/compiler/java/com/google/dart/compiler/util/apache/IOCase.java
deleted file mode 100644
index f635bed..0000000
--- a/compiler/java/com/google/dart/compiler/util/apache/IOCase.java
+++ /dev/null
@@ -1,260 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-/*
- * 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 com.google.dart.compiler.util.apache;
-
-import java.io.Serializable;
-
-/**
- * Enumeration of IO case sensitivity.
- * <p>
- * Different filing systems have different rules for case-sensitivity.
- * Windows is case-insensitive, Unix is case-sensitive.
- * <p>
- * This class captures that difference, providing an enumeration to
- * control how filename comparisons should be performed. It also provides
- * methods that use the enumeration to perform comparisons.
- * <p>
- * Wherever possible, you should use the <code>check</code> methods in this
- * class to compare filenames.
- *
- * @version $Id: IOCase.java 1307459 2012-03-30 15:11:44Z ggregory $
- * @since 1.3
- */
-public final class IOCase implements Serializable {
-
-    /**
-     * The constant for case sensitive regardless of operating system.
-     */
-    public static final IOCase SENSITIVE = new IOCase("Sensitive", true);
-    
-    /**
-     * The constant for case insensitive regardless of operating system.
-     */
-    public static final IOCase INSENSITIVE = new IOCase("Insensitive", false);
-    
-    /**
-     * The constant for case sensitivity determined by the current operating system.
-     * Windows is case-insensitive when comparing filenames, Unix is case-sensitive.
-     * <p>
-     * <strong>Note:</strong> This only caters for Windows and Unix. Other operating
-     * systems (e.g. OSX and OpenVMS) are treated as case sensitive if they use the
-     * Unix file separator and case-insensitive if they use the Windows file separator
-     * (see {@link java.io.File#separatorChar}).
-     * <p>
-     * If you derialize this constant of Windows, and deserialize on Unix, or vice
-     * versa, then the value of the case-sensitivity flag will change.
-     */
-    public static final IOCase SYSTEM = new IOCase("System", !FilenameUtils.isSystemWindows());
-
-    /** Serialization version. */
-    private static final long serialVersionUID = -6343169151696340687L;
-
-    /** The enumeration name. */
-    private final String name;
-    
-    /** The sensitivity flag. */
-    private final transient boolean sensitive;
-
-    //-----------------------------------------------------------------------
-    /**
-     * Factory method to create an IOCase from a name.
-     * 
-     * @param name  the name to find
-     * @return the IOCase object
-     * @throws IllegalArgumentException if the name is invalid
-     */
-    public static IOCase forName(String name) {
-        if (IOCase.SENSITIVE.name.equals(name)){
-            return IOCase.SENSITIVE;
-        }
-        if (IOCase.INSENSITIVE.name.equals(name)){
-            return IOCase.INSENSITIVE;
-        }
-        if (IOCase.SYSTEM.name.equals(name)){
-            return IOCase.SYSTEM;
-        }
-        throw new IllegalArgumentException("Invalid IOCase name: " + name);
-    }
-
-    //-----------------------------------------------------------------------
-    /**
-     * Private constructor.
-     * 
-     * @param name  the name
-     * @param sensitive  the sensitivity
-     */
-    private IOCase(String name, boolean sensitive) {
-        this.name = name;
-        this.sensitive = sensitive;
-    }
-
-    /**
-     * Replaces the enumeration from the stream with a real one.
-     * This ensures that the correct flag is set for SYSTEM.
-     * 
-     * @return the resolved object
-     */
-    private Object readResolve() {
-        return forName(name);
-    }
-
-    //-----------------------------------------------------------------------
-    /**
-     * Gets the name of the constant.
-     * 
-     * @return the name of the constant
-     */
-    public String getName() {
-        return name;
-    }
-
-    /**
-     * Does the object represent case sensitive comparison.
-     * 
-     * @return true if case sensitive
-     */
-    public boolean isCaseSensitive() {
-        return sensitive;
-    }
-
-    //-----------------------------------------------------------------------
-    /**
-     * Compares two strings using the case-sensitivity rule.
-     * <p>
-     * This method mimics {@link String#compareTo} but takes case-sensitivity
-     * into account.
-     * 
-     * @param str1  the first string to compare, not null
-     * @param str2  the second string to compare, not null
-     * @return true if equal using the case rules
-     * @throws NullPointerException if either string is null
-     */
-    public int checkCompareTo(String str1, String str2) {
-        if (str1 == null || str2 == null) {
-            throw new NullPointerException("The strings must not be null");
-        }
-        return sensitive ? str1.compareTo(str2) : str1.compareToIgnoreCase(str2);
-    }
-
-    /**
-     * Compares two strings using the case-sensitivity rule.
-     * <p>
-     * This method mimics {@link String#equals} but takes case-sensitivity
-     * into account.
-     * 
-     * @param str1  the first string to compare, not null
-     * @param str2  the second string to compare, not null
-     * @return true if equal using the case rules
-     * @throws NullPointerException if either string is null
-     */
-    public boolean checkEquals(String str1, String str2) {
-        if (str1 == null || str2 == null) {
-            throw new NullPointerException("The strings must not be null");
-        }
-        return sensitive ? str1.equals(str2) : str1.equalsIgnoreCase(str2);
-    }
-
-    /**
-     * Checks if one string starts with another using the case-sensitivity rule.
-     * <p>
-     * This method mimics {@link String#startsWith(String)} but takes case-sensitivity
-     * into account.
-     * 
-     * @param str  the string to check, not null
-     * @param start  the start to compare against, not null
-     * @return true if equal using the case rules
-     * @throws NullPointerException if either string is null
-     */
-    public boolean checkStartsWith(String str, String start) {
-        return str.regionMatches(!sensitive, 0, start, 0, start.length());
-    }
-
-    /**
-     * Checks if one string ends with another using the case-sensitivity rule.
-     * <p>
-     * This method mimics {@link String#endsWith} but takes case-sensitivity
-     * into account.
-     * 
-     * @param str  the string to check, not null
-     * @param end  the end to compare against, not null
-     * @return true if equal using the case rules
-     * @throws NullPointerException if either string is null
-     */
-    public boolean checkEndsWith(String str, String end) {
-        int endLen = end.length();
-        return str.regionMatches(!sensitive, str.length() - endLen, end, 0, endLen);
-    }
-
-    /**
-     * Checks if one string contains another starting at a specific index using the
-     * case-sensitivity rule.
-     * <p>
-     * This method mimics parts of {@link String#indexOf(String, int)} 
-     * but takes case-sensitivity into account.
-     * 
-     * @param str  the string to check, not null
-     * @param strStartIndex  the index to start at in str
-     * @param search  the start to search for, not null
-     * @return the first index of the search String,
-     *  -1 if no match or {@code null} string input
-     * @throws NullPointerException if either string is null
-     * @since 2.0
-     */
-    public int checkIndexOf(String str, int strStartIndex, String search) {
-        int endIndex = str.length() - search.length();
-        if (endIndex >= strStartIndex) {
-            for (int i = strStartIndex; i <= endIndex; i++) {
-                if (checkRegionMatches(str, i, search)) {
-                    return i;
-                }
-            }
-        }
-        return -1;
-    }
-
-    /**
-     * Checks if one string contains another at a specific index using the case-sensitivity rule.
-     * <p>
-     * This method mimics parts of {@link String#regionMatches(boolean, int, String, int, int)} 
-     * but takes case-sensitivity into account.
-     * 
-     * @param str  the string to check, not null
-     * @param strStartIndex  the index to start at in str
-     * @param search  the start to search for, not null
-     * @return true if equal using the case rules
-     * @throws NullPointerException if either string is null
-     */
-    public boolean checkRegionMatches(String str, int strStartIndex, String search) {
-        return str.regionMatches(!sensitive, strStartIndex, search, 0, search.length());
-    }
-
-    //-----------------------------------------------------------------------
-    /**
-     * Gets a string describing the sensitivity.
-     * 
-     * @return a string describing the sensitivity
-     */
-    @Override
-    public String toString() {
-        return name;
-    }
-
-}
diff --git a/compiler/java/com/google/dart/compiler/util/apache/LICENSE.txt b/compiler/java/com/google/dart/compiler/util/apache/LICENSE.txt
deleted file mode 100644
index d645695..0000000
--- a/compiler/java/com/google/dart/compiler/util/apache/LICENSE.txt
+++ /dev/null
@@ -1,202 +0,0 @@
-
-                                 Apache License
-                           Version 2.0, January 2004
-                        http://www.apache.org/licenses/
-
-   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
-   1. Definitions.
-
-      "License" shall mean the terms and conditions for use, reproduction,
-      and distribution as defined by Sections 1 through 9 of this document.
-
-      "Licensor" shall mean the copyright owner or entity authorized by
-      the copyright owner that is granting the License.
-
-      "Legal Entity" shall mean the union of the acting entity and all
-      other entities that control, are controlled by, or are under common
-      control with that entity. For the purposes of this definition,
-      "control" means (i) the power, direct or indirect, to cause the
-      direction or management of such entity, whether by contract or
-      otherwise, or (ii) ownership of fifty percent (50%) or more of the
-      outstanding shares, or (iii) beneficial ownership of such entity.
-
-      "You" (or "Your") shall mean an individual or Legal Entity
-      exercising permissions granted by this License.
-
-      "Source" form shall mean the preferred form for making modifications,
-      including but not limited to software source code, documentation
-      source, and configuration files.
-
-      "Object" form shall mean any form resulting from mechanical
-      transformation or translation of a Source form, including but
-      not limited to compiled object code, generated documentation,
-      and conversions to other media types.
-
-      "Work" shall mean the work of authorship, whether in Source or
-      Object form, made available under the License, as indicated by a
-      copyright notice that is included in or attached to the work
-      (an example is provided in the Appendix below).
-
-      "Derivative Works" shall mean any work, whether in Source or Object
-      form, that is based on (or derived from) the Work and for which the
-      editorial revisions, annotations, elaborations, or other modifications
-      represent, as a whole, an original work of authorship. For the purposes
-      of this License, Derivative Works shall not include works that remain
-      separable from, or merely link (or bind by name) to the interfaces of,
-      the Work and Derivative Works thereof.
-
-      "Contribution" shall mean any work of authorship, including
-      the original version of the Work and any modifications or additions
-      to that Work or Derivative Works thereof, that is intentionally
-      submitted to Licensor for inclusion in the Work by the copyright owner
-      or by an individual or Legal Entity authorized to submit on behalf of
-      the copyright owner. For the purposes of this definition, "submitted"
-      means any form of electronic, verbal, or written communication sent
-      to the Licensor or its representatives, including but not limited to
-      communication on electronic mailing lists, source code control systems,
-      and issue tracking systems that are managed by, or on behalf of, the
-      Licensor for the purpose of discussing and improving the Work, but
-      excluding communication that is conspicuously marked or otherwise
-      designated in writing by the copyright owner as "Not a Contribution."
-
-      "Contributor" shall mean Licensor and any individual or Legal Entity
-      on behalf of whom a Contribution has been received by Licensor and
-      subsequently incorporated within the Work.
-
-   2. Grant of Copyright License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      copyright license to reproduce, prepare Derivative Works of,
-      publicly display, publicly perform, sublicense, and distribute the
-      Work and such Derivative Works in Source or Object form.
-
-   3. Grant of Patent License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      (except as stated in this section) patent license to make, have made,
-      use, offer to sell, sell, import, and otherwise transfer the Work,
-      where such license applies only to those patent claims licensable
-      by such Contributor that are necessarily infringed by their
-      Contribution(s) alone or by combination of their Contribution(s)
-      with the Work to which such Contribution(s) was submitted. If You
-      institute patent litigation against any entity (including a
-      cross-claim or counterclaim in a lawsuit) alleging that the Work
-      or a Contribution incorporated within the Work constitutes direct
-      or contributory patent infringement, then any patent licenses
-      granted to You under this License for that Work shall terminate
-      as of the date such litigation is filed.
-
-   4. Redistribution. You may reproduce and distribute copies of the
-      Work or Derivative Works thereof in any medium, with or without
-      modifications, and in Source or Object form, provided that You
-      meet the following conditions:
-
-      (a) You must give any other recipients of the Work or
-          Derivative Works a copy of this License; and
-
-      (b) You must cause any modified files to carry prominent notices
-          stating that You changed the files; and
-
-      (c) You must retain, in the Source form of any Derivative Works
-          that You distribute, all copyright, patent, trademark, and
-          attribution notices from the Source form of the Work,
-          excluding those notices that do not pertain to any part of
-          the Derivative Works; and
-
-      (d) If the Work includes a "NOTICE" text file as part of its
-          distribution, then any Derivative Works that You distribute must
-          include a readable copy of the attribution notices contained
-          within such NOTICE file, excluding those notices that do not
-          pertain to any part of the Derivative Works, in at least one
-          of the following places: within a NOTICE text file distributed
-          as part of the Derivative Works; within the Source form or
-          documentation, if provided along with the Derivative Works; or,
-          within a display generated by the Derivative Works, if and
-          wherever such third-party notices normally appear. The contents
-          of the NOTICE file are for informational purposes only and
-          do not modify the License. You may add Your own attribution
-          notices within Derivative Works that You distribute, alongside
-          or as an addendum to the NOTICE text from the Work, provided
-          that such additional attribution notices cannot be construed
-          as modifying the License.
-
-      You may add Your own copyright statement to Your modifications and
-      may provide additional or different license terms and conditions
-      for use, reproduction, or distribution of Your modifications, or
-      for any such Derivative Works as a whole, provided Your use,
-      reproduction, and distribution of the Work otherwise complies with
-      the conditions stated in this License.
-
-   5. Submission of Contributions. Unless You explicitly state otherwise,
-      any Contribution intentionally submitted for inclusion in the Work
-      by You to the Licensor shall be under the terms and conditions of
-      this License, without any additional terms or conditions.
-      Notwithstanding the above, nothing herein shall supersede or modify
-      the terms of any separate license agreement you may have executed
-      with Licensor regarding such Contributions.
-
-   6. Trademarks. This License does not grant permission to use the trade
-      names, trademarks, service marks, or product names of the Licensor,
-      except as required for reasonable and customary use in describing the
-      origin of the Work and reproducing the content of the NOTICE file.
-
-   7. Disclaimer of Warranty. Unless required by applicable law or
-      agreed to in writing, Licensor provides the Work (and each
-      Contributor provides its Contributions) on an "AS IS" BASIS,
-      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-      implied, including, without limitation, any warranties or conditions
-      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
-      PARTICULAR PURPOSE. You are solely responsible for determining the
-      appropriateness of using or redistributing the Work and assume any
-      risks associated with Your exercise of permissions under this License.
-
-   8. Limitation of Liability. In no event and under no legal theory,
-      whether in tort (including negligence), contract, or otherwise,
-      unless required by applicable law (such as deliberate and grossly
-      negligent acts) or agreed to in writing, shall any Contributor be
-      liable to You for damages, including any direct, indirect, special,
-      incidental, or consequential damages of any character arising as a
-      result of this License or out of the use or inability to use the
-      Work (including but not limited to damages for loss of goodwill,
-      work stoppage, computer failure or malfunction, or any and all
-      other commercial damages or losses), even if such Contributor
-      has been advised of the possibility of such damages.
-
-   9. Accepting Warranty or Additional Liability. While redistributing
-      the Work or Derivative Works thereof, You may choose to offer,
-      and charge a fee for, acceptance of support, warranty, indemnity,
-      or other liability obligations and/or rights consistent with this
-      License. However, in accepting such obligations, You may act only
-      on Your own behalf and on Your sole responsibility, not on behalf
-      of any other Contributor, and only if You agree to indemnify,
-      defend, and hold each Contributor harmless for any liability
-      incurred by, or claims asserted against, such Contributor by reason
-      of your accepting any such warranty or additional liability.
-
-   END OF TERMS AND CONDITIONS
-
-   APPENDIX: How to apply the Apache License to your work.
-
-      To apply the Apache License to your work, attach the following
-      boilerplate notice, with the fields enclosed by brackets "[]"
-      replaced with your own identifying information. (Don't include
-      the brackets!)  The text should be enclosed in the appropriate
-      comment syntax for the file format. We also recommend that a
-      file or class name and description of purpose be included on the
-      same "printed page" as the copyright notice for easier
-      identification within third-party archives.
-
-   Copyright [yyyy] [name of copyright owner]
-
-   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.
diff --git a/compiler/java/com/google/dart/compiler/util/apache/NOTICE.txt b/compiler/java/com/google/dart/compiler/util/apache/NOTICE.txt
deleted file mode 100644
index 2f0ca38..0000000
--- a/compiler/java/com/google/dart/compiler/util/apache/NOTICE.txt
+++ /dev/null
@@ -1,8 +0,0 @@
-Apache Commons Lang
-Copyright 2001-2011 The Apache Software Foundation
-
-This product includes software developed by
-The Apache Software Foundation (http://www.apache.org/).
-
-This product includes software from the Spring Framework,
-under the Apache License 2.0 (see: StringUtils.containsWhitespace())
diff --git a/compiler/java/com/google/dart/compiler/util/apache/ObjectUtils.java b/compiler/java/com/google/dart/compiler/util/apache/ObjectUtils.java
deleted file mode 100644
index 04636bb..0000000
--- a/compiler/java/com/google/dart/compiler/util/apache/ObjectUtils.java
+++ /dev/null
@@ -1,615 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-/*
- * 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 com.google.dart.compiler.util.apache;
-
-import com.google.dart.compiler.util.apache.exception.CloneFailedException;
-import com.google.dart.compiler.util.apache.mutable.MutableInt;
-
-import java.io.Serializable;
-import java.lang.reflect.Array;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.TreeSet;
-
-/**
- * <p>Operations on {@code Object}.</p>
- *
- * <p>This class tries to handle {@code null} input gracefully.
- * An exception will generally not be thrown for a {@code null} input.
- * Each method documents its behaviour in more detail.</p>
- * <p>
- * NOTICE: This file is modified copy of its original Apache library.
- * It was moved to the different package, and changed to reduce number of dependencies.
- *
- * <p>#ThreadSafe#</p>
- * @since 1.0
- * @version $Id: ObjectUtils.java 1199894 2011-11-09 17:53:59Z ggregory $
- */
-//@Immutable
-public class ObjectUtils {
-
-    /**
-     * <p>Singleton used as a {@code null} placeholder where
-     * {@code null} has another meaning.</p>
-     *
-     * <p>For example, in a {@code HashMap} the
-     * {@link java.util.HashMap#get(java.lang.Object)} method returns
-     * {@code null} if the {@code Map} contains {@code null} or if there
-     * is no matching key. The {@code Null} placeholder can be used to
-     * distinguish between these two cases.</p>
-     *
-     * <p>Another example is {@code Hashtable}, where {@code null}
-     * cannot be stored.</p>
-     *
-     * <p>This instance is Serializable.</p>
-     */
-    public static final Null NULL = new Null();
-
-    /**
-     * <p>{@code ObjectUtils} instances should NOT be constructed in
-     * standard programming. Instead, the static methods on the class should
-     * be used, such as {@code ObjectUtils.defaultIfNull("a","b");}.</p>
-     *
-     * <p>This constructor is public to permit tools that require a JavaBean
-     * instance to operate.</p>
-     */
-    public ObjectUtils() {
-        super();
-    }
-
-    // Defaulting
-    //-----------------------------------------------------------------------
-    /**
-     * <p>Returns a default value if the object passed is {@code null}.</p>
-     *
-     * <pre>
-     * ObjectUtils.defaultIfNull(null, null)      = null
-     * ObjectUtils.defaultIfNull(null, "")        = ""
-     * ObjectUtils.defaultIfNull(null, "zz")      = "zz"
-     * ObjectUtils.defaultIfNull("abc", *)        = "abc"
-     * ObjectUtils.defaultIfNull(Boolean.TRUE, *) = Boolean.TRUE
-     * </pre>
-     *
-     * @param <T> the type of the object
-     * @param object  the {@code Object} to test, may be {@code null}
-     * @param defaultValue  the default value to return, may be {@code null}
-     * @return {@code object} if it is not {@code null}, defaultValue otherwise
-     */
-    public static <T> T defaultIfNull(T object, T defaultValue) {
-        return object != null ? object : defaultValue;
-    }
-
-    /**
-     * <p>Returns the first value in the array which is not {@code null}.
-     * If all the values are {@code null} or the array is {@code null}
-     * or empty then {@code null} is returned.</p>
-     *
-     * <pre>
-     * ObjectUtils.firstNonNull(null, null)      = null
-     * ObjectUtils.firstNonNull(null, "")        = ""
-     * ObjectUtils.firstNonNull(null, null, "")  = ""
-     * ObjectUtils.firstNonNull(null, "zz")      = "zz"
-     * ObjectUtils.firstNonNull("abc", *)        = "abc"
-     * ObjectUtils.firstNonNull(null, "xyz", *)  = "xyz"
-     * ObjectUtils.firstNonNull(Boolean.TRUE, *) = Boolean.TRUE
-     * ObjectUtils.firstNonNull()                = null
-     * </pre>
-     *
-     * @param <T> the component type of the array
-     * @param values  the values to test, may be {@code null} or empty
-     * @return the first value from {@code values} which is not {@code null},
-     *  or {@code null} if there are no non-null values
-     * @since 3.0
-     */
-    public static <T> T firstNonNull(T... values) {
-        if (values != null) {
-            for (T val : values) {
-                if (val != null) {
-                    return val;
-                }
-            }
-        }
-        return null;
-    }
-
-    // Null-safe equals/hashCode
-    //-----------------------------------------------------------------------
-    /**
-     * <p>Compares two objects for equality, where either one or both
-     * objects may be {@code null}.</p>
-     *
-     * <pre>
-     * ObjectUtils.equals(null, null)                  = true
-     * ObjectUtils.equals(null, "")                    = false
-     * ObjectUtils.equals("", null)                    = false
-     * ObjectUtils.equals("", "")                      = true
-     * ObjectUtils.equals(Boolean.TRUE, null)          = false
-     * ObjectUtils.equals(Boolean.TRUE, "true")        = false
-     * ObjectUtils.equals(Boolean.TRUE, Boolean.TRUE)  = true
-     * ObjectUtils.equals(Boolean.TRUE, Boolean.FALSE) = false
-     * </pre>
-     *
-     * @param object1  the first object, may be {@code null}
-     * @param object2  the second object, may be {@code null}
-     * @return {@code true} if the values of both objects are the same
-     */
-    public static boolean equals(Object object1, Object object2) {
-        if (object1 == object2) {
-            return true;
-        }
-        if (object1 == null || object2 == null) {
-            return false;
-        }
-        return object1.equals(object2);
-    }
-
-    /**
-     * <p>Compares two objects for inequality, where either one or both
-     * objects may be {@code null}.</p>
-     *
-     * <pre>
-     * ObjectUtils.notEqual(null, null)                  = false
-     * ObjectUtils.notEqual(null, "")                    = true
-     * ObjectUtils.notEqual("", null)                    = true
-     * ObjectUtils.notEqual("", "")                      = false
-     * ObjectUtils.notEqual(Boolean.TRUE, null)          = true
-     * ObjectUtils.notEqual(Boolean.TRUE, "true")        = true
-     * ObjectUtils.notEqual(Boolean.TRUE, Boolean.TRUE)  = false
-     * ObjectUtils.notEqual(Boolean.TRUE, Boolean.FALSE) = true
-     * </pre>
-     *
-     * @param object1  the first object, may be {@code null}
-     * @param object2  the second object, may be {@code null}
-     * @return {@code false} if the values of both objects are the same
-     */
-    public static boolean notEqual(Object object1, Object object2) {
-        return ObjectUtils.equals(object1, object2) == false;
-    }
-
-    /**
-     * <p>Gets the hash code of an object returning zero when the
-     * object is {@code null}.</p>
-     *
-     * <pre>
-     * ObjectUtils.hashCode(null)   = 0
-     * ObjectUtils.hashCode(obj)    = obj.hashCode()
-     * </pre>
-     *
-     * @param obj  the object to obtain the hash code of, may be {@code null}
-     * @return the hash code of the object, or zero if null
-     * @since 2.1
-     */
-    public static int hashCode(Object obj) {
-        // hashCode(Object) retained for performance, as hash code is often critical
-        return obj == null ? 0 : obj.hashCode();
-    }
-
-    /**
-     * <p>Gets the hash code for multiple objects.</p>
-     * 
-     * <p>This allows a hash code to be rapidly calculated for a number of objects.
-     * The hash code for a single object is the <em>not</em> same as {@link #hashCode(Object)}.
-     * The hash code for multiple objects is the same as that calculated by an
-     * {@code ArrayList} containing the specified objects.</p>
-     *
-     * <pre>
-     * ObjectUtils.hashCodeMulti()                 = 1
-     * ObjectUtils.hashCodeMulti((Object[]) null)  = 1
-     * ObjectUtils.hashCodeMulti(a)                = 31 + a.hashCode()
-     * ObjectUtils.hashCodeMulti(a,b)              = (31 + a.hashCode()) * 31 + b.hashCode()
-     * ObjectUtils.hashCodeMulti(a,b,c)            = ((31 + a.hashCode()) * 31 + b.hashCode()) * 31 + c.hashCode()
-     * </pre>
-     *
-     * @param objects  the objects to obtain the hash code of, may be {@code null}
-     * @return the hash code of the objects, or zero if null
-     * @since 3.0
-     */
-    public static int hashCodeMulti(Object... objects) {
-        int hash = 1;
-        if (objects != null) {
-            for (Object object : objects) {
-                hash = hash * 31 + ObjectUtils.hashCode(object);
-            }
-        }
-        return hash;
-    }
-
-    // Identity ToString
-    //-----------------------------------------------------------------------
-    /**
-     * <p>Gets the toString that would be produced by {@code Object}
-     * if a class did not override toString itself. {@code null}
-     * will return {@code null}.</p>
-     *
-     * <pre>
-     * ObjectUtils.identityToString(null)         = null
-     * ObjectUtils.identityToString("")           = "java.lang.String@1e23"
-     * ObjectUtils.identityToString(Boolean.TRUE) = "java.lang.Boolean@7fa"
-     * </pre>
-     *
-     * @param object  the object to create a toString for, may be
-     *  {@code null}
-     * @return the default toString text, or {@code null} if
-     *  {@code null} passed in
-     */
-    public static String identityToString(Object object) {
-        if (object == null) {
-            return null;
-        }
-        StringBuffer buffer = new StringBuffer();
-        identityToString(buffer, object);
-        return buffer.toString();
-    }
-
-    /**
-     * <p>Appends the toString that would be produced by {@code Object}
-     * if a class did not override toString itself. {@code null}
-     * will throw a NullPointerException for either of the two parameters. </p>
-     *
-     * <pre>
-     * ObjectUtils.identityToString(buf, "")            = buf.append("java.lang.String@1e23"
-     * ObjectUtils.identityToString(buf, Boolean.TRUE)  = buf.append("java.lang.Boolean@7fa"
-     * ObjectUtils.identityToString(buf, Boolean.TRUE)  = buf.append("java.lang.Boolean@7fa")
-     * </pre>
-     *
-     * @param buffer  the buffer to append to
-     * @param object  the object to create a toString for
-     * @since 2.4
-     */
-    public static void identityToString(StringBuffer buffer, Object object) {
-        if (object == null) {
-            throw new NullPointerException("Cannot get the toString of a null identity");
-        }
-        buffer.append(object.getClass().getName())
-              .append('@')
-              .append(Integer.toHexString(System.identityHashCode(object)));
-    }
-
-    // ToString
-    //-----------------------------------------------------------------------
-    /**
-     * <p>Gets the {@code toString} of an {@code Object} returning
-     * an empty string ("") if {@code null} input.</p>
-     *
-     * <pre>
-     * ObjectUtils.toString(null)         = ""
-     * ObjectUtils.toString("")           = ""
-     * ObjectUtils.toString("bat")        = "bat"
-     * ObjectUtils.toString(Boolean.TRUE) = "true"
-     * </pre>
-     *
-     * @see StringUtils#defaultString(String)
-     * @see String#valueOf(Object)
-     * @param obj  the Object to {@code toString}, may be null
-     * @return the passed in Object's toString, or nullStr if {@code null} input
-     * @since 2.0
-     */
-    public static String toString(Object obj) {
-        return obj == null ? "" : obj.toString();
-    }
-
-    /**
-     * <p>Gets the {@code toString} of an {@code Object} returning
-     * a specified text if {@code null} input.</p>
-     *
-     * <pre>
-     * ObjectUtils.toString(null, null)           = null
-     * ObjectUtils.toString(null, "null")         = "null"
-     * ObjectUtils.toString("", "null")           = ""
-     * ObjectUtils.toString("bat", "null")        = "bat"
-     * ObjectUtils.toString(Boolean.TRUE, "null") = "true"
-     * </pre>
-     *
-     * @see StringUtils#defaultString(String,String)
-     * @see String#valueOf(Object)
-     * @param obj  the Object to {@code toString}, may be null
-     * @param nullStr  the String to return if {@code null} input, may be null
-     * @return the passed in Object's toString, or nullStr if {@code null} input
-     * @since 2.0
-     */
-    public static String toString(Object obj, String nullStr) {
-        return obj == null ? nullStr : obj.toString();
-    }
-
-    // Comparable
-    //-----------------------------------------------------------------------
-    /**
-     * <p>Null safe comparison of Comparables.</p>
-     *
-     * @param <T> type of the values processed by this method
-     * @param values the set of comparable values, may be null
-     * @return
-     *  <ul>
-     *   <li>If any objects are non-null and unequal, the lesser object.
-     *   <li>If all objects are non-null and equal, the first.
-     *   <li>If any of the comparables are null, the lesser of the non-null objects.
-     *   <li>If all the comparables are null, null is returned.
-     *  </ul>
-     */
-    public static <T extends Comparable<? super T>> T min(T... values) {
-        T result = null;
-        if (values != null) {
-            for (T value : values) {
-                if (compare(value, result, true) < 0) {
-                    result = value;
-                }
-            }
-        }
-        return result;
-    }
-
-    /**
-     * <p>Null safe comparison of Comparables.</p>
-     *
-     * @param <T> type of the values processed by this method
-     * @param values the set of comparable values, may be null
-     * @return
-     *  <ul>
-     *   <li>If any objects are non-null and unequal, the greater object.
-     *   <li>If all objects are non-null and equal, the first.
-     *   <li>If any of the comparables are null, the greater of the non-null objects.
-     *   <li>If all the comparables are null, null is returned.
-     *  </ul>
-     */
-    public static <T extends Comparable<? super T>> T max(T... values) {
-        T result = null;
-        if (values != null) {
-            for (T value : values) {
-                if (compare(value, result, false) > 0) {
-                    result = value;
-                }
-            }
-        }
-        return result;
-    }
-
-    /**
-     * <p>Null safe comparison of Comparables.
-     * {@code null} is assumed to be less than a non-{@code null} value.</p>
-     *
-     * @param <T> type of the values processed by this method
-     * @param c1  the first comparable, may be null
-     * @param c2  the second comparable, may be null
-     * @return a negative value if c1 < c2, zero if c1 = c2
-     *  and a positive value if c1 > c2
-     */
-    public static <T extends Comparable<? super T>> int compare(T c1, T c2) {
-        return compare(c1, c2, false);
-    }
-
-    /**
-     * <p>Null safe comparison of Comparables.</p>
-     *
-     * @param <T> type of the values processed by this method
-     * @param c1  the first comparable, may be null
-     * @param c2  the second comparable, may be null
-     * @param nullGreater if true {@code null} is considered greater
-     *  than a non-{@code null} value or if false {@code null} is
-     *  considered less than a Non-{@code null} value
-     * @return a negative value if c1 < c2, zero if c1 = c2
-     *  and a positive value if c1 > c2
-     * @see java.util.Comparator#compare(Object, Object)
-     */
-    public static <T extends Comparable<? super T>> int compare(T c1, T c2, boolean nullGreater) {
-        if (c1 == c2) {
-            return 0;
-        } else if (c1 == null) {
-            return nullGreater ? 1 : -1;
-        } else if (c2 == null) {
-            return nullGreater ? -1 : 1;
-        }
-        return c1.compareTo(c2);
-    }
-
-    /**
-     * Find the "best guess" middle value among comparables. If there is an even
-     * number of total values, the lower of the two middle values will be returned.
-     * @param <T> type of values processed by this method
-     * @param items to compare
-     * @return T at middle position
-     * @throws NullPointerException if items is {@code null}
-     * @throws IllegalArgumentException if items is empty or contains {@code null} values
-     * @since 3.0.1
-     */
-    public static <T extends Comparable<? super T>> T median(T... items) {
-//        Validate.notEmpty(items);
-//        Validate.noNullElements(items);
-        TreeSet<T> sort = new TreeSet<T>();
-        Collections.addAll(sort, items);
-        @SuppressWarnings("unchecked") //we know all items added were T instances
-        T result = (T) sort.toArray()[(sort.size() - 1) / 2];
-        return result;
-    }
-
-    /**
-     * Find the "best guess" middle value among comparables. If there is an even
-     * number of total values, the lower of the two middle values will be returned.
-     * @param <T> type of values processed by this method
-     * @param comparator to use for comparisons
-     * @param items to compare
-     * @return T at middle position
-     * @throws NullPointerException if items or comparator is {@code null}
-     * @throws IllegalArgumentException if items is empty or contains {@code null} values
-     * @since 3.0.1
-     */
-    public static <T> T median(Comparator<T> comparator, T... items) {
-//        Validate.notEmpty(items, "null/empty items");
-//        Validate.noNullElements(items);
-//        Validate.notNull(comparator, "null comparator");
-        TreeSet<T> sort = new TreeSet<T>(comparator);
-        Collections.addAll(sort, items);
-        @SuppressWarnings("unchecked") //we know all items added were T instances
-        T result = (T) sort.toArray()[(sort.size() - 1) / 2];
-        return result;
-    }
-
-    // Mode
-    //-----------------------------------------------------------------------
-    /**
-     * Find the most frequently occurring item.
-     * 
-     * @param <T> type of values processed by this method
-     * @param items to check
-     * @return most populous T, {@code null} if non-unique or no items supplied
-     * @since 3.0.1
-     */
-    public static <T> T mode(T... items) {
-        if (ArrayUtils.isNotEmpty(items)) {
-            HashMap<T, MutableInt> occurrences = new HashMap<T, MutableInt>(items.length);
-            for (T t : items) {
-                MutableInt count = occurrences.get(t);
-                if (count == null) {
-                    occurrences.put(t, new MutableInt(1));
-                } else {
-                    count.increment();
-                }
-            }
-            T result = null;
-            int max = 0;
-            for (Map.Entry<T, MutableInt> e : occurrences.entrySet()) {
-                int cmp = e.getValue().intValue();
-                if (cmp == max) {
-                    result = null;
-                } else if (cmp > max) {
-                    max = cmp;
-                    result = e.getKey();
-                }
-            }
-            return result;
-        }
-        return null;
-    }
-
-    // cloning
-    //-----------------------------------------------------------------------
-    /**
-     * <p>Clone an object.</p>
-     *
-     * @param <T> the type of the object
-     * @param obj  the object to clone, null returns null
-     * @return the clone if the object implements {@link Cloneable} otherwise {@code null}
-     * @throws CloneFailedException if the object is cloneable and the clone operation fails
-     * @since 3.0
-     */
-    public static <T> T clone(final T obj) {
-        if (obj instanceof Cloneable) {
-            final Object result;
-            if (obj.getClass().isArray()) {
-                final Class<?> componentType = obj.getClass().getComponentType();
-                if (!componentType.isPrimitive()) {
-                    result = ((Object[]) obj).clone();
-                } else {
-                    int length = Array.getLength(obj);
-                    result = Array.newInstance(componentType, length);
-                    while (length-- > 0) {
-                        Array.set(result, length, Array.get(obj, length));
-                    }
-                }
-            } else {
-                try {
-                    final Method clone = obj.getClass().getMethod("clone");
-                    result = clone.invoke(obj);
-                } catch (final NoSuchMethodException e) {
-                    throw new CloneFailedException("Cloneable type "
-                        + obj.getClass().getName()
-                        + " has no clone method", e);
-                } catch (final IllegalAccessException e) {
-                    throw new CloneFailedException("Cannot clone Cloneable type "
-                        + obj.getClass().getName(), e);
-                } catch (final InvocationTargetException e) {
-                    throw new CloneFailedException("Exception cloning Cloneable type "
-                        + obj.getClass().getName(), e.getCause());
-                }
-            }
-            @SuppressWarnings("unchecked")
-            final T checked = (T) result;
-            return checked;
-        }
-
-        return null;
-    }
-
-    /**
-     * <p>Clone an object if possible.</p>
-     *
-     * <p>This method is similar to {@link #clone(Object)}, but will return the provided
-     * instance as the return value instead of {@code null} if the instance
-     * is not cloneable. This is more convenient if the caller uses different
-     * implementations (e.g. of a service) and some of the implementations do not allow concurrent
-     * processing or have state. In such cases the implementation can simply provide a proper
-     * clone implementation and the caller's code does not have to change.</p>
-     *
-     * @param <T> the type of the object
-     * @param obj  the object to clone, null returns null
-     * @return the clone if the object implements {@link Cloneable} otherwise the object itself
-     * @throws CloneFailedException if the object is cloneable and the clone operation fails
-     * @since 3.0
-     */
-    public static <T> T cloneIfPossible(final T obj) {
-        final T clone = clone(obj);
-        return clone == null ? obj : clone;
-    }
-
-    // Null
-    //-----------------------------------------------------------------------
-    /**
-     * <p>Class used as a null placeholder where {@code null}
-     * has another meaning.</p>
-     *
-     * <p>For example, in a {@code HashMap} the
-     * {@link java.util.HashMap#get(java.lang.Object)} method returns
-     * {@code null} if the {@code Map} contains {@code null} or if there is
-     * no matching key. The {@code Null} placeholder can be used to distinguish
-     * between these two cases.</p>
-     *
-     * <p>Another example is {@code Hashtable}, where {@code null}
-     * cannot be stored.</p>
-     */
-    public static class Null implements Serializable {
-        /**
-         * Required for serialization support. Declare serialization compatibility with Commons Lang 1.0
-         *
-         * @see java.io.Serializable
-         */
-        private static final long serialVersionUID = 7092611880189329093L;
-
-        /**
-         * Restricted constructor - singleton.
-         */
-        Null() {
-            super();
-        }
-
-        /**
-         * <p>Ensure singleton.</p>
-         *
-         * @return the singleton value
-         */
-        private Object readResolve() {
-            return ObjectUtils.NULL;
-        }
-    }
-
-}
diff --git a/compiler/java/com/google/dart/compiler/util/apache/StringUtils.java b/compiler/java/com/google/dart/compiler/util/apache/StringUtils.java
deleted file mode 100644
index 2681e87..0000000
--- a/compiler/java/com/google/dart/compiler/util/apache/StringUtils.java
+++ /dev/null
@@ -1,6589 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-/*
- * 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 com.google.dart.compiler.util.apache;
-
-import java.io.UnsupportedEncodingException;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Locale;
-import java.util.regex.Pattern;
-
-/**
- * <p>Operations on {@link java.lang.String} that are
- * {@code null} safe.</p>
- *
- * <ul>
- *  <li><b>IsEmpty/IsBlank</b>
- *      - checks if a String contains text</li>
- *  <li><b>Trim/Strip</b>
- *      - removes leading and trailing whitespace</li>
- *  <li><b>Equals</b>
- *      - compares two strings null-safe</li>
- *  <li><b>startsWith</b>
- *      - check if a String starts with a prefix null-safe</li>
- *  <li><b>endsWith</b>
- *      - check if a String ends with a suffix null-safe</li>
- *  <li><b>IndexOf/LastIndexOf/Contains</b>
- *      - null-safe index-of checks
- *  <li><b>IndexOfAny/LastIndexOfAny/IndexOfAnyBut/LastIndexOfAnyBut</b>
- *      - index-of any of a set of Strings</li>
- *  <li><b>ContainsOnly/ContainsNone/ContainsAny</b>
- *      - does String contains only/none/any of these characters</li>
- *  <li><b>Substring/Left/Right/Mid</b>
- *      - null-safe substring extractions</li>
- *  <li><b>SubstringBefore/SubstringAfter/SubstringBetween</b>
- *      - substring extraction relative to other strings</li>
- *  <li><b>Split/Join</b>
- *      - splits a String into an array of substrings and vice versa</li>
- *  <li><b>Remove/Delete</b>
- *      - removes part of a String</li>
- *  <li><b>Replace/Overlay</b>
- *      - Searches a String and replaces one String with another</li>
- *  <li><b>Chomp/Chop</b>
- *      - removes the last part of a String</li>
- *  <li><b>LeftPad/RightPad/Center/Repeat</b>
- *      - pads a String</li>
- *  <li><b>UpperCase/LowerCase/SwapCase/Capitalize/Uncapitalize</b>
- *      - changes the case of a String</li>
- *  <li><b>CountMatches</b>
- *      - counts the number of occurrences of one String in another</li>
- *  <li><b>IsAlpha/IsNumeric/IsWhitespace/IsAsciiPrintable</b>
- *      - checks the characters in a String</li>
- *  <li><b>DefaultString</b>
- *      - protects against a null input String</li>
- *  <li><b>Reverse/ReverseDelimited</b>
- *      - reverses a String</li>
- *  <li><b>Abbreviate</b>
- *      - abbreviates a string using ellipsis</li>
- *  <li><b>Difference</b>
- *      - compares Strings and reports on their differences</li>
- *  <li><b>LevenshteinDistance</b>
- *      - the number of changes needed to change one String into another</li>
- * </ul>
- *
- * <p>The {@code StringUtils} class defines certain words related to
- * String handling.</p>
- *
- * <ul>
- *  <li>null - {@code null}</li>
- *  <li>empty - a zero-length string ({@code ""})</li>
- *  <li>space - the space character ({@code ' '}, char 32)</li>
- *  <li>whitespace - the characters defined by {@link Character#isWhitespace(char)}</li>
- *  <li>trim - the characters &lt;= 32 as in {@link String#trim()}</li>
- * </ul>
- *
- * <p>{@code StringUtils} handles {@code null} input Strings quietly.
- * That is to say that a {@code null} input will return {@code null}.
- * Where a {@code boolean} or {@code int} is being returned
- * details vary by method.</p>
- *
- * <p>A side effect of the {@code null} handling is that a
- * {@code NullPointerException} should be considered a bug in
- * {@code StringUtils}.</p>
- *
- * <p>Methods in this class give sample code to explain their operation.
- * The symbol {@code *} is used to indicate any input including {@code null}.</p>
- * <p>
- * NOTICE: This file is modified copy of its original Apache library.
- * It was moved to the different package, and changed to reduce number of dependencies.
- *
- * <p>#ThreadSafe#</p>
- * @see java.lang.String
- * @since 1.0
- * @version $Id: StringUtils.java 1199894 2011-11-09 17:53:59Z ggregory $
- */
-//@Immutable
-public class StringUtils {
-    // Performance testing notes (JDK 1.4, Jul03, scolebourne)
-    // Whitespace:
-    // Character.isWhitespace() is faster than WHITESPACE.indexOf()
-    // where WHITESPACE is a string of all whitespace characters
-    //
-    // Character access:
-    // String.charAt(n) versus toCharArray(), then array[n]
-    // String.charAt(n) is about 15% worse for a 10K string
-    // They are about equal for a length 50 string
-    // String.charAt(n) is about 4 times better for a length 3 string
-    // String.charAt(n) is best bet overall
-    //
-    // Append:
-    // String.concat about twice as fast as StringBuffer.append
-    // (not sure who tested this)
-
-    /**
-     * The empty String {@code ""}.
-     * @since 2.0
-     */
-    public static final String EMPTY = "";
-
-    /**
-     * Represents a failed index search.
-     * @since 2.1
-     */
-    public static final int INDEX_NOT_FOUND = -1;
-
-    /**
-     * <p>The maximum size to which the padding constant(s) can expand.</p>
-     */
-    private static final int PAD_LIMIT = 8192;
-
-    /**
-     * A regex pattern for recognizing blocks of whitespace characters.
-     */
-    private static final Pattern WHITESPACE_BLOCK = Pattern.compile("\\s+");
-
-    /**
-     * <p>{@code StringUtils} instances should NOT be constructed in
-     * standard programming. Instead, the class should be used as
-     * {@code StringUtils.trim(" foo ");}.</p>
-     *
-     * <p>This constructor is public to permit tools that require a JavaBean
-     * instance to operate.</p>
-     */
-    public StringUtils() {
-        super();
-    }
-
-    // Empty checks
-    //-----------------------------------------------------------------------
-    /**
-     * <p>Checks if a CharSequence is empty ("") or null.</p>
-     *
-     * <pre>
-     * StringUtils.isEmpty(null)      = true
-     * StringUtils.isEmpty("")        = true
-     * StringUtils.isEmpty(" ")       = false
-     * StringUtils.isEmpty("bob")     = false
-     * StringUtils.isEmpty("  bob  ") = false
-     * </pre>
-     *
-     * <p>NOTE: This method changed in Lang version 2.0.
-     * It no longer trims the CharSequence.
-     * That functionality is available in isBlank().</p>
-     *
-     * @param cs  the CharSequence to check, may be null
-     * @return {@code true} if the CharSequence is empty or null
-     * @since 3.0 Changed signature from isEmpty(String) to isEmpty(CharSequence)
-     */
-    public static boolean isEmpty(CharSequence cs) {
-        return cs == null || cs.length() == 0;
-    }
-
-    /**
-     * <p>Checks if a CharSequence is not empty ("") and not null.</p>
-     *
-     * <pre>
-     * StringUtils.isNotEmpty(null)      = false
-     * StringUtils.isNotEmpty("")        = false
-     * StringUtils.isNotEmpty(" ")       = true
-     * StringUtils.isNotEmpty("bob")     = true
-     * StringUtils.isNotEmpty("  bob  ") = true
-     * </pre>
-     *
-     * @param cs  the CharSequence to check, may be null
-     * @return {@code true} if the CharSequence is not empty and not null
-     * @since 3.0 Changed signature from isNotEmpty(String) to isNotEmpty(CharSequence)
-     */
-    public static boolean isNotEmpty(CharSequence cs) {
-        return !StringUtils.isEmpty(cs);
-    }
-
-    /**
-     * <p>Checks if a CharSequence is whitespace, empty ("") or null.</p>
-     *
-     * <pre>
-     * StringUtils.isBlank(null)      = true
-     * StringUtils.isBlank("")        = true
-     * StringUtils.isBlank(" ")       = true
-     * StringUtils.isBlank("bob")     = false
-     * StringUtils.isBlank("  bob  ") = false
-     * </pre>
-     *
-     * @param cs  the CharSequence to check, may be null
-     * @return {@code true} if the CharSequence is null, empty or whitespace
-     * @since 2.0
-     * @since 3.0 Changed signature from isBlank(String) to isBlank(CharSequence)
-     */
-    public static boolean isBlank(CharSequence cs) {
-        int strLen;
-        if (cs == null || (strLen = cs.length()) == 0) {
-            return true;
-        }
-        for (int i = 0; i < strLen; i++) {
-            if (Character.isWhitespace(cs.charAt(i)) == false) {
-                return false;
-            }
-        }
-        return true;
-    }
-
-    /**
-     * <p>Checks if a CharSequence is not empty (""), not null and not whitespace only.</p>
-     *
-     * <pre>
-     * StringUtils.isNotBlank(null)      = false
-     * StringUtils.isNotBlank("")        = false
-     * StringUtils.isNotBlank(" ")       = false
-     * StringUtils.isNotBlank("bob")     = true
-     * StringUtils.isNotBlank("  bob  ") = true
-     * </pre>
-     *
-     * @param cs  the CharSequence to check, may be null
-     * @return {@code true} if the CharSequence is
-     *  not empty and not null and not whitespace
-     * @since 2.0
-     * @since 3.0 Changed signature from isNotBlank(String) to isNotBlank(CharSequence)
-     */
-    public static boolean isNotBlank(CharSequence cs) {
-        return !StringUtils.isBlank(cs);
-    }
-
-    // Trim
-    //-----------------------------------------------------------------------
-    /**
-     * <p>Removes control characters (char &lt;= 32) from both
-     * ends of this String, handling {@code null} by returning
-     * {@code null}.</p>
-     *
-     * <p>The String is trimmed using {@link String#trim()}.
-     * Trim removes start and end characters &lt;= 32.
-     * To strip whitespace use {@link #strip(String)}.</p>
-     *
-     * <p>To trim your choice of characters, use the
-     * {@link #strip(String, String)} methods.</p>
-     *
-     * <pre>
-     * StringUtils.trim(null)          = null
-     * StringUtils.trim("")            = ""
-     * StringUtils.trim("     ")       = ""
-     * StringUtils.trim("abc")         = "abc"
-     * StringUtils.trim("    abc    ") = "abc"
-     * </pre>
-     *
-     * @param str  the String to be trimmed, may be null
-     * @return the trimmed string, {@code null} if null String input
-     */
-    public static String trim(String str) {
-        return str == null ? null : str.trim();
-    }
-
-    /**
-     * <p>Removes control characters (char &lt;= 32) from both
-     * ends of this String returning {@code null} if the String is
-     * empty ("") after the trim or if it is {@code null}.
-     *
-     * <p>The String is trimmed using {@link String#trim()}.
-     * Trim removes start and end characters &lt;= 32.
-     * To strip whitespace use {@link #stripToNull(String)}.</p>
-     *
-     * <pre>
-     * StringUtils.trimToNull(null)          = null
-     * StringUtils.trimToNull("")            = null
-     * StringUtils.trimToNull("     ")       = null
-     * StringUtils.trimToNull("abc")         = "abc"
-     * StringUtils.trimToNull("    abc    ") = "abc"
-     * </pre>
-     *
-     * @param str  the String to be trimmed, may be null
-     * @return the trimmed String,
-     *  {@code null} if only chars &lt;= 32, empty or null String input
-     * @since 2.0
-     */
-    public static String trimToNull(String str) {
-        String ts = trim(str);
-        return isEmpty(ts) ? null : ts;
-    }
-
-    /**
-     * <p>Removes control characters (char &lt;= 32) from both
-     * ends of this String returning an empty String ("") if the String
-     * is empty ("") after the trim or if it is {@code null}.
-     *
-     * <p>The String is trimmed using {@link String#trim()}.
-     * Trim removes start and end characters &lt;= 32.
-     * To strip whitespace use {@link #stripToEmpty(String)}.</p>
-     *
-     * <pre>
-     * StringUtils.trimToEmpty(null)          = ""
-     * StringUtils.trimToEmpty("")            = ""
-     * StringUtils.trimToEmpty("     ")       = ""
-     * StringUtils.trimToEmpty("abc")         = "abc"
-     * StringUtils.trimToEmpty("    abc    ") = "abc"
-     * </pre>
-     *
-     * @param str  the String to be trimmed, may be null
-     * @return the trimmed String, or an empty String if {@code null} input
-     * @since 2.0
-     */
-    public static String trimToEmpty(String str) {
-        return str == null ? EMPTY : str.trim();
-    }
-
-    // Stripping
-    //-----------------------------------------------------------------------
-    /**
-     * <p>Strips whitespace from the start and end of a String.</p>
-     *
-     * <p>This is similar to {@link #trim(String)} but removes whitespace.
-     * Whitespace is defined by {@link Character#isWhitespace(char)}.</p>
-     *
-     * <p>A {@code null} input String returns {@code null}.</p>
-     *
-     * <pre>
-     * StringUtils.strip(null)     = null
-     * StringUtils.strip("")       = ""
-     * StringUtils.strip("   ")    = ""
-     * StringUtils.strip("abc")    = "abc"
-     * StringUtils.strip("  abc")  = "abc"
-     * StringUtils.strip("abc  ")  = "abc"
-     * StringUtils.strip(" abc ")  = "abc"
-     * StringUtils.strip(" ab c ") = "ab c"
-     * </pre>
-     *
-     * @param str  the String to remove whitespace from, may be null
-     * @return the stripped String, {@code null} if null String input
-     */
-    public static String strip(String str) {
-        return strip(str, null);
-    }
-
-    /**
-     * <p>Strips whitespace from the start and end of a String  returning
-     * {@code null} if the String is empty ("") after the strip.</p>
-     *
-     * <p>This is similar to {@link #trimToNull(String)} but removes whitespace.
-     * Whitespace is defined by {@link Character#isWhitespace(char)}.</p>
-     *
-     * <pre>
-     * StringUtils.stripToNull(null)     = null
-     * StringUtils.stripToNull("")       = null
-     * StringUtils.stripToNull("   ")    = null
-     * StringUtils.stripToNull("abc")    = "abc"
-     * StringUtils.stripToNull("  abc")  = "abc"
-     * StringUtils.stripToNull("abc  ")  = "abc"
-     * StringUtils.stripToNull(" abc ")  = "abc"
-     * StringUtils.stripToNull(" ab c ") = "ab c"
-     * </pre>
-     *
-     * @param str  the String to be stripped, may be null
-     * @return the stripped String,
-     *  {@code null} if whitespace, empty or null String input
-     * @since 2.0
-     */
-    public static String stripToNull(String str) {
-        if (str == null) {
-            return null;
-        }
-        str = strip(str, null);
-        return str.length() == 0 ? null : str;
-    }
-
-    /**
-     * <p>Strips whitespace from the start and end of a String  returning
-     * an empty String if {@code null} input.</p>
-     *
-     * <p>This is similar to {@link #trimToEmpty(String)} but removes whitespace.
-     * Whitespace is defined by {@link Character#isWhitespace(char)}.</p>
-     *
-     * <pre>
-     * StringUtils.stripToEmpty(null)     = ""
-     * StringUtils.stripToEmpty("")       = ""
-     * StringUtils.stripToEmpty("   ")    = ""
-     * StringUtils.stripToEmpty("abc")    = "abc"
-     * StringUtils.stripToEmpty("  abc")  = "abc"
-     * StringUtils.stripToEmpty("abc  ")  = "abc"
-     * StringUtils.stripToEmpty(" abc ")  = "abc"
-     * StringUtils.stripToEmpty(" ab c ") = "ab c"
-     * </pre>
-     *
-     * @param str  the String to be stripped, may be null
-     * @return the trimmed String, or an empty String if {@code null} input
-     * @since 2.0
-     */
-    public static String stripToEmpty(String str) {
-        return str == null ? EMPTY : strip(str, null);
-    }
-
-    /**
-     * <p>Strips any of a set of characters from the start and end of a String.
-     * This is similar to {@link String#trim()} but allows the characters
-     * to be stripped to be controlled.</p>
-     *
-     * <p>A {@code null} input String returns {@code null}.
-     * An empty string ("") input returns the empty string.</p>
-     *
-     * <p>If the stripChars String is {@code null}, whitespace is
-     * stripped as defined by {@link Character#isWhitespace(char)}.
-     * Alternatively use {@link #strip(String)}.</p>
-     *
-     * <pre>
-     * StringUtils.strip(null, *)          = null
-     * StringUtils.strip("", *)            = ""
-     * StringUtils.strip("abc", null)      = "abc"
-     * StringUtils.strip("  abc", null)    = "abc"
-     * StringUtils.strip("abc  ", null)    = "abc"
-     * StringUtils.strip(" abc ", null)    = "abc"
-     * StringUtils.strip("  abcyx", "xyz") = "  abc"
-     * </pre>
-     *
-     * @param str  the String to remove characters from, may be null
-     * @param stripChars  the characters to remove, null treated as whitespace
-     * @return the stripped String, {@code null} if null String input
-     */
-    public static String strip(String str, String stripChars) {
-        if (isEmpty(str)) {
-            return str;
-        }
-        str = stripStart(str, stripChars);
-        return stripEnd(str, stripChars);
-    }
-
-    /**
-     * <p>Strips any of a set of characters from the start of a String.</p>
-     *
-     * <p>A {@code null} input String returns {@code null}.
-     * An empty string ("") input returns the empty string.</p>
-     *
-     * <p>If the stripChars String is {@code null}, whitespace is
-     * stripped as defined by {@link Character#isWhitespace(char)}.</p>
-     *
-     * <pre>
-     * StringUtils.stripStart(null, *)          = null
-     * StringUtils.stripStart("", *)            = ""
-     * StringUtils.stripStart("abc", "")        = "abc"
-     * StringUtils.stripStart("abc", null)      = "abc"
-     * StringUtils.stripStart("  abc", null)    = "abc"
-     * StringUtils.stripStart("abc  ", null)    = "abc  "
-     * StringUtils.stripStart(" abc ", null)    = "abc "
-     * StringUtils.stripStart("yxabc  ", "xyz") = "abc  "
-     * </pre>
-     *
-     * @param str  the String to remove characters from, may be null
-     * @param stripChars  the characters to remove, null treated as whitespace
-     * @return the stripped String, {@code null} if null String input
-     */
-    public static String stripStart(String str, String stripChars) {
-        int strLen;
-        if (str == null || (strLen = str.length()) == 0) {
-            return str;
-        }
-        int start = 0;
-        if (stripChars == null) {
-            while (start != strLen && Character.isWhitespace(str.charAt(start))) {
-                start++;
-            }
-        } else if (stripChars.length() == 0) {
-            return str;
-        } else {
-            while (start != strLen && stripChars.indexOf(str.charAt(start)) != INDEX_NOT_FOUND) {
-                start++;
-            }
-        }
-        return str.substring(start);
-    }
-
-    /**
-     * <p>Strips any of a set of characters from the end of a String.</p>
-     *
-     * <p>A {@code null} input String returns {@code null}.
-     * An empty string ("") input returns the empty string.</p>
-     *
-     * <p>If the stripChars String is {@code null}, whitespace is
-     * stripped as defined by {@link Character#isWhitespace(char)}.</p>
-     *
-     * <pre>
-     * StringUtils.stripEnd(null, *)          = null
-     * StringUtils.stripEnd("", *)            = ""
-     * StringUtils.stripEnd("abc", "")        = "abc"
-     * StringUtils.stripEnd("abc", null)      = "abc"
-     * StringUtils.stripEnd("  abc", null)    = "  abc"
-     * StringUtils.stripEnd("abc  ", null)    = "abc"
-     * StringUtils.stripEnd(" abc ", null)    = " abc"
-     * StringUtils.stripEnd("  abcyx", "xyz") = "  abc"
-     * StringUtils.stripEnd("120.00", ".0")   = "12"
-     * </pre>
-     *
-     * @param str  the String to remove characters from, may be null
-     * @param stripChars  the set of characters to remove, null treated as whitespace
-     * @return the stripped String, {@code null} if null String input
-     */
-    public static String stripEnd(String str, String stripChars) {
-        int end;
-        if (str == null || (end = str.length()) == 0) {
-            return str;
-        }
-
-        if (stripChars == null) {
-            while (end != 0 && Character.isWhitespace(str.charAt(end - 1))) {
-                end--;
-            }
-        } else if (stripChars.length() == 0) {
-            return str;
-        } else {
-            while (end != 0 && stripChars.indexOf(str.charAt(end - 1)) != INDEX_NOT_FOUND) {
-                end--;
-            }
-        }
-        return str.substring(0, end);
-    }
-
-    // StripAll
-    //-----------------------------------------------------------------------
-    /**
-     * <p>Strips whitespace from the start and end of every String in an array.
-     * Whitespace is defined by {@link Character#isWhitespace(char)}.</p>
-     *
-     * <p>A new array is returned each time, except for length zero.
-     * A {@code null} array will return {@code null}.
-     * An empty array will return itself.
-     * A {@code null} array entry will be ignored.</p>
-     *
-     * <pre>
-     * StringUtils.stripAll(null)             = null
-     * StringUtils.stripAll([])               = []
-     * StringUtils.stripAll(["abc", "  abc"]) = ["abc", "abc"]
-     * StringUtils.stripAll(["abc  ", null])  = ["abc", null]
-     * </pre>
-     *
-     * @param strs  the array to remove whitespace from, may be null
-     * @return the stripped Strings, {@code null} if null array input
-     */
-    public static String[] stripAll(String... strs) {
-        return stripAll(strs, null);
-    }
-
-    /**
-     * <p>Strips any of a set of characters from the start and end of every
-     * String in an array.</p>
-     * Whitespace is defined by {@link Character#isWhitespace(char)}.</p>
-     *
-     * <p>A new array is returned each time, except for length zero.
-     * A {@code null} array will return {@code null}.
-     * An empty array will return itself.
-     * A {@code null} array entry will be ignored.
-     * A {@code null} stripChars will strip whitespace as defined by
-     * {@link Character#isWhitespace(char)}.</p>
-     *
-     * <pre>
-     * StringUtils.stripAll(null, *)                = null
-     * StringUtils.stripAll([], *)                  = []
-     * StringUtils.stripAll(["abc", "  abc"], null) = ["abc", "abc"]
-     * StringUtils.stripAll(["abc  ", null], null)  = ["abc", null]
-     * StringUtils.stripAll(["abc  ", null], "yz")  = ["abc  ", null]
-     * StringUtils.stripAll(["yabcz", null], "yz")  = ["abc", null]
-     * </pre>
-     *
-     * @param strs  the array to remove characters from, may be null
-     * @param stripChars  the characters to remove, null treated as whitespace
-     * @return the stripped Strings, {@code null} if null array input
-     */
-    public static String[] stripAll(String[] strs, String stripChars) {
-        int strsLen;
-        if (strs == null || (strsLen = strs.length) == 0) {
-            return strs;
-        }
-        String[] newArr = new String[strsLen];
-        for (int i = 0; i < strsLen; i++) {
-            newArr[i] = strip(strs[i], stripChars);
-        }
-        return newArr;
-    }
-
-    /**
-     * <p>Removes diacritics (~= accents) from a string. The case will not be altered.</p>
-     * <p>For instance, '&agrave;' will be replaced by 'a'.</p>
-     * <p>Note that ligatures will be left as is.</p>
-     *
-     * <p>This method will use the first available implementation of:
-     * Java 6's {@link java.text.Normalizer}, Java 1.3&ndash;1.5's {@code sun.text.Normalizer}</p>
-     *
-     * <pre>
-     * StringUtils.stripAccents(null)                = null
-     * StringUtils.stripAccents("")                  = ""
-     * StringUtils.stripAccents("control")           = "control"
-     * StringUtils.stripAccents("&eacute;clair")     = "eclair"
-     * </pre>
-     *
-     * @param input String to be stripped
-     * @return input text with diacritics removed
-     *
-     * @since 3.0
-     */
-    // See also Lucene's ASCIIFoldingFilter (Lucene 2.9) that replaces accented characters by their unaccented equivalent (and uncommitted bug fix: https://issues.apache.org/jira/browse/LUCENE-1343?focusedCommentId=12858907&page=com.atlassian.jira.plugin.system.issuetabpanels%3Acomment-tabpanel#action_12858907).
-    public static String stripAccents(String input) {
-        if(input == null) {
-            return null;
-        }
-        try {
-            String result = null;
-            if (InitStripAccents.java6NormalizeMethod != null) {
-                result = removeAccentsJava6(input);
-            } else if (InitStripAccents.sunDecomposeMethod != null) {
-                result = removeAccentsSUN(input);
-            } else {
-                throw new UnsupportedOperationException(
-                    "The stripAccents(CharSequence) method requires at least"
-                        +" Java6, but got: "+InitStripAccents.java6Exception
-                        +"; or a Sun JVM: "+InitStripAccents.sunException);
-            }
-            // Note that none of the above methods correctly remove ligatures...
-            return result;
-        } catch(IllegalArgumentException iae) {
-            throw new RuntimeException("IllegalArgumentException occurred", iae);
-        } catch(IllegalAccessException iae) {
-            throw new RuntimeException("IllegalAccessException occurred", iae);
-        } catch(InvocationTargetException ite) {
-            throw new RuntimeException("InvocationTargetException occurred", ite);
-        } catch(SecurityException se) {
-            throw new RuntimeException("SecurityException occurred", se);
-        }
-    }
-
-    /**
-     * Use {@code java.text.Normalizer#normalize(CharSequence, Normalizer.Form)}
-     * (but be careful, this class exists in Java 1.3, with an entirely different meaning!)
-     *
-     * @param text the text to be processed
-     * @return the processed string
-     * @throws IllegalAccessException may be thrown by a reflection call
-     * @throws InvocationTargetException if a reflection call throws an exception
-     * @throws IllegalStateException if the {@code Normalizer} class is not available
-     */
-    private static String removeAccentsJava6(CharSequence text)
-        throws IllegalAccessException, InvocationTargetException {
-        /*
-        String decomposed = java.text.Normalizer.normalize(CharSequence, Normalizer.Form.NFD);
-        return java6Pattern.matcher(decomposed).replaceAll("");//$NON-NLS-1$
-        */
-        if (InitStripAccents.java6NormalizeMethod == null || InitStripAccents.java6NormalizerFormNFD == null) {
-            throw new IllegalStateException("java.text.Normalizer is not available", InitStripAccents.java6Exception);
-        }
-        String result;
-        result = (String) InitStripAccents.java6NormalizeMethod.invoke(null, new Object[] {text, InitStripAccents.java6NormalizerFormNFD});
-        result = InitStripAccents.java6Pattern.matcher(result).replaceAll("");//$NON-NLS-1$
-        return result;
-    }
-
-    /**
-     * Use {@code sun.text.Normalizer#decompose(String, boolean, int)}
-     *
-     * @param text the text to be processed
-     * @return the processed string
-     * @throws IllegalAccessException may be thrown by a reflection call
-     * @throws InvocationTargetException if a reflection call throws an exception
-     * @throws IllegalStateException if the {@code Normalizer} class is not available
-     */
-    private static String removeAccentsSUN(CharSequence text)
-        throws IllegalAccessException, InvocationTargetException {
-        /*
-        String decomposed = sun.text.Normalizer.decompose(text, false, 0);
-        return sunPattern.matcher(decomposed).replaceAll("");//$NON-NLS-1$
-        */
-        if (InitStripAccents.sunDecomposeMethod == null) {
-            throw new IllegalStateException("sun.text.Normalizer is not available", InitStripAccents.sunException);
-        }
-        String result;
-        result = (String) InitStripAccents.sunDecomposeMethod.invoke(null, new Object[] {text, Boolean.FALSE, Integer.valueOf(0)});
-        result = InitStripAccents.sunPattern.matcher(result).replaceAll("");//$NON-NLS-1$
-        return result;
-    }
-
-    // IOD container for stripAccent() initialisation
-    private static class InitStripAccents {
-        // SUN internal, Java 1.3 -> Java 5
-        private static final Throwable sunException;
-        private static final Method  sunDecomposeMethod;
-        private static final Pattern sunPattern = Pattern.compile("\\p{InCombiningDiacriticalMarks}+");//$NON-NLS-1$
-        // Java 6+
-        private static final Throwable java6Exception;
-        private static final Method  java6NormalizeMethod;
-        private static final Object  java6NormalizerFormNFD;
-        private static final Pattern java6Pattern = sunPattern;
-    
-        static {
-            // Set up defaults for final static fields
-            Object _java6NormalizerFormNFD = null;
-            Method _java6NormalizeMethod = null;
-            Method _sunDecomposeMethod = null;
-            Throwable _java6Exception = null;
-            Throwable _sunException = null;
-            try {
-                // java.text.Normalizer.normalize(CharSequence, Normalizer.Form.NFD);
-                // Be careful not to get Java 1.3 java.text.Normalizer!
-                Class<?> normalizerFormClass = Thread.currentThread().getContextClassLoader()
-                    .loadClass("java.text.Normalizer$Form");//$NON-NLS-1$
-                _java6NormalizerFormNFD = normalizerFormClass.getField("NFD").get(null);//$NON-NLS-1$
-                Class<?> normalizerClass = Thread.currentThread().getContextClassLoader()
-                    .loadClass("java.text.Normalizer");//$NON-NLS-1$
-                _java6NormalizeMethod = normalizerClass.getMethod("normalize",//$NON-NLS-1$
-                        new Class[] {CharSequence.class, normalizerFormClass});//$NON-NLS-1$
-            } catch (Exception e1) {
-                // Only check for Sun method if Java 6 method is not available
-                _java6Exception = e1;
-                try {
-                    // sun.text.Normalizer.decompose(text, false, 0);
-                    Class<?> normalizerClass = Thread.currentThread().getContextClassLoader()
-                        .loadClass("sun.text.Normalizer");//$NON-NLS-1$
-                    _sunDecomposeMethod = normalizerClass.getMethod("decompose",//$NON-NLS-1$
-                            new Class[] {String.class, Boolean.TYPE, Integer.TYPE});//$NON-NLS-1$
-                } catch (Exception e2) {
-                    _sunException = e2;
-                }
-            }
-    
-            // Set up final static fields
-            java6Exception = _java6Exception;
-            java6NormalizerFormNFD = _java6NormalizerFormNFD;
-            java6NormalizeMethod = _java6NormalizeMethod;
-            sunException = _sunException;
-            sunDecomposeMethod = _sunDecomposeMethod;
-        }
-    }
-
-    // Equals
-    //-----------------------------------------------------------------------
-    /**
-     * <p>Compares two CharSequences, returning {@code true} if they are equal.</p>
-     *
-     * <p>{@code null}s are handled without exceptions. Two {@code null}
-     * references are considered to be equal. The comparison is case sensitive.</p>
-     *
-     * <pre>
-     * StringUtils.equals(null, null)   = true
-     * StringUtils.equals(null, "abc")  = false
-     * StringUtils.equals("abc", null)  = false
-     * StringUtils.equals("abc", "abc") = true
-     * StringUtils.equals("abc", "ABC") = false
-     * </pre>
-     *
-     * @see java.lang.String#equals(Object)
-     * @param cs1  the first CharSequence, may be null
-     * @param cs2  the second CharSequence, may be null
-     * @return {@code true} if the CharSequences are equal, case sensitive, or
-     *  both {@code null}
-     * @since 3.0 Changed signature from equals(String, String) to equals(CharSequence, CharSequence)
-     */
-    public static boolean equals(CharSequence cs1, CharSequence cs2) {
-        return cs1 == null ? cs2 == null : cs1.equals(cs2);
-    }
-
-    /**
-     * <p>Compares two CharSequences, returning {@code true} if they are equal ignoring
-     * the case.</p>
-     *
-     * <p>{@code null}s are handled without exceptions. Two {@code null}
-     * references are considered equal. Comparison is case insensitive.</p>
-     *
-     * <pre>
-     * StringUtils.equalsIgnoreCase(null, null)   = true
-     * StringUtils.equalsIgnoreCase(null, "abc")  = false
-     * StringUtils.equalsIgnoreCase("abc", null)  = false
-     * StringUtils.equalsIgnoreCase("abc", "abc") = true
-     * StringUtils.equalsIgnoreCase("abc", "ABC") = true
-     * </pre>
-     *
-     * @param str1  the first CharSequence, may be null
-     * @param str2  the second CharSequence, may be null
-     * @return {@code true} if the CharSequence are equal, case insensitive, or
-     *  both {@code null}
-     * @since 3.0 Changed signature from equalsIgnoreCase(String, String) to equalsIgnoreCase(CharSequence, CharSequence)
-     */
-    public static boolean equalsIgnoreCase(CharSequence str1, CharSequence str2) {
-        if (str1 == null || str2 == null) {
-            return str1 == str2;
-        } else {
-            return CharSequenceUtils.regionMatches(str1, true, 0, str2, 0, Math.max(str1.length(), str2.length()));
-        }
-    }
-
-    // IndexOf
-    //-----------------------------------------------------------------------
-    /**
-     * <p>Finds the first index within a CharSequence, handling {@code null}.
-     * This method uses {@link String#indexOf(int, int)} if possible.</p>
-     *
-     * <p>A {@code null} or empty ("") CharSequence will return {@code INDEX_NOT_FOUND (-1)}.</p>
-     *
-     * <pre>
-     * StringUtils.indexOf(null, *)         = -1
-     * StringUtils.indexOf("", *)           = -1
-     * StringUtils.indexOf("aabaabaa", 'a') = 0
-     * StringUtils.indexOf("aabaabaa", 'b') = 2
-     * </pre>
-     *
-     * @param seq  the CharSequence to check, may be null
-     * @param searchChar  the character to find
-     * @return the first index of the search character,
-     *  -1 if no match or {@code null} string input
-     * @since 2.0
-     * @since 3.0 Changed signature from indexOf(String, int) to indexOf(CharSequence, int)
-     */
-    public static int indexOf(CharSequence seq, int searchChar) {
-        if (isEmpty(seq)) {
-            return INDEX_NOT_FOUND;
-        }
-        return CharSequenceUtils.indexOf(seq, searchChar, 0);
-    }
-
-    /**
-     * <p>Finds the first index within a CharSequence from a start position,
-     * handling {@code null}.
-     * This method uses {@link String#indexOf(int, int)} if possible.</p>
-     *
-     * <p>A {@code null} or empty ("") CharSequence will return {@code (INDEX_NOT_FOUND) -1}.
-     * A negative start position is treated as zero.
-     * A start position greater than the string length returns {@code -1}.</p>
-     *
-     * <pre>
-     * StringUtils.indexOf(null, *, *)          = -1
-     * StringUtils.indexOf("", *, *)            = -1
-     * StringUtils.indexOf("aabaabaa", 'b', 0)  = 2
-     * StringUtils.indexOf("aabaabaa", 'b', 3)  = 5
-     * StringUtils.indexOf("aabaabaa", 'b', 9)  = -1
-     * StringUtils.indexOf("aabaabaa", 'b', -1) = 2
-     * </pre>
-     *
-     * @param seq  the CharSequence to check, may be null
-     * @param searchChar  the character to find
-     * @param startPos  the start position, negative treated as zero
-     * @return the first index of the search character,
-     *  -1 if no match or {@code null} string input
-     * @since 2.0
-     * @since 3.0 Changed signature from indexOf(String, int, int) to indexOf(CharSequence, int, int)
-     */
-    public static int indexOf(CharSequence seq, int searchChar, int startPos) {
-        if (isEmpty(seq)) {
-            return INDEX_NOT_FOUND;
-        }
-        return CharSequenceUtils.indexOf(seq, searchChar, startPos);
-    }
-
-    /**
-     * <p>Finds the first index within a CharSequence, handling {@code null}.
-     * This method uses {@link String#indexOf(String, int)} if possible.</p>
-     *
-     * <p>A {@code null} CharSequence will return {@code -1}.</p>
-     *
-     * <pre>
-     * StringUtils.indexOf(null, *)          = -1
-     * StringUtils.indexOf(*, null)          = -1
-     * StringUtils.indexOf("", "")           = 0
-     * StringUtils.indexOf("", *)            = -1 (except when * = "")
-     * StringUtils.indexOf("aabaabaa", "a")  = 0
-     * StringUtils.indexOf("aabaabaa", "b")  = 2
-     * StringUtils.indexOf("aabaabaa", "ab") = 1
-     * StringUtils.indexOf("aabaabaa", "")   = 0
-     * </pre>
-     *
-     * @param seq  the CharSequence to check, may be null
-     * @param searchSeq  the CharSequence to find, may be null
-     * @return the first index of the search CharSequence,
-     *  -1 if no match or {@code null} string input
-     * @since 2.0
-     * @since 3.0 Changed signature from indexOf(String, String) to indexOf(CharSequence, CharSequence)
-     */
-    public static int indexOf(CharSequence seq, CharSequence searchSeq) {
-        if (seq == null || searchSeq == null) {
-            return INDEX_NOT_FOUND;
-        }
-        return CharSequenceUtils.indexOf(seq, searchSeq, 0);
-    }
-
-    /**
-     * <p>Finds the first index within a CharSequence, handling {@code null}.
-     * This method uses {@link String#indexOf(String, int)} if possible.</p>
-     *
-     * <p>A {@code null} CharSequence will return {@code -1}.
-     * A negative start position is treated as zero.
-     * An empty ("") search CharSequence always matches.
-     * A start position greater than the string length only matches
-     * an empty search CharSequence.</p>
-     *
-     * <pre>
-     * StringUtils.indexOf(null, *, *)          = -1
-     * StringUtils.indexOf(*, null, *)          = -1
-     * StringUtils.indexOf("", "", 0)           = 0
-     * StringUtils.indexOf("", *, 0)            = -1 (except when * = "")
-     * StringUtils.indexOf("aabaabaa", "a", 0)  = 0
-     * StringUtils.indexOf("aabaabaa", "b", 0)  = 2
-     * StringUtils.indexOf("aabaabaa", "ab", 0) = 1
-     * StringUtils.indexOf("aabaabaa", "b", 3)  = 5
-     * StringUtils.indexOf("aabaabaa", "b", 9)  = -1
-     * StringUtils.indexOf("aabaabaa", "b", -1) = 2
-     * StringUtils.indexOf("aabaabaa", "", 2)   = 2
-     * StringUtils.indexOf("abc", "", 9)        = 3
-     * </pre>
-     *
-     * @param seq  the CharSequence to check, may be null
-     * @param searchSeq  the CharSequence to find, may be null
-     * @param startPos  the start position, negative treated as zero
-     * @return the first index of the search CharSequence,
-     *  -1 if no match or {@code null} string input
-     * @since 2.0
-     * @since 3.0 Changed signature from indexOf(String, String, int) to indexOf(CharSequence, CharSequence, int)
-     */
-    public static int indexOf(CharSequence seq, CharSequence searchSeq, int startPos) {
-        if (seq == null || searchSeq == null) {
-            return INDEX_NOT_FOUND;
-        }
-        return CharSequenceUtils.indexOf(seq, searchSeq, startPos);
-    }
-
-    /**
-     * <p>Finds the n-th index within a CharSequence, handling {@code null}.
-     * This method uses {@link String#indexOf(String)} if possible.</p>
-     *
-     * <p>A {@code null} CharSequence will return {@code -1}.</p>
-     *
-     * <pre>
-     * StringUtils.ordinalIndexOf(null, *, *)          = -1
-     * StringUtils.ordinalIndexOf(*, null, *)          = -1
-     * StringUtils.ordinalIndexOf("", "", *)           = 0
-     * StringUtils.ordinalIndexOf("aabaabaa", "a", 1)  = 0
-     * StringUtils.ordinalIndexOf("aabaabaa", "a", 2)  = 1
-     * StringUtils.ordinalIndexOf("aabaabaa", "b", 1)  = 2
-     * StringUtils.ordinalIndexOf("aabaabaa", "b", 2)  = 5
-     * StringUtils.ordinalIndexOf("aabaabaa", "ab", 1) = 1
-     * StringUtils.ordinalIndexOf("aabaabaa", "ab", 2) = 4
-     * StringUtils.ordinalIndexOf("aabaabaa", "", 1)   = 0
-     * StringUtils.ordinalIndexOf("aabaabaa", "", 2)   = 0
-     * </pre>
-     *
-     * <p>Note that 'head(CharSequence str, int n)' may be implemented as: </p>
-     *
-     * <pre>
-     *   str.substring(0, lastOrdinalIndexOf(str, "\n", n))
-     * </pre>
-     *
-     * @param str  the CharSequence to check, may be null
-     * @param searchStr  the CharSequence to find, may be null
-     * @param ordinal  the n-th {@code searchStr} to find
-     * @return the n-th index of the search CharSequence,
-     *  {@code -1} ({@code INDEX_NOT_FOUND}) if no match or {@code null} string input
-     * @since 2.1
-     * @since 3.0 Changed signature from ordinalIndexOf(String, String, int) to ordinalIndexOf(CharSequence, CharSequence, int)
-     */
-    public static int ordinalIndexOf(CharSequence str, CharSequence searchStr, int ordinal) {
-        return ordinalIndexOf(str, searchStr, ordinal, false);
-    }
-
-    /**
-     * <p>Finds the n-th index within a String, handling {@code null}.
-     * This method uses {@link String#indexOf(String)} if possible.</p>
-     *
-     * <p>A {@code null} CharSequence will return {@code -1}.</p>
-     *
-     * @param str  the CharSequence to check, may be null
-     * @param searchStr  the CharSequence to find, may be null
-     * @param ordinal  the n-th {@code searchStr} to find
-     * @param lastIndex true if lastOrdinalIndexOf() otherwise false if ordinalIndexOf()
-     * @return the n-th index of the search CharSequence,
-     *  {@code -1} ({@code INDEX_NOT_FOUND}) if no match or {@code null} string input
-     */
-    // Shared code between ordinalIndexOf(String,String,int) and lastOrdinalIndexOf(String,String,int)
-    private static int ordinalIndexOf(CharSequence str, CharSequence searchStr, int ordinal, boolean lastIndex) {
-        if (str == null || searchStr == null || ordinal <= 0) {
-            return INDEX_NOT_FOUND;
-        }
-        if (searchStr.length() == 0) {
-            return lastIndex ? str.length() : 0;
-        }
-        int found = 0;
-        int index = lastIndex ? str.length() : INDEX_NOT_FOUND;
-        do {
-            if (lastIndex) {
-                index = CharSequenceUtils.lastIndexOf(str, searchStr, index - 1);
-            } else {
-                index = CharSequenceUtils.indexOf(str, searchStr, index + 1);
-            }
-            if (index < 0) {
-                return index;
-            }
-            found++;
-        } while (found < ordinal);
-        return index;
-    }
-
-    /**
-     * <p>Case in-sensitive find of the first index within a CharSequence.</p>
-     *
-     * <p>A {@code null} CharSequence will return {@code -1}.
-     * A negative start position is treated as zero.
-     * An empty ("") search CharSequence always matches.
-     * A start position greater than the string length only matches
-     * an empty search CharSequence.</p>
-     *
-     * <pre>
-     * StringUtils.indexOfIgnoreCase(null, *)          = -1
-     * StringUtils.indexOfIgnoreCase(*, null)          = -1
-     * StringUtils.indexOfIgnoreCase("", "")           = 0
-     * StringUtils.indexOfIgnoreCase("aabaabaa", "a")  = 0
-     * StringUtils.indexOfIgnoreCase("aabaabaa", "b")  = 2
-     * StringUtils.indexOfIgnoreCase("aabaabaa", "ab") = 1
-     * </pre>
-     *
-     * @param str  the CharSequence to check, may be null
-     * @param searchStr  the CharSequence to find, may be null
-     * @return the first index of the search CharSequence,
-     *  -1 if no match or {@code null} string input
-     * @since 2.5
-     * @since 3.0 Changed signature from indexOfIgnoreCase(String, String) to indexOfIgnoreCase(CharSequence, CharSequence)
-     */
-    public static int indexOfIgnoreCase(CharSequence str, CharSequence searchStr) {
-        return indexOfIgnoreCase(str, searchStr, 0);
-    }
-
-    /**
-     * <p>Case in-sensitive find of the first index within a CharSequence
-     * from the specified position.</p>
-     *
-     * <p>A {@code null} CharSequence will return {@code -1}.
-     * A negative start position is treated as zero.
-     * An empty ("") search CharSequence always matches.
-     * A start position greater than the string length only matches
-     * an empty search CharSequence.</p>
-     *
-     * <pre>
-     * StringUtils.indexOfIgnoreCase(null, *, *)          = -1
-     * StringUtils.indexOfIgnoreCase(*, null, *)          = -1
-     * StringUtils.indexOfIgnoreCase("", "", 0)           = 0
-     * StringUtils.indexOfIgnoreCase("aabaabaa", "A", 0)  = 0
-     * StringUtils.indexOfIgnoreCase("aabaabaa", "B", 0)  = 2
-     * StringUtils.indexOfIgnoreCase("aabaabaa", "AB", 0) = 1
-     * StringUtils.indexOfIgnoreCase("aabaabaa", "B", 3)  = 5
-     * StringUtils.indexOfIgnoreCase("aabaabaa", "B", 9)  = -1
-     * StringUtils.indexOfIgnoreCase("aabaabaa", "B", -1) = 2
-     * StringUtils.indexOfIgnoreCase("aabaabaa", "", 2)   = 2
-     * StringUtils.indexOfIgnoreCase("abc", "", 9)        = 3
-     * </pre>
-     *
-     * @param str  the CharSequence to check, may be null
-     * @param searchStr  the CharSequence to find, may be null
-     * @param startPos  the start position, negative treated as zero
-     * @return the first index of the search CharSequence,
-     *  -1 if no match or {@code null} string input
-     * @since 2.5
-     * @since 3.0 Changed signature from indexOfIgnoreCase(String, String, int) to indexOfIgnoreCase(CharSequence, CharSequence, int)
-     */
-    public static int indexOfIgnoreCase(CharSequence str, CharSequence searchStr, int startPos) {
-        if (str == null || searchStr == null) {
-            return INDEX_NOT_FOUND;
-        }
-        if (startPos < 0) {
-            startPos = 0;
-        }
-        int endLimit = str.length() - searchStr.length() + 1;
-        if (startPos > endLimit) {
-            return INDEX_NOT_FOUND;
-        }
-        if (searchStr.length() == 0) {
-            return startPos;
-        }
-        for (int i = startPos; i < endLimit; i++) {
-            if (CharSequenceUtils.regionMatches(str, true, i, searchStr, 0, searchStr.length())) {
-                return i;
-            }
-        }
-        return INDEX_NOT_FOUND;
-    }
-
-    // LastIndexOf
-    //-----------------------------------------------------------------------
-    /**
-     * <p>Finds the last index within a CharSequence, handling {@code null}.
-     * This method uses {@link String#lastIndexOf(int)} if possible.</p>
-     *
-     * <p>A {@code null} or empty ("") CharSequence will return {@code -1}.</p>
-     *
-     * <pre>
-     * StringUtils.lastIndexOf(null, *)         = -1
-     * StringUtils.lastIndexOf("", *)           = -1
-     * StringUtils.lastIndexOf("aabaabaa", 'a') = 7
-     * StringUtils.lastIndexOf("aabaabaa", 'b') = 5
-     * </pre>
-     *
-     * @param seq  the CharSequence to check, may be null
-     * @param searchChar  the character to find
-     * @return the last index of the search character,
-     *  -1 if no match or {@code null} string input
-     * @since 2.0
-     * @since 3.0 Changed signature from lastIndexOf(String, int) to lastIndexOf(CharSequence, int)
-     */
-    public static int lastIndexOf(CharSequence seq, int searchChar) {
-        if (isEmpty(seq)) {
-            return INDEX_NOT_FOUND;
-        }
-        return CharSequenceUtils.lastIndexOf(seq, searchChar, seq.length());
-    }
-
-    /**
-     * <p>Finds the last index within a CharSequence from a start position,
-     * handling {@code null}.
-     * This method uses {@link String#lastIndexOf(int, int)} if possible.</p>
-     *
-     * <p>A {@code null} or empty ("") CharSequence will return {@code -1}.
-     * A negative start position returns {@code -1}.
-     * A start position greater than the string length searches the whole string.</p>
-     *
-     * <pre>
-     * StringUtils.lastIndexOf(null, *, *)          = -1
-     * StringUtils.lastIndexOf("", *,  *)           = -1
-     * StringUtils.lastIndexOf("aabaabaa", 'b', 8)  = 5
-     * StringUtils.lastIndexOf("aabaabaa", 'b', 4)  = 2
-     * StringUtils.lastIndexOf("aabaabaa", 'b', 0)  = -1
-     * StringUtils.lastIndexOf("aabaabaa", 'b', 9)  = 5
-     * StringUtils.lastIndexOf("aabaabaa", 'b', -1) = -1
-     * StringUtils.lastIndexOf("aabaabaa", 'a', 0)  = 0
-     * </pre>
-     *
-     * @param seq  the CharSequence to check, may be null
-     * @param searchChar  the character to find
-     * @param startPos  the start position
-     * @return the last index of the search character,
-     *  -1 if no match or {@code null} string input
-     * @since 2.0
-     * @since 3.0 Changed signature from lastIndexOf(String, int, int) to lastIndexOf(CharSequence, int, int)
-     */
-    public static int lastIndexOf(CharSequence seq, int searchChar, int startPos) {
-        if (isEmpty(seq)) {
-            return INDEX_NOT_FOUND;
-        }
-        return CharSequenceUtils.lastIndexOf(seq, searchChar, startPos);
-    }
-
-    /**
-     * <p>Finds the last index within a CharSequence, handling {@code null}.
-     * This method uses {@link String#lastIndexOf(String)} if possible.</p>
-     *
-     * <p>A {@code null} CharSequence will return {@code -1}.</p>
-     *
-     * <pre>
-     * StringUtils.lastIndexOf(null, *)          = -1
-     * StringUtils.lastIndexOf(*, null)          = -1
-     * StringUtils.lastIndexOf("", "")           = 0
-     * StringUtils.lastIndexOf("aabaabaa", "a")  = 7
-     * StringUtils.lastIndexOf("aabaabaa", "b")  = 5
-     * StringUtils.lastIndexOf("aabaabaa", "ab") = 4
-     * StringUtils.lastIndexOf("aabaabaa", "")   = 8
-     * </pre>
-     *
-     * @param seq  the CharSequence to check, may be null
-     * @param searchSeq  the CharSequence to find, may be null
-     * @return the last index of the search String,
-     *  -1 if no match or {@code null} string input
-     * @since 2.0
-     * @since 3.0 Changed signature from lastIndexOf(String, String) to lastIndexOf(CharSequence, CharSequence)
-     */
-    public static int lastIndexOf(CharSequence seq, CharSequence searchSeq) {
-        if (seq == null || searchSeq == null) {
-            return INDEX_NOT_FOUND;
-        }
-        return CharSequenceUtils.lastIndexOf(seq, searchSeq, seq.length());
-    }
-
-    /**
-     * <p>Finds the n-th last index within a String, handling {@code null}.
-     * This method uses {@link String#lastIndexOf(String)}.</p>
-     *
-     * <p>A {@code null} String will return {@code -1}.</p>
-     *
-     * <pre>
-     * StringUtils.lastOrdinalIndexOf(null, *, *)          = -1
-     * StringUtils.lastOrdinalIndexOf(*, null, *)          = -1
-     * StringUtils.lastOrdinalIndexOf("", "", *)           = 0
-     * StringUtils.lastOrdinalIndexOf("aabaabaa", "a", 1)  = 7
-     * StringUtils.lastOrdinalIndexOf("aabaabaa", "a", 2)  = 6
-     * StringUtils.lastOrdinalIndexOf("aabaabaa", "b", 1)  = 5
-     * StringUtils.lastOrdinalIndexOf("aabaabaa", "b", 2)  = 2
-     * StringUtils.lastOrdinalIndexOf("aabaabaa", "ab", 1) = 4
-     * StringUtils.lastOrdinalIndexOf("aabaabaa", "ab", 2) = 1
-     * StringUtils.lastOrdinalIndexOf("aabaabaa", "", 1)   = 8
-     * StringUtils.lastOrdinalIndexOf("aabaabaa", "", 2)   = 8
-     * </pre>
-     *
-     * <p>Note that 'tail(CharSequence str, int n)' may be implemented as: </p>
-     *
-     * <pre>
-     *   str.substring(lastOrdinalIndexOf(str, "\n", n) + 1)
-     * </pre>
-     *
-     * @param str  the CharSequence to check, may be null
-     * @param searchStr  the CharSequence to find, may be null
-     * @param ordinal  the n-th last {@code searchStr} to find
-     * @return the n-th last index of the search CharSequence,
-     *  {@code -1} ({@code INDEX_NOT_FOUND}) if no match or {@code null} string input
-     * @since 2.5
-     * @since 3.0 Changed signature from lastOrdinalIndexOf(String, String, int) to lastOrdinalIndexOf(CharSequence, CharSequence, int)
-     */
-    public static int lastOrdinalIndexOf(CharSequence str, CharSequence searchStr, int ordinal) {
-        return ordinalIndexOf(str, searchStr, ordinal, true);
-    }
-
-    /**
-     * <p>Finds the first index within a CharSequence, handling {@code null}.
-     * This method uses {@link String#lastIndexOf(String, int)} if possible.</p>
-     *
-     * <p>A {@code null} CharSequence will return {@code -1}.
-     * A negative start position returns {@code -1}.
-     * An empty ("") search CharSequence always matches unless the start position is negative.
-     * A start position greater than the string length searches the whole string.</p>
-     *
-     * <pre>
-     * StringUtils.lastIndexOf(null, *, *)          = -1
-     * StringUtils.lastIndexOf(*, null, *)          = -1
-     * StringUtils.lastIndexOf("aabaabaa", "a", 8)  = 7
-     * StringUtils.lastIndexOf("aabaabaa", "b", 8)  = 5
-     * StringUtils.lastIndexOf("aabaabaa", "ab", 8) = 4
-     * StringUtils.lastIndexOf("aabaabaa", "b", 9)  = 5
-     * StringUtils.lastIndexOf("aabaabaa", "b", -1) = -1
-     * StringUtils.lastIndexOf("aabaabaa", "a", 0)  = 0
-     * StringUtils.lastIndexOf("aabaabaa", "b", 0)  = -1
-     * </pre>
-     *
-     * @param seq  the CharSequence to check, may be null
-     * @param searchSeq  the CharSequence to find, may be null
-     * @param startPos  the start position, negative treated as zero
-     * @return the first index of the search CharSequence,
-     *  -1 if no match or {@code null} string input
-     * @since 2.0
-     * @since 3.0 Changed signature from lastIndexOf(String, String, int) to lastIndexOf(CharSequence, CharSequence, int)
-     */
-    public static int lastIndexOf(CharSequence seq, CharSequence searchSeq, int startPos) {
-        if (seq == null || searchSeq == null) {
-            return INDEX_NOT_FOUND;
-        }
-        return CharSequenceUtils.lastIndexOf(seq, searchSeq, startPos);
-    }
-
-    /**
-     * <p>Case in-sensitive find of the last index within a CharSequence.</p>
-     *
-     * <p>A {@code null} CharSequence will return {@code -1}.
-     * A negative start position returns {@code -1}.
-     * An empty ("") search CharSequence always matches unless the start position is negative.
-     * A start position greater than the string length searches the whole string.</p>
-     *
-     * <pre>
-     * StringUtils.lastIndexOfIgnoreCase(null, *)          = -1
-     * StringUtils.lastIndexOfIgnoreCase(*, null)          = -1
-     * StringUtils.lastIndexOfIgnoreCase("aabaabaa", "A")  = 7
-     * StringUtils.lastIndexOfIgnoreCase("aabaabaa", "B")  = 5
-     * StringUtils.lastIndexOfIgnoreCase("aabaabaa", "AB") = 4
-     * </pre>
-     *
-     * @param str  the CharSequence to check, may be null
-     * @param searchStr  the CharSequence to find, may be null
-     * @return the first index of the search CharSequence,
-     *  -1 if no match or {@code null} string input
-     * @since 2.5
-     * @since 3.0 Changed signature from lastIndexOfIgnoreCase(String, String) to lastIndexOfIgnoreCase(CharSequence, CharSequence)
-     */
-    public static int lastIndexOfIgnoreCase(CharSequence str, CharSequence searchStr) {
-        if (str == null || searchStr == null) {
-            return INDEX_NOT_FOUND;
-        }
-        return lastIndexOfIgnoreCase(str, searchStr, str.length());
-    }
-
-    /**
-     * <p>Case in-sensitive find of the last index within a CharSequence
-     * from the specified position.</p>
-     *
-     * <p>A {@code null} CharSequence will return {@code -1}.
-     * A negative start position returns {@code -1}.
-     * An empty ("") search CharSequence always matches unless the start position is negative.
-     * A start position greater than the string length searches the whole string.</p>
-     *
-     * <pre>
-     * StringUtils.lastIndexOfIgnoreCase(null, *, *)          = -1
-     * StringUtils.lastIndexOfIgnoreCase(*, null, *)          = -1
-     * StringUtils.lastIndexOfIgnoreCase("aabaabaa", "A", 8)  = 7
-     * StringUtils.lastIndexOfIgnoreCase("aabaabaa", "B", 8)  = 5
-     * StringUtils.lastIndexOfIgnoreCase("aabaabaa", "AB", 8) = 4
-     * StringUtils.lastIndexOfIgnoreCase("aabaabaa", "B", 9)  = 5
-     * StringUtils.lastIndexOfIgnoreCase("aabaabaa", "B", -1) = -1
-     * StringUtils.lastIndexOfIgnoreCase("aabaabaa", "A", 0)  = 0
-     * StringUtils.lastIndexOfIgnoreCase("aabaabaa", "B", 0)  = -1
-     * </pre>
-     *
-     * @param str  the CharSequence to check, may be null
-     * @param searchStr  the CharSequence to find, may be null
-     * @param startPos  the start position
-     * @return the first index of the search CharSequence,
-     *  -1 if no match or {@code null} input
-     * @since 2.5
-     * @since 3.0 Changed signature from lastIndexOfIgnoreCase(String, String, int) to lastIndexOfIgnoreCase(CharSequence, CharSequence, int)
-     */
-    public static int lastIndexOfIgnoreCase(CharSequence str, CharSequence searchStr, int startPos) {
-        if (str == null || searchStr == null) {
-            return INDEX_NOT_FOUND;
-        }
-        if (startPos > str.length() - searchStr.length()) {
-            startPos = str.length() - searchStr.length();
-        }
-        if (startPos < 0) {
-            return INDEX_NOT_FOUND;
-        }
-        if (searchStr.length() == 0) {
-            return startPos;
-        }
-
-        for (int i = startPos; i >= 0; i--) {
-            if (CharSequenceUtils.regionMatches(str, true, i, searchStr, 0, searchStr.length())) {
-                return i;
-            }
-        }
-        return INDEX_NOT_FOUND;
-    }
-
-    // Contains
-    //-----------------------------------------------------------------------
-    /**
-     * <p>Checks if CharSequence contains a search character, handling {@code null}.
-     * This method uses {@link String#indexOf(int)} if possible.</p>
-     *
-     * <p>A {@code null} or empty ("") CharSequence will return {@code false}.</p>
-     *
-     * <pre>
-     * StringUtils.contains(null, *)    = false
-     * StringUtils.contains("", *)      = false
-     * StringUtils.contains("abc", 'a') = true
-     * StringUtils.contains("abc", 'z') = false
-     * </pre>
-     *
-     * @param seq  the CharSequence to check, may be null
-     * @param searchChar  the character to find
-     * @return true if the CharSequence contains the search character,
-     *  false if not or {@code null} string input
-     * @since 2.0
-     * @since 3.0 Changed signature from contains(String, int) to contains(CharSequence, int)
-     */
-    public static boolean contains(CharSequence seq, int searchChar) {
-        if (isEmpty(seq)) {
-            return false;
-        }
-        return CharSequenceUtils.indexOf(seq, searchChar, 0) >= 0;
-    }
-
-    /**
-     * <p>Checks if CharSequence contains a search CharSequence, handling {@code null}.
-     * This method uses {@link String#indexOf(String)} if possible.</p>
-     *
-     * <p>A {@code null} CharSequence will return {@code false}.</p>
-     *
-     * <pre>
-     * StringUtils.contains(null, *)     = false
-     * StringUtils.contains(*, null)     = false
-     * StringUtils.contains("", "")      = true
-     * StringUtils.contains("abc", "")   = true
-     * StringUtils.contains("abc", "a")  = true
-     * StringUtils.contains("abc", "z")  = false
-     * </pre>
-     *
-     * @param seq  the CharSequence to check, may be null
-     * @param searchSeq  the CharSequence to find, may be null
-     * @return true if the CharSequence contains the search CharSequence,
-     *  false if not or {@code null} string input
-     * @since 2.0
-     * @since 3.0 Changed signature from contains(String, String) to contains(CharSequence, CharSequence)
-     */
-    public static boolean contains(CharSequence seq, CharSequence searchSeq) {
-        if (seq == null || searchSeq == null) {
-            return false;
-        }
-        return CharSequenceUtils.indexOf(seq, searchSeq, 0) >= 0;
-    }
-
-    /**
-     * <p>Checks if CharSequence contains a search CharSequence irrespective of case,
-     * handling {@code null}. Case-insensitivity is defined as by
-     * {@link String#equalsIgnoreCase(String)}.
-     *
-     * <p>A {@code null} CharSequence will return {@code false}.</p>
-     *
-     * <pre>
-     * StringUtils.contains(null, *) = false
-     * StringUtils.contains(*, null) = false
-     * StringUtils.contains("", "") = true
-     * StringUtils.contains("abc", "") = true
-     * StringUtils.contains("abc", "a") = true
-     * StringUtils.contains("abc", "z") = false
-     * StringUtils.contains("abc", "A") = true
-     * StringUtils.contains("abc", "Z") = false
-     * </pre>
-     *
-     * @param str  the CharSequence to check, may be null
-     * @param searchStr  the CharSequence to find, may be null
-     * @return true if the CharSequence contains the search CharSequence irrespective of
-     * case or false if not or {@code null} string input
-     * @since 3.0 Changed signature from containsIgnoreCase(String, String) to containsIgnoreCase(CharSequence, CharSequence)
-     */
-    public static boolean containsIgnoreCase(CharSequence str, CharSequence searchStr) {
-        if (str == null || searchStr == null) {
-            return false;
-        }
-        int len = searchStr.length();
-        int max = str.length() - len;
-        for (int i = 0; i <= max; i++) {
-            if (CharSequenceUtils.regionMatches(str, true, i, searchStr, 0, len)) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    /**
-     * Check whether the given CharSequence contains any whitespace characters.
-     * @param seq the CharSequence to check (may be {@code null})
-     * @return {@code true} if the CharSequence is not empty and
-     * contains at least 1 whitespace character
-     * @see java.lang.Character#isWhitespace
-     * @since 3.0
-     */
-    // From org.springframework.util.StringUtils, under Apache License 2.0
-    public static boolean containsWhitespace(CharSequence seq) {
-        if (isEmpty(seq)) {
-            return false;
-        }
-        int strLen = seq.length();
-        for (int i = 0; i < strLen; i++) {
-            if (Character.isWhitespace(seq.charAt(i))) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    // IndexOfAny chars
-    //-----------------------------------------------------------------------
-    /**
-     * <p>Search a CharSequence to find the first index of any
-     * character in the given set of characters.</p>
-     *
-     * <p>A {@code null} String will return {@code -1}.
-     * A {@code null} or zero length search array will return {@code -1}.</p>
-     *
-     * <pre>
-     * StringUtils.indexOfAny(null, *)                = -1
-     * StringUtils.indexOfAny("", *)                  = -1
-     * StringUtils.indexOfAny(*, null)                = -1
-     * StringUtils.indexOfAny(*, [])                  = -1
-     * StringUtils.indexOfAny("zzabyycdxx",['z','a']) = 0
-     * StringUtils.indexOfAny("zzabyycdxx",['b','y']) = 3
-     * StringUtils.indexOfAny("aba", ['z'])           = -1
-     * </pre>
-     *
-     * @param cs  the CharSequence to check, may be null
-     * @param searchChars  the chars to search for, may be null
-     * @return the index of any of the chars, -1 if no match or null input
-     * @since 2.0
-     * @since 3.0 Changed signature from indexOfAny(String, char[]) to indexOfAny(CharSequence, char...)
-     */
-    public static int indexOfAny(CharSequence cs, char... searchChars) {
-        if (isEmpty(cs) || ArrayUtils.isEmpty(searchChars)) {
-            return INDEX_NOT_FOUND;
-        }
-        int csLen = cs.length();
-        int csLast = csLen - 1;
-        int searchLen = searchChars.length;
-        int searchLast = searchLen - 1;
-        for (int i = 0; i < csLen; i++) {
-            char ch = cs.charAt(i);
-            for (int j = 0; j < searchLen; j++) {
-                if (searchChars[j] == ch) {
-                    if (i < csLast && j < searchLast && Character.isHighSurrogate(ch)) {
-                        // ch is a supplementary character
-                        if (searchChars[j + 1] == cs.charAt(i + 1)) {
-                            return i;
-                        }
-                    } else {
-                        return i;
-                    }
-                }
-            }
-        }
-        return INDEX_NOT_FOUND;
-    }
-
-    /**
-     * <p>Search a CharSequence to find the first index of any
-     * character in the given set of characters.</p>
-     *
-     * <p>A {@code null} String will return {@code -1}.
-     * A {@code null} search string will return {@code -1}.</p>
-     *
-     * <pre>
-     * StringUtils.indexOfAny(null, *)            = -1
-     * StringUtils.indexOfAny("", *)              = -1
-     * StringUtils.indexOfAny(*, null)            = -1
-     * StringUtils.indexOfAny(*, "")              = -1
-     * StringUtils.indexOfAny("zzabyycdxx", "za") = 0
-     * StringUtils.indexOfAny("zzabyycdxx", "by") = 3
-     * StringUtils.indexOfAny("aba","z")          = -1
-     * </pre>
-     *
-     * @param cs  the CharSequence to check, may be null
-     * @param searchChars  the chars to search for, may be null
-     * @return the index of any of the chars, -1 if no match or null input
-     * @since 2.0
-     * @since 3.0 Changed signature from indexOfAny(String, String) to indexOfAny(CharSequence, String)
-     */
-    public static int indexOfAny(CharSequence cs, String searchChars) {
-        if (isEmpty(cs) || isEmpty(searchChars)) {
-            return INDEX_NOT_FOUND;
-        }
-        return indexOfAny(cs, searchChars.toCharArray());
-    }
-
-    // ContainsAny
-    //-----------------------------------------------------------------------
-    /**
-     * <p>Checks if the CharSequence contains any character in the given
-     * set of characters.</p>
-     *
-     * <p>A {@code null} CharSequence will return {@code false}.
-     * A {@code null} or zero length search array will return {@code false}.</p>
-     *
-     * <pre>
-     * StringUtils.containsAny(null, *)                = false
-     * StringUtils.containsAny("", *)                  = false
-     * StringUtils.containsAny(*, null)                = false
-     * StringUtils.containsAny(*, [])                  = false
-     * StringUtils.containsAny("zzabyycdxx",['z','a']) = true
-     * StringUtils.containsAny("zzabyycdxx",['b','y']) = true
-     * StringUtils.containsAny("aba", ['z'])           = false
-     * </pre>
-     *
-     * @param cs  the CharSequence to check, may be null
-     * @param searchChars  the chars to search for, may be null
-     * @return the {@code true} if any of the chars are found,
-     * {@code false} if no match or null input
-     * @since 2.4
-     * @since 3.0 Changed signature from containsAny(String, char[]) to containsAny(CharSequence, char...)
-     */
-    public static boolean containsAny(CharSequence cs, char... searchChars) {
-        if (isEmpty(cs) || ArrayUtils.isEmpty(searchChars)) {
-            return false;
-        }
-        int csLength = cs.length();
-        int searchLength = searchChars.length;
-        int csLast = csLength - 1;
-        int searchLast = searchLength - 1;
-        for (int i = 0; i < csLength; i++) {
-            char ch = cs.charAt(i);
-            for (int j = 0; j < searchLength; j++) {
-                if (searchChars[j] == ch) {
-                    if (Character.isHighSurrogate(ch)) {
-                        if (j == searchLast) {
-                            // missing low surrogate, fine, like String.indexOf(String)
-                            return true;
-                        }
-                        if (i < csLast && searchChars[j + 1] == cs.charAt(i + 1)) {
-                            return true;
-                        }
-                    } else {
-                        // ch is in the Basic Multilingual Plane
-                        return true;
-                    }
-                }
-            }
-        }
-        return false;
-    }
-
-    /**
-     * <p>
-     * Checks if the CharSequence contains any character in the given set of characters.
-     * </p>
-     *
-     * <p>
-     * A {@code null} CharSequence will return {@code false}. A {@code null} search CharSequence will return
-     * {@code false}.
-     * </p>
-     *
-     * <pre>
-     * StringUtils.containsAny(null, *)            = false
-     * StringUtils.containsAny("", *)              = false
-     * StringUtils.containsAny(*, null)            = false
-     * StringUtils.containsAny(*, "")              = false
-     * StringUtils.containsAny("zzabyycdxx", "za") = true
-     * StringUtils.containsAny("zzabyycdxx", "by") = true
-     * StringUtils.containsAny("aba","z")          = false
-     * </pre>
-     *
-     * @param cs
-     *            the CharSequence to check, may be null
-     * @param searchChars
-     *            the chars to search for, may be null
-     * @return the {@code true} if any of the chars are found, {@code false} if no match or null input
-     * @since 2.4
-     * @since 3.0 Changed signature from containsAny(String, String) to containsAny(CharSequence, CharSequence)
-     */
-    public static boolean containsAny(CharSequence cs, CharSequence searchChars) {
-        if (searchChars == null) {
-            return false;
-        }
-        return containsAny(cs, CharSequenceUtils.toCharArray(searchChars));
-    }
-
-    // IndexOfAnyBut chars
-    //-----------------------------------------------------------------------
-    /**
-     * <p>Searches a CharSequence to find the first index of any
-     * character not in the given set of characters.</p>
-     *
-     * <p>A {@code null} CharSequence will return {@code -1}.
-     * A {@code null} or zero length search array will return {@code -1}.</p>
-     *
-     * <pre>
-     * StringUtils.indexOfAnyBut(null, *)                              = -1
-     * StringUtils.indexOfAnyBut("", *)                                = -1
-     * StringUtils.indexOfAnyBut(*, null)                              = -1
-     * StringUtils.indexOfAnyBut(*, [])                                = -1
-     * StringUtils.indexOfAnyBut("zzabyycdxx", new char[] {'z', 'a'} ) = 3
-     * StringUtils.indexOfAnyBut("aba", new char[] {'z'} )             = 0
-     * StringUtils.indexOfAnyBut("aba", new char[] {'a', 'b'} )        = -1
-
-     * </pre>
-     *
-     * @param cs  the CharSequence to check, may be null
-     * @param searchChars  the chars to search for, may be null
-     * @return the index of any of the chars, -1 if no match or null input
-     * @since 2.0
-     * @since 3.0 Changed signature from indexOfAnyBut(String, char[]) to indexOfAnyBut(CharSequence, char...)
-     */
-    public static int indexOfAnyBut(CharSequence cs, char... searchChars) {
-        if (isEmpty(cs) || ArrayUtils.isEmpty(searchChars)) {
-            return INDEX_NOT_FOUND;
-        }
-        int csLen = cs.length();
-        int csLast = csLen - 1;
-        int searchLen = searchChars.length;
-        int searchLast = searchLen - 1;
-        outer:
-        for (int i = 0; i < csLen; i++) {
-            char ch = cs.charAt(i);
-            for (int j = 0; j < searchLen; j++) {
-                if (searchChars[j] == ch) {
-                    if (i < csLast && j < searchLast && Character.isHighSurrogate(ch)) {
-                        if (searchChars[j + 1] == cs.charAt(i + 1)) {
-                            continue outer;
-                        }
-                    } else {
-                        continue outer;
-                    }
-                }
-            }
-            return i;
-        }
-        return INDEX_NOT_FOUND;
-    }
-
-    /**
-     * <p>Search a CharSequence to find the first index of any
-     * character not in the given set of characters.</p>
-     *
-     * <p>A {@code null} CharSequence will return {@code -1}.
-     * A {@code null} or empty search string will return {@code -1}.</p>
-     *
-     * <pre>
-     * StringUtils.indexOfAnyBut(null, *)            = -1
-     * StringUtils.indexOfAnyBut("", *)              = -1
-     * StringUtils.indexOfAnyBut(*, null)            = -1
-     * StringUtils.indexOfAnyBut(*, "")              = -1
-     * StringUtils.indexOfAnyBut("zzabyycdxx", "za") = 3
-     * StringUtils.indexOfAnyBut("zzabyycdxx", "")   = -1
-     * StringUtils.indexOfAnyBut("aba","ab")         = -1
-     * </pre>
-     *
-     * @param seq  the CharSequence to check, may be null
-     * @param searchChars  the chars to search for, may be null
-     * @return the index of any of the chars, -1 if no match or null input
-     * @since 2.0
-     * @since 3.0 Changed signature from indexOfAnyBut(String, String) to indexOfAnyBut(CharSequence, CharSequence)
-     */
-    public static int indexOfAnyBut(CharSequence seq, CharSequence searchChars) {
-        if (isEmpty(seq) || isEmpty(searchChars)) {
-            return INDEX_NOT_FOUND;
-        }
-        int strLen = seq.length();
-        for (int i = 0; i < strLen; i++) {
-            char ch = seq.charAt(i);
-            boolean chFound = CharSequenceUtils.indexOf(searchChars, ch, 0) >= 0;
-            if (i + 1 < strLen && Character.isHighSurrogate(ch)) {
-                char ch2 = seq.charAt(i + 1);
-                if (chFound && CharSequenceUtils.indexOf(searchChars, ch2, 0) < 0) {
-                    return i;
-                }
-            } else {
-                if (!chFound) {
-                    return i;
-                }
-            }
-        }
-        return INDEX_NOT_FOUND;
-    }
-
-    // ContainsOnly
-    //-----------------------------------------------------------------------
-    /**
-     * <p>Checks if the CharSequence contains only certain characters.</p>
-     *
-     * <p>A {@code null} CharSequence will return {@code false}.
-     * A {@code null} valid character array will return {@code false}.
-     * An empty CharSequence (length()=0) always returns {@code true}.</p>
-     *
-     * <pre>
-     * StringUtils.containsOnly(null, *)       = false
-     * StringUtils.containsOnly(*, null)       = false
-     * StringUtils.containsOnly("", *)         = true
-     * StringUtils.containsOnly("ab", '')      = false
-     * StringUtils.containsOnly("abab", 'abc') = true
-     * StringUtils.containsOnly("ab1", 'abc')  = false
-     * StringUtils.containsOnly("abz", 'abc')  = false
-     * </pre>
-     *
-     * @param cs  the String to check, may be null
-     * @param valid  an array of valid chars, may be null
-     * @return true if it only contains valid chars and is non-null
-     * @since 3.0 Changed signature from containsOnly(String, char[]) to containsOnly(CharSequence, char...)
-     */
-    public static boolean containsOnly(CharSequence cs, char... valid) {
-        // All these pre-checks are to maintain API with an older version
-        if (valid == null || cs == null) {
-            return false;
-        }
-        if (cs.length() == 0) {
-            return true;
-        }
-        if (valid.length == 0) {
-            return false;
-        }
-        return indexOfAnyBut(cs, valid) == INDEX_NOT_FOUND;
-    }
-
-    /**
-     * <p>Checks if the CharSequence contains only certain characters.</p>
-     *
-     * <p>A {@code null} CharSequence will return {@code false}.
-     * A {@code null} valid character String will return {@code false}.
-     * An empty String (length()=0) always returns {@code true}.</p>
-     *
-     * <pre>
-     * StringUtils.containsOnly(null, *)       = false
-     * StringUtils.containsOnly(*, null)       = false
-     * StringUtils.containsOnly("", *)         = true
-     * StringUtils.containsOnly("ab", "")      = false
-     * StringUtils.containsOnly("abab", "abc") = true
-     * StringUtils.containsOnly("ab1", "abc")  = false
-     * StringUtils.containsOnly("abz", "abc")  = false
-     * </pre>
-     *
-     * @param cs  the CharSequence to check, may be null
-     * @param validChars  a String of valid chars, may be null
-     * @return true if it only contains valid chars and is non-null
-     * @since 2.0
-     * @since 3.0 Changed signature from containsOnly(String, String) to containsOnly(CharSequence, String)
-     */
-    public static boolean containsOnly(CharSequence cs, String validChars) {
-        if (cs == null || validChars == null) {
-            return false;
-        }
-        return containsOnly(cs, validChars.toCharArray());
-    }
-
-    // ContainsNone
-    //-----------------------------------------------------------------------
-    /**
-     * <p>Checks that the CharSequence does not contain certain characters.</p>
-     *
-     * <p>A {@code null} CharSequence will return {@code true}.
-     * A {@code null} invalid character array will return {@code true}.
-     * An empty CharSequence (length()=0) always returns true.</p>
-     *
-     * <pre>
-     * StringUtils.containsNone(null, *)       = true
-     * StringUtils.containsNone(*, null)       = true
-     * StringUtils.containsNone("", *)         = true
-     * StringUtils.containsNone("ab", '')      = true
-     * StringUtils.containsNone("abab", 'xyz') = true
-     * StringUtils.containsNone("ab1", 'xyz')  = true
-     * StringUtils.containsNone("abz", 'xyz')  = false
-     * </pre>
-     *
-     * @param cs  the CharSequence to check, may be null
-     * @param searchChars  an array of invalid chars, may be null
-     * @return true if it contains none of the invalid chars, or is null
-     * @since 2.0
-     * @since 3.0 Changed signature from containsNone(String, char[]) to containsNone(CharSequence, char...)
-     */
-    public static boolean containsNone(CharSequence cs, char... searchChars) {
-        if (cs == null || searchChars == null) {
-            return true;
-        }
-        int csLen = cs.length();
-        int csLast = csLen - 1;
-        int searchLen = searchChars.length;
-        int searchLast = searchLen - 1;
-        for (int i = 0; i < csLen; i++) {
-            char ch = cs.charAt(i);
-            for (int j = 0; j < searchLen; j++) {
-                if (searchChars[j] == ch) {
-                    if (Character.isHighSurrogate(ch)) {
-                        if (j == searchLast) {
-                            // missing low surrogate, fine, like String.indexOf(String)
-                            return false;
-                        }
-                        if (i < csLast && searchChars[j + 1] == cs.charAt(i + 1)) {
-                            return false;
-                        }
-                    } else {
-                        // ch is in the Basic Multilingual Plane
-                        return false;
-                    }
-                }
-            }
-        }
-        return true;
-    }
-
-    /**
-     * <p>Checks that the CharSequence does not contain certain characters.</p>
-     *
-     * <p>A {@code null} CharSequence will return {@code true}.
-     * A {@code null} invalid character array will return {@code true}.
-     * An empty String ("") always returns true.</p>
-     *
-     * <pre>
-     * StringUtils.containsNone(null, *)       = true
-     * StringUtils.containsNone(*, null)       = true
-     * StringUtils.containsNone("", *)         = true
-     * StringUtils.containsNone("ab", "")      = true
-     * StringUtils.containsNone("abab", "xyz") = true
-     * StringUtils.containsNone("ab1", "xyz")  = true
-     * StringUtils.containsNone("abz", "xyz")  = false
-     * </pre>
-     *
-     * @param cs  the CharSequence to check, may be null
-     * @param invalidChars  a String of invalid chars, may be null
-     * @return true if it contains none of the invalid chars, or is null
-     * @since 2.0
-     * @since 3.0 Changed signature from containsNone(String, String) to containsNone(CharSequence, String)
-     */
-    public static boolean containsNone(CharSequence cs, String invalidChars) {
-        if (cs == null || invalidChars == null) {
-            return true;
-        }
-        return containsNone(cs, invalidChars.toCharArray());
-    }
-
-    // IndexOfAny strings
-    //-----------------------------------------------------------------------
-    /**
-     * <p>Find the first index of any of a set of potential substrings.</p>
-     *
-     * <p>A {@code null} CharSequence will return {@code -1}.
-     * A {@code null} or zero length search array will return {@code -1}.
-     * A {@code null} search array entry will be ignored, but a search
-     * array containing "" will return {@code 0} if {@code str} is not
-     * null. This method uses {@link String#indexOf(String)} if possible.</p>
-     *
-     * <pre>
-     * StringUtils.indexOfAny(null, *)                     = -1
-     * StringUtils.indexOfAny(*, null)                     = -1
-     * StringUtils.indexOfAny(*, [])                       = -1
-     * StringUtils.indexOfAny("zzabyycdxx", ["ab","cd"])   = 2
-     * StringUtils.indexOfAny("zzabyycdxx", ["cd","ab"])   = 2
-     * StringUtils.indexOfAny("zzabyycdxx", ["mn","op"])   = -1
-     * StringUtils.indexOfAny("zzabyycdxx", ["zab","aby"]) = 1
-     * StringUtils.indexOfAny("zzabyycdxx", [""])          = 0
-     * StringUtils.indexOfAny("", [""])                    = 0
-     * StringUtils.indexOfAny("", ["a"])                   = -1
-     * </pre>
-     *
-     * @param str  the CharSequence to check, may be null
-     * @param searchStrs  the CharSequences to search for, may be null
-     * @return the first index of any of the searchStrs in str, -1 if no match
-     * @since 3.0 Changed signature from indexOfAny(String, String[]) to indexOfAny(CharSequence, CharSequence...)
-     */
-    public static int indexOfAny(CharSequence str, CharSequence... searchStrs) {
-        if (str == null || searchStrs == null) {
-            return INDEX_NOT_FOUND;
-        }
-        int sz = searchStrs.length;
-
-        // String's can't have a MAX_VALUEth index.
-        int ret = Integer.MAX_VALUE;
-
-        int tmp = 0;
-        for (int i = 0; i < sz; i++) {
-            CharSequence search = searchStrs[i];
-            if (search == null) {
-                continue;
-            }
-            tmp = CharSequenceUtils.indexOf(str, search, 0);
-            if (tmp == INDEX_NOT_FOUND) {
-                continue;
-            }
-
-            if (tmp < ret) {
-                ret = tmp;
-            }
-        }
-
-        return ret == Integer.MAX_VALUE ? INDEX_NOT_FOUND : ret;
-    }
-
-    /**
-     * <p>Find the latest index of any of a set of potential substrings.</p>
-     *
-     * <p>A {@code null} CharSequence will return {@code -1}.
-     * A {@code null} search array will return {@code -1}.
-     * A {@code null} or zero length search array entry will be ignored,
-     * but a search array containing "" will return the length of {@code str}
-     * if {@code str} is not null. This method uses {@link String#indexOf(String)} if possible</p>
-     *
-     * <pre>
-     * StringUtils.lastIndexOfAny(null, *)                   = -1
-     * StringUtils.lastIndexOfAny(*, null)                   = -1
-     * StringUtils.lastIndexOfAny(*, [])                     = -1
-     * StringUtils.lastIndexOfAny(*, [null])                 = -1
-     * StringUtils.lastIndexOfAny("zzabyycdxx", ["ab","cd"]) = 6
-     * StringUtils.lastIndexOfAny("zzabyycdxx", ["cd","ab"]) = 6
-     * StringUtils.lastIndexOfAny("zzabyycdxx", ["mn","op"]) = -1
-     * StringUtils.lastIndexOfAny("zzabyycdxx", ["mn","op"]) = -1
-     * StringUtils.lastIndexOfAny("zzabyycdxx", ["mn",""])   = 10
-     * </pre>
-     *
-     * @param str  the CharSequence to check, may be null
-     * @param searchStrs  the CharSequences to search for, may be null
-     * @return the last index of any of the CharSequences, -1 if no match
-     * @since 3.0 Changed signature from lastIndexOfAny(String, String[]) to lastIndexOfAny(CharSequence, CharSequence)
-     */
-    public static int lastIndexOfAny(CharSequence str, CharSequence... searchStrs) {
-        if (str == null || searchStrs == null) {
-            return INDEX_NOT_FOUND;
-        }
-        int sz = searchStrs.length;
-        int ret = INDEX_NOT_FOUND;
-        int tmp = 0;
-        for (int i = 0; i < sz; i++) {
-            CharSequence search = searchStrs[i];
-            if (search == null) {
-                continue;
-            }
-            tmp = CharSequenceUtils.lastIndexOf(str, search, str.length());
-            if (tmp > ret) {
-                ret = tmp;
-            }
-        }
-        return ret;
-    }
-
-    // Substring
-    //-----------------------------------------------------------------------
-    /**
-     * <p>Gets a substring from the specified String avoiding exceptions.</p>
-     *
-     * <p>A negative start position can be used to start {@code n}
-     * characters from the end of the String.</p>
-     *
-     * <p>A {@code null} String will return {@code null}.
-     * An empty ("") String will return "".</p>
-     *
-     * <pre>
-     * StringUtils.substring(null, *)   = null
-     * StringUtils.substring("", *)     = ""
-     * StringUtils.substring("abc", 0)  = "abc"
-     * StringUtils.substring("abc", 2)  = "c"
-     * StringUtils.substring("abc", 4)  = ""
-     * StringUtils.substring("abc", -2) = "bc"
-     * StringUtils.substring("abc", -4) = "abc"
-     * </pre>
-     *
-     * @param str  the String to get the substring from, may be null
-     * @param start  the position to start from, negative means
-     *  count back from the end of the String by this many characters
-     * @return substring from start position, {@code null} if null String input
-     */
-    public static String substring(String str, int start) {
-        if (str == null) {
-            return null;
-        }
-
-        // handle negatives, which means last n characters
-        if (start < 0) {
-            start = str.length() + start; // remember start is negative
-        }
-
-        if (start < 0) {
-            start = 0;
-        }
-        if (start > str.length()) {
-            return EMPTY;
-        }
-
-        return str.substring(start);
-    }
-
-    /**
-     * <p>Gets a substring from the specified String avoiding exceptions.</p>
-     *
-     * <p>A negative start position can be used to start/end {@code n}
-     * characters from the end of the String.</p>
-     *
-     * <p>The returned substring starts with the character in the {@code start}
-     * position and ends before the {@code end} position. All position counting is
-     * zero-based -- i.e., to start at the beginning of the string use
-     * {@code start = 0}. Negative start and end positions can be used to
-     * specify offsets relative to the end of the String.</p>
-     *
-     * <p>If {@code start} is not strictly to the left of {@code end}, ""
-     * is returned.</p>
-     *
-     * <pre>
-     * StringUtils.substring(null, *, *)    = null
-     * StringUtils.substring("", * ,  *)    = "";
-     * StringUtils.substring("abc", 0, 2)   = "ab"
-     * StringUtils.substring("abc", 2, 0)   = ""
-     * StringUtils.substring("abc", 2, 4)   = "c"
-     * StringUtils.substring("abc", 4, 6)   = ""
-     * StringUtils.substring("abc", 2, 2)   = ""
-     * StringUtils.substring("abc", -2, -1) = "b"
-     * StringUtils.substring("abc", -4, 2)  = "ab"
-     * </pre>
-     *
-     * @param str  the String to get the substring from, may be null
-     * @param start  the position to start from, negative means
-     *  count back from the end of the String by this many characters
-     * @param end  the position to end at (exclusive), negative means
-     *  count back from the end of the String by this many characters
-     * @return substring from start position to end position,
-     *  {@code null} if null String input
-     */
-    public static String substring(String str, int start, int end) {
-        if (str == null) {
-            return null;
-        }
-
-        // handle negatives
-        if (end < 0) {
-            end = str.length() + end; // remember end is negative
-        }
-        if (start < 0) {
-            start = str.length() + start; // remember start is negative
-        }
-
-        // check length next
-        if (end > str.length()) {
-            end = str.length();
-        }
-
-        // if start is greater than end, return ""
-        if (start > end) {
-            return EMPTY;
-        }
-
-        if (start < 0) {
-            start = 0;
-        }
-        if (end < 0) {
-            end = 0;
-        }
-
-        return str.substring(start, end);
-    }
-
-    // Left/Right/Mid
-    //-----------------------------------------------------------------------
-    /**
-     * <p>Gets the leftmost {@code len} characters of a String.</p>
-     *
-     * <p>If {@code len} characters are not available, or the
-     * String is {@code null}, the String will be returned without
-     * an exception. An empty String is returned if len is negative.</p>
-     *
-     * <pre>
-     * StringUtils.left(null, *)    = null
-     * StringUtils.left(*, -ve)     = ""
-     * StringUtils.left("", *)      = ""
-     * StringUtils.left("abc", 0)   = ""
-     * StringUtils.left("abc", 2)   = "ab"
-     * StringUtils.left("abc", 4)   = "abc"
-     * </pre>
-     *
-     * @param str  the String to get the leftmost characters from, may be null
-     * @param len  the length of the required String
-     * @return the leftmost characters, {@code null} if null String input
-     */
-    public static String left(String str, int len) {
-        if (str == null) {
-            return null;
-        }
-        if (len < 0) {
-            return EMPTY;
-        }
-        if (str.length() <= len) {
-            return str;
-        }
-        return str.substring(0, len);
-    }
-
-    /**
-     * <p>Gets the rightmost {@code len} characters of a String.</p>
-     *
-     * <p>If {@code len} characters are not available, or the String
-     * is {@code null}, the String will be returned without an
-     * an exception. An empty String is returned if len is negative.</p>
-     *
-     * <pre>
-     * StringUtils.right(null, *)    = null
-     * StringUtils.right(*, -ve)     = ""
-     * StringUtils.right("", *)      = ""
-     * StringUtils.right("abc", 0)   = ""
-     * StringUtils.right("abc", 2)   = "bc"
-     * StringUtils.right("abc", 4)   = "abc"
-     * </pre>
-     *
-     * @param str  the String to get the rightmost characters from, may be null
-     * @param len  the length of the required String
-     * @return the rightmost characters, {@code null} if null String input
-     */
-    public static String right(String str, int len) {
-        if (str == null) {
-            return null;
-        }
-        if (len < 0) {
-            return EMPTY;
-        }
-        if (str.length() <= len) {
-            return str;
-        }
-        return str.substring(str.length() - len);
-    }
-
-    /**
-     * <p>Gets {@code len} characters from the middle of a String.</p>
-     *
-     * <p>If {@code len} characters are not available, the remainder
-     * of the String will be returned without an exception. If the
-     * String is {@code null}, {@code null} will be returned.
-     * An empty String is returned if len is negative or exceeds the
-     * length of {@code str}.</p>
-     *
-     * <pre>
-     * StringUtils.mid(null, *, *)    = null
-     * StringUtils.mid(*, *, -ve)     = ""
-     * StringUtils.mid("", 0, *)      = ""
-     * StringUtils.mid("abc", 0, 2)   = "ab"
-     * StringUtils.mid("abc", 0, 4)   = "abc"
-     * StringUtils.mid("abc", 2, 4)   = "c"
-     * StringUtils.mid("abc", 4, 2)   = ""
-     * StringUtils.mid("abc", -2, 2)  = "ab"
-     * </pre>
-     *
-     * @param str  the String to get the characters from, may be null
-     * @param pos  the position to start from, negative treated as zero
-     * @param len  the length of the required String
-     * @return the middle characters, {@code null} if null String input
-     */
-    public static String mid(String str, int pos, int len) {
-        if (str == null) {
-            return null;
-        }
-        if (len < 0 || pos > str.length()) {
-            return EMPTY;
-        }
-        if (pos < 0) {
-            pos = 0;
-        }
-        if (str.length() <= pos + len) {
-            return str.substring(pos);
-        }
-        return str.substring(pos, pos + len);
-    }
-
-    // SubStringAfter/SubStringBefore
-    //-----------------------------------------------------------------------
-    /**
-     * <p>Gets the substring before the first occurrence of a separator.
-     * The separator is not returned.</p>
-     *
-     * <p>A {@code null} string input will return {@code null}.
-     * An empty ("") string input will return the empty string.
-     * A {@code null} separator will return the input string.</p>
-     *
-     * <p>If nothing is found, the string input is returned.</p>
-     *
-     * <pre>
-     * StringUtils.substringBefore(null, *)      = null
-     * StringUtils.substringBefore("", *)        = ""
-     * StringUtils.substringBefore("abc", "a")   = ""
-     * StringUtils.substringBefore("abcba", "b") = "a"
-     * StringUtils.substringBefore("abc", "c")   = "ab"
-     * StringUtils.substringBefore("abc", "d")   = "abc"
-     * StringUtils.substringBefore("abc", "")    = ""
-     * StringUtils.substringBefore("abc", null)  = "abc"
-     * </pre>
-     *
-     * @param str  the String to get a substring from, may be null
-     * @param separator  the String to search for, may be null
-     * @return the substring before the first occurrence of the separator,
-     *  {@code null} if null String input
-     * @since 2.0
-     */
-    public static String substringBefore(String str, String separator) {
-        if (isEmpty(str) || separator == null) {
-            return str;
-        }
-        if (separator.length() == 0) {
-            return EMPTY;
-        }
-        int pos = str.indexOf(separator);
-        if (pos == INDEX_NOT_FOUND) {
-            return str;
-        }
-        return str.substring(0, pos);
-    }
-
-    /**
-     * <p>Gets the substring after the first occurrence of a separator.
-     * The separator is not returned.</p>
-     *
-     * <p>A {@code null} string input will return {@code null}.
-     * An empty ("") string input will return the empty string.
-     * A {@code null} separator will return the empty string if the
-     * input string is not {@code null}.</p>
-     *
-     * <p>If nothing is found, the empty string is returned.</p>
-     *
-     * <pre>
-     * StringUtils.substringAfter(null, *)      = null
-     * StringUtils.substringAfter("", *)        = ""
-     * StringUtils.substringAfter(*, null)      = ""
-     * StringUtils.substringAfter("abc", "a")   = "bc"
-     * StringUtils.substringAfter("abcba", "b") = "cba"
-     * StringUtils.substringAfter("abc", "c")   = ""
-     * StringUtils.substringAfter("abc", "d")   = ""
-     * StringUtils.substringAfter("abc", "")    = "abc"
-     * </pre>
-     *
-     * @param str  the String to get a substring from, may be null
-     * @param separator  the String to search for, may be null
-     * @return the substring after the first occurrence of the separator,
-     *  {@code null} if null String input
-     * @since 2.0
-     */
-    public static String substringAfter(String str, String separator) {
-        if (isEmpty(str)) {
-            return str;
-        }
-        if (separator == null) {
-            return EMPTY;
-        }
-        int pos = str.indexOf(separator);
-        if (pos == INDEX_NOT_FOUND) {
-            return EMPTY;
-        }
-        return str.substring(pos + separator.length());
-    }
-
-    /**
-     * <p>Gets the substring before the last occurrence of a separator.
-     * The separator is not returned.</p>
-     *
-     * <p>A {@code null} string input will return {@code null}.
-     * An empty ("") string input will return the empty string.
-     * An empty or {@code null} separator will return the input string.</p>
-     *
-     * <p>If nothing is found, the string input is returned.</p>
-     *
-     * <pre>
-     * StringUtils.substringBeforeLast(null, *)      = null
-     * StringUtils.substringBeforeLast("", *)        = ""
-     * StringUtils.substringBeforeLast("abcba", "b") = "abc"
-     * StringUtils.substringBeforeLast("abc", "c")   = "ab"
-     * StringUtils.substringBeforeLast("a", "a")     = ""
-     * StringUtils.substringBeforeLast("a", "z")     = "a"
-     * StringUtils.substringBeforeLast("a", null)    = "a"
-     * StringUtils.substringBeforeLast("a", "")      = "a"
-     * </pre>
-     *
-     * @param str  the String to get a substring from, may be null
-     * @param separator  the String to search for, may be null
-     * @return the substring before the last occurrence of the separator,
-     *  {@code null} if null String input
-     * @since 2.0
-     */
-    public static String substringBeforeLast(String str, String separator) {
-        if (isEmpty(str) || isEmpty(separator)) {
-            return str;
-        }
-        int pos = str.lastIndexOf(separator);
-        if (pos == INDEX_NOT_FOUND) {
-            return str;
-        }
-        return str.substring(0, pos);
-    }
-
-    /**
-     * <p>Gets the substring after the last occurrence of a separator.
-     * The separator is not returned.</p>
-     *
-     * <p>A {@code null} string input will return {@code null}.
-     * An empty ("") string input will return the empty string.
-     * An empty or {@code null} separator will return the empty string if
-     * the input string is not {@code null}.</p>
-     *
-     * <p>If nothing is found, the empty string is returned.</p>
-     *
-     * <pre>
-     * StringUtils.substringAfterLast(null, *)      = null
-     * StringUtils.substringAfterLast("", *)        = ""
-     * StringUtils.substringAfterLast(*, "")        = ""
-     * StringUtils.substringAfterLast(*, null)      = ""
-     * StringUtils.substringAfterLast("abc", "a")   = "bc"
-     * StringUtils.substringAfterLast("abcba", "b") = "a"
-     * StringUtils.substringAfterLast("abc", "c")   = ""
-     * StringUtils.substringAfterLast("a", "a")     = ""
-     * StringUtils.substringAfterLast("a", "z")     = ""
-     * </pre>
-     *
-     * @param str  the String to get a substring from, may be null
-     * @param separator  the String to search for, may be null
-     * @return the substring after the last occurrence of the separator,
-     *  {@code null} if null String input
-     * @since 2.0
-     */
-    public static String substringAfterLast(String str, String separator) {
-        if (isEmpty(str)) {
-            return str;
-        }
-        if (isEmpty(separator)) {
-            return EMPTY;
-        }
-        int pos = str.lastIndexOf(separator);
-        if (pos == INDEX_NOT_FOUND || pos == str.length() - separator.length()) {
-            return EMPTY;
-        }
-        return str.substring(pos + separator.length());
-    }
-
-    // Substring between
-    //-----------------------------------------------------------------------
-    /**
-     * <p>Gets the String that is nested in between two instances of the
-     * same String.</p>
-     *
-     * <p>A {@code null} input String returns {@code null}.
-     * A {@code null} tag returns {@code null}.</p>
-     *
-     * <pre>
-     * StringUtils.substringBetween(null, *)            = null
-     * StringUtils.substringBetween("", "")             = ""
-     * StringUtils.substringBetween("", "tag")          = null
-     * StringUtils.substringBetween("tagabctag", null)  = null
-     * StringUtils.substringBetween("tagabctag", "")    = ""
-     * StringUtils.substringBetween("tagabctag", "tag") = "abc"
-     * </pre>
-     *
-     * @param str  the String containing the substring, may be null
-     * @param tag  the String before and after the substring, may be null
-     * @return the substring, {@code null} if no match
-     * @since 2.0
-     */
-    public static String substringBetween(String str, String tag) {
-        return substringBetween(str, tag, tag);
-    }
-
-    /**
-     * <p>Gets the String that is nested in between two Strings.
-     * Only the first match is returned.</p>
-     *
-     * <p>A {@code null} input String returns {@code null}.
-     * A {@code null} open/close returns {@code null} (no match).
-     * An empty ("") open and close returns an empty string.</p>
-     *
-     * <pre>
-     * StringUtils.substringBetween("wx[b]yz", "[", "]") = "b"
-     * StringUtils.substringBetween(null, *, *)          = null
-     * StringUtils.substringBetween(*, null, *)          = null
-     * StringUtils.substringBetween(*, *, null)          = null
-     * StringUtils.substringBetween("", "", "")          = ""
-     * StringUtils.substringBetween("", "", "]")         = null
-     * StringUtils.substringBetween("", "[", "]")        = null
-     * StringUtils.substringBetween("yabcz", "", "")     = ""
-     * StringUtils.substringBetween("yabcz", "y", "z")   = "abc"
-     * StringUtils.substringBetween("yabczyabcz", "y", "z")   = "abc"
-     * </pre>
-     *
-     * @param str  the String containing the substring, may be null
-     * @param open  the String before the substring, may be null
-     * @param close  the String after the substring, may be null
-     * @return the substring, {@code null} if no match
-     * @since 2.0
-     */
-    public static String substringBetween(String str, String open, String close) {
-        if (str == null || open == null || close == null) {
-            return null;
-        }
-        int start = str.indexOf(open);
-        if (start != INDEX_NOT_FOUND) {
-            int end = str.indexOf(close, start + open.length());
-            if (end != INDEX_NOT_FOUND) {
-                return str.substring(start + open.length(), end);
-            }
-        }
-        return null;
-    }
-
-    /**
-     * <p>Searches a String for substrings delimited by a start and end tag,
-     * returning all matching substrings in an array.</p>
-     *
-     * <p>A {@code null} input String returns {@code null}.
-     * A {@code null} open/close returns {@code null} (no match).
-     * An empty ("") open/close returns {@code null} (no match).</p>
-     *
-     * <pre>
-     * StringUtils.substringsBetween("[a][b][c]", "[", "]") = ["a","b","c"]
-     * StringUtils.substringsBetween(null, *, *)            = null
-     * StringUtils.substringsBetween(*, null, *)            = null
-     * StringUtils.substringsBetween(*, *, null)            = null
-     * StringUtils.substringsBetween("", "[", "]")          = []
-     * </pre>
-     *
-     * @param str  the String containing the substrings, null returns null, empty returns empty
-     * @param open  the String identifying the start of the substring, empty returns null
-     * @param close  the String identifying the end of the substring, empty returns null
-     * @return a String Array of substrings, or {@code null} if no match
-     * @since 2.3
-     */
-    public static String[] substringsBetween(String str, String open, String close) {
-        if (str == null || isEmpty(open) || isEmpty(close)) {
-            return null;
-        }
-        int strLen = str.length();
-        if (strLen == 0) {
-            return ArrayUtils.EMPTY_STRING_ARRAY;
-        }
-        int closeLen = close.length();
-        int openLen = open.length();
-        List<String> list = new ArrayList<String>();
-        int pos = 0;
-        while (pos < strLen - closeLen) {
-            int start = str.indexOf(open, pos);
-            if (start < 0) {
-                break;
-            }
-            start += openLen;
-            int end = str.indexOf(close, start);
-            if (end < 0) {
-                break;
-            }
-            list.add(str.substring(start, end));
-            pos = end + closeLen;
-        }
-        if (list.isEmpty()) {
-            return null;
-        }
-        return list.toArray(new String [list.size()]);
-    }
-
-    // Nested extraction
-    //-----------------------------------------------------------------------
-
-    // Splitting
-    //-----------------------------------------------------------------------
-    /**
-     * <p>Splits the provided text into an array, using whitespace as the
-     * separator.
-     * Whitespace is defined by {@link Character#isWhitespace(char)}.</p>
-     *
-     * <p>The separator is not included in the returned String array.
-     * Adjacent separators are treated as one separator.
-     * For more control over the split use the StrTokenizer class.</p>
-     *
-     * <p>A {@code null} input String returns {@code null}.</p>
-     *
-     * <pre>
-     * StringUtils.split(null)       = null
-     * StringUtils.split("")         = []
-     * StringUtils.split("abc def")  = ["abc", "def"]
-     * StringUtils.split("abc  def") = ["abc", "def"]
-     * StringUtils.split(" abc ")    = ["abc"]
-     * </pre>
-     *
-     * @param str  the String to parse, may be null
-     * @return an array of parsed Strings, {@code null} if null String input
-     */
-    public static String[] split(String str) {
-        return split(str, null, -1);
-    }
-
-    /**
-     * <p>Splits the provided text into an array, separator specified.
-     * This is an alternative to using StringTokenizer.</p>
-     *
-     * <p>The separator is not included in the returned String array.
-     * Adjacent separators are treated as one separator.
-     * For more control over the split use the StrTokenizer class.</p>
-     *
-     * <p>A {@code null} input String returns {@code null}.</p>
-     *
-     * <pre>
-     * StringUtils.split(null, *)         = null
-     * StringUtils.split("", *)           = []
-     * StringUtils.split("a.b.c", '.')    = ["a", "b", "c"]
-     * StringUtils.split("a..b.c", '.')   = ["a", "b", "c"]
-     * StringUtils.split("a:b:c", '.')    = ["a:b:c"]
-     * StringUtils.split("a b c", ' ')    = ["a", "b", "c"]
-     * </pre>
-     *
-     * @param str  the String to parse, may be null
-     * @param separatorChar  the character used as the delimiter
-     * @return an array of parsed Strings, {@code null} if null String input
-     * @since 2.0
-     */
-    public static String[] split(String str, char separatorChar) {
-        return splitWorker(str, separatorChar, false);
-    }
-
-    /**
-     * <p>Splits the provided text into an array, separators specified.
-     * This is an alternative to using StringTokenizer.</p>
-     *
-     * <p>The separator is not included in the returned String array.
-     * Adjacent separators are treated as one separator.
-     * For more control over the split use the StrTokenizer class.</p>
-     *
-     * <p>A {@code null} input String returns {@code null}.
-     * A {@code null} separatorChars splits on whitespace.</p>
-     *
-     * <pre>
-     * StringUtils.split(null, *)         = null
-     * StringUtils.split("", *)           = []
-     * StringUtils.split("abc def", null) = ["abc", "def"]
-     * StringUtils.split("abc def", " ")  = ["abc", "def"]
-     * StringUtils.split("abc  def", " ") = ["abc", "def"]
-     * StringUtils.split("ab:cd:ef", ":") = ["ab", "cd", "ef"]
-     * </pre>
-     *
-     * @param str  the String to parse, may be null
-     * @param separatorChars  the characters used as the delimiters,
-     *  {@code null} splits on whitespace
-     * @return an array of parsed Strings, {@code null} if null String input
-     */
-    public static String[] split(String str, String separatorChars) {
-        return splitWorker(str, separatorChars, -1, false);
-    }
-
-    /**
-     * <p>Splits the provided text into an array with a maximum length,
-     * separators specified.</p>
-     *
-     * <p>The separator is not included in the returned String array.
-     * Adjacent separators are treated as one separator.</p>
-     *
-     * <p>A {@code null} input String returns {@code null}.
-     * A {@code null} separatorChars splits on whitespace.</p>
-     *
-     * <p>If more than {@code max} delimited substrings are found, the last
-     * returned string includes all characters after the first {@code max - 1}
-     * returned strings (including separator characters).</p>
-     *
-     * <pre>
-     * StringUtils.split(null, *, *)            = null
-     * StringUtils.split("", *, *)              = []
-     * StringUtils.split("ab de fg", null, 0)   = ["ab", "cd", "ef"]
-     * StringUtils.split("ab   de fg", null, 0) = ["ab", "cd", "ef"]
-     * StringUtils.split("ab:cd:ef", ":", 0)    = ["ab", "cd", "ef"]
-     * StringUtils.split("ab:cd:ef", ":", 2)    = ["ab", "cd:ef"]
-     * </pre>
-     *
-     * @param str  the String to parse, may be null
-     * @param separatorChars  the characters used as the delimiters,
-     *  {@code null} splits on whitespace
-     * @param max  the maximum number of elements to include in the
-     *  array. A zero or negative value implies no limit
-     * @return an array of parsed Strings, {@code null} if null String input
-     */
-    public static String[] split(String str, String separatorChars, int max) {
-        return splitWorker(str, separatorChars, max, false);
-    }
-
-    /**
-     * <p>Splits the provided text into an array, separator string specified.</p>
-     *
-     * <p>The separator(s) will not be included in the returned String array.
-     * Adjacent separators are treated as one separator.</p>
-     *
-     * <p>A {@code null} input String returns {@code null}.
-     * A {@code null} separator splits on whitespace.</p>
-     *
-     * <pre>
-     * StringUtils.splitByWholeSeparator(null, *)               = null
-     * StringUtils.splitByWholeSeparator("", *)                 = []
-     * StringUtils.splitByWholeSeparator("ab de fg", null)      = ["ab", "de", "fg"]
-     * StringUtils.splitByWholeSeparator("ab   de fg", null)    = ["ab", "de", "fg"]
-     * StringUtils.splitByWholeSeparator("ab:cd:ef", ":")       = ["ab", "cd", "ef"]
-     * StringUtils.splitByWholeSeparator("ab-!-cd-!-ef", "-!-") = ["ab", "cd", "ef"]
-     * </pre>
-     *
-     * @param str  the String to parse, may be null
-     * @param separator  String containing the String to be used as a delimiter,
-     *  {@code null} splits on whitespace
-     * @return an array of parsed Strings, {@code null} if null String was input
-     */
-    public static String[] splitByWholeSeparator(String str, String separator) {
-        return splitByWholeSeparatorWorker( str, separator, -1, false ) ;
-    }
-
-    /**
-     * <p>Splits the provided text into an array, separator string specified.
-     * Returns a maximum of {@code max} substrings.</p>
-     *
-     * <p>The separator(s) will not be included in the returned String array.
-     * Adjacent separators are treated as one separator.</p>
-     *
-     * <p>A {@code null} input String returns {@code null}.
-     * A {@code null} separator splits on whitespace.</p>
-     *
-     * <pre>
-     * StringUtils.splitByWholeSeparator(null, *, *)               = null
-     * StringUtils.splitByWholeSeparator("", *, *)                 = []
-     * StringUtils.splitByWholeSeparator("ab de fg", null, 0)      = ["ab", "de", "fg"]
-     * StringUtils.splitByWholeSeparator("ab   de fg", null, 0)    = ["ab", "de", "fg"]
-     * StringUtils.splitByWholeSeparator("ab:cd:ef", ":", 2)       = ["ab", "cd:ef"]
-     * StringUtils.splitByWholeSeparator("ab-!-cd-!-ef", "-!-", 5) = ["ab", "cd", "ef"]
-     * StringUtils.splitByWholeSeparator("ab-!-cd-!-ef", "-!-", 2) = ["ab", "cd-!-ef"]
-     * </pre>
-     *
-     * @param str  the String to parse, may be null
-     * @param separator  String containing the String to be used as a delimiter,
-     *  {@code null} splits on whitespace
-     * @param max  the maximum number of elements to include in the returned
-     *  array. A zero or negative value implies no limit.
-     * @return an array of parsed Strings, {@code null} if null String was input
-     */
-    public static String[] splitByWholeSeparator( String str, String separator, int max ) {
-        return splitByWholeSeparatorWorker(str, separator, max, false);
-    }
-
-    /**
-     * <p>Splits the provided text into an array, separator string specified. </p>
-     *
-     * <p>The separator is not included in the returned String array.
-     * Adjacent separators are treated as separators for empty tokens.
-     * For more control over the split use the StrTokenizer class.</p>
-     *
-     * <p>A {@code null} input String returns {@code null}.
-     * A {@code null} separator splits on whitespace.</p>
-     *
-     * <pre>
-     * StringUtils.splitByWholeSeparatorPreserveAllTokens(null, *)               = null
-     * StringUtils.splitByWholeSeparatorPreserveAllTokens("", *)                 = []
-     * StringUtils.splitByWholeSeparatorPreserveAllTokens("ab de fg", null)      = ["ab", "de", "fg"]
-     * StringUtils.splitByWholeSeparatorPreserveAllTokens("ab   de fg", null)    = ["ab", "", "", "de", "fg"]
-     * StringUtils.splitByWholeSeparatorPreserveAllTokens("ab:cd:ef", ":")       = ["ab", "cd", "ef"]
-     * StringUtils.splitByWholeSeparatorPreserveAllTokens("ab-!-cd-!-ef", "-!-") = ["ab", "cd", "ef"]
-     * </pre>
-     *
-     * @param str  the String to parse, may be null
-     * @param separator  String containing the String to be used as a delimiter,
-     *  {@code null} splits on whitespace
-     * @return an array of parsed Strings, {@code null} if null String was input
-     * @since 2.4
-     */
-    public static String[] splitByWholeSeparatorPreserveAllTokens(String str, String separator) {
-        return splitByWholeSeparatorWorker(str, separator, -1, true);
-    }
-
-    /**
-     * <p>Splits the provided text into an array, separator string specified.
-     * Returns a maximum of {@code max} substrings.</p>
-     *
-     * <p>The separator is not included in the returned String array.
-     * Adjacent separators are treated as separators for empty tokens.
-     * For more control over the split use the StrTokenizer class.</p>
-     *
-     * <p>A {@code null} input String returns {@code null}.
-     * A {@code null} separator splits on whitespace.</p>
-     *
-     * <pre>
-     * StringUtils.splitByWholeSeparatorPreserveAllTokens(null, *, *)               = null
-     * StringUtils.splitByWholeSeparatorPreserveAllTokens("", *, *)                 = []
-     * StringUtils.splitByWholeSeparatorPreserveAllTokens("ab de fg", null, 0)      = ["ab", "de", "fg"]
-     * StringUtils.splitByWholeSeparatorPreserveAllTokens("ab   de fg", null, 0)    = ["ab", "", "", "de", "fg"]
-     * StringUtils.splitByWholeSeparatorPreserveAllTokens("ab:cd:ef", ":", 2)       = ["ab", "cd:ef"]
-     * StringUtils.splitByWholeSeparatorPreserveAllTokens("ab-!-cd-!-ef", "-!-", 5) = ["ab", "cd", "ef"]
-     * StringUtils.splitByWholeSeparatorPreserveAllTokens("ab-!-cd-!-ef", "-!-", 2) = ["ab", "cd-!-ef"]
-     * </pre>
-     *
-     * @param str  the String to parse, may be null
-     * @param separator  String containing the String to be used as a delimiter,
-     *  {@code null} splits on whitespace
-     * @param max  the maximum number of elements to include in the returned
-     *  array. A zero or negative value implies no limit.
-     * @return an array of parsed Strings, {@code null} if null String was input
-     * @since 2.4
-     */
-    public static String[] splitByWholeSeparatorPreserveAllTokens(String str, String separator, int max) {
-        return splitByWholeSeparatorWorker(str, separator, max, true);
-    }
-
-    /**
-     * Performs the logic for the {@code splitByWholeSeparatorPreserveAllTokens} methods.
-     *
-     * @param str  the String to parse, may be {@code null}
-     * @param separator  String containing the String to be used as a delimiter,
-     *  {@code null} splits on whitespace
-     * @param max  the maximum number of elements to include in the returned
-     *  array. A zero or negative value implies no limit.
-     * @param preserveAllTokens if {@code true}, adjacent separators are
-     * treated as empty token separators; if {@code false}, adjacent
-     * separators are treated as one separator.
-     * @return an array of parsed Strings, {@code null} if null String input
-     * @since 2.4
-     */
-    private static String[] splitByWholeSeparatorWorker(
-            String str, String separator, int max, boolean preserveAllTokens) {
-        if (str == null) {
-            return null;
-        }
-
-        int len = str.length();
-
-        if (len == 0) {
-            return ArrayUtils.EMPTY_STRING_ARRAY;
-        }
-
-        if (separator == null || EMPTY.equals(separator)) {
-            // Split on whitespace.
-            return splitWorker(str, null, max, preserveAllTokens);
-        }
-
-        int separatorLength = separator.length();
-
-        ArrayList<String> substrings = new ArrayList<String>();
-        int numberOfSubstrings = 0;
-        int beg = 0;
-        int end = 0;
-        while (end < len) {
-            end = str.indexOf(separator, beg);
-
-            if (end > -1) {
-                if (end > beg) {
-                    numberOfSubstrings += 1;
-
-                    if (numberOfSubstrings == max) {
-                        end = len;
-                        substrings.add(str.substring(beg));
-                    } else {
-                        // The following is OK, because String.substring( beg, end ) excludes
-                        // the character at the position 'end'.
-                        substrings.add(str.substring(beg, end));
-
-                        // Set the starting point for the next search.
-                        // The following is equivalent to beg = end + (separatorLength - 1) + 1,
-                        // which is the right calculation:
-                        beg = end + separatorLength;
-                    }
-                } else {
-                    // We found a consecutive occurrence of the separator, so skip it.
-                    if (preserveAllTokens) {
-                        numberOfSubstrings += 1;
-                        if (numberOfSubstrings == max) {
-                            end = len;
-                            substrings.add(str.substring(beg));
-                        } else {
-                            substrings.add(EMPTY);
-                        }
-                    }
-                    beg = end + separatorLength;
-                }
-            } else {
-                // String.substring( beg ) goes from 'beg' to the end of the String.
-                substrings.add(str.substring(beg));
-                end = len;
-            }
-        }
-
-        return substrings.toArray(new String[substrings.size()]);
-    }
-
-    // -----------------------------------------------------------------------
-    /**
-     * <p>Splits the provided text into an array, using whitespace as the
-     * separator, preserving all tokens, including empty tokens created by
-     * adjacent separators. This is an alternative to using StringTokenizer.
-     * Whitespace is defined by {@link Character#isWhitespace(char)}.</p>
-     *
-     * <p>The separator is not included in the returned String array.
-     * Adjacent separators are treated as separators for empty tokens.
-     * For more control over the split use the StrTokenizer class.</p>
-     *
-     * <p>A {@code null} input String returns {@code null}.</p>
-     *
-     * <pre>
-     * StringUtils.splitPreserveAllTokens(null)       = null
-     * StringUtils.splitPreserveAllTokens("")         = []
-     * StringUtils.splitPreserveAllTokens("abc def")  = ["abc", "def"]
-     * StringUtils.splitPreserveAllTokens("abc  def") = ["abc", "", "def"]
-     * StringUtils.splitPreserveAllTokens(" abc ")    = ["", "abc", ""]
-     * </pre>
-     *
-     * @param str  the String to parse, may be {@code null}
-     * @return an array of parsed Strings, {@code null} if null String input
-     * @since 2.1
-     */
-    public static String[] splitPreserveAllTokens(String str) {
-        return splitWorker(str, null, -1, true);
-    }
-
-    /**
-     * <p>Splits the provided text into an array, separator specified,
-     * preserving all tokens, including empty tokens created by adjacent
-     * separators. This is an alternative to using StringTokenizer.</p>
-     *
-     * <p>The separator is not included in the returned String array.
-     * Adjacent separators are treated as separators for empty tokens.
-     * For more control over the split use the StrTokenizer class.</p>
-     *
-     * <p>A {@code null} input String returns {@code null}.</p>
-     *
-     * <pre>
-     * StringUtils.splitPreserveAllTokens(null, *)         = null
-     * StringUtils.splitPreserveAllTokens("", *)           = []
-     * StringUtils.splitPreserveAllTokens("a.b.c", '.')    = ["a", "b", "c"]
-     * StringUtils.splitPreserveAllTokens("a..b.c", '.')   = ["a", "", "b", "c"]
-     * StringUtils.splitPreserveAllTokens("a:b:c", '.')    = ["a:b:c"]
-     * StringUtils.splitPreserveAllTokens("a\tb\nc", null) = ["a", "b", "c"]
-     * StringUtils.splitPreserveAllTokens("a b c", ' ')    = ["a", "b", "c"]
-     * StringUtils.splitPreserveAllTokens("a b c ", ' ')   = ["a", "b", "c", ""]
-     * StringUtils.splitPreserveAllTokens("a b c  ", ' ')   = ["a", "b", "c", "", ""]
-     * StringUtils.splitPreserveAllTokens(" a b c", ' ')   = ["", a", "b", "c"]
-     * StringUtils.splitPreserveAllTokens("  a b c", ' ')  = ["", "", a", "b", "c"]
-     * StringUtils.splitPreserveAllTokens(" a b c ", ' ')  = ["", a", "b", "c", ""]
-     * </pre>
-     *
-     * @param str  the String to parse, may be {@code null}
-     * @param separatorChar  the character used as the delimiter,
-     *  {@code null} splits on whitespace
-     * @return an array of parsed Strings, {@code null} if null String input
-     * @since 2.1
-     */
-    public static String[] splitPreserveAllTokens(String str, char separatorChar) {
-        return splitWorker(str, separatorChar, true);
-    }
-
-    /**
-     * Performs the logic for the {@code split} and
-     * {@code splitPreserveAllTokens} methods that do not return a
-     * maximum array length.
-     *
-     * @param str  the String to parse, may be {@code null}
-     * @param separatorChar the separate character
-     * @param preserveAllTokens if {@code true}, adjacent separators are
-     * treated as empty token separators; if {@code false}, adjacent
-     * separators are treated as one separator.
-     * @return an array of parsed Strings, {@code null} if null String input
-     */
-    private static String[] splitWorker(String str, char separatorChar, boolean preserveAllTokens) {
-        // Performance tuned for 2.0 (JDK1.4)
-
-        if (str == null) {
-            return null;
-        }
-        int len = str.length();
-        if (len == 0) {
-            return ArrayUtils.EMPTY_STRING_ARRAY;
-        }
-        List<String> list = new ArrayList<String>();
-        int i = 0, start = 0;
-        boolean match = false;
-        boolean lastMatch = false;
-        while (i < len) {
-            if (str.charAt(i) == separatorChar) {
-                if (match || preserveAllTokens) {
-                    list.add(str.substring(start, i));
-                    match = false;
-                    lastMatch = true;
-                }
-                start = ++i;
-                continue;
-            }
-            lastMatch = false;
-            match = true;
-            i++;
-        }
-        if (match || preserveAllTokens && lastMatch) {
-            list.add(str.substring(start, i));
-        }
-        return list.toArray(new String[list.size()]);
-    }
-
-    /**
-     * <p>Splits the provided text into an array, separators specified,
-     * preserving all tokens, including empty tokens created by adjacent
-     * separators. This is an alternative to using StringTokenizer.</p>
-     *
-     * <p>The separator is not included in the returned String array.
-     * Adjacent separators are treated as separators for empty tokens.
-     * For more control over the split use the StrTokenizer class.</p>
-     *
-     * <p>A {@code null} input String returns {@code null}.
-     * A {@code null} separatorChars splits on whitespace.</p>
-     *
-     * <pre>
-     * StringUtils.splitPreserveAllTokens(null, *)           = null
-     * StringUtils.splitPreserveAllTokens("", *)             = []
-     * StringUtils.splitPreserveAllTokens("abc def", null)   = ["abc", "def"]
-     * StringUtils.splitPreserveAllTokens("abc def", " ")    = ["abc", "def"]
-     * StringUtils.splitPreserveAllTokens("abc  def", " ")   = ["abc", "", def"]
-     * StringUtils.splitPreserveAllTokens("ab:cd:ef", ":")   = ["ab", "cd", "ef"]
-     * StringUtils.splitPreserveAllTokens("ab:cd:ef:", ":")  = ["ab", "cd", "ef", ""]
-     * StringUtils.splitPreserveAllTokens("ab:cd:ef::", ":") = ["ab", "cd", "ef", "", ""]
-     * StringUtils.splitPreserveAllTokens("ab::cd:ef", ":")  = ["ab", "", cd", "ef"]
-     * StringUtils.splitPreserveAllTokens(":cd:ef", ":")     = ["", cd", "ef"]
-     * StringUtils.splitPreserveAllTokens("::cd:ef", ":")    = ["", "", cd", "ef"]
-     * StringUtils.splitPreserveAllTokens(":cd:ef:", ":")    = ["", cd", "ef", ""]
-     * </pre>
-     *
-     * @param str  the String to parse, may be {@code null}
-     * @param separatorChars  the characters used as the delimiters,
-     *  {@code null} splits on whitespace
-     * @return an array of parsed Strings, {@code null} if null String input
-     * @since 2.1
-     */
-    public static String[] splitPreserveAllTokens(String str, String separatorChars) {
-        return splitWorker(str, separatorChars, -1, true);
-    }
-
-    /**
-     * <p>Splits the provided text into an array with a maximum length,
-     * separators specified, preserving all tokens, including empty tokens
-     * created by adjacent separators.</p>
-     *
-     * <p>The separator is not included in the returned String array.
-     * Adjacent separators are treated as separators for empty tokens.
-     * Adjacent separators are treated as one separator.</p>
-     *
-     * <p>A {@code null} input String returns {@code null}.
-     * A {@code null} separatorChars splits on whitespace.</p>
-     *
-     * <p>If more than {@code max} delimited substrings are found, the last
-     * returned string includes all characters after the first {@code max - 1}
-     * returned strings (including separator characters).</p>
-     *
-     * <pre>
-     * StringUtils.splitPreserveAllTokens(null, *, *)            = null
-     * StringUtils.splitPreserveAllTokens("", *, *)              = []
-     * StringUtils.splitPreserveAllTokens("ab de fg", null, 0)   = ["ab", "cd", "ef"]
-     * StringUtils.splitPreserveAllTokens("ab   de fg", null, 0) = ["ab", "cd", "ef"]
-     * StringUtils.splitPreserveAllTokens("ab:cd:ef", ":", 0)    = ["ab", "cd", "ef"]
-     * StringUtils.splitPreserveAllTokens("ab:cd:ef", ":", 2)    = ["ab", "cd:ef"]
-     * StringUtils.splitPreserveAllTokens("ab   de fg", null, 2) = ["ab", "  de fg"]
-     * StringUtils.splitPreserveAllTokens("ab   de fg", null, 3) = ["ab", "", " de fg"]
-     * StringUtils.splitPreserveAllTokens("ab   de fg", null, 4) = ["ab", "", "", "de fg"]
-     * </pre>
-     *
-     * @param str  the String to parse, may be {@code null}
-     * @param separatorChars  the characters used as the delimiters,
-     *  {@code null} splits on whitespace
-     * @param max  the maximum number of elements to include in the
-     *  array. A zero or negative value implies no limit
-     * @return an array of parsed Strings, {@code null} if null String input
-     * @since 2.1
-     */
-    public static String[] splitPreserveAllTokens(String str, String separatorChars, int max) {
-        return splitWorker(str, separatorChars, max, true);
-    }
-
-    /**
-     * Performs the logic for the {@code split} and
-     * {@code splitPreserveAllTokens} methods that return a maximum array
-     * length.
-     *
-     * @param str  the String to parse, may be {@code null}
-     * @param separatorChars the separate character
-     * @param max  the maximum number of elements to include in the
-     *  array. A zero or negative value implies no limit.
-     * @param preserveAllTokens if {@code true}, adjacent separators are
-     * treated as empty token separators; if {@code false}, adjacent
-     * separators are treated as one separator.
-     * @return an array of parsed Strings, {@code null} if null String input
-     */
-    private static String[] splitWorker(String str, String separatorChars, int max, boolean preserveAllTokens) {
-        // Performance tuned for 2.0 (JDK1.4)
-        // Direct code is quicker than StringTokenizer.
-        // Also, StringTokenizer uses isSpace() not isWhitespace()
-
-        if (str == null) {
-            return null;
-        }
-        int len = str.length();
-        if (len == 0) {
-            return ArrayUtils.EMPTY_STRING_ARRAY;
-        }
-        List<String> list = new ArrayList<String>();
-        int sizePlus1 = 1;
-        int i = 0, start = 0;
-        boolean match = false;
-        boolean lastMatch = false;
-        if (separatorChars == null) {
-            // Null separator means use whitespace
-            while (i < len) {
-                if (Character.isWhitespace(str.charAt(i))) {
-                    if (match || preserveAllTokens) {
-                        lastMatch = true;
-                        if (sizePlus1++ == max) {
-                            i = len;
-                            lastMatch = false;
-                        }
-                        list.add(str.substring(start, i));
-                        match = false;
-                    }
-                    start = ++i;
-                    continue;
-                }
-                lastMatch = false;
-                match = true;
-                i++;
-            }
-        } else if (separatorChars.length() == 1) {
-            // Optimise 1 character case
-            char sep = separatorChars.charAt(0);
-            while (i < len) {
-                if (str.charAt(i) == sep) {
-                    if (match || preserveAllTokens) {
-                        lastMatch = true;
-                        if (sizePlus1++ == max) {
-                            i = len;
-                            lastMatch = false;
-                        }
-                        list.add(str.substring(start, i));
-                        match = false;
-                    }
-                    start = ++i;
-                    continue;
-                }
-                lastMatch = false;
-                match = true;
-                i++;
-            }
-        } else {
-            // standard case
-            while (i < len) {
-                if (separatorChars.indexOf(str.charAt(i)) >= 0) {
-                    if (match || preserveAllTokens) {
-                        lastMatch = true;
-                        if (sizePlus1++ == max) {
-                            i = len;
-                            lastMatch = false;
-                        }
-                        list.add(str.substring(start, i));
-                        match = false;
-                    }
-                    start = ++i;
-                    continue;
-                }
-                lastMatch = false;
-                match = true;
-                i++;
-            }
-        }
-        if (match || preserveAllTokens && lastMatch) {
-            list.add(str.substring(start, i));
-        }
-        return list.toArray(new String[list.size()]);
-    }
-
-    /**
-     * <p>Splits a String by Character type as returned by
-     * {@code java.lang.Character.getType(char)}. Groups of contiguous
-     * characters of the same type are returned as complete tokens.
-     * <pre>
-     * StringUtils.splitByCharacterType(null)         = null
-     * StringUtils.splitByCharacterType("")           = []
-     * StringUtils.splitByCharacterType("ab de fg")   = ["ab", " ", "de", " ", "fg"]
-     * StringUtils.splitByCharacterType("ab   de fg") = ["ab", "   ", "de", " ", "fg"]
-     * StringUtils.splitByCharacterType("ab:cd:ef")   = ["ab", ":", "cd", ":", "ef"]
-     * StringUtils.splitByCharacterType("number5")    = ["number", "5"]
-     * StringUtils.splitByCharacterType("fooBar")     = ["foo", "B", "ar"]
-     * StringUtils.splitByCharacterType("foo200Bar")  = ["foo", "200", "B", "ar"]
-     * StringUtils.splitByCharacterType("ASFRules")   = ["ASFR", "ules"]
-     * </pre>
-     * @param str the String to split, may be {@code null}
-     * @return an array of parsed Strings, {@code null} if null String input
-     * @since 2.4
-     */
-    public static String[] splitByCharacterType(String str) {
-        return splitByCharacterType(str, false);
-    }
-
-    /**
-     * <p>Splits a String by Character type as returned by
-     * {@code java.lang.Character.getType(char)}. Groups of contiguous
-     * characters of the same type are returned as complete tokens, with the
-     * following exception: the character of type
-     * {@code Character.UPPERCASE_LETTER}, if any, immediately
-     * preceding a token of type {@code Character.LOWERCASE_LETTER}
-     * will belong to the following token rather than to the preceding, if any,
-     * {@code Character.UPPERCASE_LETTER} token.
-     * <pre>
-     * StringUtils.splitByCharacterTypeCamelCase(null)         = null
-     * StringUtils.splitByCharacterTypeCamelCase("")           = []
-     * StringUtils.splitByCharacterTypeCamelCase("ab de fg")   = ["ab", " ", "de", " ", "fg"]
-     * StringUtils.splitByCharacterTypeCamelCase("ab   de fg") = ["ab", "   ", "de", " ", "fg"]
-     * StringUtils.splitByCharacterTypeCamelCase("ab:cd:ef")   = ["ab", ":", "cd", ":", "ef"]
-     * StringUtils.splitByCharacterTypeCamelCase("number5")    = ["number", "5"]
-     * StringUtils.splitByCharacterTypeCamelCase("fooBar")     = ["foo", "Bar"]
-     * StringUtils.splitByCharacterTypeCamelCase("foo200Bar")  = ["foo", "200", "Bar"]
-     * StringUtils.splitByCharacterTypeCamelCase("ASFRules")   = ["ASF", "Rules"]
-     * </pre>
-     * @param str the String to split, may be {@code null}
-     * @return an array of parsed Strings, {@code null} if null String input
-     * @since 2.4
-     */
-    public static String[] splitByCharacterTypeCamelCase(String str) {
-        return splitByCharacterType(str, true);
-    }
-
-    /**
-     * <p>Splits a String by Character type as returned by
-     * {@code java.lang.Character.getType(char)}. Groups of contiguous
-     * characters of the same type are returned as complete tokens, with the
-     * following exception: if {@code camelCase} is {@code true},
-     * the character of type {@code Character.UPPERCASE_LETTER}, if any,
-     * immediately preceding a token of type {@code Character.LOWERCASE_LETTER}
-     * will belong to the following token rather than to the preceding, if any,
-     * {@code Character.UPPERCASE_LETTER} token.
-     * @param str the String to split, may be {@code null}
-     * @param camelCase whether to use so-called "camel-case" for letter types
-     * @return an array of parsed Strings, {@code null} if null String input
-     * @since 2.4
-     */
-    private static String[] splitByCharacterType(String str, boolean camelCase) {
-        if (str == null) {
-            return null;
-        }
-        if (str.length() == 0) {
-            return ArrayUtils.EMPTY_STRING_ARRAY;
-        }
-        char[] c = str.toCharArray();
-        List<String> list = new ArrayList<String>();
-        int tokenStart = 0;
-        int currentType = Character.getType(c[tokenStart]);
-        for (int pos = tokenStart + 1; pos < c.length; pos++) {
-            int type = Character.getType(c[pos]);
-            if (type == currentType) {
-                continue;
-            }
-            if (camelCase && type == Character.LOWERCASE_LETTER && currentType == Character.UPPERCASE_LETTER) {
-                int newTokenStart = pos - 1;
-                if (newTokenStart != tokenStart) {
-                    list.add(new String(c, tokenStart, newTokenStart - tokenStart));
-                    tokenStart = newTokenStart;
-                }
-            } else {
-                list.add(new String(c, tokenStart, pos - tokenStart));
-                tokenStart = pos;
-            }
-            currentType = type;
-        }
-        list.add(new String(c, tokenStart, c.length - tokenStart));
-        return list.toArray(new String[list.size()]);
-    }
-
-    // Joining
-    //-----------------------------------------------------------------------
-    /**
-     * <p>Joins the elements of the provided array into a single String
-     * containing the provided list of elements.</p>
-     *
-     * <p>No separator is added to the joined String.
-     * Null objects or empty strings within the array are represented by
-     * empty strings.</p>
-     *
-     * <pre>
-     * StringUtils.join(null)            = null
-     * StringUtils.join([])              = ""
-     * StringUtils.join([null])          = ""
-     * StringUtils.join(["a", "b", "c"]) = "abc"
-     * StringUtils.join([null, "", "a"]) = "a"
-     * </pre>
-     *
-     * @param <T> the specific type of values to join together
-     * @param elements  the values to join together, may be null
-     * @return the joined String, {@code null} if null array input
-     * @since 2.0
-     * @since 3.0 Changed signature to use varargs
-     */
-    public static <T> String join(T... elements) {
-        return join(elements, null);
-    }
-
-    /**
-     * <p>Joins the elements of the provided array into a single String
-     * containing the provided list of elements.</p>
-     *
-     * <p>No delimiter is added before or after the list.
-     * Null objects or empty strings within the array are represented by
-     * empty strings.</p>
-     *
-     * <pre>
-     * StringUtils.join(null, *)               = null
-     * StringUtils.join([], *)                 = ""
-     * StringUtils.join([null], *)             = ""
-     * StringUtils.join(["a", "b", "c"], ';')  = "a;b;c"
-     * StringUtils.join(["a", "b", "c"], null) = "abc"
-     * StringUtils.join([null, "", "a"], ';')  = ";;a"
-     * </pre>
-     *
-     * @param array  the array of values to join together, may be null
-     * @param separator  the separator character to use
-     * @return the joined String, {@code null} if null array input
-     * @since 2.0
-     */
-    public static String join(Object[] array, char separator) {
-        if (array == null) {
-            return null;
-        }
-
-        return join(array, separator, 0, array.length);
-    }
-
-    /**
-     * <p>Joins the elements of the provided array into a single String
-     * containing the provided list of elements.</p>
-     *
-     * <p>No delimiter is added before or after the list.
-     * Null objects or empty strings within the array are represented by
-     * empty strings.</p>
-     *
-     * <pre>
-     * StringUtils.join(null, *)               = null
-     * StringUtils.join([], *)                 = ""
-     * StringUtils.join([null], *)             = ""
-     * StringUtils.join(["a", "b", "c"], ';')  = "a;b;c"
-     * StringUtils.join(["a", "b", "c"], null) = "abc"
-     * StringUtils.join([null, "", "a"], ';')  = ";;a"
-     * </pre>
-     *
-     * @param array  the array of values to join together, may be null
-     * @param separator  the separator character to use
-     * @param startIndex the first index to start joining from.  It is
-     * an error to pass in an end index past the end of the array
-     * @param endIndex the index to stop joining from (exclusive). It is
-     * an error to pass in an end index past the end of the array
-     * @return the joined String, {@code null} if null array input
-     * @since 2.0
-     */
-    public static String join(Object[] array, char separator, int startIndex, int endIndex) {
-        if (array == null) {
-            return null;
-        }
-        int noOfItems = endIndex - startIndex;
-        if (noOfItems <= 0) {
-            return EMPTY;
-        }
-        
-        StringBuilder buf = new StringBuilder(noOfItems * 16);
-
-        for (int i = startIndex; i < endIndex; i++) {
-            if (i > startIndex) {
-                buf.append(separator);
-            }
-            if (array[i] != null) {
-                buf.append(array[i]);
-            }
-        }
-        return buf.toString();
-    }
-
-    /**
-     * <p>Joins the elements of the provided array into a single String
-     * containing the provided list of elements.</p>
-     *
-     * <p>No delimiter is added before or after the list.
-     * A {@code null} separator is the same as an empty String ("").
-     * Null objects or empty strings within the array are represented by
-     * empty strings.</p>
-     *
-     * <pre>
-     * StringUtils.join(null, *)                = null
-     * StringUtils.join([], *)                  = ""
-     * StringUtils.join([null], *)              = ""
-     * StringUtils.join(["a", "b", "c"], "--")  = "a--b--c"
-     * StringUtils.join(["a", "b", "c"], null)  = "abc"
-     * StringUtils.join(["a", "b", "c"], "")    = "abc"
-     * StringUtils.join([null, "", "a"], ',')   = ",,a"
-     * </pre>
-     *
-     * @param array  the array of values to join together, may be null
-     * @param separator  the separator character to use, null treated as ""
-     * @return the joined String, {@code null} if null array input
-     */
-    public static String join(Object[] array, String separator) {
-        if (array == null) {
-            return null;
-        }
-        return join(array, separator, 0, array.length);
-    }
-
-    /**
-     * <p>Joins the elements of the provided array into a single String
-     * containing the provided list of elements.</p>
-     *
-     * <p>No delimiter is added before or after the list.
-     * A {@code null} separator is the same as an empty String ("").
-     * Null objects or empty strings within the array are represented by
-     * empty strings.</p>
-     *
-     * <pre>
-     * StringUtils.join(null, *)                = null
-     * StringUtils.join([], *)                  = ""
-     * StringUtils.join([null], *)              = ""
-     * StringUtils.join(["a", "b", "c"], "--")  = "a--b--c"
-     * StringUtils.join(["a", "b", "c"], null)  = "abc"
-     * StringUtils.join(["a", "b", "c"], "")    = "abc"
-     * StringUtils.join([null, "", "a"], ',')   = ",,a"
-     * </pre>
-     *
-     * @param array  the array of values to join together, may be null
-     * @param separator  the separator character to use, null treated as ""
-     * @param startIndex the first index to start joining from.  It is
-     * an error to pass in an end index past the end of the array
-     * @param endIndex the index to stop joining from (exclusive). It is
-     * an error to pass in an end index past the end of the array
-     * @return the joined String, {@code null} if null array input
-     */
-    public static String join(Object[] array, String separator, int startIndex, int endIndex) {
-        if (array == null) {
-            return null;
-        }
-        if (separator == null) {
-            separator = EMPTY;
-        }
-
-        // endIndex - startIndex > 0:   Len = NofStrings *(len(firstString) + len(separator))
-        //           (Assuming that all Strings are roughly equally long)
-        int noOfItems = endIndex - startIndex;
-        if (noOfItems <= 0) {
-            return EMPTY;
-        }
-
-        StringBuilder buf = new StringBuilder(noOfItems * 16);
-
-        for (int i = startIndex; i < endIndex; i++) {
-            if (i > startIndex) {
-                buf.append(separator);
-            }
-            if (array[i] != null) {
-                buf.append(array[i]);
-            }
-        }
-        return buf.toString();
-    }
-
-    /**
-     * <p>Joins the elements of the provided {@code Iterator} into
-     * a single String containing the provided elements.</p>
-     *
-     * <p>No delimiter is added before or after the list. Null objects or empty
-     * strings within the iteration are represented by empty strings.</p>
-     *
-     * <p>See the examples here: {@link #join(Object[],char)}. </p>
-     *
-     * @param iterator  the {@code Iterator} of values to join together, may be null
-     * @param separator  the separator character to use
-     * @return the joined String, {@code null} if null iterator input
-     * @since 2.0
-     */
-    public static String join(Iterator<?> iterator, char separator) {
-
-        // handle null, zero and one elements before building a buffer
-        if (iterator == null) {
-            return null;
-        }
-        if (!iterator.hasNext()) {
-            return EMPTY;
-        }
-        Object first = iterator.next();
-        if (!iterator.hasNext()) {
-            return ObjectUtils.toString(first);
-        }
-
-        // two or more elements
-        StringBuilder buf = new StringBuilder(256); // Java default is 16, probably too small
-        if (first != null) {
-            buf.append(first);
-        }
-
-        while (iterator.hasNext()) {
-            buf.append(separator);
-            Object obj = iterator.next();
-            if (obj != null) {
-                buf.append(obj);
-            }
-        }
-
-        return buf.toString();
-    }
-
-    /**
-     * <p>Joins the elements of the provided {@code Iterator} into
-     * a single String containing the provided elements.</p>
-     *
-     * <p>No delimiter is added before or after the list.
-     * A {@code null} separator is the same as an empty String ("").</p>
-     *
-     * <p>See the examples here: {@link #join(Object[],String)}. </p>
-     *
-     * @param iterator  the {@code Iterator} of values to join together, may be null
-     * @param separator  the separator character to use, null treated as ""
-     * @return the joined String, {@code null} if null iterator input
-     */
-    public static String join(Iterator<?> iterator, String separator) {
-
-        // handle null, zero and one elements before building a buffer
-        if (iterator == null) {
-            return null;
-        }
-        if (!iterator.hasNext()) {
-            return EMPTY;
-        }
-        Object first = iterator.next();
-        if (!iterator.hasNext()) {
-            return ObjectUtils.toString(first);
-        }
-
-        // two or more elements
-        StringBuilder buf = new StringBuilder(256); // Java default is 16, probably too small
-        if (first != null) {
-            buf.append(first);
-        }
-
-        while (iterator.hasNext()) {
-            if (separator != null) {
-                buf.append(separator);
-            }
-            Object obj = iterator.next();
-            if (obj != null) {
-                buf.append(obj);
-            }
-        }
-        return buf.toString();
-    }
-
-    /**
-     * <p>Joins the elements of the provided {@code Iterable} into
-     * a single String containing the provided elements.</p>
-     *
-     * <p>No delimiter is added before or after the list. Null objects or empty
-     * strings within the iteration are represented by empty strings.</p>
-     *
-     * <p>See the examples here: {@link #join(Object[],char)}. </p>
-     *
-     * @param iterable  the {@code Iterable} providing the values to join together, may be null
-     * @param separator  the separator character to use
-     * @return the joined String, {@code null} if null iterator input
-     * @since 2.3
-     */
-    public static String join(Iterable<?> iterable, char separator) {
-        if (iterable == null) {
-            return null;
-        }
-        return join(iterable.iterator(), separator);
-    }
-
-    /**
-     * <p>Joins the elements of the provided {@code Iterable} into
-     * a single String containing the provided elements.</p>
-     *
-     * <p>No delimiter is added before or after the list.
-     * A {@code null} separator is the same as an empty String ("").</p>
-     *
-     * <p>See the examples here: {@link #join(Object[],String)}. </p>
-     *
-     * @param iterable  the {@code Iterable} providing the values to join together, may be null
-     * @param separator  the separator character to use, null treated as ""
-     * @return the joined String, {@code null} if null iterator input
-     * @since 2.3
-     */
-    public static String join(Iterable<?> iterable, String separator) {
-        if (iterable == null) {
-            return null;
-        }
-        return join(iterable.iterator(), separator);
-    }
-
-    // Delete
-    //-----------------------------------------------------------------------
-    /**
-     * <p>Deletes all whitespaces from a String as defined by
-     * {@link Character#isWhitespace(char)}.</p>
-     *
-     * <pre>
-     * StringUtils.deleteWhitespace(null)         = null
-     * StringUtils.deleteWhitespace("")           = ""
-     * StringUtils.deleteWhitespace("abc")        = "abc"
-     * StringUtils.deleteWhitespace("   ab  c  ") = "abc"
-     * </pre>
-     *
-     * @param str  the String to delete whitespace from, may be null
-     * @return the String without whitespaces, {@code null} if null String input
-     */
-    public static String deleteWhitespace(String str) {
-        if (isEmpty(str)) {
-            return str;
-        }
-        int sz = str.length();
-        char[] chs = new char[sz];
-        int count = 0;
-        for (int i = 0; i < sz; i++) {
-            if (!Character.isWhitespace(str.charAt(i))) {
-                chs[count++] = str.charAt(i);
-            }
-        }
-        if (count == sz) {
-            return str;
-        }
-        return new String(chs, 0, count);
-    }
-
-    // Remove
-    //-----------------------------------------------------------------------
-    /**
-     * <p>Removes a substring only if it is at the beginning of a source string,
-     * otherwise returns the source string.</p>
-     *
-     * <p>A {@code null} source string will return {@code null}.
-     * An empty ("") source string will return the empty string.
-     * A {@code null} search string will return the source string.</p>
-     *
-     * <pre>
-     * StringUtils.removeStart(null, *)      = null
-     * StringUtils.removeStart("", *)        = ""
-     * StringUtils.removeStart(*, null)      = *
-     * StringUtils.removeStart("www.domain.com", "www.")   = "domain.com"
-     * StringUtils.removeStart("domain.com", "www.")       = "domain.com"
-     * StringUtils.removeStart("www.domain.com", "domain") = "www.domain.com"
-     * StringUtils.removeStart("abc", "")    = "abc"
-     * </pre>
-     *
-     * @param str  the source String to search, may be null
-     * @param remove  the String to search for and remove, may be null
-     * @return the substring with the string removed if found,
-     *  {@code null} if null String input
-     * @since 2.1
-     */
-    public static String removeStart(String str, String remove) {
-        if (isEmpty(str) || isEmpty(remove)) {
-            return str;
-        }
-        if (str.startsWith(remove)){
-            return str.substring(remove.length());
-        }
-        return str;
-    }
-
-    /**
-     * <p>Case insensitive removal of a substring if it is at the beginning of a source string,
-     * otherwise returns the source string.</p>
-     *
-     * <p>A {@code null} source string will return {@code null}.
-     * An empty ("") source string will return the empty string.
-     * A {@code null} search string will return the source string.</p>
-     *
-     * <pre>
-     * StringUtils.removeStartIgnoreCase(null, *)      = null
-     * StringUtils.removeStartIgnoreCase("", *)        = ""
-     * StringUtils.removeStartIgnoreCase(*, null)      = *
-     * StringUtils.removeStartIgnoreCase("www.domain.com", "www.")   = "domain.com"
-     * StringUtils.removeStartIgnoreCase("www.domain.com", "WWW.")   = "domain.com"
-     * StringUtils.removeStartIgnoreCase("domain.com", "www.")       = "domain.com"
-     * StringUtils.removeStartIgnoreCase("www.domain.com", "domain") = "www.domain.com"
-     * StringUtils.removeStartIgnoreCase("abc", "")    = "abc"
-     * </pre>
-     *
-     * @param str  the source String to search, may be null
-     * @param remove  the String to search for (case insensitive) and remove, may be null
-     * @return the substring with the string removed if found,
-     *  {@code null} if null String input
-     * @since 2.4
-     */
-    public static String removeStartIgnoreCase(String str, String remove) {
-        if (isEmpty(str) || isEmpty(remove)) {
-            return str;
-        }
-        if (startsWithIgnoreCase(str, remove)) {
-            return str.substring(remove.length());
-        }
-        return str;
-    }
-
-    /**
-     * <p>Removes a substring only if it is at the end of a source string,
-     * otherwise returns the source string.</p>
-     *
-     * <p>A {@code null} source string will return {@code null}.
-     * An empty ("") source string will return the empty string.
-     * A {@code null} search string will return the source string.</p>
-     *
-     * <pre>
-     * StringUtils.removeEnd(null, *)      = null
-     * StringUtils.removeEnd("", *)        = ""
-     * StringUtils.removeEnd(*, null)      = *
-     * StringUtils.removeEnd("www.domain.com", ".com.")  = "www.domain.com"
-     * StringUtils.removeEnd("www.domain.com", ".com")   = "www.domain"
-     * StringUtils.removeEnd("www.domain.com", "domain") = "www.domain.com"
-     * StringUtils.removeEnd("abc", "")    = "abc"
-     * </pre>
-     *
-     * @param str  the source String to search, may be null
-     * @param remove  the String to search for and remove, may be null
-     * @return the substring with the string removed if found,
-     *  {@code null} if null String input
-     * @since 2.1
-     */
-    public static String removeEnd(String str, String remove) {
-        if (isEmpty(str) || isEmpty(remove)) {
-            return str;
-        }
-        if (str.endsWith(remove)) {
-            return str.substring(0, str.length() - remove.length());
-        }
-        return str;
-    }
-
-    /**
-     * <p>Case insensitive removal of a substring if it is at the end of a source string,
-     * otherwise returns the source string.</p>
-     *
-     * <p>A {@code null} source string will return {@code null}.
-     * An empty ("") source string will return the empty string.
-     * A {@code null} search string will return the source string.</p>
-     *
-     * <pre>
-     * StringUtils.removeEndIgnoreCase(null, *)      = null
-     * StringUtils.removeEndIgnoreCase("", *)        = ""
-     * StringUtils.removeEndIgnoreCase(*, null)      = *
-     * StringUtils.removeEndIgnoreCase("www.domain.com", ".com.")  = "www.domain.com"
-     * StringUtils.removeEndIgnoreCase("www.domain.com", ".com")   = "www.domain"
-     * StringUtils.removeEndIgnoreCase("www.domain.com", "domain") = "www.domain.com"
-     * StringUtils.removeEndIgnoreCase("abc", "")    = "abc"
-     * StringUtils.removeEndIgnoreCase("www.domain.com", ".COM") = "www.domain")
-     * StringUtils.removeEndIgnoreCase("www.domain.COM", ".com") = "www.domain")
-     * </pre>
-     *
-     * @param str  the source String to search, may be null
-     * @param remove  the String to search for (case insensitive) and remove, may be null
-     * @return the substring with the string removed if found,
-     *  {@code null} if null String input
-     * @since 2.4
-     */
-    public static String removeEndIgnoreCase(String str, String remove) {
-        if (isEmpty(str) || isEmpty(remove)) {
-            return str;
-        }
-        if (endsWithIgnoreCase(str, remove)) {
-            return str.substring(0, str.length() - remove.length());
-        }
-        return str;
-    }
-
-    /**
-     * <p>Removes all occurrences of a substring from within the source string.</p>
-     *
-     * <p>A {@code null} source string will return {@code null}.
-     * An empty ("") source string will return the empty string.
-     * A {@code null} remove string will return the source string.
-     * An empty ("") remove string will return the source string.</p>
-     *
-     * <pre>
-     * StringUtils.remove(null, *)        = null
-     * StringUtils.remove("", *)          = ""
-     * StringUtils.remove(*, null)        = *
-     * StringUtils.remove(*, "")          = *
-     * StringUtils.remove("queued", "ue") = "qd"
-     * StringUtils.remove("queued", "zz") = "queued"
-     * </pre>
-     *
-     * @param str  the source String to search, may be null
-     * @param remove  the String to search for and remove, may be null
-     * @return the substring with the string removed if found,
-     *  {@code null} if null String input
-     * @since 2.1
-     */
-    public static String remove(String str, String remove) {
-        if (isEmpty(str) || isEmpty(remove)) {
-            return str;
-        }
-        return replace(str, remove, EMPTY, -1);
-    }
-
-    /**
-     * <p>Removes all occurrences of a character from within the source string.</p>
-     *
-     * <p>A {@code null} source string will return {@code null}.
-     * An empty ("") source string will return the empty string.</p>
-     *
-     * <pre>
-     * StringUtils.remove(null, *)       = null
-     * StringUtils.remove("", *)         = ""
-     * StringUtils.remove("queued", 'u') = "qeed"
-     * StringUtils.remove("queued", 'z') = "queued"
-     * </pre>
-     *
-     * @param str  the source String to search, may be null
-     * @param remove  the char to search for and remove, may be null
-     * @return the substring with the char removed if found,
-     *  {@code null} if null String input
-     * @since 2.1
-     */
-    public static String remove(String str, char remove) {
-        if (isEmpty(str) || str.indexOf(remove) == INDEX_NOT_FOUND) {
-            return str;
-        }
-        char[] chars = str.toCharArray();
-        int pos = 0;
-        for (int i = 0; i < chars.length; i++) {
-            if (chars[i] != remove) {
-                chars[pos++] = chars[i];
-            }
-        }
-        return new String(chars, 0, pos);
-    }
-
-    // Replacing
-    //-----------------------------------------------------------------------
-    /**
-     * <p>Replaces a String with another String inside a larger String, once.</p>
-     *
-     * <p>A {@code null} reference passed to this method is a no-op.</p>
-     *
-     * <pre>
-     * StringUtils.replaceOnce(null, *, *)        = null
-     * StringUtils.replaceOnce("", *, *)          = ""
-     * StringUtils.replaceOnce("any", null, *)    = "any"
-     * StringUtils.replaceOnce("any", *, null)    = "any"
-     * StringUtils.replaceOnce("any", "", *)      = "any"
-     * StringUtils.replaceOnce("aba", "a", null)  = "aba"
-     * StringUtils.replaceOnce("aba", "a", "")    = "ba"
-     * StringUtils.replaceOnce("aba", "a", "z")   = "zba"
-     * </pre>
-     *
-     * @see #replace(String text, String searchString, String replacement, int max)
-     * @param text  text to search and replace in, may be null
-     * @param searchString  the String to search for, may be null
-     * @param replacement  the String to replace with, may be null
-     * @return the text with any replacements processed,
-     *  {@code null} if null String input
-     */
-    public static String replaceOnce(String text, String searchString, String replacement) {
-        return replace(text, searchString, replacement, 1);
-    }
-
-    /**
-     * <p>Replaces all occurrences of a String within another String.</p>
-     *
-     * <p>A {@code null} reference passed to this method is a no-op.</p>
-     *
-     * <pre>
-     * StringUtils.replace(null, *, *)        = null
-     * StringUtils.replace("", *, *)          = ""
-     * StringUtils.replace("any", null, *)    = "any"
-     * StringUtils.replace("any", *, null)    = "any"
-     * StringUtils.replace("any", "", *)      = "any"
-     * StringUtils.replace("aba", "a", null)  = "aba"
-     * StringUtils.replace("aba", "a", "")    = "b"
-     * StringUtils.replace("aba", "a", "z")   = "zbz"
-     * </pre>
-     *
-     * @see #replace(String text, String searchString, String replacement, int max)
-     * @param text  text to search and replace in, may be null
-     * @param searchString  the String to search for, may be null
-     * @param replacement  the String to replace it with, may be null
-     * @return the text with any replacements processed,
-     *  {@code null} if null String input
-     */
-    public static String replace(String text, String searchString, String replacement) {
-        return replace(text, searchString, replacement, -1);
-    }
-
-    /**
-     * <p>Replaces a String with another String inside a larger String,
-     * for the first {@code max} values of the search String.</p>
-     *
-     * <p>A {@code null} reference passed to this method is a no-op.</p>
-     *
-     * <pre>
-     * StringUtils.replace(null, *, *, *)         = null
-     * StringUtils.replace("", *, *, *)           = ""
-     * StringUtils.replace("any", null, *, *)     = "any"
-     * StringUtils.replace("any", *, null, *)     = "any"
-     * StringUtils.replace("any", "", *, *)       = "any"
-     * StringUtils.replace("any", *, *, 0)        = "any"
-     * StringUtils.replace("abaa", "a", null, -1) = "abaa"
-     * StringUtils.replace("abaa", "a", "", -1)   = "b"
-     * StringUtils.replace("abaa", "a", "z", 0)   = "abaa"
-     * StringUtils.replace("abaa", "a", "z", 1)   = "zbaa"
-     * StringUtils.replace("abaa", "a", "z", 2)   = "zbza"
-     * StringUtils.replace("abaa", "a", "z", -1)  = "zbzz"
-     * </pre>
-     *
-     * @param text  text to search and replace in, may be null
-     * @param searchString  the String to search for, may be null
-     * @param replacement  the String to replace it with, may be null
-     * @param max  maximum number of values to replace, or {@code -1} if no maximum
-     * @return the text with any replacements processed,
-     *  {@code null} if null String input
-     */
-    public static String replace(String text, String searchString, String replacement, int max) {
-        if (isEmpty(text) || isEmpty(searchString) || replacement == null || max == 0) {
-            return text;
-        }
-        int start = 0;
-        int end = text.indexOf(searchString, start);
-        if (end == INDEX_NOT_FOUND) {
-            return text;
-        }
-        int replLength = searchString.length();
-        int increase = replacement.length() - replLength;
-        increase = increase < 0 ? 0 : increase;
-        increase *= max < 0 ? 16 : max > 64 ? 64 : max;
-        StringBuilder buf = new StringBuilder(text.length() + increase);
-        while (end != INDEX_NOT_FOUND) {
-            buf.append(text.substring(start, end)).append(replacement);
-            start = end + replLength;
-            if (--max == 0) {
-                break;
-            }
-            end = text.indexOf(searchString, start);
-        }
-        buf.append(text.substring(start));
-        return buf.toString();
-    }
-
-    /**
-     * <p>
-     * Replaces all occurrences of Strings within another String.
-     * </p>
-     *
-     * <p>
-     * A {@code null} reference passed to this method is a no-op, or if
-     * any "search string" or "string to replace" is null, that replace will be
-     * ignored. This will not repeat. For repeating replaces, call the
-     * overloaded method.
-     * </p>
-     *
-     * <pre>
-     *  StringUtils.replaceEach(null, *, *)        = null
-     *  StringUtils.replaceEach("", *, *)          = ""
-     *  StringUtils.replaceEach("aba", null, null) = "aba"
-     *  StringUtils.replaceEach("aba", new String[0], null) = "aba"
-     *  StringUtils.replaceEach("aba", null, new String[0]) = "aba"
-     *  StringUtils.replaceEach("aba", new String[]{"a"}, null)  = "aba"
-     *  StringUtils.replaceEach("aba", new String[]{"a"}, new String[]{""})  = "b"
-     *  StringUtils.replaceEach("aba", new String[]{null}, new String[]{"a"})  = "aba"
-     *  StringUtils.replaceEach("abcde", new String[]{"ab", "d"}, new String[]{"w", "t"})  = "wcte"
-     *  (example of how it does not repeat)
-     *  StringUtils.replaceEach("abcde", new String[]{"ab", "d"}, new String[]{"d", "t"})  = "dcte"
-     * </pre>
-     *
-     * @param text
-     *            text to search and replace in, no-op if null
-     * @param searchList
-     *            the Strings to search for, no-op if null
-     * @param replacementList
-     *            the Strings to replace them with, no-op if null
-     * @return the text with any replacements processed, {@code null} if
-     *         null String input
-     * @throws IllegalArgumentException
-     *             if the lengths of the arrays are not the same (null is ok,
-     *             and/or size 0)
-     * @since 2.4
-     */
-    public static String replaceEach(String text, String[] searchList, String[] replacementList) {
-        return replaceEach(text, searchList, replacementList, false, 0);
-    }
-
-    /**
-     * <p>
-     * Replaces all occurrences of Strings within another String.
-     * </p>
-     *
-     * <p>
-     * A {@code null} reference passed to this method is a no-op, or if
-     * any "search string" or "string to replace" is null, that replace will be
-     * ignored. 
-     * </p>
-     *
-     * <pre>
-     *  StringUtils.replaceEach(null, *, *, *) = null
-     *  StringUtils.replaceEach("", *, *, *) = ""
-     *  StringUtils.replaceEach("aba", null, null, *) = "aba"
-     *  StringUtils.replaceEach("aba", new String[0], null, *) = "aba"
-     *  StringUtils.replaceEach("aba", null, new String[0], *) = "aba"
-     *  StringUtils.replaceEach("aba", new String[]{"a"}, null, *) = "aba"
-     *  StringUtils.replaceEach("aba", new String[]{"a"}, new String[]{""}, *) = "b"
-     *  StringUtils.replaceEach("aba", new String[]{null}, new String[]{"a"}, *) = "aba"
-     *  StringUtils.replaceEach("abcde", new String[]{"ab", "d"}, new String[]{"w", "t"}, *) = "wcte"
-     *  (example of how it repeats)
-     *  StringUtils.replaceEach("abcde", new String[]{"ab", "d"}, new String[]{"d", "t"}, false) = "dcte"
-     *  StringUtils.replaceEach("abcde", new String[]{"ab", "d"}, new String[]{"d", "t"}, true) = "tcte"
-     *  StringUtils.replaceEach("abcde", new String[]{"ab", "d"}, new String[]{"d", "ab"}, true) = IllegalStateException
-     *  StringUtils.replaceEach("abcde", new String[]{"ab", "d"}, new String[]{"d", "ab"}, false) = "dcabe"
-     * </pre>
-     *
-     * @param text
-     *            text to search and replace in, no-op if null
-     * @param searchList
-     *            the Strings to search for, no-op if null
-     * @param replacementList
-     *            the Strings to replace them with, no-op if null
-     * @return the text with any replacements processed, {@code null} if
-     *         null String input
-     * @throws IllegalStateException
-     *             if the search is repeating and there is an endless loop due
-     *             to outputs of one being inputs to another
-     * @throws IllegalArgumentException
-     *             if the lengths of the arrays are not the same (null is ok,
-     *             and/or size 0)
-     * @since 2.4
-     */
-    public static String replaceEachRepeatedly(String text, String[] searchList, String[] replacementList) {
-        // timeToLive should be 0 if not used or nothing to replace, else it's
-        // the length of the replace array
-        int timeToLive = searchList == null ? 0 : searchList.length;
-        return replaceEach(text, searchList, replacementList, true, timeToLive);
-    }
-
-    /**
-     * <p>
-     * Replaces all occurrences of Strings within another String.
-     * </p>
-     *
-     * <p>
-     * A {@code null} reference passed to this method is a no-op, or if
-     * any "search string" or "string to replace" is null, that replace will be
-     * ignored.
-     * </p>
-     *
-     * <pre>
-     *  StringUtils.replaceEach(null, *, *, *) = null
-     *  StringUtils.replaceEach("", *, *, *) = ""
-     *  StringUtils.replaceEach("aba", null, null, *) = "aba"
-     *  StringUtils.replaceEach("aba", new String[0], null, *) = "aba"
-     *  StringUtils.replaceEach("aba", null, new String[0], *) = "aba"
-     *  StringUtils.replaceEach("aba", new String[]{"a"}, null, *) = "aba"
-     *  StringUtils.replaceEach("aba", new String[]{"a"}, new String[]{""}, *) = "b"
-     *  StringUtils.replaceEach("aba", new String[]{null}, new String[]{"a"}, *) = "aba"
-     *  StringUtils.replaceEach("abcde", new String[]{"ab", "d"}, new String[]{"w", "t"}, *) = "wcte"
-     *  (example of how it repeats)
-     *  StringUtils.replaceEach("abcde", new String[]{"ab", "d"}, new String[]{"d", "t"}, false) = "dcte"
-     *  StringUtils.replaceEach("abcde", new String[]{"ab", "d"}, new String[]{"d", "t"}, true) = "tcte"
-     *  StringUtils.replaceEach("abcde", new String[]{"ab", "d"}, new String[]{"d", "ab"}, *) = IllegalStateException
-     * </pre>
-     *
-     * @param text
-     *            text to search and replace in, no-op if null
-     * @param searchList
-     *            the Strings to search for, no-op if null
-     * @param replacementList
-     *            the Strings to replace them with, no-op if null
-     * @param repeat if true, then replace repeatedly
-     *       until there are no more possible replacements or timeToLive < 0
-     * @param timeToLive
-     *            if less than 0 then there is a circular reference and endless
-     *            loop
-     * @return the text with any replacements processed, {@code null} if
-     *         null String input
-     * @throws IllegalStateException
-     *             if the search is repeating and there is an endless loop due
-     *             to outputs of one being inputs to another
-     * @throws IllegalArgumentException
-     *             if the lengths of the arrays are not the same (null is ok,
-     *             and/or size 0)
-     * @since 2.4
-     */
-    private static String replaceEach(
-            String text, String[] searchList, String[] replacementList, boolean repeat, int timeToLive) {
-
-        // mchyzer Performance note: This creates very few new objects (one major goal)
-        // let me know if there are performance requests, we can create a harness to measure
-
-        if (text == null || text.length() == 0 || searchList == null ||
-                searchList.length == 0 || replacementList == null || replacementList.length == 0) {
-            return text;
-        }
-
-        // if recursing, this shouldn't be less than 0
-        if (timeToLive < 0) {
-            throw new IllegalStateException("Aborting to protect against StackOverflowError - " +
-                                            "output of one loop is the input of another");
-        }
-
-        int searchLength = searchList.length;
-        int replacementLength = replacementList.length;
-
-        // make sure lengths are ok, these need to be equal
-        if (searchLength != replacementLength) {
-            throw new IllegalArgumentException("Search and Replace array lengths don't match: "
-                + searchLength
-                + " vs "
-                + replacementLength);
-        }
-
-        // keep track of which still have matches
-        boolean[] noMoreMatchesForReplIndex = new boolean[searchLength];
-
-        // index on index that the match was found
-        int textIndex = -1;
-        int replaceIndex = -1;
-        int tempIndex = -1;
-
-        // index of replace array that will replace the search string found
-        // NOTE: logic duplicated below START
-        for (int i = 0; i < searchLength; i++) {
-            if (noMoreMatchesForReplIndex[i] || searchList[i] == null ||
-                    searchList[i].length() == 0 || replacementList[i] == null) {
-                continue;
-            }
-            tempIndex = text.indexOf(searchList[i]);
-
-            // see if we need to keep searching for this
-            if (tempIndex == -1) {
-                noMoreMatchesForReplIndex[i] = true;
-            } else {
-                if (textIndex == -1 || tempIndex < textIndex) {
-                    textIndex = tempIndex;
-                    replaceIndex = i;
-                }
-            }
-        }
-        // NOTE: logic mostly below END
-
-        // no search strings found, we are done
-        if (textIndex == -1) {
-            return text;
-        }
-
-        int start = 0;
-
-        // get a good guess on the size of the result buffer so it doesn't have to double if it goes over a bit
-        int increase = 0;
-
-        // count the replacement text elements that are larger than their corresponding text being replaced
-        for (int i = 0; i < searchList.length; i++) {
-            if (searchList[i] == null || replacementList[i] == null) {
-                continue;
-            }
-            int greater = replacementList[i].length() - searchList[i].length();
-            if (greater > 0) {
-                increase += 3 * greater; // assume 3 matches
-            }
-        }
-        // have upper-bound at 20% increase, then let Java take over
-        increase = Math.min(increase, text.length() / 5);
-
-        StringBuilder buf = new StringBuilder(text.length() + increase);
-
-        while (textIndex != -1) {
-
-            for (int i = start; i < textIndex; i++) {
-                buf.append(text.charAt(i));
-            }
-            buf.append(replacementList[replaceIndex]);
-
-            start = textIndex + searchList[replaceIndex].length();
-
-            textIndex = -1;
-            replaceIndex = -1;
-            tempIndex = -1;
-            // find the next earliest match
-            // NOTE: logic mostly duplicated above START
-            for (int i = 0; i < searchLength; i++) {
-                if (noMoreMatchesForReplIndex[i] || searchList[i] == null ||
-                        searchList[i].length() == 0 || replacementList[i] == null) {
-                    continue;
-                }
-                tempIndex = text.indexOf(searchList[i], start);
-
-                // see if we need to keep searching for this
-                if (tempIndex == -1) {
-                    noMoreMatchesForReplIndex[i] = true;
-                } else {
-                    if (textIndex == -1 || tempIndex < textIndex) {
-                        textIndex = tempIndex;
-                        replaceIndex = i;
-                    }
-                }
-            }
-            // NOTE: logic duplicated above END
-
-        }
-        int textLength = text.length();
-        for (int i = start; i < textLength; i++) {
-            buf.append(text.charAt(i));
-        }
-        String result = buf.toString();
-        if (!repeat) {
-            return result;
-        }
-
-        return replaceEach(result, searchList, replacementList, repeat, timeToLive - 1);
-    }
-
-    // Replace, character based
-    //-----------------------------------------------------------------------
-    /**
-     * <p>Replaces all occurrences of a character in a String with another.
-     * This is a null-safe version of {@link String#replace(char, char)}.</p>
-     *
-     * <p>A {@code null} string input returns {@code null}.
-     * An empty ("") string input returns an empty string.</p>
-     *
-     * <pre>
-     * StringUtils.replaceChars(null, *, *)        = null
-     * StringUtils.replaceChars("", *, *)          = ""
-     * StringUtils.replaceChars("abcba", 'b', 'y') = "aycya"
-     * StringUtils.replaceChars("abcba", 'z', 'y') = "abcba"
-     * </pre>
-     *
-     * @param str  String to replace characters in, may be null
-     * @param searchChar  the character to search for, may be null
-     * @param replaceChar  the character to replace, may be null
-     * @return modified String, {@code null} if null string input
-     * @since 2.0
-     */
-    public static String replaceChars(String str, char searchChar, char replaceChar) {
-        if (str == null) {
-            return null;
-        }
-        return str.replace(searchChar, replaceChar);
-    }
-
-    /**
-     * <p>Replaces multiple characters in a String in one go.
-     * This method can also be used to delete characters.</p>
-     *
-     * <p>For example:<br />
-     * <code>replaceChars(&quot;hello&quot;, &quot;ho&quot;, &quot;jy&quot;) = jelly</code>.</p>
-     *
-     * <p>A {@code null} string input returns {@code null}.
-     * An empty ("") string input returns an empty string.
-     * A null or empty set of search characters returns the input string.</p>
-     *
-     * <p>The length of the search characters should normally equal the length
-     * of the replace characters.
-     * If the search characters is longer, then the extra search characters
-     * are deleted.
-     * If the search characters is shorter, then the extra replace characters
-     * are ignored.</p>
-     *
-     * <pre>
-     * StringUtils.replaceChars(null, *, *)           = null
-     * StringUtils.replaceChars("", *, *)             = ""
-     * StringUtils.replaceChars("abc", null, *)       = "abc"
-     * StringUtils.replaceChars("abc", "", *)         = "abc"
-     * StringUtils.replaceChars("abc", "b", null)     = "ac"
-     * StringUtils.replaceChars("abc", "b", "")       = "ac"
-     * StringUtils.replaceChars("abcba", "bc", "yz")  = "ayzya"
-     * StringUtils.replaceChars("abcba", "bc", "y")   = "ayya"
-     * StringUtils.replaceChars("abcba", "bc", "yzx") = "ayzya"
-     * </pre>
-     *
-     * @param str  String to replace characters in, may be null
-     * @param searchChars  a set of characters to search for, may be null
-     * @param replaceChars  a set of characters to replace, may be null
-     * @return modified String, {@code null} if null string input
-     * @since 2.0
-     */
-    public static String replaceChars(String str, String searchChars, String replaceChars) {
-        if (isEmpty(str) || isEmpty(searchChars)) {
-            return str;
-        }
-        if (replaceChars == null) {
-            replaceChars = EMPTY;
-        }
-        boolean modified = false;
-        int replaceCharsLength = replaceChars.length();
-        int strLength = str.length();
-        StringBuilder buf = new StringBuilder(strLength);
-        for (int i = 0; i < strLength; i++) {
-            char ch = str.charAt(i);
-            int index = searchChars.indexOf(ch);
-            if (index >= 0) {
-                modified = true;
-                if (index < replaceCharsLength) {
-                    buf.append(replaceChars.charAt(index));
-                }
-            } else {
-                buf.append(ch);
-            }
-        }
-        if (modified) {
-            return buf.toString();
-        }
-        return str;
-    }
-
-    // Overlay
-    //-----------------------------------------------------------------------
-    /**
-     * <p>Overlays part of a String with another String.</p>
-     *
-     * <p>A {@code null} string input returns {@code null}.
-     * A negative index is treated as zero.
-     * An index greater than the string length is treated as the string length.
-     * The start index is always the smaller of the two indices.</p>
-     *
-     * <pre>
-     * StringUtils.overlay(null, *, *, *)            = null
-     * StringUtils.overlay("", "abc", 0, 0)          = "abc"
-     * StringUtils.overlay("abcdef", null, 2, 4)     = "abef"
-     * StringUtils.overlay("abcdef", "", 2, 4)       = "abef"
-     * StringUtils.overlay("abcdef", "", 4, 2)       = "abef"
-     * StringUtils.overlay("abcdef", "zzzz", 2, 4)   = "abzzzzef"
-     * StringUtils.overlay("abcdef", "zzzz", 4, 2)   = "abzzzzef"
-     * StringUtils.overlay("abcdef", "zzzz", -1, 4)  = "zzzzef"
-     * StringUtils.overlay("abcdef", "zzzz", 2, 8)   = "abzzzz"
-     * StringUtils.overlay("abcdef", "zzzz", -2, -3) = "zzzzabcdef"
-     * StringUtils.overlay("abcdef", "zzzz", 8, 10)  = "abcdefzzzz"
-     * </pre>
-     *
-     * @param str  the String to do overlaying in, may be null
-     * @param overlay  the String to overlay, may be null
-     * @param start  the position to start overlaying at
-     * @param end  the position to stop overlaying before
-     * @return overlayed String, {@code null} if null String input
-     * @since 2.0
-     */
-    public static String overlay(String str, String overlay, int start, int end) {
-        if (str == null) {
-            return null;
-        }
-        if (overlay == null) {
-            overlay = EMPTY;
-        }
-        int len = str.length();
-        if (start < 0) {
-            start = 0;
-        }
-        if (start > len) {
-            start = len;
-        }
-        if (end < 0) {
-            end = 0;
-        }
-        if (end > len) {
-            end = len;
-        }
-        if (start > end) {
-            int temp = start;
-            start = end;
-            end = temp;
-        }
-        return new StringBuilder(len + start - end + overlay.length() + 1)
-            .append(str.substring(0, start))
-            .append(overlay)
-            .append(str.substring(end))
-            .toString();
-    }
-
-    // Chomping
-    //-----------------------------------------------------------------------
-    /**
-     * <p>Removes one newline from end of a String if it's there,
-     * otherwise leave it alone.  A newline is &quot;{@code \n}&quot;,
-     * &quot;{@code \r}&quot;, or &quot;{@code \r\n}&quot;.</p>
-     *
-     * <p>NOTE: This method changed in 2.0.
-     * It now more closely matches Perl chomp.</p>
-     *
-     * <pre>
-     * StringUtils.chomp(null)          = null
-     * StringUtils.chomp("")            = ""
-     * StringUtils.chomp("abc \r")      = "abc "
-     * StringUtils.chomp("abc\n")       = "abc"
-     * StringUtils.chomp("abc\r\n")     = "abc"
-     * StringUtils.chomp("abc\r\n\r\n") = "abc\r\n"
-     * StringUtils.chomp("abc\n\r")     = "abc\n"
-     * StringUtils.chomp("abc\n\rabc")  = "abc\n\rabc"
-     * StringUtils.chomp("\r")          = ""
-     * StringUtils.chomp("\n")          = ""
-     * StringUtils.chomp("\r\n")        = ""
-     * </pre>
-     *
-     * @param str  the String to chomp a newline from, may be null
-     * @return String without newline, {@code null} if null String input
-     */
-    public static String chomp(String str) {
-        if (isEmpty(str)) {
-            return str;
-        }
-
-        if (str.length() == 1) {
-            char ch = str.charAt(0);
-            if (ch == CharUtils.CR || ch == CharUtils.LF) {
-                return EMPTY;
-            }
-            return str;
-        }
-
-        int lastIdx = str.length() - 1;
-        char last = str.charAt(lastIdx);
-
-        if (last == CharUtils.LF) {
-            if (str.charAt(lastIdx - 1) == CharUtils.CR) {
-                lastIdx--;
-            }
-        } else if (last != CharUtils.CR) {
-            lastIdx++;
-        }
-        return str.substring(0, lastIdx);
-    }
-
-    /**
-     * <p>Removes {@code separator} from the end of
-     * {@code str} if it's there, otherwise leave it alone.</p>
-     *
-     * <p>NOTE: This method changed in version 2.0.
-     * It now more closely matches Perl chomp.
-     * For the previous behavior, use {@link #substringBeforeLast(String, String)}.
-     * This method uses {@link String#endsWith(String)}.</p>
-     *
-     * <pre>
-     * StringUtils.chomp(null, *)         = null
-     * StringUtils.chomp("", *)           = ""
-     * StringUtils.chomp("foobar", "bar") = "foo"
-     * StringUtils.chomp("foobar", "baz") = "foobar"
-     * StringUtils.chomp("foo", "foo")    = ""
-     * StringUtils.chomp("foo ", "foo")   = "foo "
-     * StringUtils.chomp(" foo", "foo")   = " "
-     * StringUtils.chomp("foo", "foooo")  = "foo"
-     * StringUtils.chomp("foo", "")       = "foo"
-     * StringUtils.chomp("foo", null)     = "foo"
-     * </pre>
-     *
-     * @param str  the String to chomp from, may be null
-     * @param separator  separator String, may be null
-     * @return String without trailing separator, {@code null} if null String input
-     * @deprecated This feature will be removed in Lang 4.0, use {@link StringUtils#removeEnd(String, String)} instead
-     */
-    @Deprecated
-    public static String chomp(String str, String separator) {
-        return removeEnd(str,separator);
-    }
-
-    // Chopping
-    //-----------------------------------------------------------------------
-    /**
-     * <p>Remove the last character from a String.</p>
-     *
-     * <p>If the String ends in {@code \r\n}, then remove both
-     * of them.</p>
-     *
-     * <pre>
-     * StringUtils.chop(null)          = null
-     * StringUtils.chop("")            = ""
-     * StringUtils.chop("abc \r")      = "abc "
-     * StringUtils.chop("abc\n")       = "abc"
-     * StringUtils.chop("abc\r\n")     = "abc"
-     * StringUtils.chop("abc")         = "ab"
-     * StringUtils.chop("abc\nabc")    = "abc\nab"
-     * StringUtils.chop("a")           = ""
-     * StringUtils.chop("\r")          = ""
-     * StringUtils.chop("\n")          = ""
-     * StringUtils.chop("\r\n")        = ""
-     * </pre>
-     *
-     * @param str  the String to chop last character from, may be null
-     * @return String without last character, {@code null} if null String input
-     */
-    public static String chop(String str) {
-        if (str == null) {
-            return null;
-        }
-        int strLen = str.length();
-        if (strLen < 2) {
-            return EMPTY;
-        }
-        int lastIdx = strLen - 1;
-        String ret = str.substring(0, lastIdx);
-        char last = str.charAt(lastIdx);
-        if (last == CharUtils.LF && ret.charAt(lastIdx - 1) == CharUtils.CR) {
-            return ret.substring(0, lastIdx - 1);
-        }
-        return ret;
-    }
-
-    // Conversion
-    //-----------------------------------------------------------------------
-
-    // Padding
-    //-----------------------------------------------------------------------
-    /**
-     * <p>Repeat a String {@code repeat} times to form a
-     * new String.</p>
-     *
-     * <pre>
-     * StringUtils.repeat(null, 2) = null
-     * StringUtils.repeat("", 0)   = ""
-     * StringUtils.repeat("", 2)   = ""
-     * StringUtils.repeat("a", 3)  = "aaa"
-     * StringUtils.repeat("ab", 2) = "abab"
-     * StringUtils.repeat("a", -2) = ""
-     * </pre>
-     *
-     * @param str  the String to repeat, may be null
-     * @param repeat  number of times to repeat str, negative treated as zero
-     * @return a new String consisting of the original String repeated,
-     *  {@code null} if null String input
-     */
-    public static String repeat(String str, int repeat) {
-        // Performance tuned for 2.0 (JDK1.4)
-
-        if (str == null) {
-            return null;
-        }
-        if (repeat <= 0) {
-            return EMPTY;
-        }
-        int inputLength = str.length();
-        if (repeat == 1 || inputLength == 0) {
-            return str;
-        }
-        if (inputLength == 1 && repeat <= PAD_LIMIT) {
-            return repeat(str.charAt(0), repeat);
-        }
-
-        int outputLength = inputLength * repeat;
-        switch (inputLength) {
-            case 1 :
-                return repeat(str.charAt(0), repeat);
-            case 2 :
-                char ch0 = str.charAt(0);
-                char ch1 = str.charAt(1);
-                char[] output2 = new char[outputLength];
-                for (int i = repeat * 2 - 2; i >= 0; i--, i--) {
-                    output2[i] = ch0;
-                    output2[i + 1] = ch1;
-                }
-                return new String(output2);
-            default :
-                StringBuilder buf = new StringBuilder(outputLength);
-                for (int i = 0; i < repeat; i++) {
-                    buf.append(str);
-                }
-                return buf.toString();
-        }
-    }
-
-    /**
-     * <p>Repeat a String {@code repeat} times to form a
-     * new String, with a String separator injected each time. </p>
-     *
-     * <pre>
-     * StringUtils.repeat(null, null, 2) = null
-     * StringUtils.repeat(null, "x", 2)  = null
-     * StringUtils.repeat("", null, 0)   = ""
-     * StringUtils.repeat("", "", 2)     = ""
-     * StringUtils.repeat("", "x", 3)    = "xxx"
-     * StringUtils.repeat("?", ", ", 3)  = "?, ?, ?"
-     * </pre>
-     *
-     * @param str        the String to repeat, may be null
-     * @param separator  the String to inject, may be null
-     * @param repeat     number of times to repeat str, negative treated as zero
-     * @return a new String consisting of the original String repeated,
-     *  {@code null} if null String input
-     * @since 2.5
-     */
-    public static String repeat(String str, String separator, int repeat) {
-        if(str == null || separator == null) {
-            return repeat(str, repeat);
-        } else {
-            // given that repeat(String, int) is quite optimized, better to rely on it than try and splice this into it
-            String result = repeat(str + separator, repeat);
-            return removeEnd(result, separator);
-        }
-    }
-
-    /**
-     * <p>Returns padding using the specified delimiter repeated
-     * to a given length.</p>
-     *
-     * <pre>
-     * StringUtils.repeat(0, 'e')  = ""
-     * StringUtils.repeat(3, 'e')  = "eee"
-     * StringUtils.repeat(-2, 'e') = ""
-     * </pre>
-     *
-     * <p>Note: this method doesn't not support padding with
-     * <a href="http://www.unicode.org/glossary/#supplementary_character">Unicode Supplementary Characters</a>
-     * as they require a pair of {@code char}s to be represented.
-     * If you are needing to support full I18N of your applications
-     * consider using {@link #repeat(String, int)} instead.
-     * </p>
-     *
-     * @param ch  character to repeat
-     * @param repeat  number of times to repeat char, negative treated as zero
-     * @return String with repeated character
-     * @see #repeat(String, int)
-     */
-    public static String repeat(char ch, int repeat) {
-        char[] buf = new char[repeat];
-        for (int i = repeat - 1; i >= 0; i--) {
-            buf[i] = ch;
-        }
-        return new String(buf);
-    }
-
-    /**
-     * <p>Right pad a String with spaces (' ').</p>
-     *
-     * <p>The String is padded to the size of {@code size}.</p>
-     *
-     * <pre>
-     * StringUtils.rightPad(null, *)   = null
-     * StringUtils.rightPad("", 3)     = "   "
-     * StringUtils.rightPad("bat", 3)  = "bat"
-     * StringUtils.rightPad("bat", 5)  = "bat  "
-     * StringUtils.rightPad("bat", 1)  = "bat"
-     * StringUtils.rightPad("bat", -1) = "bat"
-     * </pre>
-     *
-     * @param str  the String to pad out, may be null
-     * @param size  the size to pad to
-     * @return right padded String or original String if no padding is necessary,
-     *  {@code null} if null String input
-     */
-    public static String rightPad(String str, int size) {
-        return rightPad(str, size, ' ');
-    }
-
-    /**
-     * <p>Right pad a String with a specified character.</p>
-     *
-     * <p>The String is padded to the size of {@code size}.</p>
-     *
-     * <pre>
-     * StringUtils.rightPad(null, *, *)     = null
-     * StringUtils.rightPad("", 3, 'z')     = "zzz"
-     * StringUtils.rightPad("bat", 3, 'z')  = "bat"
-     * StringUtils.rightPad("bat", 5, 'z')  = "batzz"
-     * StringUtils.rightPad("bat", 1, 'z')  = "bat"
-     * StringUtils.rightPad("bat", -1, 'z') = "bat"
-     * </pre>
-     *
-     * @param str  the String to pad out, may be null
-     * @param size  the size to pad to
-     * @param padChar  the character to pad with
-     * @return right padded String or original String if no padding is necessary,
-     *  {@code null} if null String input
-     * @since 2.0
-     */
-    public static String rightPad(String str, int size, char padChar) {
-        if (str == null) {
-            return null;
-        }
-        int pads = size - str.length();
-        if (pads <= 0) {
-            return str; // returns original String when possible
-        }
-        if (pads > PAD_LIMIT) {
-            return rightPad(str, size, String.valueOf(padChar));
-        }
-        return str.concat(repeat(padChar, pads));
-    }
-
-    /**
-     * <p>Right pad a String with a specified String.</p>
-     *
-     * <p>The String is padded to the size of {@code size}.</p>
-     *
-     * <pre>
-     * StringUtils.rightPad(null, *, *)      = null
-     * StringUtils.rightPad("", 3, "z")      = "zzz"
-     * StringUtils.rightPad("bat", 3, "yz")  = "bat"
-     * StringUtils.rightPad("bat", 5, "yz")  = "batyz"
-     * StringUtils.rightPad("bat", 8, "yz")  = "batyzyzy"
-     * StringUtils.rightPad("bat", 1, "yz")  = "bat"
-     * StringUtils.rightPad("bat", -1, "yz") = "bat"
-     * StringUtils.rightPad("bat", 5, null)  = "bat  "
-     * StringUtils.rightPad("bat", 5, "")    = "bat  "
-     * </pre>
-     *
-     * @param str  the String to pad out, may be null
-     * @param size  the size to pad to
-     * @param padStr  the String to pad with, null or empty treated as single space
-     * @return right padded String or original String if no padding is necessary,
-     *  {@code null} if null String input
-     */
-    public static String rightPad(String str, int size, String padStr) {
-        if (str == null) {
-            return null;
-        }
-        if (isEmpty(padStr)) {
-            padStr = " ";
-        }
-        int padLen = padStr.length();
-        int strLen = str.length();
-        int pads = size - strLen;
-        if (pads <= 0) {
-            return str; // returns original String when possible
-        }
-        if (padLen == 1 && pads <= PAD_LIMIT) {
-            return rightPad(str, size, padStr.charAt(0));
-        }
-
-        if (pads == padLen) {
-            return str.concat(padStr);
-        } else if (pads < padLen) {
-            return str.concat(padStr.substring(0, pads));
-        } else {
-            char[] padding = new char[pads];
-            char[] padChars = padStr.toCharArray();
-            for (int i = 0; i < pads; i++) {
-                padding[i] = padChars[i % padLen];
-            }
-            return str.concat(new String(padding));
-        }
-    }
-
-    /**
-     * <p>Left pad a String with spaces (' ').</p>
-     *
-     * <p>The String is padded to the size of {@code size}.</p>
-     *
-     * <pre>
-     * StringUtils.leftPad(null, *)   = null
-     * StringUtils.leftPad("", 3)     = "   "
-     * StringUtils.leftPad("bat", 3)  = "bat"
-     * StringUtils.leftPad("bat", 5)  = "  bat"
-     * StringUtils.leftPad("bat", 1)  = "bat"
-     * StringUtils.leftPad("bat", -1) = "bat"
-     * </pre>
-     *
-     * @param str  the String to pad out, may be null
-     * @param size  the size to pad to
-     * @return left padded String or original String if no padding is necessary,
-     *  {@code null} if null String input
-     */
-    public static String leftPad(String str, int size) {
-        return leftPad(str, size, ' ');
-    }
-
-    /**
-     * <p>Left pad a String with a specified character.</p>
-     *
-     * <p>Pad to a size of {@code size}.</p>
-     *
-     * <pre>
-     * StringUtils.leftPad(null, *, *)     = null
-     * StringUtils.leftPad("", 3, 'z')     = "zzz"
-     * StringUtils.leftPad("bat", 3, 'z')  = "bat"
-     * StringUtils.leftPad("bat", 5, 'z')  = "zzbat"
-     * StringUtils.leftPad("bat", 1, 'z')  = "bat"
-     * StringUtils.leftPad("bat", -1, 'z') = "bat"
-     * </pre>
-     *
-     * @param str  the String to pad out, may be null
-     * @param size  the size to pad to
-     * @param padChar  the character to pad with
-     * @return left padded String or original String if no padding is necessary,
-     *  {@code null} if null String input
-     * @since 2.0
-     */
-    public static String leftPad(String str, int size, char padChar) {
-        if (str == null) {
-            return null;
-        }
-        int pads = size - str.length();
-        if (pads <= 0) {
-            return str; // returns original String when possible
-        }
-        if (pads > PAD_LIMIT) {
-            return leftPad(str, size, String.valueOf(padChar));
-        }
-        return repeat(padChar, pads).concat(str);
-    }
-
-    /**
-     * <p>Left pad a String with a specified String.</p>
-     *
-     * <p>Pad to a size of {@code size}.</p>
-     *
-     * <pre>
-     * StringUtils.leftPad(null, *, *)      = null
-     * StringUtils.leftPad("", 3, "z")      = "zzz"
-     * StringUtils.leftPad("bat", 3, "yz")  = "bat"
-     * StringUtils.leftPad("bat", 5, "yz")  = "yzbat"
-     * StringUtils.leftPad("bat", 8, "yz")  = "yzyzybat"
-     * StringUtils.leftPad("bat", 1, "yz")  = "bat"
-     * StringUtils.leftPad("bat", -1, "yz") = "bat"
-     * StringUtils.leftPad("bat", 5, null)  = "  bat"
-     * StringUtils.leftPad("bat", 5, "")    = "  bat"
-     * </pre>
-     *
-     * @param str  the String to pad out, may be null
-     * @param size  the size to pad to
-     * @param padStr  the String to pad with, null or empty treated as single space
-     * @return left padded String or original String if no padding is necessary,
-     *  {@code null} if null String input
-     */
-    public static String leftPad(String str, int size, String padStr) {
-        if (str == null) {
-            return null;
-        }
-        if (isEmpty(padStr)) {
-            padStr = " ";
-        }
-        int padLen = padStr.length();
-        int strLen = str.length();
-        int pads = size - strLen;
-        if (pads <= 0) {
-            return str; // returns original String when possible
-        }
-        if (padLen == 1 && pads <= PAD_LIMIT) {
-            return leftPad(str, size, padStr.charAt(0));
-        }
-
-        if (pads == padLen) {
-            return padStr.concat(str);
-        } else if (pads < padLen) {
-            return padStr.substring(0, pads).concat(str);
-        } else {
-            char[] padding = new char[pads];
-            char[] padChars = padStr.toCharArray();
-            for (int i = 0; i < pads; i++) {
-                padding[i] = padChars[i % padLen];
-            }
-            return new String(padding).concat(str);
-        }
-    }
-
-    /**
-     * Gets a CharSequence length or {@code 0} if the CharSequence is
-     * {@code null}.
-     *
-     * @param cs
-     *            a CharSequence or {@code null}
-     * @return CharSequence length or {@code 0} if the CharSequence is
-     *         {@code null}.
-     * @since 2.4
-     * @since 3.0 Changed signature from length(String) to length(CharSequence)
-     */
-    public static int length(CharSequence cs) {
-        return cs == null ? 0 : cs.length();
-    }
-
-    // Centering
-    //-----------------------------------------------------------------------
-    /**
-     * <p>Centers a String in a larger String of size {@code size}
-     * using the space character (' ').<p>
-     *
-     * <p>If the size is less than the String length, the String is returned.
-     * A {@code null} String returns {@code null}.
-     * A negative size is treated as zero.</p>
-     *
-     * <p>Equivalent to {@code center(str, size, " ")}.</p>
-     *
-     * <pre>
-     * StringUtils.center(null, *)   = null
-     * StringUtils.center("", 4)     = "    "
-     * StringUtils.center("ab", -1)  = "ab"
-     * StringUtils.center("ab", 4)   = " ab "
-     * StringUtils.center("abcd", 2) = "abcd"
-     * StringUtils.center("a", 4)    = " a  "
-     * </pre>
-     *
-     * @param str  the String to center, may be null
-     * @param size  the int size of new String, negative treated as zero
-     * @return centered String, {@code null} if null String input
-     */
-    public static String center(String str, int size) {
-        return center(str, size, ' ');
-    }
-
-    /**
-     * <p>Centers a String in a larger String of size {@code size}.
-     * Uses a supplied character as the value to pad the String with.</p>
-     *
-     * <p>If the size is less than the String length, the String is returned.
-     * A {@code null} String returns {@code null}.
-     * A negative size is treated as zero.</p>
-     *
-     * <pre>
-     * StringUtils.center(null, *, *)     = null
-     * StringUtils.center("", 4, ' ')     = "    "
-     * StringUtils.center("ab", -1, ' ')  = "ab"
-     * StringUtils.center("ab", 4, ' ')   = " ab"
-     * StringUtils.center("abcd", 2, ' ') = "abcd"
-     * StringUtils.center("a", 4, ' ')    = " a  "
-     * StringUtils.center("a", 4, 'y')    = "yayy"
-     * </pre>
-     *
-     * @param str  the String to center, may be null
-     * @param size  the int size of new String, negative treated as zero
-     * @param padChar  the character to pad the new String with
-     * @return centered String, {@code null} if null String input
-     * @since 2.0
-     */
-    public static String center(String str, int size, char padChar) {
-        if (str == null || size <= 0) {
-            return str;
-        }
-        int strLen = str.length();
-        int pads = size - strLen;
-        if (pads <= 0) {
-            return str;
-        }
-        str = leftPad(str, strLen + pads / 2, padChar);
-        str = rightPad(str, size, padChar);
-        return str;
-    }
-
-    /**
-     * <p>Centers a String in a larger String of size {@code size}.
-     * Uses a supplied String as the value to pad the String with.</p>
-     *
-     * <p>If the size is less than the String length, the String is returned.
-     * A {@code null} String returns {@code null}.
-     * A negative size is treated as zero.</p>
-     *
-     * <pre>
-     * StringUtils.center(null, *, *)     = null
-     * StringUtils.center("", 4, " ")     = "    "
-     * StringUtils.center("ab", -1, " ")  = "ab"
-     * StringUtils.center("ab", 4, " ")   = " ab"
-     * StringUtils.center("abcd", 2, " ") = "abcd"
-     * StringUtils.center("a", 4, " ")    = " a  "
-     * StringUtils.center("a", 4, "yz")   = "yayz"
-     * StringUtils.center("abc", 7, null) = "  abc  "
-     * StringUtils.center("abc", 7, "")   = "  abc  "
-     * </pre>
-     *
-     * @param str  the String to center, may be null
-     * @param size  the int size of new String, negative treated as zero
-     * @param padStr  the String to pad the new String with, must not be null or empty
-     * @return centered String, {@code null} if null String input
-     * @throws IllegalArgumentException if padStr is {@code null} or empty
-     */
-    public static String center(String str, int size, String padStr) {
-        if (str == null || size <= 0) {
-            return str;
-        }
-        if (isEmpty(padStr)) {
-            padStr = " ";
-        }
-        int strLen = str.length();
-        int pads = size - strLen;
-        if (pads <= 0) {
-            return str;
-        }
-        str = leftPad(str, strLen + pads / 2, padStr);
-        str = rightPad(str, size, padStr);
-        return str;
-    }
-
-    // Case conversion
-    //-----------------------------------------------------------------------
-    /**
-     * <p>Converts a String to upper case as per {@link String#toUpperCase()}.</p>
-     *
-     * <p>A {@code null} input String returns {@code null}.</p>
-     *
-     * <pre>
-     * StringUtils.upperCase(null)  = null
-     * StringUtils.upperCase("")    = ""
-     * StringUtils.upperCase("aBc") = "ABC"
-     * </pre>
-     *
-     * <p><strong>Note:</strong> As described in the documentation for {@link String#toUpperCase()},
-     * the result of this method is affected by the current locale.
-     * For platform-independent case transformations, the method {@link #lowerCase(String, Locale)}
-     * should be used with a specific locale (e.g. {@link Locale#ENGLISH}).</p>
-     *
-     * @param str  the String to upper case, may be null
-     * @return the upper cased String, {@code null} if null String input
-     */
-    public static String upperCase(String str) {
-        if (str == null) {
-            return null;
-        }
-        return str.toUpperCase();
-    }
-
-    /**
-     * <p>Converts a String to upper case as per {@link String#toUpperCase(Locale)}.</p>
-     *
-     * <p>A {@code null} input String returns {@code null}.</p>
-     *
-     * <pre>
-     * StringUtils.upperCase(null, Locale.ENGLISH)  = null
-     * StringUtils.upperCase("", Locale.ENGLISH)    = ""
-     * StringUtils.upperCase("aBc", Locale.ENGLISH) = "ABC"
-     * </pre>
-     *
-     * @param str  the String to upper case, may be null
-     * @param locale  the locale that defines the case transformation rules, must not be null
-     * @return the upper cased String, {@code null} if null String input
-     * @since 2.5
-     */
-    public static String upperCase(String str, Locale locale) {
-        if (str == null) {
-            return null;
-        }
-        return str.toUpperCase(locale);
-    }
-
-    /**
-     * <p>Converts a String to lower case as per {@link String#toLowerCase()}.</p>
-     *
-     * <p>A {@code null} input String returns {@code null}.</p>
-     *
-     * <pre>
-     * StringUtils.lowerCase(null)  = null
-     * StringUtils.lowerCase("")    = ""
-     * StringUtils.lowerCase("aBc") = "abc"
-     * </pre>
-     *
-     * <p><strong>Note:</strong> As described in the documentation for {@link String#toLowerCase()},
-     * the result of this method is affected by the current locale.
-     * For platform-independent case transformations, the method {@link #lowerCase(String, Locale)}
-     * should be used with a specific locale (e.g. {@link Locale#ENGLISH}).</p>
-     *
-     * @param str  the String to lower case, may be null
-     * @return the lower cased String, {@code null} if null String input
-     */
-    public static String lowerCase(String str) {
-        if (str == null) {
-            return null;
-        }
-        return str.toLowerCase();
-    }
-
-    /**
-     * <p>Converts a String to lower case as per {@link String#toLowerCase(Locale)}.</p>
-     *
-     * <p>A {@code null} input String returns {@code null}.</p>
-     *
-     * <pre>
-     * StringUtils.lowerCase(null, Locale.ENGLISH)  = null
-     * StringUtils.lowerCase("", Locale.ENGLISH)    = ""
-     * StringUtils.lowerCase("aBc", Locale.ENGLISH) = "abc"
-     * </pre>
-     *
-     * @param str  the String to lower case, may be null
-     * @param locale  the locale that defines the case transformation rules, must not be null
-     * @return the lower cased String, {@code null} if null String input
-     * @since 2.5
-     */
-    public static String lowerCase(String str, Locale locale) {
-        if (str == null) {
-            return null;
-        }
-        return str.toLowerCase(locale);
-    }
-
-    /**
-     * <p>Capitalizes a String changing the first letter to title case as
-     * per {@link Character#toTitleCase(char)}. No other letters are changed.</p>
-     *
-     * <p>For a word based algorithm, see {@link org.apache.commons.lang3.text.WordUtils#capitalize(String)}.
-     * A {@code null} input String returns {@code null}.</p>
-     *
-     * <pre>
-     * StringUtils.capitalize(null)  = null
-     * StringUtils.capitalize("")    = ""
-     * StringUtils.capitalize("cat") = "Cat"
-     * StringUtils.capitalize("cAt") = "CAt"
-     * </pre>
-     *
-     * @param str the String to capitalize, may be null
-     * @return the capitalized String, {@code null} if null String input
-     * @see org.apache.commons.lang3.text.WordUtils#capitalize(String)
-     * @see #uncapitalize(String)
-     * @since 2.0
-     */
-    public static String capitalize(String str) {
-        int strLen;
-        if (str == null || (strLen = str.length()) == 0) {
-            return str;
-        }
-        return new StringBuilder(strLen)
-            .append(Character.toTitleCase(str.charAt(0)))
-            .append(str.substring(1))
-            .toString();
-    }
-
-    /**
-     * <p>Uncapitalizes a String changing the first letter to title case as
-     * per {@link Character#toLowerCase(char)}. No other letters are changed.</p>
-     *
-     * <p>For a word based algorithm, see {@link org.apache.commons.lang3.text.WordUtils#uncapitalize(String)}.
-     * A {@code null} input String returns {@code null}.</p>
-     *
-     * <pre>
-     * StringUtils.uncapitalize(null)  = null
-     * StringUtils.uncapitalize("")    = ""
-     * StringUtils.uncapitalize("Cat") = "cat"
-     * StringUtils.uncapitalize("CAT") = "cAT"
-     * </pre>
-     *
-     * @param str the String to uncapitalize, may be null
-     * @return the uncapitalized String, {@code null} if null String input
-     * @see org.apache.commons.lang3.text.WordUtils#uncapitalize(String)
-     * @see #capitalize(String)
-     * @since 2.0
-     */
-    public static String uncapitalize(String str) {
-        int strLen;
-        if (str == null || (strLen = str.length()) == 0) {
-            return str;
-        }
-        return new StringBuilder(strLen)
-            .append(Character.toLowerCase(str.charAt(0)))
-            .append(str.substring(1))
-            .toString();
-    }
-
-    /**
-     * <p>Swaps the case of a String changing upper and title case to
-     * lower case, and lower case to upper case.</p>
-     *
-     * <ul>
-     *  <li>Upper case character converts to Lower case</li>
-     *  <li>Title case character converts to Lower case</li>
-     *  <li>Lower case character converts to Upper case</li>
-     * </ul>
-     *
-     * <p>For a word based algorithm, see {@link org.apache.commons.lang3.text.WordUtils#swapCase(String)}.
-     * A {@code null} input String returns {@code null}.</p>
-     *
-     * <pre>
-     * StringUtils.swapCase(null)                 = null
-     * StringUtils.swapCase("")                   = ""
-     * StringUtils.swapCase("The dog has a BONE") = "tHE DOG HAS A bone"
-     * </pre>
-     *
-     * <p>NOTE: This method changed in Lang version 2.0.
-     * It no longer performs a word based algorithm.
-     * If you only use ASCII, you will notice no change.
-     * That functionality is available in org.apache.commons.lang3.text.WordUtils.</p>
-     *
-     * @param str  the String to swap case, may be null
-     * @return the changed String, {@code null} if null String input
-     */
-    public static String swapCase(String str) {
-        if (StringUtils.isEmpty(str)) {
-            return str;
-        }
-
-        char[] buffer = str.toCharArray();
-
-        for (int i = 0; i < buffer.length; i++) {
-            char ch = buffer[i];
-            if (Character.isUpperCase(ch)) {
-                buffer[i] = Character.toLowerCase(ch);
-            } else if (Character.isTitleCase(ch)) {
-                buffer[i] = Character.toLowerCase(ch);
-            } else if (Character.isLowerCase(ch)) {
-                buffer[i] = Character.toUpperCase(ch);
-            }
-        }
-        return new String(buffer);
-    }
-
-    // Count matches
-    //-----------------------------------------------------------------------
-    /**
-     * <p>Counts how many times the substring appears in the larger string.</p>
-     *
-     * <p>A {@code null} or empty ("") String input returns {@code 0}.</p>
-     *
-     * <pre>
-     * StringUtils.countMatches(null, *)       = 0
-     * StringUtils.countMatches("", *)         = 0
-     * StringUtils.countMatches("abba", null)  = 0
-     * StringUtils.countMatches("abba", "")    = 0
-     * StringUtils.countMatches("abba", "a")   = 2
-     * StringUtils.countMatches("abba", "ab")  = 1
-     * StringUtils.countMatches("abba", "xxx") = 0
-     * </pre>
-     *
-     * @param str  the CharSequence to check, may be null
-     * @param sub  the substring to count, may be null
-     * @return the number of occurrences, 0 if either CharSequence is {@code null}
-     * @since 3.0 Changed signature from countMatches(String, String) to countMatches(CharSequence, CharSequence)
-     */
-    public static int countMatches(CharSequence str, CharSequence sub) {
-        if (isEmpty(str) || isEmpty(sub)) {
-            return 0;
-        }
-        int count = 0;
-        int idx = 0;
-        while ((idx = CharSequenceUtils.indexOf(str, sub, idx)) != INDEX_NOT_FOUND) {
-            count++;
-            idx += sub.length();
-        }
-        return count;
-    }
-
-    // Character Tests
-    //-----------------------------------------------------------------------
-    /**
-     * <p>Checks if the CharSequence contains only Unicode letters.</p>
-     *
-     * <p>{@code null} will return {@code false}.
-     * An empty CharSequence (length()=0) will return {@code false}.</p>
-     *
-     * <pre>
-     * StringUtils.isAlpha(null)   = false
-     * StringUtils.isAlpha("")     = false
-     * StringUtils.isAlpha("  ")   = false
-     * StringUtils.isAlpha("abc")  = true
-     * StringUtils.isAlpha("ab2c") = false
-     * StringUtils.isAlpha("ab-c") = false
-     * </pre>
-     *
-     * @param cs  the CharSequence to check, may be null
-     * @return {@code true} if only contains letters, and is non-null
-     * @since 3.0 Changed signature from isAlpha(String) to isAlpha(CharSequence)
-     * @since 3.0 Changed "" to return false and not true
-     */
-    public static boolean isAlpha(CharSequence cs) {
-        if (cs == null || cs.length() == 0) {
-            return false;
-        }
-        int sz = cs.length();
-        for (int i = 0; i < sz; i++) {
-            if (Character.isLetter(cs.charAt(i)) == false) {
-                return false;
-            }
-        }
-        return true;
-    }
-
-    /**
-     * <p>Checks if the CharSequence contains only Unicode letters and
-     * space (' ').</p>
-     *
-     * <p>{@code null} will return {@code false}
-     * An empty CharSequence (length()=0) will return {@code true}.</p>
-     *
-     * <pre>
-     * StringUtils.isAlphaSpace(null)   = false
-     * StringUtils.isAlphaSpace("")     = true
-     * StringUtils.isAlphaSpace("  ")   = true
-     * StringUtils.isAlphaSpace("abc")  = true
-     * StringUtils.isAlphaSpace("ab c") = true
-     * StringUtils.isAlphaSpace("ab2c") = false
-     * StringUtils.isAlphaSpace("ab-c") = false
-     * </pre>
-     *
-     * @param cs  the CharSequence to check, may be null
-     * @return {@code true} if only contains letters and space,
-     *  and is non-null
-     * @since 3.0 Changed signature from isAlphaSpace(String) to isAlphaSpace(CharSequence)
-     */
-    public static boolean isAlphaSpace(CharSequence cs) {
-        if (cs == null) {
-            return false;
-        }
-        int sz = cs.length();
-        for (int i = 0; i < sz; i++) {
-            if (Character.isLetter(cs.charAt(i)) == false && cs.charAt(i) != ' ') {
-                return false;
-            }
-        }
-        return true;
-    }
-
-    /**
-     * <p>Checks if the CharSequence contains only Unicode letters or digits.</p>
-     *
-     * <p>{@code null} will return {@code false}.
-     * An empty CharSequence (length()=0) will return {@code false}.</p>
-     *
-     * <pre>
-     * StringUtils.isAlphanumeric(null)   = false
-     * StringUtils.isAlphanumeric("")     = false
-     * StringUtils.isAlphanumeric("  ")   = false
-     * StringUtils.isAlphanumeric("abc")  = true
-     * StringUtils.isAlphanumeric("ab c") = false
-     * StringUtils.isAlphanumeric("ab2c") = true
-     * StringUtils.isAlphanumeric("ab-c") = false
-     * </pre>
-     *
-     * @param cs  the CharSequence to check, may be null
-     * @return {@code true} if only contains letters or digits,
-     *  and is non-null
-     * @since 3.0 Changed signature from isAlphanumeric(String) to isAlphanumeric(CharSequence)
-     * @since 3.0 Changed "" to return false and not true
-     */
-    public static boolean isAlphanumeric(CharSequence cs) {
-        if (cs == null || cs.length() == 0) {
-            return false;
-        }
-        int sz = cs.length();
-        for (int i = 0; i < sz; i++) {
-            if (Character.isLetterOrDigit(cs.charAt(i)) == false) {
-                return false;
-            }
-        }
-        return true;
-    }
-
-    /**
-     * <p>Checks if the CharSequence contains only Unicode letters, digits
-     * or space ({@code ' '}).</p>
-     *
-     * <p>{@code null} will return {@code false}.
-     * An empty CharSequence (length()=0) will return {@code true}.</p>
-     *
-     * <pre>
-     * StringUtils.isAlphanumericSpace(null)   = false
-     * StringUtils.isAlphanumericSpace("")     = true
-     * StringUtils.isAlphanumericSpace("  ")   = true
-     * StringUtils.isAlphanumericSpace("abc")  = true
-     * StringUtils.isAlphanumericSpace("ab c") = true
-     * StringUtils.isAlphanumericSpace("ab2c") = true
-     * StringUtils.isAlphanumericSpace("ab-c") = false
-     * </pre>
-     *
-     * @param cs  the CharSequence to check, may be null
-     * @return {@code true} if only contains letters, digits or space,
-     *  and is non-null
-     * @since 3.0 Changed signature from isAlphanumericSpace(String) to isAlphanumericSpace(CharSequence)
-     */
-    public static boolean isAlphanumericSpace(CharSequence cs) {
-        if (cs == null) {
-            return false;
-        }
-        int sz = cs.length();
-        for (int i = 0; i < sz; i++) {
-            if (Character.isLetterOrDigit(cs.charAt(i)) == false && cs.charAt(i) != ' ') {
-                return false;
-            }
-        }
-        return true;
-    }
-
-    /**
-     * <p>Checks if the CharSequence contains only ASCII printable characters.</p>
-     *
-     * <p>{@code null} will return {@code false}.
-     * An empty CharSequence (length()=0) will return {@code true}.</p>
-     *
-     * <pre>
-     * StringUtils.isAsciiPrintable(null)     = false
-     * StringUtils.isAsciiPrintable("")       = true
-     * StringUtils.isAsciiPrintable(" ")      = true
-     * StringUtils.isAsciiPrintable("Ceki")   = true
-     * StringUtils.isAsciiPrintable("ab2c")   = true
-     * StringUtils.isAsciiPrintable("!ab-c~") = true
-     * StringUtils.isAsciiPrintable("\u0020") = true
-     * StringUtils.isAsciiPrintable("\u0021") = true
-     * StringUtils.isAsciiPrintable("\u007e") = true
-     * StringUtils.isAsciiPrintable("\u007f") = false
-     * StringUtils.isAsciiPrintable("Ceki G\u00fclc\u00fc") = false
-     * </pre>
-     *
-     * @param cs the CharSequence to check, may be null
-     * @return {@code true} if every character is in the range
-     *  32 thru 126
-     * @since 2.1
-     * @since 3.0 Changed signature from isAsciiPrintable(String) to isAsciiPrintable(CharSequence)
-     */
-    public static boolean isAsciiPrintable(CharSequence cs) {
-        if (cs == null) {
-            return false;
-        }
-        int sz = cs.length();
-        for (int i = 0; i < sz; i++) {
-            if (CharUtils.isAsciiPrintable(cs.charAt(i)) == false) {
-                return false;
-            }
-        }
-        return true;
-    }
-
-    /**
-     * <p>Checks if the CharSequence contains only Unicode digits.
-     * A decimal point is not a Unicode digit and returns false.</p>
-     *
-     * <p>{@code null} will return {@code false}.
-     * An empty CharSequence (length()=0) will return {@code false}.</p>
-     *
-     * <pre>
-     * StringUtils.isNumeric(null)   = false
-     * StringUtils.isNumeric("")     = false
-     * StringUtils.isNumeric("  ")   = false
-     * StringUtils.isNumeric("123")  = true
-     * StringUtils.isNumeric("12 3") = false
-     * StringUtils.isNumeric("ab2c") = false
-     * StringUtils.isNumeric("12-3") = false
-     * StringUtils.isNumeric("12.3") = false
-     * </pre>
-     *
-     * @param cs  the CharSequence to check, may be null
-     * @return {@code true} if only contains digits, and is non-null
-     * @since 3.0 Changed signature from isNumeric(String) to isNumeric(CharSequence)
-     * @since 3.0 Changed "" to return false and not true
-     */
-    public static boolean isNumeric(CharSequence cs) {
-        if (cs == null || cs.length() == 0) {
-            return false;
-        }
-        int sz = cs.length();
-        for (int i = 0; i < sz; i++) {
-            if (Character.isDigit(cs.charAt(i)) == false) {
-                return false;
-            }
-        }
-        return true;
-    }
-
-    /**
-     * <p>Checks if the CharSequence contains only Unicode digits or space
-     * ({@code ' '}).
-     * A decimal point is not a Unicode digit and returns false.</p>
-     *
-     * <p>{@code null} will return {@code false}.
-     * An empty CharSequence (length()=0) will return {@code true}.</p>
-     *
-     * <pre>
-     * StringUtils.isNumericSpace(null)   = false
-     * StringUtils.isNumericSpace("")     = true
-     * StringUtils.isNumericSpace("  ")   = true
-     * StringUtils.isNumericSpace("123")  = true
-     * StringUtils.isNumericSpace("12 3") = true
-     * StringUtils.isNumericSpace("ab2c") = false
-     * StringUtils.isNumericSpace("12-3") = false
-     * StringUtils.isNumericSpace("12.3") = false
-     * </pre>
-     *
-     * @param cs  the CharSequence to check, may be null
-     * @return {@code true} if only contains digits or space,
-     *  and is non-null
-     * @since 3.0 Changed signature from isNumericSpace(String) to isNumericSpace(CharSequence)
-     */
-    public static boolean isNumericSpace(CharSequence cs) {
-        if (cs == null) {
-            return false;
-        }
-        int sz = cs.length();
-        for (int i = 0; i < sz; i++) {
-            if (Character.isDigit(cs.charAt(i)) == false && cs.charAt(i) != ' ') {
-                return false;
-            }
-        }
-        return true;
-    }
-
-    /**
-     * <p>Checks if the CharSequence contains only whitespace.</p>
-     *
-     * <p>{@code null} will return {@code false}.
-     * An empty CharSequence (length()=0) will return {@code true}.</p>
-     *
-     * <pre>
-     * StringUtils.isWhitespace(null)   = false
-     * StringUtils.isWhitespace("")     = true
-     * StringUtils.isWhitespace("  ")   = true
-     * StringUtils.isWhitespace("abc")  = false
-     * StringUtils.isWhitespace("ab2c") = false
-     * StringUtils.isWhitespace("ab-c") = false
-     * </pre>
-     *
-     * @param cs  the CharSequence to check, may be null
-     * @return {@code true} if only contains whitespace, and is non-null
-     * @since 2.0
-     * @since 3.0 Changed signature from isWhitespace(String) to isWhitespace(CharSequence)
-     */
-    public static boolean isWhitespace(CharSequence cs) {
-        if (cs == null) {
-            return false;
-        }
-        int sz = cs.length();
-        for (int i = 0; i < sz; i++) {
-            if (Character.isWhitespace(cs.charAt(i)) == false) {
-                return false;
-            }
-        }
-        return true;
-    }
-
-    /**
-     * <p>Checks if the CharSequence contains only lowercase characters.</p>
-     *
-     * <p>{@code null} will return {@code false}.
-     * An empty CharSequence (length()=0) will return {@code false}.</p>
-     *
-     * <pre>
-     * StringUtils.isAllLowerCase(null)   = false
-     * StringUtils.isAllLowerCase("")     = false
-     * StringUtils.isAllLowerCase("  ")   = false
-     * StringUtils.isAllLowerCase("abc")  = true
-     * StringUtils.isAllLowerCase("abC") = false
-     * </pre>
-     *
-     * @param cs  the CharSequence to check, may be null
-     * @return {@code true} if only contains lowercase characters, and is non-null
-     * @since 2.5
-     * @since 3.0 Changed signature from isAllLowerCase(String) to isAllLowerCase(CharSequence)
-     */
-    public static boolean isAllLowerCase(CharSequence cs) {
-        if (cs == null || isEmpty(cs)) {
-            return false;
-        }
-        int sz = cs.length();
-        for (int i = 0; i < sz; i++) {
-            if (Character.isLowerCase(cs.charAt(i)) == false) {
-                return false;
-            }
-        }
-        return true;
-    }
-
-    /**
-     * <p>Checks if the CharSequence contains only uppercase characters.</p>
-     *
-     * <p>{@code null} will return {@code false}.
-     * An empty String (length()=0) will return {@code false}.</p>
-     *
-     * <pre>
-     * StringUtils.isAllUpperCase(null)   = false
-     * StringUtils.isAllUpperCase("")     = false
-     * StringUtils.isAllUpperCase("  ")   = false
-     * StringUtils.isAllUpperCase("ABC")  = true
-     * StringUtils.isAllUpperCase("aBC") = false
-     * </pre>
-     *
-     * @param cs the CharSequence to check, may be null
-     * @return {@code true} if only contains uppercase characters, and is non-null
-     * @since 2.5
-     * @since 3.0 Changed signature from isAllUpperCase(String) to isAllUpperCase(CharSequence)
-     */
-    public static boolean isAllUpperCase(CharSequence cs) {
-        if (cs == null || isEmpty(cs)) {
-            return false;
-        }
-        int sz = cs.length();
-        for (int i = 0; i < sz; i++) {
-            if (Character.isUpperCase(cs.charAt(i)) == false) {
-                return false;
-            }
-        }
-        return true;
-    }
-
-    // Defaults
-    //-----------------------------------------------------------------------
-    /**
-     * <p>Returns either the passed in String,
-     * or if the String is {@code null}, an empty String ("").</p>
-     *
-     * <pre>
-     * StringUtils.defaultString(null)  = ""
-     * StringUtils.defaultString("")    = ""
-     * StringUtils.defaultString("bat") = "bat"
-     * </pre>
-     *
-     * @see ObjectUtils#toString(Object)
-     * @see String#valueOf(Object)
-     * @param str  the String to check, may be null
-     * @return the passed in String, or the empty String if it
-     *  was {@code null}
-     */
-    public static String defaultString(String str) {
-        return str == null ? EMPTY : str;
-    }
-
-    /**
-     * <p>Returns either the passed in String, or if the String is
-     * {@code null}, the value of {@code defaultStr}.</p>
-     *
-     * <pre>
-     * StringUtils.defaultString(null, "NULL")  = "NULL"
-     * StringUtils.defaultString("", "NULL")    = ""
-     * StringUtils.defaultString("bat", "NULL") = "bat"
-     * </pre>
-     *
-     * @see ObjectUtils#toString(Object,String)
-     * @see String#valueOf(Object)
-     * @param str  the String to check, may be null
-     * @param defaultStr  the default String to return
-     *  if the input is {@code null}, may be null
-     * @return the passed in String, or the default if it was {@code null}
-     */
-    public static String defaultString(String str, String defaultStr) {
-        return str == null ? defaultStr : str;
-    }
-
-    /**
-     * <p>Returns either the passed in CharSequence, or if the CharSequence is
-     * whitespace, empty ("") or {@code null}, the value of {@code defaultStr}.</p>
-     *
-     * <pre>
-     * StringUtils.defaultIfBlank(null, "NULL")  = "NULL"
-     * StringUtils.defaultIfBlank("", "NULL")    = "NULL"
-     * StringUtils.defaultIfBlank(" ", "NULL")   = "NULL"
-     * StringUtils.defaultIfBlank("bat", "NULL") = "bat"
-     * StringUtils.defaultIfBlank("", null)      = null
-     * </pre>
-     * @param <T> the specific kind of CharSequence
-     * @param str the CharSequence to check, may be null
-     * @param defaultStr  the default CharSequence to return
-     *  if the input is whitespace, empty ("") or {@code null}, may be null
-     * @return the passed in CharSequence, or the default
-     * @see StringUtils#defaultString(String, String)
-     */
-    public static <T extends CharSequence> T defaultIfBlank(T str, T defaultStr) {
-        return StringUtils.isBlank(str) ? defaultStr : str;
-    }
-
-    /**
-     * <p>Returns either the passed in CharSequence, or if the CharSequence is
-     * empty or {@code null}, the value of {@code defaultStr}.</p>
-     *
-     * <pre>
-     * StringUtils.defaultIfEmpty(null, "NULL")  = "NULL"
-     * StringUtils.defaultIfEmpty("", "NULL")    = "NULL"
-     * StringUtils.defaultIfEmpty(" ", "NULL")   = " "
-     * StringUtils.defaultIfEmpty("bat", "NULL") = "bat"
-     * StringUtils.defaultIfEmpty("", null)      = null
-     * </pre>
-     * @param <T> the specific kind of CharSequence
-     * @param str  the CharSequence to check, may be null
-     * @param defaultStr  the default CharSequence to return
-     *  if the input is empty ("") or {@code null}, may be null
-     * @return the passed in CharSequence, or the default
-     * @see StringUtils#defaultString(String, String)
-     */
-    public static <T extends CharSequence> T defaultIfEmpty(T str, T defaultStr) {
-        return StringUtils.isEmpty(str) ? defaultStr : str;
-    }
-
-    // Reversing
-    //-----------------------------------------------------------------------
-    /**
-     * <p>Reverses a String as per {@link StringBuilder#reverse()}.</p>
-     *
-     * <p>A {@code null} String returns {@code null}.</p>
-     *
-     * <pre>
-     * StringUtils.reverse(null)  = null
-     * StringUtils.reverse("")    = ""
-     * StringUtils.reverse("bat") = "tab"
-     * </pre>
-     *
-     * @param str  the String to reverse, may be null
-     * @return the reversed String, {@code null} if null String input
-     */
-    public static String reverse(String str) {
-        if (str == null) {
-            return null;
-        }
-        return new StringBuilder(str).reverse().toString();
-    }
-
-    /**
-     * <p>Reverses a String that is delimited by a specific character.</p>
-     *
-     * <p>The Strings between the delimiters are not reversed.
-     * Thus java.lang.String becomes String.lang.java (if the delimiter
-     * is {@code '.'}).</p>
-     *
-     * <pre>
-     * StringUtils.reverseDelimited(null, *)      = null
-     * StringUtils.reverseDelimited("", *)        = ""
-     * StringUtils.reverseDelimited("a.b.c", 'x') = "a.b.c"
-     * StringUtils.reverseDelimited("a.b.c", ".") = "c.b.a"
-     * </pre>
-     *
-     * @param str  the String to reverse, may be null
-     * @param separatorChar  the separator character to use
-     * @return the reversed String, {@code null} if null String input
-     * @since 2.0
-     */
-    public static String reverseDelimited(String str, char separatorChar) {
-        if (str == null) {
-            return null;
-        }
-        // could implement manually, but simple way is to reuse other,
-        // probably slower, methods.
-        String[] strs = split(str, separatorChar);
-        ArrayUtils.reverse(strs);
-        return join(strs, separatorChar);
-    }
-
-    // Abbreviating
-    //-----------------------------------------------------------------------
-    /**
-     * <p>Abbreviates a String using ellipses. This will turn
-     * "Now is the time for all good men" into "Now is the time for..."</p>
-     *
-     * <p>Specifically:
-     * <ul>
-     *   <li>If {@code str} is less than {@code maxWidth} characters
-     *       long, return it.</li>
-     *   <li>Else abbreviate it to {@code (substring(str, 0, max-3) + "...")}.</li>
-     *   <li>If {@code maxWidth} is less than {@code 4}, throw an
-     *       {@code IllegalArgumentException}.</li>
-     *   <li>In no case will it return a String of length greater than
-     *       {@code maxWidth}.</li>
-     * </ul>
-     * </p>
-     *
-     * <pre>
-     * StringUtils.abbreviate(null, *)      = null
-     * StringUtils.abbreviate("", 4)        = ""
-     * StringUtils.abbreviate("abcdefg", 6) = "abc..."
-     * StringUtils.abbreviate("abcdefg", 7) = "abcdefg"
-     * StringUtils.abbreviate("abcdefg", 8) = "abcdefg"
-     * StringUtils.abbreviate("abcdefg", 4) = "a..."
-     * StringUtils.abbreviate("abcdefg", 3) = IllegalArgumentException
-     * </pre>
-     *
-     * @param str  the String to check, may be null
-     * @param maxWidth  maximum length of result String, must be at least 4
-     * @return abbreviated String, {@code null} if null String input
-     * @throws IllegalArgumentException if the width is too small
-     * @since 2.0
-     */
-    public static String abbreviate(String str, int maxWidth) {
-        return abbreviate(str, 0, maxWidth);
-    }
-
-    /**
-     * <p>Abbreviates a String using ellipses. This will turn
-     * "Now is the time for all good men" into "...is the time for..."</p>
-     *
-     * <p>Works like {@code abbreviate(String, int)}, but allows you to specify
-     * a "left edge" offset.  Note that this left edge is not necessarily going to
-     * be the leftmost character in the result, or the first character following the
-     * ellipses, but it will appear somewhere in the result.
-     *
-     * <p>In no case will it return a String of length greater than
-     * {@code maxWidth}.</p>
-     *
-     * <pre>
-     * StringUtils.abbreviate(null, *, *)                = null
-     * StringUtils.abbreviate("", 0, 4)                  = ""
-     * StringUtils.abbreviate("abcdefghijklmno", -1, 10) = "abcdefg..."
-     * StringUtils.abbreviate("abcdefghijklmno", 0, 10)  = "abcdefg..."
-     * StringUtils.abbreviate("abcdefghijklmno", 1, 10)  = "abcdefg..."
-     * StringUtils.abbreviate("abcdefghijklmno", 4, 10)  = "abcdefg..."
-     * StringUtils.abbreviate("abcdefghijklmno", 5, 10)  = "...fghi..."
-     * StringUtils.abbreviate("abcdefghijklmno", 6, 10)  = "...ghij..."
-     * StringUtils.abbreviate("abcdefghijklmno", 8, 10)  = "...ijklmno"
-     * StringUtils.abbreviate("abcdefghijklmno", 10, 10) = "...ijklmno"
-     * StringUtils.abbreviate("abcdefghijklmno", 12, 10) = "...ijklmno"
-     * StringUtils.abbreviate("abcdefghij", 0, 3)        = IllegalArgumentException
-     * StringUtils.abbreviate("abcdefghij", 5, 6)        = IllegalArgumentException
-     * </pre>
-     *
-     * @param str  the String to check, may be null
-     * @param offset  left edge of source String
-     * @param maxWidth  maximum length of result String, must be at least 4
-     * @return abbreviated String, {@code null} if null String input
-     * @throws IllegalArgumentException if the width is too small
-     * @since 2.0
-     */
-    public static String abbreviate(String str, int offset, int maxWidth) {
-        if (str == null) {
-            return null;
-        }
-        if (maxWidth < 4) {
-            throw new IllegalArgumentException("Minimum abbreviation width is 4");
-        }
-        if (str.length() <= maxWidth) {
-            return str;
-        }
-        if (offset > str.length()) {
-            offset = str.length();
-        }
-        if (str.length() - offset < maxWidth - 3) {
-            offset = str.length() - (maxWidth - 3);
-        }
-        final String abrevMarker = "...";
-        if (offset <= 4) {
-            return str.substring(0, maxWidth - 3) + abrevMarker;
-        }
-        if (maxWidth < 7) {
-            throw new IllegalArgumentException("Minimum abbreviation width with offset is 7");
-        }
-        if (offset + maxWidth - 3 < str.length()) {
-            return abrevMarker + abbreviate(str.substring(offset), maxWidth - 3);
-        }
-        return abrevMarker + str.substring(str.length() - (maxWidth - 3));
-    }
-
-    /**
-     * <p>Abbreviates a String to the length passed, replacing the middle characters with the supplied
-     * replacement String.</p>
-     *
-     * <p>This abbreviation only occurs if the following criteria is met:
-     * <ul>
-     * <li>Neither the String for abbreviation nor the replacement String are null or empty </li>
-     * <li>The length to truncate to is less than the length of the supplied String</li>
-     * <li>The length to truncate to is greater than 0</li>
-     * <li>The abbreviated String will have enough room for the length supplied replacement String
-     * and the first and last characters of the supplied String for abbreviation</li>
-     * </ul>
-     * Otherwise, the returned String will be the same as the supplied String for abbreviation.
-     * </p>
-     *
-     * <pre>
-     * StringUtils.abbreviateMiddle(null, null, 0)      = null
-     * StringUtils.abbreviateMiddle("abc", null, 0)      = "abc"
-     * StringUtils.abbreviateMiddle("abc", ".", 0)      = "abc"
-     * StringUtils.abbreviateMiddle("abc", ".", 3)      = "abc"
-     * StringUtils.abbreviateMiddle("abcdef", ".", 4)     = "ab.f"
-     * </pre>
-     *
-     * @param str  the String to abbreviate, may be null
-     * @param middle the String to replace the middle characters with, may be null
-     * @param length the length to abbreviate {@code str} to.
-     * @return the abbreviated String if the above criteria is met, or the original String supplied for abbreviation.
-     * @since 2.5
-     */
-    public static String abbreviateMiddle(String str, String middle, int length) {
-        if (isEmpty(str) || isEmpty(middle)) {
-            return str;
-        }
-
-        if (length >= str.length() || length < middle.length()+2) {
-            return str;
-        }
-
-        int targetSting = length-middle.length();
-        int startOffset = targetSting/2+targetSting%2;
-        int endOffset = str.length()-targetSting/2;
-
-        StringBuilder builder = new StringBuilder(length);
-        builder.append(str.substring(0,startOffset));
-        builder.append(middle);
-        builder.append(str.substring(endOffset));
-
-        return builder.toString();
-    }
-
-    // Difference
-    //-----------------------------------------------------------------------
-    /**
-     * <p>Compares two Strings, and returns the portion where they differ.
-     * (More precisely, return the remainder of the second String,
-     * starting from where it's different from the first.)</p>
-     *
-     * <p>For example,
-     * {@code difference("i am a machine", "i am a robot") -> "robot"}.</p>
-     *
-     * <pre>
-     * StringUtils.difference(null, null) = null
-     * StringUtils.difference("", "") = ""
-     * StringUtils.difference("", "abc") = "abc"
-     * StringUtils.difference("abc", "") = ""
-     * StringUtils.difference("abc", "abc") = ""
-     * StringUtils.difference("ab", "abxyz") = "xyz"
-     * StringUtils.difference("abcde", "abxyz") = "xyz"
-     * StringUtils.difference("abcde", "xyz") = "xyz"
-     * </pre>
-     *
-     * @param str1  the first String, may be null
-     * @param str2  the second String, may be null
-     * @return the portion of str2 where it differs from str1; returns the
-     * empty String if they are equal
-     * @since 2.0
-     */
-    public static String difference(String str1, String str2) {
-        if (str1 == null) {
-            return str2;
-        }
-        if (str2 == null) {
-            return str1;
-        }
-        int at = indexOfDifference(str1, str2);
-        if (at == INDEX_NOT_FOUND) {
-            return EMPTY;
-        }
-        return str2.substring(at);
-    }
-
-    /**
-     * <p>Compares two CharSequences, and returns the index at which the
-     * CharSequences begin to differ.</p>
-     *
-     * <p>For example,
-     * {@code indexOfDifference("i am a machine", "i am a robot") -> 7}</p>
-     *
-     * <pre>
-     * StringUtils.indexOfDifference(null, null) = -1
-     * StringUtils.indexOfDifference("", "") = -1
-     * StringUtils.indexOfDifference("", "abc") = 0
-     * StringUtils.indexOfDifference("abc", "") = 0
-     * StringUtils.indexOfDifference("abc", "abc") = -1
-     * StringUtils.indexOfDifference("ab", "abxyz") = 2
-     * StringUtils.indexOfDifference("abcde", "abxyz") = 2
-     * StringUtils.indexOfDifference("abcde", "xyz") = 0
-     * </pre>
-     *
-     * @param cs1  the first CharSequence, may be null
-     * @param cs2  the second CharSequence, may be null
-     * @return the index where cs1 and cs2 begin to differ; -1 if they are equal
-     * @since 2.0
-     * @since 3.0 Changed signature from indexOfDifference(String, String) to
-     * indexOfDifference(CharSequence, CharSequence)
-     */
-    public static int indexOfDifference(CharSequence cs1, CharSequence cs2) {
-        if (cs1 == cs2) {
-            return INDEX_NOT_FOUND;
-        }
-        if (cs1 == null || cs2 == null) {
-            return 0;
-        }
-        int i;
-        for (i = 0; i < cs1.length() && i < cs2.length(); ++i) {
-            if (cs1.charAt(i) != cs2.charAt(i)) {
-                break;
-            }
-        }
-        if (i < cs2.length() || i < cs1.length()) {
-            return i;
-        }
-        return INDEX_NOT_FOUND;
-    }
-
-    /**
-     * <p>Compares all CharSequences in an array and returns the index at which the
-     * CharSequences begin to differ.</p>
-     *
-     * <p>For example,
-     * <code>indexOfDifference(new String[] {"i am a machine", "i am a robot"}) -> 7</code></p>
-     *
-     * <pre>
-     * StringUtils.indexOfDifference(null) = -1
-     * StringUtils.indexOfDifference(new String[] {}) = -1
-     * StringUtils.indexOfDifference(new String[] {"abc"}) = -1
-     * StringUtils.indexOfDifference(new String[] {null, null}) = -1
-     * StringUtils.indexOfDifference(new String[] {"", ""}) = -1
-     * StringUtils.indexOfDifference(new String[] {"", null}) = 0
-     * StringUtils.indexOfDifference(new String[] {"abc", null, null}) = 0
-     * StringUtils.indexOfDifference(new String[] {null, null, "abc"}) = 0
-     * StringUtils.indexOfDifference(new String[] {"", "abc"}) = 0
-     * StringUtils.indexOfDifference(new String[] {"abc", ""}) = 0
-     * StringUtils.indexOfDifference(new String[] {"abc", "abc"}) = -1
-     * StringUtils.indexOfDifference(new String[] {"abc", "a"}) = 1
-     * StringUtils.indexOfDifference(new String[] {"ab", "abxyz"}) = 2
-     * StringUtils.indexOfDifference(new String[] {"abcde", "abxyz"}) = 2
-     * StringUtils.indexOfDifference(new String[] {"abcde", "xyz"}) = 0
-     * StringUtils.indexOfDifference(new String[] {"xyz", "abcde"}) = 0
-     * StringUtils.indexOfDifference(new String[] {"i am a machine", "i am a robot"}) = 7
-     * </pre>
-     *
-     * @param css  array of CharSequences, entries may be null
-     * @return the index where the strings begin to differ; -1 if they are all equal
-     * @since 2.4
-     * @since 3.0 Changed signature from indexOfDifference(String...) to indexOfDifference(CharSequence...)
-     */
-    public static int indexOfDifference(CharSequence... css) {
-        if (css == null || css.length <= 1) {
-            return INDEX_NOT_FOUND;
-        }
-        boolean anyStringNull = false;
-        boolean allStringsNull = true;
-        int arrayLen = css.length;
-        int shortestStrLen = Integer.MAX_VALUE;
-        int longestStrLen = 0;
-
-        // find the min and max string lengths; this avoids checking to make
-        // sure we are not exceeding the length of the string each time through
-        // the bottom loop.
-        for (int i = 0; i < arrayLen; i++) {
-            if (css[i] == null) {
-                anyStringNull = true;
-                shortestStrLen = 0;
-            } else {
-                allStringsNull = false;
-                shortestStrLen = Math.min(css[i].length(), shortestStrLen);
-                longestStrLen = Math.max(css[i].length(), longestStrLen);
-            }
-        }
-
-        // handle lists containing all nulls or all empty strings
-        if (allStringsNull || longestStrLen == 0 && !anyStringNull) {
-            return INDEX_NOT_FOUND;
-        }
-
-        // handle lists containing some nulls or some empty strings
-        if (shortestStrLen == 0) {
-            return 0;
-        }
-
-        // find the position with the first difference across all strings
-        int firstDiff = -1;
-        for (int stringPos = 0; stringPos < shortestStrLen; stringPos++) {
-            char comparisonChar = css[0].charAt(stringPos);
-            for (int arrayPos = 1; arrayPos < arrayLen; arrayPos++) {
-                if (css[arrayPos].charAt(stringPos) != comparisonChar) {
-                    firstDiff = stringPos;
-                    break;
-                }
-            }
-            if (firstDiff != -1) {
-                break;
-            }
-        }
-
-        if (firstDiff == -1 && shortestStrLen != longestStrLen) {
-            // we compared all of the characters up to the length of the
-            // shortest string and didn't find a match, but the string lengths
-            // vary, so return the length of the shortest string.
-            return shortestStrLen;
-        }
-        return firstDiff;
-    }
-
-    /**
-     * <p>Compares all Strings in an array and returns the initial sequence of
-     * characters that is common to all of them.</p>
-     *
-     * <p>For example,
-     * <code>getCommonPrefix(new String[] {"i am a machine", "i am a robot"}) -> "i am a "</code></p>
-     *
-     * <pre>
-     * StringUtils.getCommonPrefix(null) = ""
-     * StringUtils.getCommonPrefix(new String[] {}) = ""
-     * StringUtils.getCommonPrefix(new String[] {"abc"}) = "abc"
-     * StringUtils.getCommonPrefix(new String[] {null, null}) = ""
-     * StringUtils.getCommonPrefix(new String[] {"", ""}) = ""
-     * StringUtils.getCommonPrefix(new String[] {"", null}) = ""
-     * StringUtils.getCommonPrefix(new String[] {"abc", null, null}) = ""
-     * StringUtils.getCommonPrefix(new String[] {null, null, "abc"}) = ""
-     * StringUtils.getCommonPrefix(new String[] {"", "abc"}) = ""
-     * StringUtils.getCommonPrefix(new String[] {"abc", ""}) = ""
-     * StringUtils.getCommonPrefix(new String[] {"abc", "abc"}) = "abc"
-     * StringUtils.getCommonPrefix(new String[] {"abc", "a"}) = "a"
-     * StringUtils.getCommonPrefix(new String[] {"ab", "abxyz"}) = "ab"
-     * StringUtils.getCommonPrefix(new String[] {"abcde", "abxyz"}) = "ab"
-     * StringUtils.getCommonPrefix(new String[] {"abcde", "xyz"}) = ""
-     * StringUtils.getCommonPrefix(new String[] {"xyz", "abcde"}) = ""
-     * StringUtils.getCommonPrefix(new String[] {"i am a machine", "i am a robot"}) = "i am a "
-     * </pre>
-     *
-     * @param strs  array of String objects, entries may be null
-     * @return the initial sequence of characters that are common to all Strings
-     * in the array; empty String if the array is null, the elements are all null
-     * or if there is no common prefix.
-     * @since 2.4
-     */
-    public static String getCommonPrefix(String... strs) {
-        if (strs == null || strs.length == 0) {
-            return EMPTY;
-        }
-        int smallestIndexOfDiff = indexOfDifference(strs);
-        if (smallestIndexOfDiff == INDEX_NOT_FOUND) {
-            // all strings were identical
-            if (strs[0] == null) {
-                return EMPTY;
-            }
-            return strs[0];
-        } else if (smallestIndexOfDiff == 0) {
-            // there were no common initial characters
-            return EMPTY;
-        } else {
-            // we found a common initial character sequence
-            return strs[0].substring(0, smallestIndexOfDiff);
-        }
-    }
-
-    // Misc
-    //-----------------------------------------------------------------------
-    /**
-     * <p>Find the Levenshtein distance between two Strings.</p>
-     *
-     * <p>This is the number of changes needed to change one String into
-     * another, where each change is a single character modification (deletion,
-     * insertion or substitution).</p>
-     *
-     * <p>The previous implementation of the Levenshtein distance algorithm
-     * was from <a href="http://www.merriampark.com/ld.htm">http://www.merriampark.com/ld.htm</a></p>
-     *
-     * <p>Chas Emerick has written an implementation in Java, which avoids an OutOfMemoryError
-     * which can occur when my Java implementation is used with very large strings.<br>
-     * This implementation of the Levenshtein distance algorithm
-     * is from <a href="http://www.merriampark.com/ldjava.htm">http://www.merriampark.com/ldjava.htm</a></p>
-     *
-     * <pre>
-     * StringUtils.getLevenshteinDistance(null, *)             = IllegalArgumentException
-     * StringUtils.getLevenshteinDistance(*, null)             = IllegalArgumentException
-     * StringUtils.getLevenshteinDistance("","")               = 0
-     * StringUtils.getLevenshteinDistance("","a")              = 1
-     * StringUtils.getLevenshteinDistance("aaapppp", "")       = 7
-     * StringUtils.getLevenshteinDistance("frig", "fig")       = 1
-     * StringUtils.getLevenshteinDistance("fly", "ant")        = 3
-     * StringUtils.getLevenshteinDistance("elephant", "hippo") = 7
-     * StringUtils.getLevenshteinDistance("hippo", "elephant") = 7
-     * StringUtils.getLevenshteinDistance("hippo", "zzzzzzzz") = 8
-     * StringUtils.getLevenshteinDistance("hello", "hallo")    = 1
-     * </pre>
-     *
-     * @param s  the first String, must not be null
-     * @param t  the second String, must not be null
-     * @return result distance
-     * @throws IllegalArgumentException if either String input {@code null}
-     * @since 3.0 Changed signature from getLevenshteinDistance(String, String) to
-     * getLevenshteinDistance(CharSequence, CharSequence)
-     */
-    public static int getLevenshteinDistance(CharSequence s, CharSequence t) {
-        if (s == null || t == null) {
-            throw new IllegalArgumentException("Strings must not be null");
-        }
-
-        /*
-           The difference between this impl. and the previous is that, rather
-           than creating and retaining a matrix of size s.length() + 1 by t.length() + 1,
-           we maintain two single-dimensional arrays of length s.length() + 1.  The first, d,
-           is the 'current working' distance array that maintains the newest distance cost
-           counts as we iterate through the characters of String s.  Each time we increment
-           the index of String t we are comparing, d is copied to p, the second int[].  Doing so
-           allows us to retain the previous cost counts as required by the algorithm (taking
-           the minimum of the cost count to the left, up one, and diagonally up and to the left
-           of the current cost count being calculated).  (Note that the arrays aren't really
-           copied anymore, just switched...this is clearly much better than cloning an array
-           or doing a System.arraycopy() each time  through the outer loop.)
-
-           Effectively, the difference between the two implementations is this one does not
-           cause an out of memory condition when calculating the LD over two very large strings.
-         */
-
-        int n = s.length(); // length of s
-        int m = t.length(); // length of t
-
-        if (n == 0) {
-            return m;
-        } else if (m == 0) {
-            return n;
-        }
-
-        if (n > m) {
-            // swap the input strings to consume less memory
-            CharSequence tmp = s;
-            s = t;
-            t = tmp;
-            n = m;
-            m = t.length();
-        }
-
-        int p[] = new int[n + 1]; //'previous' cost array, horizontally
-        int d[] = new int[n + 1]; // cost array, horizontally
-        int _d[]; //placeholder to assist in swapping p and d
-
-        // indexes into strings s and t
-        int i; // iterates through s
-        int j; // iterates through t
-
-        char t_j; // jth character of t
-
-        int cost; // cost
-
-        for (i = 0; i <= n; i++) {
-            p[i] = i;
-        }
-
-        for (j = 1; j <= m; j++) {
-            t_j = t.charAt(j - 1);
-            d[0] = j;
-
-            for (i = 1; i <= n; i++) {
-                cost = s.charAt(i - 1) == t_j ? 0 : 1;
-                // minimum of cell to the left+1, to the top+1, diagonally left and up +cost
-                d[i] = Math.min(Math.min(d[i - 1] + 1, p[i] + 1), p[i - 1] + cost);
-            }
-
-            // copy current distance counts to 'previous row' distance counts
-            _d = p;
-            p = d;
-            d = _d;
-        }
-
-        // our last action in the above loop was to switch d and p, so p now
-        // actually has the most recent cost counts
-        return p[n];
-    }
-
-    /**
-     * <p>Find the Levenshtein distance between two Strings if it's less than or equal to a given 
-     * threshold.</p>
-     *
-     * <p>This is the number of changes needed to change one String into
-     * another, where each change is a single character modification (deletion,
-     * insertion or substitution).</p>
-     *
-     * <p>This implementation follows from Algorithms on Strings, Trees and Sequences by Dan Gusfield
-     * and Chas Emerick's implementation of the Levenshtein distance algorithm from
-     * <a href="http://www.merriampark.com/ld.htm">http://www.merriampark.com/ld.htm</a></p>
-     *
-     * <pre>
-     * StringUtils.getLevenshteinDistance(null, *, *)             = IllegalArgumentException
-     * StringUtils.getLevenshteinDistance(*, null, *)             = IllegalArgumentException
-     * StringUtils.getLevenshteinDistance(*, *, -1)               = IllegalArgumentException
-     * StringUtils.getLevenshteinDistance("","", 0)               = 0
-     * StringUtils.getLevenshteinDistance("aaapppp", "", 8)       = 7
-     * StringUtils.getLevenshteinDistance("aaapppp", "", 7)       = 7
-     * StringUtils.getLevenshteinDistance("aaapppp", "", 6))      = -1
-     * StringUtils.getLevenshteinDistance("elephant", "hippo", 7) = 7
-     * StringUtils.getLevenshteinDistance("elephant", "hippo", 6) = -1
-     * StringUtils.getLevenshteinDistance("hippo", "elephant", 7) = 7
-     * StringUtils.getLevenshteinDistance("hippo", "elephant", 6) = -1
-     * </pre>
-     *
-     * @param s  the first String, must not be null
-     * @param t  the second String, must not be null
-     * @param threshold the target threshold, must not be negative
-     * @return result distance, or {@code -1} if the distance would be greater than the threshold
-     * @throws IllegalArgumentException if either String input {@code null} or negative threshold
-     */
-    public static int getLevenshteinDistance(CharSequence s, CharSequence t, int threshold) {
-        if (s == null || t == null) {
-            throw new IllegalArgumentException("Strings must not be null");
-        }
-        if (threshold < 0) {
-            throw new IllegalArgumentException("Threshold must not be negative");
-        }
-
-        /*
-        This implementation only computes the distance if it's less than or equal to the
-        threshold value, returning -1 if it's greater.  The advantage is performance: unbounded
-        distance is O(nm), but a bound of k allows us to reduce it to O(km) time by only 
-        computing a diagonal stripe of width 2k + 1 of the cost table.
-        It is also possible to use this to compute the unbounded Levenshtein distance by starting
-        the threshold at 1 and doubling each time until the distance is found; this is O(dm), where
-        d is the distance.
-        
-        One subtlety comes from needing to ignore entries on the border of our stripe
-        eg.
-        p[] = |#|#|#|*
-        d[] =  *|#|#|#|
-        We must ignore the entry to the left of the leftmost member
-        We must ignore the entry above the rightmost member
-        
-        Another subtlety comes from our stripe running off the matrix if the strings aren't
-        of the same size.  Since string s is always swapped to be the shorter of the two, 
-        the stripe will always run off to the upper right instead of the lower left of the matrix.
-        
-        As a concrete example, suppose s is of length 5, t is of length 7, and our threshold is 1.
-        In this case we're going to walk a stripe of length 3.  The matrix would look like so:
-        
-           1 2 3 4 5
-        1 |#|#| | | |
-        2 |#|#|#| | |
-        3 | |#|#|#| |
-        4 | | |#|#|#|
-        5 | | | |#|#|
-        6 | | | | |#|
-        7 | | | | | |
-
-        Note how the stripe leads off the table as there is no possible way to turn a string of length 5
-        into one of length 7 in edit distance of 1.
-        
-        Additionally, this implementation decreases memory usage by using two 
-        single-dimensional arrays and swapping them back and forth instead of allocating
-        an entire n by m matrix.  This requires a few minor changes, such as immediately returning 
-        when it's detected that the stripe has run off the matrix and initially filling the arrays with
-        large values so that entries we don't compute are ignored.
-
-        See Algorithms on Strings, Trees and Sequences by Dan Gusfield for some discussion.
-         */
-
-        int n = s.length(); // length of s
-        int m = t.length(); // length of t
-
-        // if one string is empty, the edit distance is necessarily the length of the other
-        if (n == 0) {
-            return m <= threshold ? m : -1;
-        } else if (m == 0) {
-            return n <= threshold ? n : -1;
-        }
-
-        if (n > m) {
-            // swap the two strings to consume less memory
-            CharSequence tmp = s;
-            s = t;
-            t = tmp;
-            n = m;
-            m = t.length();
-        }
-
-        int p[] = new int[n + 1]; // 'previous' cost array, horizontally
-        int d[] = new int[n + 1]; // cost array, horizontally
-        int _d[]; // placeholder to assist in swapping p and d
-
-        // fill in starting table values
-        int boundary = Math.min(n, threshold) + 1;
-        for (int i = 0; i < boundary; i++) {
-            p[i] = i;
-        }
-        // these fills ensure that the value above the rightmost entry of our 
-        // stripe will be ignored in following loop iterations
-        Arrays.fill(p, boundary, p.length, Integer.MAX_VALUE);
-        Arrays.fill(d, Integer.MAX_VALUE);
-
-        // iterates through t
-        for (int j = 1; j <= m; j++) {
-            char t_j = t.charAt(j - 1); // jth character of t
-            d[0] = j;
-
-            // compute stripe indices, constrain to array size
-            int min = Math.max(1, j - threshold);
-            int max = Math.min(n, j + threshold);
-
-            // the stripe may lead off of the table if s and t are of different sizes
-            if (min > max) {
-                return -1;
-            }
-
-            // ignore entry left of leftmost
-            if (min > 1) {
-                d[min - 1] = Integer.MAX_VALUE;
-            }
-
-            // iterates through [min, max] in s
-            for (int i = min; i <= max; i++) {
-                if (s.charAt(i - 1) == t_j) {
-                    // diagonally left and up
-                    d[i] = p[i - 1];
-                } else {
-                    // 1 + minimum of cell to the left, to the top, diagonally left and up
-                    d[i] = 1 + Math.min(Math.min(d[i - 1], p[i]), p[i - 1]);
-                }
-            }
-
-            // copy current distance counts to 'previous row' distance counts
-            _d = p;
-            p = d;
-            d = _d;
-        }
-
-        // if p[n] is greater than the threshold, there's no guarantee on it being the correct
-        // distance
-        if (p[n] <= threshold) {
-            return p[n];
-        } else {
-            return -1;
-        }
-    }
-
-    // startsWith
-    //-----------------------------------------------------------------------
-
-    /**
-     * <p>Check if a CharSequence starts with a specified prefix.</p>
-     *
-     * <p>{@code null}s are handled without exceptions. Two {@code null}
-     * references are considered to be equal. The comparison is case sensitive.</p>
-     *
-     * <pre>
-     * StringUtils.startsWith(null, null)      = true
-     * StringUtils.startsWith(null, "abc")     = false
-     * StringUtils.startsWith("abcdef", null)  = false
-     * StringUtils.startsWith("abcdef", "abc") = true
-     * StringUtils.startsWith("ABCDEF", "abc") = false
-     * </pre>
-     *
-     * @see java.lang.String#startsWith(String)
-     * @param str  the CharSequence to check, may be null
-     * @param prefix the prefix to find, may be null
-     * @return {@code true} if the CharSequence starts with the prefix, case sensitive, or
-     *  both {@code null}
-     * @since 2.4
-     * @since 3.0 Changed signature from startsWith(String, String) to startsWith(CharSequence, CharSequence)
-     */
-    public static boolean startsWith(CharSequence str, CharSequence prefix) {
-        return startsWith(str, prefix, false);
-    }
-
-    /**
-     * <p>Case insensitive check if a CharSequence starts with a specified prefix.</p>
-     *
-     * <p>{@code null}s are handled without exceptions. Two {@code null}
-     * references are considered to be equal. The comparison is case insensitive.</p>
-     *
-     * <pre>
-     * StringUtils.startsWithIgnoreCase(null, null)      = true
-     * StringUtils.startsWithIgnoreCase(null, "abc")     = false
-     * StringUtils.startsWithIgnoreCase("abcdef", null)  = false
-     * StringUtils.startsWithIgnoreCase("abcdef", "abc") = true
-     * StringUtils.startsWithIgnoreCase("ABCDEF", "abc") = true
-     * </pre>
-     *
-     * @see java.lang.String#startsWith(String)
-     * @param str  the CharSequence to check, may be null
-     * @param prefix the prefix to find, may be null
-     * @return {@code true} if the CharSequence starts with the prefix, case insensitive, or
-     *  both {@code null}
-     * @since 2.4
-     * @since 3.0 Changed signature from startsWithIgnoreCase(String, String) to startsWithIgnoreCase(CharSequence, CharSequence)
-     */
-    public static boolean startsWithIgnoreCase(CharSequence str, CharSequence prefix) {
-        return startsWith(str, prefix, true);
-    }
-
-    /**
-     * <p>Check if a CharSequence starts with a specified prefix (optionally case insensitive).</p>
-     *
-     * @see java.lang.String#startsWith(String)
-     * @param str  the CharSequence to check, may be null
-     * @param prefix the prefix to find, may be null
-     * @param ignoreCase indicates whether the compare should ignore case
-     *  (case insensitive) or not.
-     * @return {@code true} if the CharSequence starts with the prefix or
-     *  both {@code null}
-     */
-    private static boolean startsWith(CharSequence str, CharSequence prefix, boolean ignoreCase) {
-        if (str == null || prefix == null) {
-            return str == null && prefix == null;
-        }
-        if (prefix.length() > str.length()) {
-            return false;
-        }
-        return CharSequenceUtils.regionMatches(str, ignoreCase, 0, prefix, 0, prefix.length());
-    }
-
-    /**
-     * <p>Check if a CharSequence starts with any of an array of specified strings.</p>
-     *
-     * <pre>
-     * StringUtils.startsWithAny(null, null)      = false
-     * StringUtils.startsWithAny(null, new String[] {"abc"})  = false
-     * StringUtils.startsWithAny("abcxyz", null)     = false
-     * StringUtils.startsWithAny("abcxyz", new String[] {""}) = false
-     * StringUtils.startsWithAny("abcxyz", new String[] {"abc"}) = true
-     * StringUtils.startsWithAny("abcxyz", new String[] {null, "xyz", "abc"}) = true
-     * </pre>
-     *
-     * @param string  the CharSequence to check, may be null
-     * @param searchStrings the CharSequences to find, may be null or empty
-     * @return {@code true} if the CharSequence starts with any of the the prefixes, case insensitive, or
-     *  both {@code null}
-     * @since 2.5
-     * @since 3.0 Changed signature from startsWithAny(String, String[]) to startsWithAny(CharSequence, CharSequence...)
-     */
-    public static boolean startsWithAny(CharSequence string, CharSequence... searchStrings) {
-        if (isEmpty(string) || ArrayUtils.isEmpty(searchStrings)) {
-            return false;
-        }
-        for (CharSequence searchString : searchStrings) {
-            if (StringUtils.startsWith(string, searchString)) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    // endsWith
-    //-----------------------------------------------------------------------
-
-    /**
-     * <p>Check if a CharSequence ends with a specified suffix.</p>
-     *
-     * <p>{@code null}s are handled without exceptions. Two {@code null}
-     * references are considered to be equal. The comparison is case sensitive.</p>
-     *
-     * <pre>
-     * StringUtils.endsWith(null, null)      = true
-     * StringUtils.endsWith(null, "def")     = false
-     * StringUtils.endsWith("abcdef", null)  = false
-     * StringUtils.endsWith("abcdef", "def") = true
-     * StringUtils.endsWith("ABCDEF", "def") = false
-     * StringUtils.endsWith("ABCDEF", "cde") = false
-     * </pre>
-     *
-     * @see java.lang.String#endsWith(String)
-     * @param str  the CharSequence to check, may be null
-     * @param suffix the suffix to find, may be null
-     * @return {@code true} if the CharSequence ends with the suffix, case sensitive, or
-     *  both {@code null}
-     * @since 2.4
-     * @since 3.0 Changed signature from endsWith(String, String) to endsWith(CharSequence, CharSequence)
-     */
-    public static boolean endsWith(CharSequence str, CharSequence suffix) {
-        return endsWith(str, suffix, false);
-    }
-
-    /**
-     * <p>Case insensitive check if a CharSequence ends with a specified suffix.</p>
-     *
-     * <p>{@code null}s are handled without exceptions. Two {@code null}
-     * references are considered to be equal. The comparison is case insensitive.</p>
-     *
-     * <pre>
-     * StringUtils.endsWithIgnoreCase(null, null)      = true
-     * StringUtils.endsWithIgnoreCase(null, "def")     = false
-     * StringUtils.endsWithIgnoreCase("abcdef", null)  = false
-     * StringUtils.endsWithIgnoreCase("abcdef", "def") = true
-     * StringUtils.endsWithIgnoreCase("ABCDEF", "def") = true
-     * StringUtils.endsWithIgnoreCase("ABCDEF", "cde") = false
-     * </pre>
-     *
-     * @see java.lang.String#endsWith(String)
-     * @param str  the CharSequence to check, may be null
-     * @param suffix the suffix to find, may be null
-     * @return {@code true} if the CharSequence ends with the suffix, case insensitive, or
-     *  both {@code null}
-     * @since 2.4
-     * @since 3.0 Changed signature from endsWithIgnoreCase(String, String) to endsWithIgnoreCase(CharSequence, CharSequence)
-     */
-    public static boolean endsWithIgnoreCase(CharSequence str, CharSequence suffix) {
-        return endsWith(str, suffix, true);
-    }
-
-    /**
-     * <p>Check if a CharSequence ends with a specified suffix (optionally case insensitive).</p>
-     *
-     * @see java.lang.String#endsWith(String)
-     * @param str  the CharSequence to check, may be null
-     * @param suffix the suffix to find, may be null
-     * @param ignoreCase indicates whether the compare should ignore case
-     *  (case insensitive) or not.
-     * @return {@code true} if the CharSequence starts with the prefix or
-     *  both {@code null}
-     */
-    private static boolean endsWith(CharSequence str, CharSequence suffix, boolean ignoreCase) {
-        if (str == null || suffix == null) {
-            return str == null && suffix == null;
-        }
-        if (suffix.length() > str.length()) {
-            return false;
-        }
-        int strOffset = str.length() - suffix.length();
-        return CharSequenceUtils.regionMatches(str, ignoreCase, strOffset, suffix, 0, suffix.length());
-    }
-
-    /**
-     * <p>
-     * Similar to <a
-     * href="http://www.w3.org/TR/xpath/#function-normalize-space">http://www.w3.org/TR/xpath/#function-normalize
-     * -space</a>
-     * </p>
-     * <p>
-     * The function returns the argument string with whitespace normalized by using
-     * <code>{@link #trim(String)}</code> to remove leading and trailing whitespace
-     * and then replacing sequences of whitespace characters by a single space.
-     * </p>
-     * In XML Whitespace characters are the same as those allowed by the <a
-     * href="http://www.w3.org/TR/REC-xml/#NT-S">S</a> production, which is S ::= (#x20 | #x9 | #xD | #xA)+
-     * <p>
-     * Java's regexp pattern \s defines whitespace as [ \t\n\x0B\f\r]
-     * <p>
-     * For reference:
-     * <ul>
-     * <li>\x0B = vertical tab</li>
-     * <li>\f = #xC = form feed</li>
-     * <li>#x20 = space</li>
-     * <li>#x9 = \t</li>
-     * <li>#xA = \n</li>
-     * <li>#xD = \r</li>
-     * </ul>
-     * </p>
-     * <p>
-     * The difference is that Java's whitespace includes vertical tab and form feed, which this functional will also
-     * normalize. Additionally <code>{@link #trim(String)}</code> removes control characters (char &lt;= 32) from both
-     * ends of this String.
-     * </p>
-     *
-     * @see Pattern
-     * @see #trim(String)
-     * @see <a
-     *      href="http://www.w3.org/TR/xpath/#function-normalize-space">http://www.w3.org/TR/xpath/#function-normalize-space</a>
-     * @param str the source String to normalize whitespaces from, may be null
-     * @return the modified string with whitespace normalized, {@code null} if null String input
-     *
-     * @since 3.0
-     */
-    public static String normalizeSpace(String str) {
-        if (str == null) {
-            return null;
-        }
-        return WHITESPACE_BLOCK.matcher(trim(str)).replaceAll(" ");
-    }
-
-    /**
-     * <p>Check if a CharSequence ends with any of an array of specified strings.</p>
-     *
-     * <pre>
-     * StringUtils.endsWithAny(null, null)      = false
-     * StringUtils.endsWithAny(null, new String[] {"abc"})  = false
-     * StringUtils.endsWithAny("abcxyz", null)     = false
-     * StringUtils.endsWithAny("abcxyz", new String[] {""}) = true
-     * StringUtils.endsWithAny("abcxyz", new String[] {"xyz"}) = true
-     * StringUtils.endsWithAny("abcxyz", new String[] {null, "xyz", "abc"}) = true
-     * </pre>
-     *
-     * @param string  the CharSequence to check, may be null
-     * @param searchStrings the CharSequences to find, may be null or empty
-     * @return {@code true} if the CharSequence ends with any of the the prefixes, case insensitive, or
-     *  both {@code null}
-     * @since 3.0
-     */
-    public static boolean endsWithAny(CharSequence string, CharSequence... searchStrings) {
-        if (isEmpty(string) || ArrayUtils.isEmpty(searchStrings)) {
-            return false;
-        }
-        for (CharSequence searchString : searchStrings) {
-            if (StringUtils.endsWith(string, searchString)) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    /**
-     * Converts a <code>byte[]</code> to a String using the specified character encoding.
-     * 
-     * @param bytes
-     *            the byte array to read from
-     * @param charsetName
-     *            the encoding to use, if null then use the platform default
-     * @return a new String
-     * @throws UnsupportedEncodingException
-     *             If the named charset is not supported
-     * @throws NullPointerException
-     *             if the input is null
-     * @since 3.1
-     */
-    public static String toString(byte[] bytes, String charsetName) throws UnsupportedEncodingException {
-        return charsetName == null ? new String(bytes) : new String(bytes, charsetName);
-    }
-
-}
diff --git a/compiler/java/com/google/dart/compiler/util/apache/exception/CloneFailedException.java b/compiler/java/com/google/dart/compiler/util/apache/exception/CloneFailedException.java
deleted file mode 100644
index cd93dd9..0000000
--- a/compiler/java/com/google/dart/compiler/util/apache/exception/CloneFailedException.java
+++ /dev/null
@@ -1,69 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-/*
- * 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 com.google.dart.compiler.util.apache.exception;
-
-/**
- * Exception thrown when a clone cannot be created. In contrast to
- * {@link CloneNotSupportedException} this is a {@link RuntimeException}.
- * <p>
- * NOTICE: This file is modified copy of its original Apache library.
- * It was moved to the different package, and changed to reduce number of dependencies.
- * 
- * @since 3.0
- */
-public class CloneFailedException extends RuntimeException {
-    // ~ Static fields/initializers ---------------------------------------------
-
-    private static final long serialVersionUID = 20091223L;
-
-    // ~ Constructors -----------------------------------------------------------
-
-    /**
-     * Constructs a CloneFailedException.
-     * 
-     * @param message description of the exception
-     * @since upcoming
-     */
-    public CloneFailedException(final String message) {
-        super(message);
-    }
-
-    /**
-     * Constructs a CloneFailedException.
-     * 
-     * @param cause cause of the exception
-     * @since upcoming
-     */
-    public CloneFailedException(final Throwable cause) {
-        super(cause);
-    }
-
-    /**
-     * Constructs a CloneFailedException.
-     * 
-     * @param message description of the exception
-     * @param cause cause of the exception
-     * @since upcoming
-     */
-    public CloneFailedException(final String message, final Throwable cause) {
-        super(message, cause);
-    }
-}
diff --git a/compiler/java/com/google/dart/compiler/util/apache/mutable/Mutable.java b/compiler/java/com/google/dart/compiler/util/apache/mutable/Mutable.java
deleted file mode 100644
index 1f6b9f2..0000000
--- a/compiler/java/com/google/dart/compiler/util/apache/mutable/Mutable.java
+++ /dev/null
@@ -1,61 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-/*
- * 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 com.google.dart.compiler.util.apache.mutable;
-
-/**
- * Provides mutable access to a value.
- * <p>
- * <code>Mutable</code> is used as a generic interface to the implementations in this package.
- * <p>
- * A typical use case would be to enable a primitive or string to be passed to a method and allow that method to
- * effectively change the value of the primitive/string. Another use case is to store a frequently changing primitive in
- * a collection (for example a total in a map) without needing to create new Integer/Long wrapper objects.
- * <p>
- * NOTICE: This file is modified copy of its original Apache library.
- * It was moved to the different package, and changed to reduce number of dependencies.
- * 
- * @since 2.1
- * @param <T> the type to set and get 
- * @version $Id: Mutable.java 1153213 2011-08-02 17:35:39Z ggregory $
- */
-public interface Mutable<T> {
-
-    /**
-     * Gets the value of this mutable.
-     * 
-     * @return the stored value
-     */
-    T getValue();
-
-    /**
-     * Sets the value of this mutable.
-     * 
-     * @param value
-     *            the value to store
-     * @throws NullPointerException
-     *             if the object is null and null is invalid
-     * @throws ClassCastException
-     *             if the type is invalid
-     */
-    void setValue(T value);
-
-}
diff --git a/compiler/java/com/google/dart/compiler/util/apache/mutable/MutableInt.java b/compiler/java/com/google/dart/compiler/util/apache/mutable/MutableInt.java
deleted file mode 100644
index 51aba6f..0000000
--- a/compiler/java/com/google/dart/compiler/util/apache/mutable/MutableInt.java
+++ /dev/null
@@ -1,280 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-/*
- * 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 com.google.dart.compiler.util.apache.mutable;
-
-/**
- * A mutable <code>int</code> wrapper.
- * <p>
- * Note that as MutableInt does not extend Integer, it is not treated by String.format as an Integer parameter. 
- * <p>
- * NOTICE: This file is modified copy of its original Apache library.
- * It was moved to the different package, and changed to reduce number of dependencies.
- * 
- * @see Integer
- * @since 2.1
- * @version $Id: MutableInt.java 1160571 2011-08-23 07:36:08Z bayard $
- */
-public class MutableInt extends Number implements Comparable<MutableInt>, Mutable<Number> {
-
-    /**
-     * Required for serialization support.
-     * 
-     * @see java.io.Serializable
-     */
-    private static final long serialVersionUID = 512176391864L;
-
-    /** The mutable value. */
-    private int value;
-
-    /**
-     * Constructs a new MutableInt with the default value of zero.
-     */
-    public MutableInt() {
-        super();
-    }
-
-    /**
-     * Constructs a new MutableInt with the specified value.
-     * 
-     * @param value  the initial value to store
-     */
-    public MutableInt(int value) {
-        super();
-        this.value = value;
-    }
-
-    /**
-     * Constructs a new MutableInt with the specified value.
-     * 
-     * @param value  the initial value to store, not null
-     * @throws NullPointerException if the object is null
-     */
-    public MutableInt(Number value) {
-        super();
-        this.value = value.intValue();
-    }
-
-    /**
-     * Constructs a new MutableInt parsing the given string.
-     * 
-     * @param value  the string to parse, not null
-     * @throws NumberFormatException if the string cannot be parsed into an int
-     * @since 2.5
-     */
-    public MutableInt(String value) throws NumberFormatException {
-        super();
-        this.value = Integer.parseInt(value);
-    }
-
-    //-----------------------------------------------------------------------
-    /**
-     * Gets the value as a Integer instance.
-     * 
-     * @return the value as a Integer, never null
-     */
-    public Integer getValue() {
-        return Integer.valueOf(this.value);
-    }
-
-    /**
-     * Sets the value.
-     * 
-     * @param value  the value to set
-     */
-    public void setValue(int value) {
-        this.value = value;
-    }
-
-    /**
-     * Sets the value from any Number instance.
-     * 
-     * @param value  the value to set, not null
-     * @throws NullPointerException if the object is null
-     */
-    public void setValue(Number value) {
-        this.value = value.intValue();
-    }
-
-    //-----------------------------------------------------------------------
-    /**
-     * Increments the value.
-     *
-     * @since Commons Lang 2.2
-     */
-    public void increment() {
-        value++;
-    }
-
-    /**
-     * Decrements the value.
-     *
-     * @since Commons Lang 2.2
-     */
-    public void decrement() {
-        value--;
-    }
-
-    //-----------------------------------------------------------------------
-    /**
-     * Adds a value to the value of this instance.
-     * 
-     * @param operand  the value to add, not null
-     * @since Commons Lang 2.2
-     */
-    public void add(int operand) {
-        this.value += operand;
-    }
-
-    /**
-     * Adds a value to the value of this instance.
-     * 
-     * @param operand  the value to add, not null
-     * @throws NullPointerException if the object is null
-     * @since Commons Lang 2.2
-     */
-    public void add(Number operand) {
-        this.value += operand.intValue();
-    }
-
-    /**
-     * Subtracts a value from the value of this instance.
-     * 
-     * @param operand  the value to subtract, not null
-     * @since Commons Lang 2.2
-     */
-    public void subtract(int operand) {
-        this.value -= operand;
-    }
-
-    /**
-     * Subtracts a value from the value of this instance.
-     * 
-     * @param operand  the value to subtract, not null
-     * @throws NullPointerException if the object is null
-     * @since Commons Lang 2.2
-     */
-    public void subtract(Number operand) {
-        this.value -= operand.intValue();
-    }
-
-    //-----------------------------------------------------------------------
-    // shortValue and byteValue rely on Number implementation
-    /**
-     * Returns the value of this MutableInt as an int.
-     *
-     * @return the numeric value represented by this object after conversion to type int.
-     */
-    @Override
-    public int intValue() {
-        return value;
-    }
-
-    /**
-     * Returns the value of this MutableInt as a long.
-     *
-     * @return the numeric value represented by this object after conversion to type long.
-     */
-    @Override
-    public long longValue() {
-        return value;
-    }
-
-    /**
-     * Returns the value of this MutableInt as a float.
-     *
-     * @return the numeric value represented by this object after conversion to type float.
-     */
-    @Override
-    public float floatValue() {
-        return value;
-    }
-
-    /**
-     * Returns the value of this MutableInt as a double.
-     *
-     * @return the numeric value represented by this object after conversion to type double.
-     */
-    @Override
-    public double doubleValue() {
-        return value;
-    }
-
-    //-----------------------------------------------------------------------
-    /**
-     * Gets this mutable as an instance of Integer.
-     *
-     * @return a Integer instance containing the value from this mutable, never null
-     */
-    public Integer toInteger() {
-        return Integer.valueOf(intValue());
-    }
-
-    //-----------------------------------------------------------------------
-    /**
-     * Compares this object to the specified object. The result is <code>true</code> if and only if the argument is
-     * not <code>null</code> and is a <code>MutableInt</code> object that contains the same <code>int</code> value
-     * as this object.
-     * 
-     * @param obj  the object to compare with, null returns false
-     * @return <code>true</code> if the objects are the same; <code>false</code> otherwise.
-     */
-    @Override
-    public boolean equals(Object obj) {
-        if (obj instanceof MutableInt) {
-            return value == ((MutableInt) obj).intValue();
-        }
-        return false;
-    }
-
-    /**
-     * Returns a suitable hash code for this mutable.
-     * 
-     * @return a suitable hash code
-     */
-    @Override
-    public int hashCode() {
-        return value;
-    }
-
-    //-----------------------------------------------------------------------
-    /**
-     * Compares this mutable to another in ascending order.
-     * 
-     * @param other  the other mutable to compare to, not null
-     * @return negative if this is less, zero if equal, positive if greater
-     */
-    public int compareTo(MutableInt other) {
-        int anotherVal = other.value;
-        return value < anotherVal ? -1 : (value == anotherVal ? 0 : 1);
-    }
-
-    //-----------------------------------------------------------------------
-    /**
-     * Returns the String value of this mutable.
-     * 
-     * @return the mutable value as a string
-     */
-    @Override
-    public String toString() {
-        return String.valueOf(value);
-    }
-
-}
diff --git a/compiler/javatests/com/google/dart/compiler/AbstractSourceFileTest.java b/compiler/javatests/com/google/dart/compiler/AbstractSourceFileTest.java
deleted file mode 100644
index 5b9a27d..0000000
--- a/compiler/javatests/com/google/dart/compiler/AbstractSourceFileTest.java
+++ /dev/null
@@ -1,56 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler;
-
-import com.google.dart.compiler.common.LibrarySourceFileTest;
-
-import java.io.File;
-import java.io.FileWriter;
-import java.io.IOException;
-
-/**
- * Shared behavior for creating a temporary file from a java resource
- * to support testing {@link File} based classes
- */
-public abstract class AbstractSourceFileTest extends CompilerTestCase {
-
-  private File tempFile;
-
-  /**
-   * Create a temporary file to be cleaned up when the test is complete
-   *
-   * @param filePath the path to the file relative to the test class
-   * @return the temporary file
-   */
-  protected File createTempFile(String filePath) throws IOException {
-    String source = readUrl(inputUrlFor(LibrarySourceFileTest.class, filePath));
-    return createTempFile(filePath, source);
-  }
-
-  protected File createTempFile(String filePath, String source) throws IOException {
-    String fileExt = filePath.substring(filePath.lastIndexOf('.'));
-    String fileName = filePath.substring(filePath.lastIndexOf('/') + 1,
-        filePath.length() - fileExt.length());
-    tempFile = File.createTempFile(fileName, fileExt);
-    FileWriter writer = new FileWriter(tempFile);
-    writer.write(source);
-    writer.close();
-    return tempFile;
-  }
-
-  /**
-   * Delete the temporary file if it was created.
-   *
-   * @see junit.framework.TestCase#tearDown()
-   */
-  @Override
-  protected void tearDown() throws Exception {
-    if (tempFile != null) {
-      tempFile.delete();
-    }
-    super.tearDown();
-  }
-
-}
diff --git a/compiler/javatests/com/google/dart/compiler/AnalysisError.java b/compiler/javatests/com/google/dart/compiler/AnalysisError.java
deleted file mode 100644
index 6b2cabc..0000000
--- a/compiler/javatests/com/google/dart/compiler/AnalysisError.java
+++ /dev/null
@@ -1,19 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler;
-
-public class AnalysisError extends Exception {
-  public AnalysisError(String message) {
-    super(message);
-  }
-
-  AnalysisError(String message, Throwable cause) {
-    super(message, cause);
-  }
-
-  AnalysisError(Throwable cause) {
-    super(cause);
-  }
-}
diff --git a/compiler/javatests/com/google/dart/compiler/CodeCompletionParseTest.java b/compiler/javatests/com/google/dart/compiler/CodeCompletionParseTest.java
deleted file mode 100644
index 6776675..0000000
--- a/compiler/javatests/com/google/dart/compiler/CodeCompletionParseTest.java
+++ /dev/null
@@ -1,86 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler;
-
-import com.google.dart.compiler.ast.LibraryUnit;
-
-/**
- * Tests the use of the parser and analysis phases as used by the IDE for code
- * completion.
- */
-public class CodeCompletionParseTest extends CompilerTestCase {
-
-  public void test1() throws Exception {
-    AnalyzeLibraryResult result = analyzeLibrary(makeCode(
-        "class CellLocation {",
-        "  int _field1;",
-        "  String _field2;",
-        "",
-        "  CellLoc", // cursor
-        "",
-        "  int hashCode() {",
-        "     return _field1 * 31 ^ _field2.hashCode();",
-        "  }",
-        "}"));
-    LibraryUnit lib = result.getLibraryUnitResult();
-    assertNotNull(lib);
-  }
-
-  public void test2() throws Exception {
-    AnalyzeLibraryResult result = analyzeLibrary(makeCode(
-        "doFoo() {",
-        "  new ", // cursor
-        "}"));
-    LibraryUnit lib = result.getLibraryUnitResult();
-    assertNotNull(lib);
-  }
-
-  public void test3() throws Exception {
-    AnalyzeLibraryResult result = analyzeLibrary(makeCode(
-        "class Foo {",
-        "  static final Bar b = const ", // cursor
-        "}",
-        "",
-        "class Bar {",
-        "  factory Bar() {}",
-        "}"));
-    LibraryUnit lib = result.getLibraryUnitResult();
-    assertNotNull(lib);
-  }
-
-  public void test4() throws Exception {
-    AnalyzeLibraryResult result = analyzeLibrary(makeCode(
-        "foo() {",
-        "  int SEED;",
-        "  for (int i = 0; i < S)", // cursor before )
-        "}"));
-    LibraryUnit lib = result.getLibraryUnitResult();
-    assertNotNull(lib);
-  }
-
-  public void test5() throws Exception {
-    AnalyzeLibraryResult result = analyzeLibrary(makeCode(
-        "ckass Sunflower {",
-        "  static final int SEED_RADIUS = 2;",
-        "  static final int SCALE_FACTOR = 4;",
-        "  static final num PI2 = Math.PI * 2;",
-        "  static final num PI4 = M", // cursor
-        "}"));
-    LibraryUnit lib = result.getLibraryUnitResult();
-    assertNotNull(lib);
-  }
-
-  public void test6() throws Exception {
-    AnalyzeLibraryResult result = analyzeLibrary(makeCode(
-        "class Sunflower {",
-        "  static final int SEED_RADIUS = 2;",
-        "  static final int SCALE_FACTOR = 4;",
-        "  static final num PI2 = Math.PI * 2;",
-        "  static final num PI4 = M", // cursor
-        "}"));
-    LibraryUnit lib = result.getLibraryUnitResult();
-    assertNotNull(lib);
-  }
-}
diff --git a/compiler/javatests/com/google/dart/compiler/CompilerTestCase.java b/compiler/javatests/com/google/dart/compiler/CompilerTestCase.java
deleted file mode 100644
index 92247b1..0000000
--- a/compiler/javatests/com/google/dart/compiler/CompilerTestCase.java
+++ /dev/null
@@ -1,510 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler;
-
-import com.google.common.collect.Lists;
-import com.google.common.collect.Maps;
-import com.google.common.collect.Sets;
-import com.google.dart.compiler.CommandLineOptions.CompilerOptions;
-import com.google.dart.compiler.ast.ASTVisitor;
-import com.google.dart.compiler.ast.DartExpression;
-import com.google.dart.compiler.ast.DartFunctionTypeAlias;
-import com.google.dart.compiler.ast.DartIdentifier;
-import com.google.dart.compiler.ast.DartNode;
-import com.google.dart.compiler.ast.DartUnit;
-import com.google.dart.compiler.ast.LibraryUnit;
-import com.google.dart.compiler.common.ErrorExpectation;
-import com.google.dart.compiler.common.SourceInfo;
-import com.google.dart.compiler.end2end.inc.MemoryLibrarySource;
-import com.google.dart.compiler.parser.DartParser;
-import com.google.dart.compiler.parser.DartParserRunner;
-import com.google.dart.compiler.resolver.Element;
-import com.google.dart.compiler.type.Type;
-import com.google.dart.compiler.type.TypeQuality;
-
-import static com.google.dart.compiler.common.ErrorExpectation.assertErrors;
-
-import junit.framework.TestCase;
-
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.io.Reader;
-import java.net.URI;
-import java.net.URL;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.atomic.AtomicReference;
-
-/**
- * Base class for compiler tests, with helpful utility methods.
- */
-public abstract class CompilerTestCase extends TestCase {
-
-  private static final String UTF8 = "UTF-8";
-  protected CompilerConfiguration compilerConfiguration;
-  protected String testSource;
-  protected DartUnit testUnit;
-
-  /**
-   * Instance of {@link CompilerConfiguration} for incremental check-only compilation.
-   */
-  protected static final CompilerConfiguration CHECK_ONLY_CONFIGURATION =
-      new DefaultCompilerConfiguration(new CompilerOptions()) {
-        @Override
-        public boolean incremental() {
-          return true;
-        }
-
-        @Override
-        public boolean resolveDespiteParseErrors() {
-          return true;
-        }
-      };
-
-  /**
-   * Read a resource from the given URL.
-   */
-  protected static String readUrl(URL url) {
-    try {
-      StringBuffer out = new StringBuffer();
-      Reader in = new InputStreamReader(url.openStream(), UTF8);
-      char[] buf = new char[10240];
-      int n;
-      while ((n = in.read(buf)) > 0) {
-        out.append(buf, 0, n);
-      }
-      in.close();
-      return out.toString();
-    } catch (IOException e) {
-      // Just punt a RuntimeException out the top if something goes wrong.
-      // It will simply cause the test to fail, which is exactly what we want.
-      throw new RuntimeException(e);
-    }
-  }
-
-  /**
-   * Return a URL that can be used to read an input file for the given test name
-   * and path.
-   */
-  protected static URL inputUrlFor(Class<?> testClass, String testName) {
-    String fullPath = testClass.getPackage().getName().replace('.', '/') + "/"
-        + testName;
-    URL url = chooseClassLoader().getResource(fullPath);
-    if (url == null) {
-      fail("Could not find input file: " + fullPath);
-    }
-    return url;
-  }
-
-  private static ClassLoader chooseClassLoader() {
-    if (Thread.currentThread().getContextClassLoader() != null) {
-      return Thread.currentThread().getContextClassLoader();
-    }
-    return CompilerTestCase.class.getClassLoader();
-  }
-
-  /**
-   * Collects the results of running analyzeLibrary.
-   */
-  protected static class AnalyzeLibraryResult extends DartCompilerListener.Empty {
-    public String source;
-    private final List<DartCompilationError> errors = Lists.newArrayList();
-    private final List<DartCompilationError> compilationErrors = Lists.newArrayList();
-    private final List<DartCompilationError> compilationWarnings = Lists.newArrayList();
-    private final List<DartCompilationError> typeErrors = Lists.newArrayList();
-    private LibraryUnit result;
-
-    @Override
-    public void onError(DartCompilationError event) {
-      errors.add(event);
-      if (event.getErrorCode().getSubSystem() == SubSystem.STATIC_TYPE) {
-        typeErrors.add(event);
-      } else if (event.getErrorCode().getErrorSeverity() == ErrorSeverity.ERROR) {
-        compilationErrors.add(event);
-      }   else if (event.getErrorCode().getErrorSeverity() == ErrorSeverity.WARNING) {
-        compilationWarnings.add(event);
-      }
-    }
-
-    public List<DartCompilationError> getErrors() {
-      return errors;
-    }
-
-    public List<DartCompilationError> getTypeErrors() {
-      return typeErrors;
-    }
-
-    public List<DartCompilationError> getCompilationErrors() {
-      return compilationErrors;
-    }
-
-    public List<DartCompilationError> getCompilationWarnings() {
-      return compilationWarnings;
-    }
-
-    /**
-     * @param lib
-     */
-    public void setLibraryUnitResult(LibraryUnit lib) {
-      result = lib;
-    }
-
-    /**
-     * @return the analyzed library
-     */
-    public LibraryUnit getLibraryUnitResult() {
-      return result;
-    }
-  }
-
-  /**
-   * Build a multi-line string from a list of strings.
-   *
-   * @param lines
-   * @return a single string containing {@code lines}, each terminated by \n
-   */
-  protected static String makeCode(String... lines) {
-    StringBuilder buf = new StringBuilder();
-    for (String line : lines) {
-      buf.append(line).append('\n');
-    }
-    return buf.toString();
-  }
-  
-  @Override
-  protected void setUp() throws Exception {
-    super.setUp();
-    compilerConfiguration = CHECK_ONLY_CONFIGURATION;
-  }
-
-  @Override
-  protected void tearDown() throws Exception {
-    compilerConfiguration = null;
-    testSource = null;
-    testUnit = null;
-    super.tearDown();
-  }
-
-  protected AnalyzeLibraryResult analyzeLibrary(String... lines) throws Exception {
-    testSource = makeCode(lines);
-    AnalyzeLibraryResult libraryResult = analyzeLibrary(testSource);
-    testUnit = libraryResult.getLibraryUnitResult().getUnits().iterator().next();
-    return libraryResult;
-  }
-
-  /**
-   * Simulate running {@code analyzeLibrary} the way the IDE will.
-   * <p>
-   * <b>Note:</b> if the IDE changes how it calls analyzeLibrary, this should
-   * be changed to match.
-   * @param code the Dart code to parse/analyze
-   *
-   * @return an {@link AnalyzeLibraryResult} containing the {@link LibraryUnit}
-   *     and all the errors/warnings generated from the supplied code
-   * @throws Exception
-   */
-  protected AnalyzeLibraryResult analyzeLibrary(String code)
-      throws Exception {
-    AnalyzeLibraryResult result = new AnalyzeLibraryResult();
-    result.source = code;
-    // Prepare library.
-    MemoryLibrarySource lib = new MemoryLibrarySource("Test.dart");
-    lib.setContent("Test.dart", code);
-    // Prepare unit.
-    Map<URI, DartUnit> testUnits =  Maps.newHashMap();
-    {
-      DartSource src = lib.getSourceFor("Test.dart");
-      DartUnit unit = makeParser(src, code, result).parseUnit();
-      testUnits.put(src.getUri(), unit);
-    }
-    DartArtifactProvider provider = new MockArtifactProvider();
-    result.setLibraryUnitResult(DartCompiler.analyzeLibrary(
-        lib,
-        testUnits,
-        compilerConfiguration,
-        provider,
-        result));
-    // TODO(zundel): One day, we want all AST nodes that are identifiers to point to
-    // elements if they are resolved.  Uncommenting this line helps track missing elements
-    // down.
-    // ResolverAuditVisitor.exec(unit);
-    return result;
-  }
-
-  /**
-   * Compiles a single unit with a synthesized application.
-   */
-  protected DartSource compileSingleUnit(String name, String code,
-       DartArtifactProvider provider) throws IOException {
-     MockLibrarySource lib = new MockLibrarySource();
-     DartSourceTest src = new DartSourceTest(name, code, lib);
-     lib.addSource(src);
-     CompilerConfiguration config = getCompilerConfiguration();
-     DartCompilerListener listener = new DartCompilerListenerTest(src.getName());
-     DartCompiler.compileLib(lib, config, provider, listener);
-     return src;
-  }
-
-  /**
-   * Allow tests to override the configuration used.
-   */
-  protected CompilerConfiguration getCompilerConfiguration() {
-    return new DefaultCompilerConfiguration();
-  }
-
-  /**
-   * Parse a single compilation unit for the given input file.
-   */
-  protected final DartUnit parseUnit(String path) {
-    // final because we delegate to the method below, and only that one should
-    // be overriden to do extra checks.
-    URL url = inputUrlFor(getClass(), path);
-    String source = readUrl(url);
-    return parseUnit(path, source);
-  }
-
-  /**
-   * Parse a single compilation unit for the name and source.
-   */
-  protected DartUnit parseUnit(String srcName, String sourceCode, Object... errors) {
-    testSource = sourceCode;
-    // TODO(jgw): We'll need to fill in the library parameter when testing multiple units.
-    DartSourceTest src = new DartSourceTest(srcName, sourceCode, null);
-    DartCompilerListenerTest listener = new DartCompilerListenerTest(srcName, errors);
-    testUnit = makeParser(src, sourceCode, listener).parseUnit();
-    listener.checkAllErrorsReported();
-    return testUnit;
-  }
-
-  /**
-   * Parse a single compilation unit for the name and source. The parse expects some kind of error,
-   * but isn't picky about the actual contents. This is useful for testing parser recovery where we
-   * don't want to make the test too brittle.
-   */
-  protected DartUnit parseUnitUnspecifiedErrors(String srcName, String sourceCode) {
-    DartSourceTest src = new DartSourceTest(srcName, sourceCode, null);
-    final List<DartCompilationError> errorsEncountered = Lists.newArrayList();
-    DartCompilerListener listener = new DartCompilerListener.Empty() {
-      @Override
-      public void onError(DartCompilationError event) {
-        errorsEncountered.add(event);
-      }
-    };
-    DartUnit unit = makeParser(src, sourceCode, listener).parseUnit();
-    assertTrue("Expected some compilation errors, got none.", errorsEncountered.size() > 0);
-    return unit;
-    }
-
-    protected DartUnit parseUnitAsSystemLibrary(final String srcName, String sourceCode,
-                                              Object... errors) {
-    DartSourceTest src = new DartSourceTest(srcName, sourceCode, null) {
-      @Override
-      public URI getUri() {
-        return URI.create("dart:core/" + srcName);
-      }
-    };
-    DartCompilerListenerTest listener = new DartCompilerListenerTest(srcName, errors);
-    DartUnit unit = makeParser(src, sourceCode, listener).parseUnit();
-    listener.checkAllErrorsReported();
-    return unit;
-  }
-
-
-  /**
-   * Parse a single compilation unit with given name and source, and check for a set of expected errors.
-   *
-   * @param errors a sequence of errors represented as triples of the form
-   *        (String msg, int line, int column) or
-   *        (ErrorCode code, int line, int column)
-   */
-  protected DartUnit parseSourceUnitErrors(String sourceCode,  Object... errors) {
-    String srcName = "Test.dart";
-    DartSourceTest src = new DartSourceTest(srcName, sourceCode, null);
-    DartCompilerListenerTest listener = new DartCompilerListenerTest(srcName, errors);
-    DartUnit unit = makeParser(src, sourceCode, listener).parseUnit();
-    listener.checkAllErrorsReported();
-    return unit;
-  }
-
-  /**
-   * Parse a single compilation unit for the given input file, and check for a
-   * set of expected errors.
-   *
-   * @param errors a sequence of errors represented as triples of the form
-   *        (String msg, int line, int column) or
-   *        (ErrorCode code, int line, int column)
-   */
-  protected DartUnit parseUnitErrors(final String path, final Object... errors) {
-    URL url = inputUrlFor(getClass(), path);
-    String sourceCode = readUrl(url);
-    // TODO(jgw): We'll need to fill in the library parameter when testing multiple units.
-    DartSourceTest src = new DartSourceTest(path, sourceCode, null);
-    DartCompilerListenerTest listener = new DartCompilerListenerTest(path, errors);
-    DartUnit unit = makeParser(src, sourceCode, listener).parseUnit();
-    listener.checkAllErrorsReported();
-    return unit;
-  }
-
-  /**
-   * Override this method to provide an alternate {@link DartParser}.
-   */
-  protected DartParser makeParser(Source src, String sourceCode,
-      DartCompilerListener listener) {
-    return new DartParser(src, sourceCode, false, Sets.<String>newHashSet(), listener, null);
-  }
-
-  /**
-   * @return the {@link DartParserRunner} with parsed source. It can be used to request
-   *         {@link DartUnit} or compilation problems.
-   */
-  protected final DartParserRunner parseSource(String code) {
-    return DartParserRunner.parse(getName(), code, Integer.MAX_VALUE, false);
-  }
-
-  /**
-   * Parses given source and checks parsing problems.
-   */
-  protected final DartParserRunner parseExpectErrors(String code,
-      ErrorExpectation... expectedErrors) {
-    DartParserRunner parserRunner = parseSource(code);
-    List<DartCompilationError> errors = parserRunner.getErrors();
-    assertErrors(errors, expectedErrors);
-    return parserRunner;
-  }
-
-  /**
-   * Parses given source and checks parsing problems.
-   */
-  protected final void parseExpectWarnings(String code, ErrorExpectation... expectedWarnings) {
-    DartParserRunner runner =  DartParserRunner.parse(getName(), code, Integer.MAX_VALUE, true);
-    List<DartCompilationError> errors = runner.getErrors();
-    assertErrors(errors, expectedWarnings);
-  }
-  
-  /**
-   * Find node in {@link #testUnit} parsed form {@link #testSource}.
-   */
-  public <T extends DartNode> T findNode(final Class<T> clazz, String pattern) {
-    final int index = testSource.indexOf(pattern);
-    assertTrue(index != -1);
-    final AtomicReference<T> result = new AtomicReference<T>();
-    testUnit.accept(new ASTVisitor<Void>() {
-      @Override
-      @SuppressWarnings("unchecked")
-      public Void visitNode(DartNode node) {
-        SourceInfo sourceInfo = node.getSourceInfo();
-        if (sourceInfo.getOffset() <= index
-            && index < sourceInfo.getEnd()
-            && clazz.isInstance(node)) {
-          result.set((T) node);
-        }
-        return super.visitNode(node);
-      }
-    });
-    return result.get();
-  }
-
-  /**
-   * @return the {@link DartExpression} with given {@link DartNode#toSource()}. This is inaccurate approach, but good
-   *         enough for specific tests.
-   */
-  @SuppressWarnings("unchecked")
-  protected static <T extends DartNode> T findNodeBySource(DartNode rootNode, final String sampleSource) {
-    final DartNode result[] = new DartNode[1];
-    rootNode.accept(new ASTVisitor<Void>() {
-      @Override
-      public Void visitNode(DartNode node) {
-        if (node.toSource().equals(sampleSource)) {
-          result[0] = node;
-        }
-        return super.visitNode(node);
-      }
-    });
-    return (T) result[0];
-  }
-
-  protected static DartFunctionTypeAlias findTypedef(DartNode rootNode, final String name) {
-    final DartFunctionTypeAlias result[] = new DartFunctionTypeAlias[1];
-    rootNode.accept(new ASTVisitor<Void>() {
-      @Override
-      public Void visitFunctionTypeAlias(DartFunctionTypeAlias node) {
-        if (node.getName().getName().equals(name)) {
-          result[0] = node;
-        }
-        return null;
-      }
-    });
-    return result[0];
-  }
-
-  public static String getNodeSource(String code, DartNode node) {
-    SourceInfo sourceInfo = node.getSourceInfo();
-    return code.substring(sourceInfo.getOffset(), sourceInfo.getEnd());
-  }
-
-  /**
-   * Asserts that parsed {@link DartUnit} has {@link DartExpression} with given source and its
-   * {@link SourceInfo} points to the given source.
-   */
-  protected void assertNodeSourceInfo(String nodeSource) {
-    DartNode node = findNode(DartNode.class, nodeSource);
-    assertNotNull(node);
-    SourceInfo sourceInfo = node.getSourceInfo();
-    String actualSource = testSource.substring(sourceInfo.getOffset(), sourceInfo.getEnd());
-    assertEquals(nodeSource, actualSource);
-  }
-
-  /**
-   * Asserts that {@link Element} with given name has expected type.
-   */
-  protected static void assertInferredElementTypeString(
-      DartUnit unit,
-      String variableName,
-      String expectedType,
-      TypeQuality quality) {
-    // find element
-    Element element = getNamedElement(unit, variableName);
-    assertNotNull(element);
-    // check type
-    Type actualType = element.getType();
-    assertInferredElementTypeString(actualType, element.getName(), expectedType, quality);
-  }
-
-  protected static void assertInferredElementTypeString(
-      Type actualType,
-      String testName,
-      String expectedType,
-      TypeQuality quality) {
-    assertEquals(testName, expectedType, getTypeSource(actualType));
-    if (quality != null) {
-      assertSame(quality, actualType.getQuality());
-    }
-  }
-
-  /**
-   * @return the source-like {@link String} for the given {@link Type}.
-   */
-  protected static String getTypeSource(Type actualType) {
-    return actualType.toString();
-  }
-
-  /**
-   * @return the {@link Element} with given name, may be <code>null</code>.
-   */
-  private static Element getNamedElement(DartUnit unit, final String name) {
-    final Element[] result = {null};
-    unit.accept(new ASTVisitor<Void>() {
-      @Override
-      public Void visitIdentifier(DartIdentifier node) {
-        Element element = node.getElement();
-        if (element != null && element.getName().equals(name)) {
-          result[0] = element;
-        }
-        return super.visitIdentifier(node);
-      }
-    });
-    return result[0];
-  }
-}
diff --git a/compiler/javatests/com/google/dart/compiler/CompilerTests.java b/compiler/javatests/com/google/dart/compiler/CompilerTests.java
deleted file mode 100644
index 02e2e96..0000000
--- a/compiler/javatests/com/google/dart/compiler/CompilerTests.java
+++ /dev/null
@@ -1,24 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler;
-
-import junit.extensions.TestSetup;
-import junit.framework.Test;
-import junit.framework.TestSuite;
-
-public class CompilerTests extends TestSetup {
-
-  public CompilerTests(Test test) {
-    super(test);
-  }
-
-  public static Test suite() {
-    TestSuite suite = new TestSuite("DartC compiler test suite.");
-    suite.addTestSuite(PackageLibraryManagerTest.class);
-    suite.addTestSuite(PrettyErrorFormatterTest.class);
-    suite.addTestSuite(SystemLibrariesReaderTest.class);
-    return suite;
-  }
-}
diff --git a/compiler/javatests/com/google/dart/compiler/DartCompilerListenerTest.java b/compiler/javatests/com/google/dart/compiler/DartCompilerListenerTest.java
deleted file mode 100644
index c6fbf39..0000000
--- a/compiler/javatests/com/google/dart/compiler/DartCompilerListenerTest.java
+++ /dev/null
@@ -1,94 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler;
-
-import com.google.dart.compiler.resolver.TypeErrorCode;
-
-/**
- * Testing implementation of {@link DartCompilerListener}.
- */
-public class DartCompilerListenerTest extends DartCompilerListener.Empty {
-
-  private final String srcName;
-  private String[] messages;
-  private ErrorCode[] errorCodes;
-  private int[] line;
-  private int[] column;
-  private int total;
-  private int current;
-
-  /**
-   * Creates a listener with expected errors (if any).
-   *
-   * @param srcName name of the source file
-   * @param errors a sequence of errors represented as triples of the form
-   *        (String msg, int line, int column) or
-   *        (ErrorCode code, int line, int column)
-   */
-  public DartCompilerListenerTest(String srcName, Object... errors) {
-    this.srcName = srcName;
-    CompilerTestCase.assertEquals(
-        "Invalid sequence of error expectations", 0, errors.length % 3);
-    this.total = errors.length / 3;
-    this.current = 0;
-    this.messages = new String[total];
-    this.errorCodes = new ErrorCode[total];
-    this.line = new int[total];
-    this.column = new int[total];
-    for (int i = 0; i < total; i++) {
-      Object stringOrErrorCode = errors[3 * i];
-      if (stringOrErrorCode instanceof ErrorCode) {
-        this.errorCodes[i] = (ErrorCode) stringOrErrorCode;
-      } else {
-        this.messages[i] = (String) stringOrErrorCode;
-      }
-      this.line[i] = (Integer) errors[(3 * i) + 1];
-      this.column[i] = (Integer) errors[(3 * i) + 2];
-    }
-  }
-
-  @Override
-  public void onError(DartCompilationError event) {
-    // ignore deprecated
-    if (event.getErrorCode() == TypeErrorCode.DEPRECATED_ELEMENT) {
-      return;
-    }
-    // validate
-    String reportedSrcName = (event.getSource() != null)
-        ? event.getSource().getName()
-        : null;
-    if (reportedSrcName == null) {
-      reportedSrcName = "<unknown>";
-    }
-    CompilerTestCase.assertTrue("More errors (" + (current + 1)
-        + ") than expected (" + total + "):\n" + event.getErrorCode().toString() + " : " + event,
-        current < total);
-
-    CompilerTestCase.assertEquals(srcName, reportedSrcName);
-
-    if (errorCodes[current] != null) {
-      CompilerTestCase.assertEquals(
-        "Wrong error code at " + event.getLineNumber() + ":" + event.getColumnNumber(),
-        errorCodes[current], event.getErrorCode());
-    } else {
-      CompilerTestCase.assertEquals(
-        "Wrong error message at " + event.getLineNumber() + ":" + event.getColumnNumber(),
-        messages[current], event.getMessage());
-    }
-    CompilerTestCase.assertEquals(
-        "Wrong line number at " + event.getLineNumber() + ":" + event.getColumnNumber(),
-        line[current], event.getLineNumber());
-    CompilerTestCase.assertEquals(
-        "Wrong column number at " + event.getLineNumber() + ":" + event.getColumnNumber(),
-        column[current], event.getColumnNumber());
-    current++;
-  }
-
-  /** Checks that all expected errors were reported. */
-  public void checkAllErrorsReported() {
-    CompilerTestCase.assertEquals("Not all expected errors were reported",
-        total, current);
-  }
-}
diff --git a/compiler/javatests/com/google/dart/compiler/DartLibrarySourceTest.java b/compiler/javatests/com/google/dart/compiler/DartLibrarySourceTest.java
deleted file mode 100644
index c430741..0000000
--- a/compiler/javatests/com/google/dart/compiler/DartLibrarySourceTest.java
+++ /dev/null
@@ -1,38 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler;
-
-import java.io.IOException;
-import java.io.Reader;
-import java.io.StringReader;
-import java.net.URL;
-
-public class DartLibrarySourceTest extends SourceTest implements LibrarySource {
-  private final String src;
-  private final Class<?> base;
-
-  public DartLibrarySourceTest(Class<?> base, String path) {
-    super(path);
-
-    this.base = base;
-    URL url = CompilerTestCase.inputUrlFor(base, path);
-    src = CompilerTestCase.readUrl(url);
-  }
-
-  @Override
-  public Reader getSourceReader() throws IOException {
-    return new StringReader(src);
-  }
-
-  @Override
-  public LibrarySource getImportFor(String relPath) throws IOException {
-    return null;
-  }
-
-  @Override
-  public DartSource getSourceFor(String relPath) {
-    return new DartSourceTest(base, relPath, this);
-  }
-}
diff --git a/compiler/javatests/com/google/dart/compiler/DartSourceTest.java b/compiler/javatests/com/google/dart/compiler/DartSourceTest.java
deleted file mode 100644
index bbb27fd..0000000
--- a/compiler/javatests/com/google/dart/compiler/DartSourceTest.java
+++ /dev/null
@@ -1,52 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler;
-
-import java.io.Reader;
-import java.io.StringReader;
-import java.net.URL;
-
-public class DartSourceTest extends SourceTest implements DartSource {
-  private final String path;
-  private final String src;
-  private final LibrarySource lib;
-
-  public DartSourceTest(Class<?> base, String path, LibrarySource lib) {
-    super(path);
-
-    this.path = path;
-    this.lib = lib;
-    URL url = CompilerTestCase.inputUrlFor(base, path);
-    src = CompilerTestCase.readUrl(url);
-  }
-
-  public DartSourceTest(String path, String source, LibrarySource lib) {
-    super(path + ".dart");
-
-    this.path = path;
-    this.src = source;
-    this.lib = lib;
-  }
-
-  @Override
-  public LibrarySource getLibrary() {
-    return lib;
-  }
-
-  @Override
-  public String getName() {
-    return path;
-  }
-
-  @Override
-  public Reader getSourceReader() {
-    return new StringReader(src);
-  }
-
-  @Override
-  public String getRelativePath() {
-    return path;
-  }
-}
diff --git a/compiler/javatests/com/google/dart/compiler/DeltaAnalyzerTest.java b/compiler/javatests/com/google/dart/compiler/DeltaAnalyzerTest.java
deleted file mode 100644
index e4deb24..0000000
--- a/compiler/javatests/com/google/dart/compiler/DeltaAnalyzerTest.java
+++ /dev/null
@@ -1,139 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler;
-
-import com.google.common.base.Joiner;
-import com.google.dart.compiler.ast.DartUnit;
-import com.google.dart.compiler.ast.LibraryUnit;
-import com.google.dart.compiler.end2end.inc.MemoryLibrarySource;
-import com.google.dart.compiler.resolver.ClassElement;
-import com.google.dart.compiler.resolver.Element;
-import com.google.dart.compiler.resolver.LibraryElement;
-import com.google.dart.compiler.resolver.MethodElement;
-import com.google.dart.compiler.testing.TestCompilerConfiguration;
-import com.google.dart.compiler.testing.TestCompilerContext;
-import com.google.dart.compiler.testing.TestDartArtifactProvider;
-import com.google.dart.compiler.util.DartSourceString;
-
-import junit.framework.TestCase;
-
-import java.io.IOException;
-
-public class DeltaAnalyzerTest extends TestCase {
-  private final TestCompilerConfiguration config = new TestCompilerConfiguration();
-  private final DartCompilerListener listener = new TestCompilerContext();
-  private final DartArtifactProvider provider = new TestDartArtifactProvider();
-
-  public void testNoChangeSingleFile() throws IOException {
-    MemoryLibrarySource librarySource = new MemoryLibrarySource("App.dart");
-    librarySource.setContent("App.dart", "library App; part 'before.dart';");
-    librarySource.setContent("before.dart",
-        Joiner.on("\n").join(new String[] {
-                            "part of App;",
-                            "class Foo {}",
-                            "m() {}"}));
-    DartUnit change = analyzeNoChange(librarySource);
-    assertEquals(2, change.getTopLevelNodes().size());
-    ClassElement cls = (ClassElement) change.getTopLevelNodes().get(0).getElement();
-    assertNotNull(cls);
-    assertEquals("Foo", cls.getName());
-    Element element = change.getLibrary().getElement().lookupLocalElement("Foo");
-    assertEquals(cls, element);
-    MethodElement method = (MethodElement) change.getTopLevelNodes().get(1).getElement();
-    assertNotNull(method);
-    assertEquals("m", method.getName());
-    element = change.getLibrary().getElement().lookupLocalElement("m");
-    assertSame(method, element);
-  }
-
-  public void testNoChangeTwoFiles() throws IOException {
-    MemoryLibrarySource librarySource = new MemoryLibrarySource("App.dart");
-    librarySource.setContent("App.dart", "library App; part 'before.dart'; part 'common.dart';");
-    librarySource.setContent("before.dart",
-        Joiner.on("\n").join(new String[] {
-                            "part of App;",
-                            "class Foo extends Bar {}",
-                            "m() {}"}));
-    librarySource.setContent("common.dart",
-        Joiner.on("\n").join(new String[] {
-                            "part of App;",
-                            "class Bar {}"}));
-    DartUnit change = analyzeNoChange(librarySource);
-    assertEquals(2, change.getTopLevelNodes().size());
-    ClassElement cls = (ClassElement) change.getTopLevelNodes().get(0).getElement();
-    assertNotNull(cls);
-    assertEquals("Foo", cls.getName());
-    assertNotNull(change.getLibrary().getElement().lookupLocalElement("Foo"));
-    assertEquals("Bar", cls.getSupertype().toString());
-    assertNotNull(change.getLibrary().getElement().lookupLocalElement("Bar"));
-    MethodElement method = (MethodElement) change.getTopLevelNodes().get(1).getElement();
-    assertNotNull(method);
-    assertEquals("m", method.getName());
-    Element element = change.getLibrary().getElement().lookupLocalElement("m");
-    assertSame(method, element);
-  }
-
-  public void testChangeSingleFile() throws IOException {
-    MemoryLibrarySource librarySource = new MemoryLibrarySource("App.dart");
-    librarySource.setContent("App.dart", "library App;");
-    librarySource.setContent(
-        "before.dart",
-        Joiner.on("\n").join(new String[] {"part of App;", "class Foo {}", "m() {}"}));
-    DartSource sourceBefore = librarySource.getSourceFor("before.dart");
-    DartSource sourceAfter = new DartSourceString("after.dart", Joiner.on("\n").join(
-        new String[] {"part of App;", "class Foo {}", ""}));
-    DartUnit change = analyze(librarySource, sourceBefore, sourceAfter);
-    assertEquals(1, change.getTopLevelNodes().size());
-    Element element = change.getLibrary().getElement().lookupLocalElement("m");
-    assertNull(element);
-    element = change.getLibrary().getElement().lookupLocalElement("Foo");
-    assertNotNull(element);
-    ClassElement cls = (ClassElement) change.getTopLevelNodes().get(0).getElement();
-    assertEquals("Foo", cls.getName());
-    assertSame(cls, element);
-  }
-
-  public void testChangeTwoFiles() throws IOException {
-    MemoryLibrarySource librarySource = new MemoryLibrarySource("App.dart");
-    librarySource.setContent("App.dart", "library App; part 'before.dart'; part 'common.dart';");
-    librarySource.setContent("before.dart",
-        Joiner.on("\n").join(new String[] {
-                            "part of App;",
-                            "class Foo extends Bar {}",
-                            "m() {}"}));
-    librarySource.setContent("common.dart",
-        Joiner.on("\n").join(new String[] {
-                            "part of App;",
-                            "class Bar {}"}));
-    DartSource sourceBefore = librarySource.getSourceFor("before.dart");
-    DartSource sourceAfter = new DartSourceString("after.dart", "part of App; class Foo extends Bar {}");
-    DartUnit change = analyze(librarySource, sourceBefore, sourceAfter);
-    assertEquals(1, change.getTopLevelNodes().size());
-    assertNull(change.getLibrary().getElement().lookupLocalElement("m"));
-    ClassElement cls = (ClassElement) change.getTopLevelNodes().get(0).getElement();
-    assertNotNull(cls);
-    assertEquals("Foo", cls.getName());
-    assertEquals("Bar", cls.getSupertype().toString());
-    Element element = change.getLibrary().getElement().lookupLocalElement("Foo");
-    assertSame(cls, element);
-  }
-
-  private DartUnit analyzeNoChange(LibrarySource librarySource) throws IOException {
-    DartSource sourceBefore = librarySource.getSourceFor("before.dart");
-    DartSource sourceAfter = sourceBefore;
-    return analyze(librarySource, sourceBefore, sourceAfter);
-  }
-
-  private DartUnit analyze(LibrarySource librarySource, DartSource sourceBefore,
-                           DartSource sourceAfter) throws IOException {
-    LibraryUnit libraryUnit = DartCompiler.analyzeLibrary(librarySource, null,
-                                                          config, provider, listener);
-    LibraryElement enclosingLibrary = libraryUnit.getElement();
-    LibraryElement coreLibrary = libraryUnit.getImportedLibraries().iterator().next().getElement();
-    return (DartUnit) DartCompiler.analyzeDelta(SourceDelta.before(sourceBefore).after(sourceAfter),
-                                                enclosingLibrary, coreLibrary,
-                                                null, -1, -1, config, listener);
-  }
-}
diff --git a/compiler/javatests/com/google/dart/compiler/DeltaBench.java b/compiler/javatests/com/google/dart/compiler/DeltaBench.java
deleted file mode 100644
index 2c46f4e..0000000
--- a/compiler/javatests/com/google/dart/compiler/DeltaBench.java
+++ /dev/null
@@ -1,71 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler;
-
-import com.google.dart.compiler.ast.DartUnit;
-import com.google.dart.compiler.ast.LibraryUnit;
-import com.google.dart.compiler.resolver.LibraryElement;
-import com.google.dart.compiler.testing.TestCompilerConfiguration;
-import com.google.dart.compiler.testing.TestCompilerContext;
-
-import java.io.File;
-import java.io.IOException;
-import java.util.HashSet;
-
-public class DeltaBench {
-  public static void main(String[] args) throws IOException {
-    File trunkDir = new File(args[0]);
-    File libraryFile = new File(trunkDir, args[1]);
-    File outputDirectory = new File(trunkDir, args[2]);
-    for (int i = 0; i < 100; i++) {
-      analyze(libraryFile, outputDirectory, null);
-      for (int j = 3; j < args.length; j++) {
-        analyze(libraryFile, outputDirectory, args[j]);
-      }
-    }
-  }
-
-  private static void analyze(File libraryFile, File outputDirectory, String interestingFile)
-      throws IOException {
-    final boolean incremental = interestingFile == null;
-    long start = System.currentTimeMillis();
-    LibrarySource librarySource = new UrlLibrarySource(libraryFile);
-    CompilerConfiguration config = new TestCompilerConfiguration() {
-      @Override
-      public boolean incremental() {
-        return incremental;
-      }
-    };
-    DartCompilerListener listener = new TestCompilerContext();
-    DartArtifactProvider provider = new DefaultDartArtifactProvider(outputDirectory);
-    LibraryUnit libraryUnit = DartCompiler.analyzeLibrary(librarySource, null, config, provider,
-                                                          listener);
-    System.err.println("analyzeLibrary" + (incremental ? "+incremental" : "") +
-                       "(" + libraryUnit.getName() + ") took " +
-                       (System.currentTimeMillis() - start) + "ms");
-    if (incremental) {
-      return;
-    }
-    LibraryUnit enclosingLibraryUnit = DartCompiler.findLibrary(libraryUnit, interestingFile,
-                                                   new HashSet<LibraryElement>());
-    LibraryUnit coreLibraryUnit = DartCompiler.findLibrary(libraryUnit, "object.dart",
-                                              new HashSet<LibraryElement>());
-    DartUnit unit = null;
-    for (DartUnit current : enclosingLibraryUnit.getUnits()) {
-      if (current.getSourceInfo().getSource().getName().endsWith(interestingFile)) {
-        unit = current;
-        break;
-      }
-    }
-    start = System.currentTimeMillis();
-    DartSource unitSource = (DartSource) unit.getSourceInfo().getSource();
-    DartCompiler.analyzeDelta(SourceDelta.before(unitSource),
-                              enclosingLibraryUnit.getElement(),
-                              coreLibraryUnit.getElement(),
-                              null, -1, -1, config, listener);
-    System.err.println("analyzeDelta(" + unitSource.getName() + ") took " +
-        (System.currentTimeMillis() - start) + "ms");
-  }
-}
diff --git a/compiler/javatests/com/google/dart/compiler/MockArtifactProvider.java b/compiler/javatests/com/google/dart/compiler/MockArtifactProvider.java
deleted file mode 100644
index bb2d534..0000000
--- a/compiler/javatests/com/google/dart/compiler/MockArtifactProvider.java
+++ /dev/null
@@ -1,91 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler;
-
-import java.io.Reader;
-import java.io.StringReader;
-import java.io.StringWriter;
-import java.io.Writer;
-import java.net.URI;
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
-
-/**
- * Testing implementation of {@link DartArtifactProvider}.
- */
-public class MockArtifactProvider extends DartArtifactProvider {
-
-  private static class Artifact {
-    StringWriter writer = new StringWriter();
-    long lastModified;
-  }
-
-  private final Map<String, Artifact> artifacts = new ConcurrentHashMap<String, Artifact>();
-
-  public MockArtifactProvider() {
-  }
-
-  @Override
-  public Reader getArtifactReader(Source source, String part, String ext) {
-    Artifact artifact = artifacts.get(keyFor(source, part, ext));
-    if (artifact == null) {
-      return null;
-    }
-    return new StringReader(artifact.writer.toString());
-  }
-
-  @Override
-  public URI getArtifactUri(Source source, String part, String ext) {
-    return URI.create("file:" + keyFor(source, part, ext));
-  }
-
-  @Override
-  public Writer getArtifactWriter(Source source, String part, String ext) {
-    Artifact artifact = new Artifact();
-    artifacts.put(keyFor(source, part, ext), artifact);
-    artifact.lastModified = System.currentTimeMillis();
-    return artifact.writer;
-  }
-
-  @Override
-  public boolean isOutOfDate(Source source, Source base, String ext) {
-    Artifact artifact = artifacts.get(keyFor(base, "", ext));
-    if (artifact == null) {
-      return true;
-    }
-
-    return source.getLastModified() > artifact.lastModified;
-  }
-
-  /**
-   * Quick way to get an artifact without going through the reader.
-   */
-  public String getArtifactString(Source source, String part, String ext) {
-    Artifact artifact = artifacts.get(keyFor(source, part, ext));
-    if (artifact == null) {
-      return null;
-    }
-
-    return artifact.writer.toString();
-  }
-
-  /**
-   * Removes the given artifact, by name.
-   */
-  public void removeArtifact(String name, String part, String ext) {
-    artifacts.remove(keyFor(name, part, ext));
-  }
-
-  private String keyFor(Source source, String part, String ext) {
-    return keyFor(source.getName(), part, ext);
-  }
-
-  private String keyFor(String sourceName, String part, String ext) {
-    if (!part.isEmpty()) {
-      part = "$" + part;
-    }
-    return sourceName + part + "/" + ext;
-  }
-}
diff --git a/compiler/javatests/com/google/dart/compiler/MockBundleLibrarySource.java b/compiler/javatests/com/google/dart/compiler/MockBundleLibrarySource.java
deleted file mode 100644
index fbf66f1..0000000
--- a/compiler/javatests/com/google/dart/compiler/MockBundleLibrarySource.java
+++ /dev/null
@@ -1,187 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler;
-
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.Reader;
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.net.URL;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-
-/**
- * A mock application source that uses resources bundled in the classpath, along with methods for
- * remapping sources and modifying their timestamps.
- */
-public class MockBundleLibrarySource extends UrlLibrarySource implements LibrarySource {
-
-  private class NonexistentDartSource implements DartSource {
-    private final String relPath;
-
-    public NonexistentDartSource(String relPath) {
-      this.relPath = relPath;
-    }
-
-    @Override
-    public boolean exists() {
-      return false;
-    }
-
-    @Override
-    public long getLastModified() {
-      return 0;
-    }
-
-    @Override
-    public String getName() {
-      return relPath;
-    }
-
-    @Override
-    public Reader getSourceReader() throws IOException {
-      throw new FileNotFoundException();
-    }
-
-    @Override
-    public String getUniqueIdentifier() {
-      return relPath;
-    }
-
-    @Override
-    public URI getUri() {
-      try {
-        return new URI(relPath);
-      } catch (URISyntaxException e) {
-        throw new AssertionError(e.getMessage());
-      }
-    }
-
-    @Override
-    public LibrarySource getLibrary() {
-      return MockBundleLibrarySource.this;
-    }
-
-    @Override
-    public String getRelativePath() {
-      return relPath;
-    }
-  }
-
-  private final String basePath;
-  private final ClassLoader loader;
-  private final String libName;
-
-  private final Map<String, MockBundleLibrarySource> imports =
-      new HashMap<String, MockBundleLibrarySource>();
-
-  /**
-   * Source remappings. Each key identifies the name of a source file that will be remapped to an
-   * alternate source file in {@link #getSourceFor(String)}.
-   */
-  private final Map<String, String> sourceRemapping = new HashMap<String, String>();
-  private final Set<String> sourceTimestamps = new HashSet<String>();
-
-  public MockBundleLibrarySource(ClassLoader loader, String basePath, String libName)
-      throws URISyntaxException {
-    this(loader, basePath, libName, libName);
-  }
-
-  public MockBundleLibrarySource(ClassLoader loader, String basePath, String libName,
-      String altName) throws URISyntaxException {
-    super(loader.getResource(basePath + libName).toURI());
-    this.loader = loader;
-    this.basePath = basePath;
-    this.libName = altName;
-  }
-
-  @Override
-  public MockBundleLibrarySource getImportFor(String relPath) {
-    MockBundleLibrarySource libSrc = imports.get(relPath);
-    if (libSrc == null) {
-      try {
-        libSrc = new MockBundleLibrarySource(loader, basePath, relPath);
-      } catch (URISyntaxException e) {
-        throw new AssertionError();
-      }
-      imports.put(relPath, libSrc);
-    }
-    return libSrc;
-  }
-
-  @Override
-  public DartSource getSourceFor(final String relPath) {
-    String remap = sourceRemapping.get(relPath);
-    final boolean touched = sourceTimestamps.contains(relPath);
-
-    String fullPath = basePath + ((remap != null) ? remap : relPath);
-    URI uri;
-    try {
-      URL url = loader.getResource(fullPath);
-      if (url == null) {
-        return new NonexistentDartSource(relPath);
-      }
-
-      uri = url.toURI();
-    } catch (URISyntaxException e) {
-      throw new AssertionError();
-    }
-
-    return new UrlDartSource(uri, relPath, this) {
-      @Override
-      public long getLastModified() {
-        if (touched) {
-          return new Date().getTime();
-        }
-        return super.getLastModified();
-      }
-
-      @Override
-      public String getName() {
-        return relPath;
-      }
-    };
-  }
-
-  @Override
-  public String getName() {
-    return libName;
-  }
-
-  /**
-   * Remaps the given source to an alternate. This allows testing of changes to source contents.
-   * Note that you'll still need to call {@link #touchSource(String)} to cause it to be recompiled.
-   */
-  public void remapSource(String relPath, String remappedRelPath) {
-    sourceRemapping.put(relPath, remappedRelPath);
-    touchSource(relPath);
-  }
-
-  /**
-   * Removes the given source. Any attempt to read it will result in an NPE.
-   */
-  public void removeSource(String relPath) {
-    sourceRemapping.put(relPath, "does/not/exist");
-  }
-
-  /**
-   * Touches the given source file, forcing a recompile.
-   */
-  public void touchSource(String relPath) {
-    sourceTimestamps.add(relPath);
-  }
-
-  /**
-   * Clears all remappings and source timestamps.
-   */
-  public void resetRemappings() {
-    sourceRemapping.clear();
-    sourceTimestamps.clear();
-  }
-}
diff --git a/compiler/javatests/com/google/dart/compiler/MockLibrarySource.java b/compiler/javatests/com/google/dart/compiler/MockLibrarySource.java
deleted file mode 100644
index 7c06ffb..0000000
--- a/compiler/javatests/com/google/dart/compiler/MockLibrarySource.java
+++ /dev/null
@@ -1,91 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler;
-
-import java.io.Reader;
-import java.io.StringReader;
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Testing implementation of {@link LibrarySource}.
- */
-public class MockLibrarySource extends SourceTest implements LibrarySource {
-
-  private final static String TEST_APP_NAME = "Test_app";
-
-  private final List<LibrarySource> imports = new ArrayList<LibrarySource>();
-  private final List<DartSource> sources = new ArrayList<DartSource>();
-
-  public MockLibrarySource() {
-    super(TEST_APP_NAME);
-  }
-
-  @Override
-  public Reader getSourceReader() {
-    ArrayList<String> libNames = new ArrayList<String>();
-    for (LibrarySource lib : imports) {
-      libNames.add(lib.getName());
-    }
-    ArrayList<String> sourceNames = new ArrayList<String>();
-    for (DartSource source : sources) {
-      sourceNames.add(source.getName());
-    }
-    // Passing null for the entryPoint, assuming the source already contains a
-    // toplevel main() or is a library that doesn't require an entryPoint.
-    return new StringReader(DefaultLibrarySource.generateSource(
-        getName(), libNames, sourceNames, null));
-  }
-
-  @Override
-  public LibrarySource getImportFor(String relPath) {
-    for (LibrarySource lib : imports) {
-      if (lib.getName().equals(relPath)) {
-        return lib;
-      }
-    }
-    return null;
-  }
-
-  @Override
-  public DartSource getSourceFor(String relPath) {
-    if (relPath.equals(TEST_APP_NAME)) {
-      return new MockDartSource(this);
-    }
-    for (DartSource source : sources) {
-      if (source.getName().equals(relPath)) {
-        return source;
-      }
-    }
-    return null;
-  }
-
-  public void addSource(DartSource src) {
-    sources.add(src);
-  }
-
-  private static class MockDartSource extends SourceTest implements DartSource {
-    final MockLibrarySource libSource;
-    public MockDartSource(MockLibrarySource libSource) {
-      super(libSource.getName());
-      this.libSource = libSource;
-    }
-
-    @Override
-    public Reader getSourceReader() {
-      return libSource.getSourceReader();
-    }
-
-    @Override
-    public LibrarySource getLibrary() {
-      return libSource;
-    }
-
-    @Override
-    public String getRelativePath() {
-      return libSource.getUri().toString();
-    }
-  }
-}
diff --git a/compiler/javatests/com/google/dart/compiler/PackageLibraryManagerTest.java b/compiler/javatests/com/google/dart/compiler/PackageLibraryManagerTest.java
deleted file mode 100644
index f455ee5..0000000
--- a/compiler/javatests/com/google/dart/compiler/PackageLibraryManagerTest.java
+++ /dev/null
@@ -1,89 +0,0 @@
-// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-package com.google.dart.compiler;
-
-import junit.framework.TestCase;
-
-import java.net.URI;
-
-public class PackageLibraryManagerTest extends TestCase {
-  /**
-   * For FS based {@link URI} the path is not <code>null</code>, for JAR {@link URI} the scheme
-   * specific part is not <code>null</code>.
-   * 
-   * @return the scheme specific path.
-   */
-  private static String getPath(URI uri) {
-    if (uri.getPath() != null && uri.getPath().length() != 0){
-      return uri.getPath();
-    }
-    return uri.getSchemeSpecificPart();
-  }
-
-  PackageLibraryManager packageLibraryManager = new PackageLibraryManager();
- 
-
-  public void testExpand1() throws Exception {
-    URI shortUri = new URI("dart:core");
-    URI fullUri = packageLibraryManager.expandRelativeDartUri(shortUri);
-    assertNotNull(fullUri);
-    assertEquals("dart", fullUri.getScheme());
-    assertEquals("core", fullUri.getHost());
-    assertTrue(getPath(fullUri).endsWith("/core.dart"));
-  }
-
-  public void testExpand2() throws Exception {
-    URI shortUri = new URI("dart:doesnotexist");
-    URI fullUri = packageLibraryManager.expandRelativeDartUri(shortUri);
-    assertNull(fullUri);
-  }
-
-  public void testTranslate1() throws Exception {
-    URI shortUri = new URI("dart:core");
-    URI fullUri = packageLibraryManager.expandRelativeDartUri(shortUri);
-    URI translatedURI = packageLibraryManager.resolveDartUri(fullUri);
-    assertNotNull(translatedURI);
-    String scheme = translatedURI.getScheme();
-    assertTrue(scheme.equals("file"));
-    assertTrue(getPath(translatedURI).endsWith("/core.dart"));
-  }
-
-  public void testTranslate2() throws Exception {
-    URI fullUri = new URI("dart://doesnotexist/some/file.dart");
-    URI translatedURI = packageLibraryManager.resolveDartUri(fullUri);
-    assertNotNull(translatedURI);
-    String scheme = translatedURI.getScheme();
-    assertTrue(scheme.equals("file"));
-    assertTrue(getPath(translatedURI).endsWith("some/file.dart"));
-  }
-  
-  public void testPackageExpand1() throws Exception {
-    URI shortUri = new URI("package:test.dart");
-    URI fullUri = packageLibraryManager.expandRelativeDartUri(shortUri);
-    assertNotNull(fullUri);
-    assertEquals("package", fullUri.getScheme());
-    assertEquals("test.dart", fullUri.getHost());
-    assertTrue(getPath(fullUri).endsWith("/test.dart"));
-  }
-
-  public void testPackageExpand2() throws Exception {
-    URI shortUri = new URI("package:test.dart");
-    URI fullUri1 = packageLibraryManager.expandRelativeDartUri(shortUri);
-    URI fullUri2 = packageLibraryManager.expandRelativeDartUri(fullUri1);
-    assertNotNull(fullUri2);
-    assertEquals("package", fullUri2.getScheme());
-    assertEquals("test.dart", fullUri2.getHost());
-    assertTrue(getPath(fullUri2).endsWith("/test.dart"));
-  }
-
-  public void testPackageTranslate1() throws Exception {
-    URI shortUri = new URI("package:test.dart");
-    URI fullUri = packageLibraryManager.expandRelativeDartUri(shortUri);
-    URI translatedURI = packageLibraryManager.resolveDartUri(fullUri);
-    assertNotNull(translatedURI);
-    String scheme = translatedURI.getScheme();
-    assertTrue(scheme.equals("file"));
-    assertTrue(getPath(translatedURI).endsWith("/test.dart"));
-  }
-}
diff --git a/compiler/javatests/com/google/dart/compiler/PrettyErrorFormatterTest.java b/compiler/javatests/com/google/dart/compiler/PrettyErrorFormatterTest.java
deleted file mode 100644
index 94839a9..0000000
--- a/compiler/javatests/com/google/dart/compiler/PrettyErrorFormatterTest.java
+++ /dev/null
@@ -1,279 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-package com.google.dart.compiler;
-
-import com.google.common.base.Joiner;
-import com.google.dart.compiler.CompilerConfiguration.ErrorFormat;
-import com.google.dart.compiler.parser.DartScanner.Location;
-import com.google.dart.compiler.resolver.ResolverErrorCode;
-import com.google.dart.compiler.resolver.TypeErrorCode;
-
-import junit.framework.TestCase;
-
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.PrintStream;
-import java.io.Reader;
-
-/**
- * Test for {@link PrettyErrorFormatter}.
- */
-public class PrettyErrorFormatterTest extends TestCase {
-  private static final String ERROR_BOLD_COLOR = PrettyErrorFormatter.ERROR_BOLD_COLOR;
-  private static final String ERROR_COLOR = PrettyErrorFormatter.ERROR_COLOR;
-  private static final String WARNING_BOLD_COLOR = PrettyErrorFormatter.WARNING_BOLD_COLOR;
-  private static final String WARNING_COLOR = PrettyErrorFormatter.WARNING_COLOR;
-  private static final String NO_COLOR = PrettyErrorFormatter.NO_COLOR;
-
-  private static final Source SOURCE = new DartSourceTest("my/path/Test.dart",
-      Joiner.on("\n").join("lineAAA", "lineBBB", "lineCCC"),
-      new MockLibrarySource());
-
-  /**
-   * Not a {@link DartSource}, rollback to {@link DefaultErrorFormatter}.
-   */
-  public void test_notDartSource() throws Exception {
-    Source emptyDartSource = new SourceTest("Test.dart") {
-      @Override
-      public Reader getSourceReader() {
-        return null;
-      }
-    };
-    Location location = new Location(2);
-    DartCompilationError error =
-        new DartCompilationError(emptyDartSource, location, TypeErrorCode.NO_SUCH_TYPE, "Foo");
-    //
-    String errorString = getErrorString(error, false, false);
-    assertEquals("Test.dart:1:3: no such type \"Foo\"\n", errorString);
-  }
-
-  /**
-   * Use {@link DartSource} with source {@link Reader} which throws {@link IOException}, rollback to
-   * {@link DefaultErrorFormatter}.
-   */
-  public void test_throwsIOException() throws Exception {
-    Source badDartSource = new DartSourceTest("my/path/Test.dart", "", new MockLibrarySource()) {
-      @Override
-      public Reader getSourceReader() {
-        return new Reader() {
-          @Override
-          public int read(char[] cbuf, int off, int len) throws IOException {
-            throw new IOException("boo!");
-          }
-
-          @Override
-          public void close() {
-          }
-        };
-      }
-    };
-    Location location = new Location(2);
-    DartCompilationError error =
-        new DartCompilationError(badDartSource, location, TypeErrorCode.NO_SUCH_TYPE, "Foo");
-    //
-    String errorString = getErrorString(error, false, false);
-    assertEquals(
-        "my/path/Test.dart:1:3: no such type \"Foo\" (sourced from Test_app)\n",
-        errorString);
-  }
-
-  /**
-   * Empty {@link DartSource}, rollback to {@link DefaultErrorFormatter}.
-   */
-  public void test_emptyDartSource() throws Exception {
-    Source emptyDartSource = new DartSourceTest("my/path/Test.dart", "", new MockLibrarySource());
-    Location location = new Location(2);
-    DartCompilationError error =
-        new DartCompilationError(emptyDartSource, location, TypeErrorCode.NO_SUCH_TYPE, "Foo");
-    //
-    String errorString = getErrorString(error, false, false);
-    assertEquals(
-        "my/path/Test.dart:1:3: no such type \"Foo\" (sourced from Test_app)\n",
-        errorString);
-  }
-
-  /**
-   * Error on first line, so no previous line printed.
-   */
-  public void test_noColor_notMachine_firstLine() throws Exception {
-    Location location = new Location(2, 5);
-    DartCompilationError error =
-        new DartCompilationError(SOURCE, location, TypeErrorCode.NO_SUCH_TYPE, "Foo");
-    //
-    String errorString = getErrorString(error, false, false);
-    assertEquals(
-        Joiner.on("\n").join(
-            "my/path/Test.dart:1:3: no such type \"Foo\" (sourced from Test_app)",
-            "     1: lineAAA",
-            "          ~~~",
-            ""),
-        errorString);
-  }
-
-  /**
-   * {@link Location} with single <code>Position</code>, underline single character.
-   */
-  public void test_noColor_notMachine_singlePosition() throws Exception {
-    Location location = new Location(10);
-    DartCompilationError error =
-        new DartCompilationError(SOURCE, location, TypeErrorCode.NO_SUCH_TYPE, "Foo");
-    //
-    String errorString = getErrorString(error, false, false);
-    assertEquals(
-        Joiner.on("\n").join(
-            "my/path/Test.dart:2:3: no such type \"Foo\" (sourced from Test_app)",
-            "     1: lineAAA",
-            "     2: lineBBB",
-            "          ~~~~~",
-            ""),
-        errorString);
-  }
-
-  /**
-   * {@link Location} with single <code>Position</code>, underline single character.
-   */
-  public void test_withColor_notMachine_singlePosition() throws Exception {
-    Location location = new Location(10);
-    DartCompilationError error =
-        new DartCompilationError(SOURCE, location, TypeErrorCode.NO_SUCH_TYPE, "Foo");
-    String errorString = getErrorString(error, true, false);
-    assertEquals(
-        Joiner.on("\n").join(
-            WARNING_BOLD_COLOR
-                + "my/path/Test.dart:2:3: no such type \"Foo\" (sourced from Test_app)"
-                + NO_COLOR,
-            "     1: lineAAA",
-            "     2: li" + WARNING_COLOR + "neBBB" + NO_COLOR,
-            ""),
-        errorString);
-
-    error = new DartCompilationError(SOURCE, location, ResolverErrorCode.NO_SUCH_TYPE, "Foo");
-    errorString = getErrorString(error, true, false);
-    assertEquals(
-        Joiner.on("\n").join(
-            ERROR_BOLD_COLOR
-                + "my/path/Test.dart:2:3: no such type \"Foo\" (sourced from Test_app)"
-                + NO_COLOR,
-            "     1: lineAAA",
-            "     2: li" + ERROR_COLOR + "neBBB" + NO_COLOR,
-            ""),
-        errorString);
-  }
-
-  /**
-   * Underline range of characters.
-   */
-  public void test_noColor_notMachine() throws Exception {
-    Location location = new Location(10, 10 + 3);
-    DartCompilationError error =
-        new DartCompilationError(SOURCE, location, TypeErrorCode.NO_SUCH_TYPE, "Foo");
-    //
-    String errorString = getErrorString(error, false, false);
-    assertEquals(
-        Joiner.on("\n").join(
-            "my/path/Test.dart:2:3: no such type \"Foo\" (sourced from Test_app)",
-            "     1: lineAAA",
-            "     2: lineBBB",
-            "          ~~~",
-            ""),
-        errorString);
-  }
-
-  /**
-   * Use color to highlight range of characters.
-   */
-  public void test_withColor_notMachine() throws Exception {
-    Location location = new Location(10, 10 + 3);
-    DartCompilationError error =
-        new DartCompilationError(SOURCE, location, TypeErrorCode.NO_SUCH_TYPE, "Foo");
-    String errorString = getErrorString(error, true, false);
-    assertEquals(
-        Joiner.on("\n").join(
-            WARNING_BOLD_COLOR
-                + "my/path/Test.dart:2:3: no such type \"Foo\" (sourced from Test_app)"
-                + NO_COLOR,
-            "     1: lineAAA",
-            "     2: li" + WARNING_COLOR + "neB" + NO_COLOR + "BB",
-            ""),
-        errorString);
-
-    error = new DartCompilationError(SOURCE, location, ResolverErrorCode.NO_SUCH_TYPE, "Foo");
-    errorString = getErrorString(error, true, false);
-    assertEquals(
-        Joiner.on("\n").join(
-            ERROR_BOLD_COLOR
-                + "my/path/Test.dart:2:3: no such type \"Foo\" (sourced from Test_app)"
-                + NO_COLOR,
-            "     1: lineAAA",
-            "     2: li" + ERROR_COLOR + "neB" + NO_COLOR + "BB",
-            ""),
-        errorString);
-  }
-
-  /**
-   * Include all information about error context.
-   */
-  public void test_noColor_forMachine() throws Exception {
-    Location location = new Location(10, 10 + 4);
-    DartCompilationError error =
-        new DartCompilationError(SOURCE, location, TypeErrorCode.NO_SUCH_TYPE, "Foo");
-    //
-    String errorString = getErrorString(error, false, true);
-    assertEquals(
-        Joiner.on("\n").join(
-            "WARNING|STATIC_TYPE|NO_SUCH_TYPE|my/path/Test.dart|2|3|4|no such type \"Foo\"",
-            "     1: lineAAA",
-            "     2: lineBBB",
-            "          ~~~~",
-            ""),
-        errorString);
-  }
-
-  /**
-   * Use color to highlight range of characters. Include all information about error context.
-   */
-  public void test_withColor_forMachine() throws Exception {
-    Location location = new Location(10, 10 + 4);
-    DartCompilationError error =
-        new DartCompilationError(SOURCE, location, TypeErrorCode.NO_SUCH_TYPE, "Foo");
-    String errorString = getErrorString(error, true, true);
-    assertEquals(
-        Joiner.on("\n").join(
-            WARNING_BOLD_COLOR
-                + "WARNING|STATIC_TYPE|NO_SUCH_TYPE|my/path/Test.dart|2|3|4|no such type \"Foo\""
-                + NO_COLOR,
-            "     1: lineAAA",
-            "     2: li" + WARNING_COLOR + "neBB" + NO_COLOR + "B",
-            ""),
-        errorString);
-
-    error = new DartCompilationError(SOURCE, location, ResolverErrorCode.NO_SUCH_TYPE, "Foo");
-    errorString = getErrorString(error, true, true);
-    assertEquals(
-        Joiner.on("\n").join(
-            ERROR_BOLD_COLOR
-                + "ERROR|RESOLVER|NO_SUCH_TYPE|my/path/Test.dart|2|3|4|no such type \"Foo\""
-                + NO_COLOR,
-            "     1: lineAAA",
-            "     2: li" + ERROR_COLOR + "neBB" + NO_COLOR + "B",
-            ""),
-        errorString);
-  }
-
-  /**
-   * @return output produced by {@link PrettyErrorFormatter}.
-   */
-  private String getErrorString(DartCompilationError error,
-      boolean useColor,
-      boolean printMachineProblems) {
-    ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
-    PrintStream printStream = new PrintStream(outputStream);
-    ErrorFormatter errorFormatter =
-        new PrettyErrorFormatter(printStream, useColor, printMachineProblems
-            ? ErrorFormat.MACHINE
-            : ErrorFormat.NORMAL);
-    errorFormatter.format(error);
-    return outputStream.toString();
-  }
-}
diff --git a/compiler/javatests/com/google/dart/compiler/SourceTest.java b/compiler/javatests/com/google/dart/compiler/SourceTest.java
deleted file mode 100644
index cc20251..0000000
--- a/compiler/javatests/com/google/dart/compiler/SourceTest.java
+++ /dev/null
@@ -1,44 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler;
-
-import java.net.URI;
-
-/**
- * Testing implementation of {@link Source}.
- */
-public abstract class SourceTest implements Source {
-
-  private final String name;
-
-  public SourceTest(String name) {
-    this.name = name;
-  }
-
-  @Override
-  public boolean exists() {
-    return true;
-  }
-
-  @Override
-  public long getLastModified() {
-    return 0;
-  }
-
-  @Override
-  public String getName() {
-    return name;
-  }
-
-  @Override
-  public String getUniqueIdentifier() {
-    return URI.create(getName()).normalize().toString();
-  }
-
-  @Override
-  public URI getUri() {
-    return URI.create(getName()).normalize();
-  }
-}
diff --git a/compiler/javatests/com/google/dart/compiler/SystemLibrariesReaderTest.java b/compiler/javatests/com/google/dart/compiler/SystemLibrariesReaderTest.java
deleted file mode 100644
index 4e205e4..0000000
--- a/compiler/javatests/com/google/dart/compiler/SystemLibrariesReaderTest.java
+++ /dev/null
@@ -1,48 +0,0 @@
-// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-package com.google.dart.compiler;
-
-import com.google.dart.compiler.SystemLibrariesReader.DartLibrary;
-
-import junit.framework.TestCase;
-
-import java.io.File;
-import java.io.IOException;
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.util.Map;
-import java.util.Map.Entry;
-
-/**
- * Test the {@link SystemLibrariesReader}
- */
-public class SystemLibrariesReaderTest extends TestCase {
-
-  
-  public void testLibrariesFileExists(){
-    File sdkLibPath = new File(PackageLibraryManager.DEFAULT_SDK_PATH, "lib");
-    File librariesFile = new File(new File(sdkLibPath, SystemLibrariesReader.INTERNAL_DIR), SystemLibrariesReader.LIBRARIES_FILE);
-    assertTrue(librariesFile.exists());
-  }
-  
-  public void testLibrariesFileContent() throws URISyntaxException, IOException{
-    File sdkLibPath = new File(PackageLibraryManager.DEFAULT_SDK_PATH, "lib");
-    URI base = sdkLibPath.toURI();
-    SystemLibrariesReader reader = new SystemLibrariesReader(sdkLibPath);
-    Map<String, DartLibrary> librariesMap = reader.getLibrariesMap();
-    assertTrue(!librariesMap.isEmpty());
-    for (Entry<String, DartLibrary> entry : librariesMap.entrySet()) {
-      if (entry.getValue().getCategory().equals("Internal")){
-        continue;
-      }
-      String path = entry.getValue().getPath();
-      File file = new File(base.resolve(new URI(null, null, path, null, null)).normalize());
-      if (!file.exists()) {
-        fail("Expected " + entry.getKey() + " path in libraries.dart to exist in SDK"
-            + "\n  could not find " + file);
-      }
-    }
-  }
-  
-}
diff --git a/compiler/javatests/com/google/dart/compiler/TestAll.java b/compiler/javatests/com/google/dart/compiler/TestAll.java
deleted file mode 100644
index 249e544..0000000
--- a/compiler/javatests/com/google/dart/compiler/TestAll.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright (c) 2013, the Dart project authors.
- *
- * Licensed under the Eclipse Public License v1.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.eclipse.org/legal/epl-v10.html
- *
- * 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.dart.compiler;
-
-import com.google.dart.compiler.ast.AstTests;
-import com.google.dart.compiler.common.CommonTests;
-import com.google.dart.compiler.end2end.End2EndTests;
-import com.google.dart.compiler.parser.ParserTests;
-import com.google.dart.compiler.resolver.ResolverTests;
-import com.google.dart.compiler.util.UtilTests;
-
-import junit.framework.Test;
-import junit.framework.TestSuite;
-
-public class TestAll {
-
-  public static Test suite() {
-    TestSuite suite = new TestSuite("Tests in " + TestAll.class.getPackage().getName());
-
-    suite.addTest(CompilerTests.suite());
-    suite.addTest(AstTests.suite());
-    suite.addTest(CommonTests.suite());
-    suite.addTest(End2EndTests.suite());
-    suite.addTest(ParserTests.suite());
-    suite.addTest(ResolverTests.suite());
-    //suite.addTest(TypeTests.suite());
-    suite.addTest(UtilTests.suite());
-
-    return suite;
-  }
-
-}
diff --git a/compiler/javatests/com/google/dart/compiler/ast/AstTests.java b/compiler/javatests/com/google/dart/compiler/ast/AstTests.java
deleted file mode 100644
index c143bde..0000000
--- a/compiler/javatests/com/google/dart/compiler/ast/AstTests.java
+++ /dev/null
@@ -1,23 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.ast;
-
-import junit.extensions.TestSetup;
-import junit.framework.Test;
-import junit.framework.TestSuite;
-
-public class AstTests extends TestSetup {
-
-  public AstTests(TestSuite test) {
-    super(test);
-  }
-
-  public static Test suite() {
-    TestSuite suite = new TestSuite("Dart AST test suite.");
-
-    suite.addTestSuite(DartToSourceVisitorTest.class);
-    return new AstTests(suite);
-  }
-}
diff --git a/compiler/javatests/com/google/dart/compiler/ast/DartToSourceVisitorTest.java b/compiler/javatests/com/google/dart/compiler/ast/DartToSourceVisitorTest.java
deleted file mode 100644
index a324d94..0000000
--- a/compiler/javatests/com/google/dart/compiler/ast/DartToSourceVisitorTest.java
+++ /dev/null
@@ -1,127 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.ast;
-
-import com.google.common.base.Joiner;
-import com.google.dart.compiler.CompilerTestCase;
-
-/**
- * @author johnlenz@google.com (John Lenz)
- */
-public class DartToSourceVisitorTest extends CompilerTestCase {
-   public void testDartStatements() {
-     testStmt("return");
-     testStmt("x");
-     testStmt("x.y");
-     testStmt("x + 1.0");
-     testStmt("x.y()");
-     // rethrow is an error outside a catch block
-     String rethrow =
-       "  m() {\n" +
-       "    try {\n" +
-       "    }\n" +
-       "    catch (e) {\n" +
-       "      throw;\n" +
-       "    }\n" +
-       "  }\n";
-     testClassMemeber(rethrow);
-
-     testStmt("throw e");
-     testStmt("Array<String> strings");
-   }
-
-   public void testStringBackslashEscaping() {
-     testStmt("String foo = \" \\\\ \"");
-   }
-
-   public void testDartMembers() {
-     testClassMemeber(
-       "  m() {\n" +
-       "  }\n");
-     testClassMemeber(
-       "  operator -() {\n" +
-       "  }\n");
-     // get is mangled
-     // testClassMemeber(
-     //  "  get f() {\n" +
-     //  "  }\n");
-   }
-
-   public void testClassWithFactory() {
-     same(
-          "// unit testcode\n" +
-          "class c {\n" +
-          "\n" +
-          "  factory Array() {\n  }\n" +
-          "}\n" +
-          "\n");
-   }
-
-   public void testClassWithFactoryParameterized() {
-     same(
-          "// unit testcode\n" +
-          "class c<E> {\n" +
-          "\n" +
-          "  factory Array() {\n  }\n" +
-          "}\n" +
-          "\n");
-   }
-
-   public void testNativeClass() {
-     same(
-          "// unit testcode\n" +
-          "class c native \"C\" {\n" +
-          "}\n" +
-          "\n");
-   }
-
-   public void testArrayLiteral() {
-     same(Joiner.on("\n").join(
-         "// unit testcode",
-         "var m = [1, 2, 3];",
-         ""));
-     same(Joiner.on("\n").join(
-         "// unit testcode",
-         "var m = <int>[1, 2, 3];",
-         ""));
-   }
-
-   public void testMapLiteral() {
-     same(Joiner.on("\n").join(
-         "// unit testcode",
-         "var m = {\"a\" : 1, \"b\" : 2, \"c\" : 3};",
-         ""));
-     same(Joiner.on("\n").join(
-         "// unit testcode",
-         "var m = <int>{\"a\" : 1, \"b\" : 2, \"c\" : 3};",
-         ""));
-   }
-
-   private void same(String sourceCode) {
-     // Some of the syntax we are testing is only valid in a system library
-     DartUnit unit = parseUnitAsSystemLibrary("testcode", sourceCode);
-     String result = unit.toSource();
-     assertEquals(sourceCode, result);
-   }
-
-   private void testClassMemeber(String stmt) {
-     String boilerplated =
-       "// unit testcode\n" +
-       "class c {\n" +
-       "\n" +
-       ""+stmt+"" +
-       "}\n" +
-       "\n";
-     same(boilerplated);
-   }
-
-   private void testStmt(String stmt) {
-     String boilerplated =
-       "  m() {\n" +
-       "    "+stmt+";\n" +
-       "  }\n";
-     testClassMemeber(boilerplated);
-   }
-}
diff --git a/compiler/javatests/com/google/dart/compiler/common/ApplicationSourceFileTest.dart b/compiler/javatests/com/google/dart/compiler/common/ApplicationSourceFileTest.dart
deleted file mode 100644
index 3e05766..0000000
--- a/compiler/javatests/com/google/dart/compiler/common/ApplicationSourceFileTest.dart
+++ /dev/null
@@ -1,8 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import "somedir/somelib.dart";
-part "MyFirstApp.dart";
-part "AnotherSource2.dart";
-part "subdir2/Source3x.dart";
diff --git a/compiler/javatests/com/google/dart/compiler/common/CommonTests.java b/compiler/javatests/com/google/dart/compiler/common/CommonTests.java
deleted file mode 100644
index e3109d5..0000000
--- a/compiler/javatests/com/google/dart/compiler/common/CommonTests.java
+++ /dev/null
@@ -1,22 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.common;
-
-import junit.extensions.TestSetup;
-import junit.framework.Test;
-import junit.framework.TestSuite;
-
-public class CommonTests extends TestSetup {
-
-  public CommonTests(TestSuite test) {
-    super(test);
-  }
-
-  public static Test suite() {
-    TestSuite suite = new TestSuite("Dart common test suite.");
-    suite.addTestSuite(LibrarySourceFileTest.class);
-    return new CommonTests(suite);
-  }
-}
diff --git a/compiler/javatests/com/google/dart/compiler/common/ErrorExpectation.java b/compiler/javatests/com/google/dart/compiler/common/ErrorExpectation.java
deleted file mode 100644
index e10948e..0000000
--- a/compiler/javatests/com/google/dart/compiler/common/ErrorExpectation.java
+++ /dev/null
@@ -1,108 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-package com.google.dart.compiler.common;
-
-import com.google.dart.compiler.DartCompilationError;
-import com.google.dart.compiler.ErrorCode;
-
-import junit.framework.Assert;
-
-import java.util.List;
-
-public class ErrorExpectation {
-  private final String sourceName;
-  final ErrorCode errorCode;
-  final int line;
-  final int column;
-  final int length;
-
-  public ErrorExpectation(String sourceName, ErrorCode errorCode, int line, int column, int length) {
-    this.sourceName = sourceName;
-    this.errorCode = errorCode;
-    this.line = line;
-    this.column = column;
-    this.length = length;
-  }
-
-  public static ErrorExpectation errEx(String sourceName,
-      ErrorCode errorCode,
-      int line,
-      int column,
-      int length) {
-    sourceName = sourceName != null ? sourceName : "";
-    return new ErrorExpectation(sourceName, errorCode, line, column, length);
-  }
-
-  public static ErrorExpectation errEx(ErrorCode errorCode, int line, int column, int length) {
-    return new ErrorExpectation("", errorCode, line, column, length);
-  }
-
-  public static void formatExpectations(StringBuffer out,
-      List<DartCompilationError> errors,
-      ErrorExpectation[] expectedErrors) {
-    out.append(String.format("Expected %d errors\n", expectedErrors.length));
-    boolean hasExpectedSourceName = false;
-    for (ErrorExpectation expected : expectedErrors) {
-      hasExpectedSourceName |= expected.sourceName.length() != 0;
-      out.append(String.format(
-          "  %s %s (%d,%d/%d)\n",
-          expected.sourceName,
-          expected.errorCode.toString(),
-          expected.line,
-          expected.column,
-          expected.length));
-    }
-    out.append(String.format("Encountered %d errors\n", errors.size()));
-    for (DartCompilationError actual : errors) {
-      String sourceName =
-          hasExpectedSourceName && actual.getSource() != null ? actual.getSource().getName() : "";
-      out.append(String.format(
-          "  %s %s (%d,%d/%d): %s\n",
-          sourceName,
-          actual.getErrorCode().toString(),
-          actual.getLineNumber(),
-          actual.getColumnNumber(),
-          actual.getLength(),
-          actual.getMessage()));
-    }
-  }
-
-  /**
-   * Asserts that given list of {@link DartCompilationError} is exactly same as expected.
-   */
-  public static void assertErrors(List<DartCompilationError> errors,
-      ErrorExpectation... expectedErrors) {
-    StringBuffer errorMessage = new StringBuffer();
-    // count of errors
-    if (errors.size() != expectedErrors.length) {
-      errorMessage.append(String.format(
-          "Wrong number of errors encountered\n",
-          expectedErrors.length,
-          errors.size()));
-      formatExpectations(errorMessage, errors, expectedErrors);
-    } else {
-      // content of errors
-      for (int i = 0; i < expectedErrors.length; i++) {
-        ErrorExpectation expected = expectedErrors[i];
-        DartCompilationError actual = errors.get(i);
-        String expectedSourceName = expected.sourceName;
-        String actualSourceName = actual.getSource() != null ? actual.getSource().getName() : "";
-        if (actual.getErrorCode() != expected.errorCode
-            || actual.getLineNumber() != expected.line
-            || actual.getColumnNumber() != expected.column
-            || actual.getLength() != expected.length
-            || !(expectedSourceName.length() == 0 || expectedSourceName.equals(actualSourceName))) {
-          errorMessage.append(String.format("Expected errors didn't match actual\n"));
-          formatExpectations(errorMessage, errors, expectedErrors);
-          break;
-        }
-      }
-    }
-    // fail
-    if (errorMessage.length() > 0) {
-      System.err.println(errorMessage);
-      Assert.fail(errorMessage.toString());
-    }
-  }
-}
diff --git a/compiler/javatests/com/google/dart/compiler/common/LibrarySourceFileTest.dart b/compiler/javatests/com/google/dart/compiler/common/LibrarySourceFileTest.dart
deleted file mode 100644
index 110558c..0000000
--- a/compiler/javatests/com/google/dart/compiler/common/LibrarySourceFileTest.dart
+++ /dev/null
@@ -1,8 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library LibrarySourceFileTest;
-part "OneSourceFile.dart";
-part "Source2.dart";
-part "subdir/Source3.dart";
diff --git a/compiler/javatests/com/google/dart/compiler/common/LibrarySourceFileTest.java b/compiler/javatests/com/google/dart/compiler/common/LibrarySourceFileTest.java
deleted file mode 100644
index 7dd4498..0000000
--- a/compiler/javatests/com/google/dart/compiler/common/LibrarySourceFileTest.java
+++ /dev/null
@@ -1,110 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.common;
-
-import com.google.common.collect.Sets;
-import com.google.dart.compiler.AbstractSourceFileTest;
-import com.google.dart.compiler.DartCompilationError;
-import com.google.dart.compiler.DartCompilerListener;
-import com.google.dart.compiler.ErrorSeverity;
-import com.google.dart.compiler.LibrarySource;
-import com.google.dart.compiler.UrlLibrarySource;
-import com.google.dart.compiler.ast.LibraryNode;
-import com.google.dart.compiler.ast.LibraryUnit;
-import com.google.dart.compiler.parser.DartParser;
-
-import java.io.File;
-import java.io.IOException;
-import java.util.Iterator;
-
-/**
- * Tests {@link LibrarySource}
- */
-public class LibrarySourceFileTest extends AbstractSourceFileTest {
-  private LibraryUnit libUnit;
-
-  public void testGetImports() throws IOException {
-    LibraryUnit libUnit = getLibraryUnit("LibrarySourceFileTest.dart");
-    Iterable<LibraryNode> imports = libUnit.getImportPaths();
-    assertFalse(imports.iterator().hasNext());
-  }
-
-  public void testGetAppImports() throws IOException {
-    LibraryUnit appUnit = getLibraryUnit("ApplicationSourceFileTest.dart");
-    Iterable<LibraryNode> imports = appUnit.getImportPaths();
-    Iterator<LibraryNode> iter = imports.iterator();
-    assertEquals("somedir/somelib.dart", iter.next().getText());
-    assertFalse(iter.hasNext());
-  }
-
-  public void testGetSources() throws IOException {
-    LibraryUnit libUnit = getLibraryUnit("LibrarySourceFileTest.dart");
-    Iterable<LibraryNode> sources = libUnit.getSourcePaths();
-    Iterator<LibraryNode> iter = sources.iterator();
-    assertEquals("OneSourceFile.dart", iter.next().getText());
-    assertEquals("Source2.dart", iter.next().getText());
-    assertEquals("subdir/Source3.dart", iter.next().getText());
-    assertEquals(libUnit.getSelfSourcePath(), iter.next());
-    assertFalse(iter.hasNext());
-  }
-
-  public void testGetAppSources() throws IOException {
-    LibraryUnit appUnit = getLibraryUnit("ApplicationSourceFileTest.dart");
-    Iterable<LibraryNode> paths = appUnit.getSourcePaths();
-    Iterator<LibraryNode> iter = paths.iterator();
-    assertEquals("MyFirstApp.dart", iter.next().getText());
-    assertEquals("AnotherSource2.dart", iter.next().getText());
-    assertEquals("subdir2/Source3x.dart", iter.next().getText());
-    assertEquals(libUnit.getSelfSourcePath(), iter.next());
-    assertFalse(iter.hasNext());
-  }
-
-  /**
-   * Answer the {@link LibraryUnit} on which tests are performed
-   *
-   * @param filePath the path to the file relative to the test class
-   * @return the library unit (not <code>null</code>)
-   */
-  protected LibraryUnit getLibraryUnit(String filePath) throws IOException {
-    File tempFile = createTempFile(filePath);
-    return getLibraryUnit(tempFile);
-  }
-
-  protected LibraryUnit getLibraryUnit(String filePath, String source) throws IOException {
-    File tempFile = createTempFile(filePath, source);
-    return getLibraryUnit(tempFile);
-  }
-
-  protected LibraryUnit getLibraryUnit(File file) {
-    if (libUnit == null) {
-      UrlLibrarySource lib = new UrlLibrarySource(file);
-
-      DartCompilerListener listener = new DartCompilerListener.Empty() {
-        @Override
-        public void onError(DartCompilationError event) {
-          // Ignore warnings when testing.
-          if (event.getErrorCode().getErrorSeverity() == ErrorSeverity.WARNING) {
-            return;
-          }
-          // Rethrow error.
-          throw new RuntimeException(event.getMessage());
-        }
-      };
-
-      try {
-        libUnit = new DartParser(
-            lib,
-            DartParser.read(lib),
-            false,
-            Sets.<String>newHashSet(),
-            listener,
-            null).preProcessLibraryDirectives(lib);
-      } catch (IOException ioEx) {
-        libUnit = null;
-      }
-    }
-    return libUnit;
-  }
-}
diff --git a/compiler/javatests/com/google/dart/compiler/end2end/End2EndTests.java b/compiler/javatests/com/google/dart/compiler/end2end/End2EndTests.java
deleted file mode 100644
index de8d813..0000000
--- a/compiler/javatests/com/google/dart/compiler/end2end/End2EndTests.java
+++ /dev/null
@@ -1,28 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.end2end;
-
-import com.google.dart.compiler.end2end.inc.IncrementalCompilation2Test;
-import com.google.dart.compiler.end2end.inc.IncrementalCompilationTest;
-import com.google.dart.compiler.end2end.inc.IncrementalCompilationWithPrefixTest;
-
-import junit.extensions.TestSetup;
-import junit.framework.Test;
-import junit.framework.TestSuite;
-
-public class End2EndTests extends TestSetup {
-
-  public End2EndTests(TestSuite test) {
-    super(test);
-  }
-
-  public static Test suite() {
-    TestSuite suite = new TestSuite("Dart end-to-end test suite.");
-    suite.addTestSuite(IncrementalCompilationTest.class);
-    suite.addTestSuite(IncrementalCompilation2Test.class);
-    suite.addTestSuite(IncrementalCompilationWithPrefixTest.class);
-    return new End2EndTests(suite);
-  }
-}
diff --git a/compiler/javatests/com/google/dart/compiler/end2end/NonStrictResolutionNegativeTest1.dart b/compiler/javatests/com/google/dart/compiler/end2end/NonStrictResolutionNegativeTest1.dart
deleted file mode 100644
index 6931916..0000000
--- a/compiler/javatests/com/google/dart/compiler/end2end/NonStrictResolutionNegativeTest1.dart
+++ /dev/null
@@ -1,16 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-// uses experimental flag: --warn_no_such_type that allows compilation 
-// to succeed even when types fail to resolve. in the case below, the 
-// application should throw a runtime error.
-
-class A {
-  A();
-}
-
-main() {
-  A a = new A();
-  Expect.equals(a.foo(123), 1);
-}
diff --git a/compiler/javatests/com/google/dart/compiler/end2end/NonStrictResolutionNegativeTest2.dart b/compiler/javatests/com/google/dart/compiler/end2end/NonStrictResolutionNegativeTest2.dart
deleted file mode 100644
index 4f65f0d..0000000
--- a/compiler/javatests/com/google/dart/compiler/end2end/NonStrictResolutionNegativeTest2.dart
+++ /dev/null
@@ -1,11 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-// uses experimental flag: --warn_no_such_type that allows compilation to 
-// succeed even when types fail to resolve. in the case below, the 
-// application should throw a runtime error.
-
-main() {
-  var a = new A();
-}
diff --git a/compiler/javatests/com/google/dart/compiler/end2end/NonStrictResolutionTest.dart b/compiler/javatests/com/google/dart/compiler/end2end/NonStrictResolutionTest.dart
deleted file mode 100644
index 0a59022..0000000
--- a/compiler/javatests/com/google/dart/compiler/end2end/NonStrictResolutionTest.dart
+++ /dev/null
@@ -1,49 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-// uses experimental flag: --warn_no_such_type that allows compilation 
-// to succeed even when types fail to resolve. in the cases below, the 
-// application should still succeed at runtime.
-
-class A {
-  A(this.x);
-
-  static type1 foo() {
-     return 123;
-  }
-
-  type2 x;
-
-  type3 myMethod(type4 param) {
-    return param + x;
-  }
-  
-  type5 get X {
-    return x;
-  }
-
-  type6 bar(type7 param) {
-    type8 v1 = param + 1;
-    type9 v2 = v1 + X;
-    return v2;
-  }
-}
-
-main() {
-  // static method returning unresolved type.
-  Expect.equals(A.foo(), 123);
-
-  // Field with unresolved type
-  A a = new A(1);
-  Expect.equals(a.x, 1);
-
-  // Parameter with unresolved type.
-  Expect.equals(a.myMethod(1), 2);
-
-  // Getter
-  Expect.equals(a.X, 1);
-
-  // Local vars
-  Expect.equals(a.bar(1), 3);
-}
diff --git a/compiler/javatests/com/google/dart/compiler/end2end/inc/IncrementalCompilation2Test.java b/compiler/javatests/com/google/dart/compiler/end2end/inc/IncrementalCompilation2Test.java
deleted file mode 100644
index a106aa8..0000000
--- a/compiler/javatests/com/google/dart/compiler/end2end/inc/IncrementalCompilation2Test.java
+++ /dev/null
@@ -1,1876 +0,0 @@
-// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-package com.google.dart.compiler.end2end.inc;
-
-import com.google.common.base.Joiner;
-import com.google.common.collect.Lists;
-import com.google.common.collect.Maps;
-import com.google.common.collect.Sets;
-import com.google.dart.compiler.CompilerTestCase;
-import com.google.dart.compiler.DartCompilationError;
-import com.google.dart.compiler.DartCompiler;
-import com.google.dart.compiler.DartCompilerErrorCode;
-import com.google.dart.compiler.DartCompilerListener;
-import com.google.dart.compiler.DartSource;
-import com.google.dart.compiler.DefaultCompilerConfiguration;
-import com.google.dart.compiler.LibrarySource;
-import com.google.dart.compiler.MockArtifactProvider;
-import com.google.dart.compiler.PackageLibraryManager;
-import com.google.dart.compiler.Source;
-import com.google.dart.compiler.UrlSource;
-import com.google.dart.compiler.ast.DartUnit;
-import com.google.dart.compiler.ast.LibraryUnit;
-import com.google.dart.compiler.common.ErrorExpectation;
-import com.google.dart.compiler.resolver.ResolverErrorCode;
-import com.google.dart.compiler.resolver.TypeErrorCode;
-import com.google.dart.compiler.type.TypeQuality;
-
-import static com.google.dart.compiler.DartCompiler.EXTENSION_DEPS;
-import static com.google.dart.compiler.DartCompiler.EXTENSION_TIMESTAMP;
-import static com.google.dart.compiler.common.ErrorExpectation.assertErrors;
-import static com.google.dart.compiler.common.ErrorExpectation.errEx;
-
-import junit.framework.AssertionFailedError;
-
-import java.io.IOException;
-import java.io.Reader;
-import java.io.Writer;
-import java.net.URI;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.ConcurrentSkipListSet;
-
-// TODO(zundel): update this test not to rely on code generation
-public class IncrementalCompilation2Test extends CompilerTestCase {
-  private static final String APP = "Application.dart";
-
-  private static class IncMockArtifactProvider extends MockArtifactProvider {
-    Set<String> reads = new ConcurrentSkipListSet<String>();
-    Set<String> writes = new ConcurrentSkipListSet<String>();
-
-    @Override
-    public Reader getArtifactReader(Source source, String part, String extension) {
-      reads.add(source.getName() + "/" + extension);
-      return super.getArtifactReader(source, part, extension);
-    }
-
-    @Override
-    public Writer getArtifactWriter(Source source, String part, String extension) {
-      writes.add(source.getName() + "/" + extension);
-      return super.getArtifactWriter(source, part, extension);
-    }
-
-    void resetReadsAndWrites() {
-      reads.clear();
-      writes.clear();
-    }
-  }
-
-  private DefaultCompilerConfiguration config;
-  private IncMockArtifactProvider provider;
-  private MemoryLibrarySource appSource;
-  private final List<DartCompilationError> errors = Lists.newArrayList();
-  private final Map<String, DartUnit> units = Maps.newHashMap();
-
-  @Override
-  protected void setUp() throws Exception {
-    config = new DefaultCompilerConfiguration() {
-      @Override
-      public boolean incremental() {
-        return true;
-      }
-    };
-    provider = new IncMockArtifactProvider();
-    appSource = new MemoryLibrarySource(APP);
-    appSource.setContent(
-        APP,
-        makeCode(
-            "// filler filler filler filler filler filler filler filler filler filler filler",
-            "library application;",
-            "part 'A.dart';",
-            "part 'B.dart';",
-            "part 'C.dart';",
-            ""));
-    appSource.setContent("A.dart", "part of application;");
-    appSource.setContent("B.dart", "part of application;");
-    appSource.setContent("C.dart", "part of application;");
-  }
-
-  @Override
-  protected void tearDown() {
-    config = null;
-    provider = null;
-    appSource = null;
-    errors.clear();
-    units.clear();
-  }
-
-  /**
-   * "not_hole" is referenced using "super" qualifier, so is not affected by declaring top-level
-   * field with same name.
-   */
-  public void test_useQualifiedFieldReference_ignoreTopLevelDeclaration() {
-    appSource.setContent(
-        "B.dart",
-        makeCode(
-            "// filler filler filler filler filler filler filler filler filler filler filler",
-            "part of application;",
-            "class A {",
-            "  int not_hole;",
-            "}",
-            ""));
-    appSource.setContent(
-        "C.dart",
-        makeCode(
-            "// filler filler filler filler filler filler filler filler filler filler filler",
-            "part of application;",
-            "class B extends A {",
-            "  int bar() {",
-            "    return super.not_hole;", // qualified reference
-            "  }",
-            "}",
-            ""));
-    compile();
-    assertErrors(errors);
-    // Update units and compile.
-    appSource.setContent(
-        "A.dart",
-        makeCode(
-            "// filler filler filler filler filler filler filler filler filler filler filler",
-            "part of application;",
-            "int not_hole;",
-            ""));
-    compile();
-    // TODO(scheglov) Fix this after 1159
-    //assertErrors(errors, errEx(ResolverErrorCode.DUPLICATE_LOCAL_VARIABLE_WARNING, -1, 7, 20));
-    // B should be compiled because it now conflicts with A.
-    // C should not be compiled, because it reference "not_hole" field, not top-level variable.
-    didWrite("A.dart", EXTENSION_TIMESTAMP);
-    didWrite("B.dart", EXTENSION_TIMESTAMP);
-    didNotWrite("C.dart", EXTENSION_TIMESTAMP);
-    assertAppBuilt();
-  }
-
-  /**
-   * Referenced "hole" identifier can not be resolved, but when we declare it in A, then B should be
-   * recompiled and error message disappear.
-   */
-  public void test_useUnresolvedField_recompileOnTopLevelDeclaration() {
-    appSource.setContent(
-        "B.dart",
-        makeCode(
-            "// filler filler filler filler filler filler filler filler filler filler filler",
-            "part of application;",
-            "class A {",
-            "  int foo() {",
-            "    return hole;", // no such field
-            "  }",
-            "}",
-            ""));
-    compile();
-    assertErrors(errors, errEx(TypeErrorCode.CANNOT_BE_RESOLVED, 5, 12, 4));
-    // Update units and compile.
-    appSource.setContent(
-        "A.dart",
-        makeCode(
-            "// filler filler filler filler filler filler filler filler filler filler filler",
-            "part of application;",
-            "int hole;",
-            ""));
-    compile();
-    // A and B should be compiled.
-    didWrite("A.dart", EXTENSION_TIMESTAMP);
-    didWrite("B.dart", EXTENSION_TIMESTAMP);
-    assertAppBuilt();
-    // "hole" was filled with top-level field.
-    assertErrors(errors);
-  }
-
-  /**
-   * Test for "hole" feature. If we use unqualified invocation and add/remove top-level method, this
-   * should cause compilation of invocation unit.
-   */
-  public void test_isMethodHole_useUnqualifiedInvocation() throws Exception {
-    appSource.setContent(
-        "B.dart",
-        makeCode(
-            "// filler filler filler filler filler filler filler filler filler filler filler",
-            "part of application;",
-            "class A {",
-            "  foo() {}",
-            "}",
-            ""));
-    appSource.setContent(
-        "C.dart",
-        makeCode(
-            "// filler filler filler filler filler filler filler filler filler filler filler",
-            "part of application;",
-            "class B extends A {",
-            "  int bar() {",
-            "    foo();", // unqualified invocation
-            "  }",
-            "}",
-            ""));
-    compile();
-    assertErrors(errors);
-    // Declare top-level foo(), now invocation of foo() in B should be bound to this top-level.
-    {
-      appSource.setContent(
-          "A.dart",
-          makeCode(
-              "// filler filler filler filler filler filler filler filler filler filler filler",
-              "part of application;",
-              "foo() {}",
-              ""));
-      compile();
-      // B should be compiled because it also declares foo(), so produces "shadow" conflict.
-      // C should be compiled because it has unqualified invocation which was declared in A.
-      didWrite("A.dart", EXTENSION_TIMESTAMP);
-      didWrite("B.dart", EXTENSION_TIMESTAMP);
-      didWrite("C.dart", EXTENSION_TIMESTAMP);
-      assertAppBuilt();
-    }
-    // Wait, because analysis is so fast that may be A will have same time as old artifact.
-    Thread.sleep(5);
-    // Remove top-level foo(), so invocation of foo() in B should be bound to the super class.
-    {
-      appSource.setContent("A.dart", "part of application;");
-      compile();
-      // B should be compiled because it also declares foo(), so produces "shadow" conflict.
-      // C should be compiled because it has unqualified invocation which was declared in A.
-      didWrite("A.dart", EXTENSION_TIMESTAMP);
-      didWrite("B.dart", EXTENSION_TIMESTAMP);
-      didWrite("C.dart", EXTENSION_TIMESTAMP);
-    }
-  }
-
-  /**
-   * Test for "hole" feature. If we use qualified invocation and add/remove top-level method, this
-   * should not cause compilation of invocation unit.
-   */
-  public void test_notMethodHole_useQualifiedInvocation() {
-    appSource.setContent(
-        "B.dart",
-        makeCode(
-            "// filler filler filler filler filler filler filler filler filler filler filler",
-            "part of application;",
-            "class A {",
-            "  foo() {}",
-            "}",
-            ""));
-    appSource.setContent(
-        "C.dart",
-        makeCode(
-            "// filler filler filler filler filler filler filler filler filler filler filler",
-            "part of application;",
-            "class B extends A {",
-            "  int bar() {",
-            "    super.foo();", // qualified invocation
-            "  }",
-            "}",
-            ""));
-    compile();
-    assertErrors(errors);
-    // Declare top-level foo(), but it is ignored.
-    {
-      appSource.setContent(
-          "A.dart",
-          makeCode(
-              "// filler filler filler filler filler filler filler filler filler filler filler",
-              "part of application;",
-              "foo() {}",
-              ""));
-      compile();
-      // B should be compiled because it also declares foo(), so produces "shadow" conflict.
-      // C should not be compiled because.
-      didWrite("A.dart", EXTENSION_TIMESTAMP);
-      didWrite("B.dart", EXTENSION_TIMESTAMP);
-      didNotWrite("C.dart", EXTENSION_TIMESTAMP);
-      assertAppBuilt();
-    }
-  }
-
-  /**
-   * Test for "hole" feature. If we use unqualified access and add/remove top-level field, this
-   * should cause compilation of invocation unit.
-   */
-  public void test_fieldHole_useUnqualifiedAccess() throws Exception {
-    appSource.setContent(
-        "B.dart",
-        makeCode(
-            "// filler filler filler filler filler filler filler filler filler filler filler",
-            "part of application;",
-            "class A {",
-            "  var foo;",
-            "}",
-            ""));
-    appSource.setContent(
-        "C.dart",
-        makeCode(
-            "// filler filler filler filler filler filler filler filler filler filler filler",
-            "part of application;",
-            "class B extends A {",
-            "  int bar() {",
-            "    foo = 0;", // unqualified access
-            "  }",
-            "}",
-            ""));
-    compile();
-    assertErrors(errors);
-    // Declare top-level "foo", now access to "foo" in B should be bound to this top-level.
-    {
-      appSource.setContent(
-          "A.dart",
-          makeCode(
-              "// filler filler filler filler filler filler filler filler filler filler filler",
-              "part of application;",
-              "var foo;",
-              ""));
-      compile();
-      // B should be compiled because it also declares "foo", so produces "shadow" conflict.
-      // C should be compiled because it has unqualified invocation which was declared in A.
-      didWrite("A.dart", EXTENSION_TIMESTAMP);
-      didWrite("B.dart", EXTENSION_TIMESTAMP);
-      didWrite("C.dart", EXTENSION_TIMESTAMP);
-      assertAppBuilt();
-    }
-    // Wait, because analysis is so fast that may be A will have same time as old artifact.
-    Thread.sleep(5);
-    // Remove top-level "foo", so access to "foo" in B should be bound to the super class.
-    {
-      appSource.setContent("A.dart", "part of application;");
-      compile();
-      // B should be compiled because it also declares "foo", so produces "shadow" conflict.
-      // C should be compiled because it has unqualified access which was declared in A.
-      didWrite("A.dart", EXTENSION_TIMESTAMP);
-      didWrite("B.dart", EXTENSION_TIMESTAMP);
-      didWrite("C.dart", EXTENSION_TIMESTAMP);
-    }
-  }
-
-  /**
-   * Test for "hole" feature. If we use qualified access and add/remove top-level field, this should
-   * not cause compilation of invocation unit.
-   */
-  public void test_fieldHole_useQualifiedAccess() {
-    appSource.setContent(
-        "B.dart",
-        makeCode(
-            "// filler filler filler filler filler filler filler filler filler filler filler",
-            "part of application;",
-            "class A {",
-            "  var foo;",
-            "}",
-            ""));
-    appSource.setContent(
-        "C.dart",
-        makeCode(
-            "// filler filler filler filler filler filler filler filler filler filler filler",
-            "part of application;",
-            "class B extends A {",
-            "  int bar() {",
-            "    super.foo = 0;", // qualified access
-            "  }",
-            "}",
-            ""));
-    compile();
-    assertErrors(errors);
-    // Declare top-level "foo", but it is ignored.
-    {
-      appSource.setContent(
-          "A.dart",
-          makeCode(
-              "// filler filler filler filler filler filler filler filler filler filler filler",
-              "part of application;",
-              "var foo;",
-              ""));
-      compile();
-      // B should be compiled because it also declares "foo", so produces "shadow" conflict.
-      // C should not be compiled because it has qualified access to "foo".
-      didWrite("A.dart", EXTENSION_TIMESTAMP);
-      didWrite("B.dart", EXTENSION_TIMESTAMP);
-      didNotWrite("C.dart", EXTENSION_TIMESTAMP);
-      assertAppBuilt();
-    }
-  }
-
-  public void test_declareTopLevel_conflictWithLocalVariable() {
-    appSource.setContent(
-        "B.dart",
-        makeCode(
-            "// filler filler filler filler filler filler filler filler filler filler filler",
-            "part of application;",
-            "methodB() {",
-            "  var symbolDependency_foo;",
-            "}"));
-    compile();
-    assertErrors(errors);
-    // Update units and compile.
-    appSource.setContent(
-        "A.dart",
-        makeCode(
-            "// filler filler filler filler filler filler filler filler filler filler filler",
-            "part of application;",
-            "var symbolDependency_foo;"));
-    compile();
-    // Now there is top-level declarations conflict between A and B.
-    // So, B should be compiled.
-    didWrite("B.dart", EXTENSION_TIMESTAMP);
-    // But application should be build.
-    assertAppBuilt();
-  }
-
-  public void test_undeclareTopLevel_conflictWithLocalVariable() {
-    appSource.setContent(
-        "A.dart",
-        makeCode(
-            "// filler filler filler filler filler filler filler filler filler filler filler",
-            "part of application;",
-            "var duplicate;"));
-    appSource.setContent(
-        "B.dart",
-        makeCode(
-            "// filler filler filler filler filler filler filler filler filler filler filler",
-            "part of application;",
-            "bar() {",
-            "  var duplicate;",
-            "}"));
-    compile();
-    // Update units and compile.
-    appSource.setContent("A.dart", "part of application;");
-    compile();
-    // Top-level declaration in A was removed, so no conflict.
-    // So:
-    // ... B should be recompiled.
-    didWrite("B.dart", EXTENSION_TIMESTAMP);
-    // ... but application should be rebuild.
-    assertAppBuilt();
-  }
-
-  /**
-   * Removes A, so changes set of top level units and forces compilation.
-   */
-  public void test_removeOneSource() {
-    appSource.setContent(
-        "A.dart",
-        makeCode(
-            "// filler filler filler filler filler filler filler filler filler filler filler",
-            "part of application;",
-            "var duplicate;"));
-    appSource.setContent(
-        "B.dart",
-        makeCode(
-            "// filler filler filler filler filler filler filler filler filler filler filler",
-            "part of application;",
-            "bar() {",
-            "  var duplicate;",
-            "}"));
-    compile();
-    // Exclude A and compile.
-    appSource.setContent(
-        APP,
-        makeCode(
-            "// filler filler filler filler filler filler filler filler filler filler filler",
-            "library app;",
-            "part 'B.dart';",
-            ""));
-    compile();
-    // Now there is top-level declarations conflict between A and B.
-    // So:
-    // ... B should be recompiled.
-    didWrite("B.dart", EXTENSION_TIMESTAMP);
-    // ... but application should be rebuild.
-    didWrite(APP, EXTENSION_DEPS);
-  }
-
-  public void test_declareField_conflictWithLocalVariable() {
-    appSource.setContent(
-        "A.dart",
-        makeCode(
-            "// filler filler filler filler filler filler filler filler filler filler filler",
-            "part of application;",
-            "class A {",
-            "}",
-            ""));
-    appSource.setContent(
-        "B.dart",
-        makeCode(
-            "// filler filler filler filler filler filler filler filler filler filler filler",
-            "part of application;",
-            "class B extends A {",
-            "  foo() {",
-            "    var bar;",
-            "  }",
-            "}",
-            ""));
-    compile();
-    assertErrors(errors);
-    // Update units and compile.
-    appSource.setContent(
-        "A.dart",
-        makeCode(
-            "// filler filler filler filler filler filler filler filler filler filler filler",
-            "part of application;",
-            "class A {",
-            "  var bar;",
-            "}",
-            ""));
-    compile();
-    // B depends on A class, so compiled.
-    didWrite("B.dart", EXTENSION_TIMESTAMP);
-    assertAppBuilt();
-  }
-
-  public void test_declareTopLevelVariable_conflictOtherTopLevelVariable() {
-    appSource.setContent(
-        "A.dart",
-        makeCode(
-            "// filler filler filler filler filler filler filler filler filler filler filler",
-            "part of application;",
-            "var conflict;",
-            ""));
-    compile();
-    assertErrors(errors);
-    // Update units and compile.
-    appSource.setContent(
-        "B.dart",
-        makeCode(
-            "// filler filler filler filler filler filler filler filler filler filler filler",
-            "part of application;",
-            "var conflict;",
-            ""));
-    compile();
-    // A symbols intersect with new B symbols, so we compile A too.
-    // Both A and B have errors.
-    assertErrors(
-        errors,
-        errEx("A.dart", ResolverErrorCode.DUPLICATE_TOP_LEVEL_DECLARATION, 3, 5, 8),
-        errEx("B.dart", ResolverErrorCode.DUPLICATE_TOP_LEVEL_DECLARATION, 3, 5, 8));
-  }
-
-  /**
-   * Test that invalid "import" is reported as any other error between "unitAboutToCompile" and
-   * "unitCompiled".
-   */
-  public void test_reportMissingImport() throws Exception {
-    appSource.setContent(
-        APP,
-        makeCode(
-            "// filler filler filler filler filler filler filler filler filler filler filler",
-            "library app;",
-            "import 'dart:noSuchLib.dart';",
-            ""));
-    // Remember errors only between unitAboutToCompile/unitCompiled.
-    errors.clear();
-    DartCompilerListener listener = new DartCompilerListener.Empty() {
-      boolean isCompiling = false;
-
-      @Override
-      public void unitAboutToCompile(DartSource source, boolean diet) {
-        isCompiling = true;
-      }
-
-      @Override
-      public void onError(DartCompilationError event) {
-        if (isCompiling) {
-          errors.add(event);
-        }
-      }
-
-      @Override
-      public void unitCompiled(DartUnit unit) {
-        isCompiling = false;
-      }
-    };
-    DartCompiler.compileLib(appSource, config, provider, listener);
-    // Check that errors where reported (and in correct time).
-    assertErrors(errors, errEx(DartCompilerErrorCode.MISSING_SOURCE, 3, 1, 29));
-  }
-
-  /**
-   * <p>
-   * http://code.google.com/p/dart/issues/detail?id=6859
-   */
-  public void test_reportMissingImport_dart() throws Exception {
-    appSource.setContent(
-        APP,
-        makeCode(
-            "// filler filler filler filler filler filler filler filler filler filler filler",
-            "library app;",
-            "import 'dart:mirrors as mirrors';",
-            ""));
-    compile();
-    // Check that errors where reported (and in correct time).
-    assertErrors(errors, errEx(DartCompilerErrorCode.MISSING_SOURCE, 3, 1, 33));
-  }
-
-  /**
-   * Test that same prefix can be used to import several libraries.
-   */
-  public void test_samePrefix_severalLibraries() throws Exception {
-    appSource.setContent(
-        APP,
-        makeCode(
-            "// filler filler filler filler filler filler filler filler filler filler filler",
-            "library application;",
-            "import 'A.dart' as p;",
-            "import 'B.dart' as p;",
-            "f() {",
-            "  p.a = 1;",
-            "  p.b = 2;",
-            "}",
-            ""));
-    appSource.setContent(
-        "A.dart",
-        makeCode(
-            "// filler filler filler filler filler filler filler filler filler filler filler",
-            "library A;",
-            "var a;",
-            ""));
-    appSource.setContent(
-        "B.dart",
-        makeCode(
-            "// filler filler filler filler filler filler filler filler filler filler filler",
-            "library B;",
-            "var b;",
-            ""));
-    // do compile, no errors expected
-    compile();
-    assertErrors(errors);
-  }
-
-  /**
-   * Checks that it is a compile-time error when a library directly imports two other libraries that
-   * have the same library name.
-   */
-  public void test_importTwoLibraries_withSameName() throws Exception {
-    appSource.setContent(
-        "A.dart",
-        makeCode(
-            "// filler filler filler filler filler filler filler filler filler filler filler",
-            "library duplicate_name;",
-            ""));
-    appSource.setContent(
-        "B.dart",
-        makeCode(
-            "// filler filler filler filler filler filler filler filler filler filler filler",
-            "library duplicate_name;",
-            ""));
-    appSource.setContent(
-        APP,
-        makeCode(
-            "// filler filler filler filler filler filler filler filler filler filler filler",
-            "library test.app;",
-            "import 'A.dart';",
-            "import 'B.dart';",
-            "main() {",
-            "}",
-            ""));
-    compile();
-    assertErrors(
-        errors,
-        errEx(APP, DartCompilerErrorCode.DUPLICATE_IMPORTED_LIBRARY_NAME, 4, 1, 16));
-  }
-
-  /**
-   * Checks valid library definitions with metadata.
-   */
-  public void test_importLibrary_withMetaBeforeLibraryDirective() throws Exception {
-    appSource.setContent(
-        "A.dart",
-        makeCode(
-            "// filler filler filler filler filler filler filler filler filler filler filler",
-            "@meta library A;",
-            "const int meta = 1;",
-            ""));
-    appSource.setContent(
-        APP,
-        makeCode(
-            "// filler filler filler filler filler filler filler filler filler filler filler",
-            "library test.app;",
-            "import 'A.dart';",
-            ""));
-    compile();
-    assertErrors(errors);
-  }
-
-  /**
-   * Checks that it is not an error to use a multi-line string literal as a URI in a part directive.
-   * Even with leading whitespace since it's getting trimmed. Even with Windows \r\n style.
-   */
-  public void test_importLibrary_multiLineStringUri() throws Exception {
-    appSource.setContent(
-        "A.dart",
-        makeCode(
-            "// filler filler filler filler filler filler filler filler filler filler filler",
-            "library A;",
-            "var foo;",
-            ""));
-    appSource.setContent(
-        APP,
-        Joiner.on("\r\n").join(
-            "// filler filler filler filler filler filler filler filler filler filler filler",
-            "library app;",
-            "import '''",
-            "A.dart''';",
-            "main() {",
-            " foo;",
-            "}",
-            ""));
-    compile();
-    assertErrors(errors);
-  }
-
-  /**
-   * Checks that it is a compile-time error when the library being exported does not have a library
-   * definition.
-   */
-  public void test_exportLibrary_withoutLibraryDirective() throws Exception {
-    appSource.setContent("A.dart", "");
-    appSource.setContent(
-        APP,
-        makeCode(
-            "// filler filler filler filler filler filler filler filler filler filler filler",
-            "library test.app;",
-            "export 'A.dart';",
-            ""));
-    compile();
-    assertErrors(
-        errors,
-        errEx(APP, DartCompilerErrorCode.MISSING_LIBRARY_DIRECTIVE_EXPORT, 3, 1, 16));
-  }
-
-  /**
-   * Enabled in 0.13
-   */
-  public void test_exportLibrary_fromScript() throws Exception {
-    appSource.setContent(
-        "A.dart",
-        makeCode(
-            "// filler filler filler filler filler filler filler filler filler filler filler",
-            "library A;",
-            ""));
-    appSource.setContent(
-        APP,
-        makeCode(
-            "// filler filler filler filler filler filler filler filler filler filler filler",
-            "library myScript;",
-            "export 'A.dart';",
-            "main() {",
-            "}",
-            ""));
-    compile();
-    assertErrors(errors);
-  }
-
-  /**
-   * It is neither an error nor a warning if N is introduced by two or more imports but never
-   * referred to.
-   */
-  public void test_importConflict_notUsed() throws Exception {
-    prepare_importConflictAB();
-    appSource.setContent(
-        APP,
-        makeCode(
-            "// filler filler filler filler filler filler filler filler filler filler filler",
-            "library test.app;",
-            "import 'A.dart';",
-            "import 'B.dart';",
-            "main() {",
-            "}",
-            ""));
-    compile();
-    assertErrors(errors);
-  }
-
-  public void test_importConflict_used_asTypeAnnotation() throws Exception {
-    prepare_importConflictAB();
-    appSource.setContent(
-        APP,
-        makeCode(
-            "// filler filler filler filler filler filler filler filler filler filler filler",
-            "library test.app;",
-            "import 'A.dart';",
-            "import 'B.dart';",
-            "typedef Test MyTypeDef(Test p);",
-            "Test myFunction(Test p) {",
-            "  Test test;",
-            "}",
-            ""));
-    compile();
-    assertErrors(
-        errors,
-        errEx(APP, ResolverErrorCode.DUPLICATE_IMPORTED_NAME_TYPE, 5, 24, 4),
-        errEx(APP, ResolverErrorCode.DUPLICATE_IMPORTED_NAME_TYPE, 5, 9, 4),
-        errEx(APP, ResolverErrorCode.DUPLICATE_IMPORTED_NAME_TYPE, 6, 17, 4),
-        errEx(APP, ResolverErrorCode.DUPLICATE_IMPORTED_NAME_TYPE, 6, 1, 4),
-        errEx(APP, ResolverErrorCode.DUPLICATE_IMPORTED_NAME_TYPE, 7, 3, 4));
-  }
-
-  public void test_importConflict_used_notTypeAnnotation_1() throws Exception {
-    prepare_importConflictAB();
-    appSource.setContent(
-        APP,
-        makeCode(
-            "// filler filler filler filler filler filler filler filler filler filler filler",
-            "library test.app;",
-            "import 'A.dart';",
-            "import 'B.dart';",
-            "class A extends Test {}",
-            "main() {",
-            "}",
-            ""));
-    compile();
-    assertErrors(
-        errors,
-        errEx(APP, ResolverErrorCode.DUPLICATE_IMPORTED_NAME, 5, 17, 4));
-  }
-
-  public void test_importConflict_used_notTypeAnnotation_2() throws Exception {
-    prepare_importConflictAB();
-    appSource.setContent(
-        APP,
-        makeCode(
-            "// filler filler filler filler filler filler filler filler filler filler filler",
-            "library test.app;",
-            "import 'A.dart';",
-            "import 'B.dart';",
-            "main() {",
-            "  Test();",
-            "  Test.FOO;",
-            "  Test = 0;",
-            "  0 is Test;",
-            "}",
-            ""));
-    compile();
-    assertErrors(
-        errors,
-        errEx(APP, ResolverErrorCode.DUPLICATE_IMPORTED_NAME, 6, 3, 4),
-        errEx(APP, ResolverErrorCode.DUPLICATE_IMPORTED_NAME, 7, 3, 4),
-        errEx(APP, ResolverErrorCode.DUPLICATE_IMPORTED_NAME, 8, 3, 4),
-        errEx(APP, ResolverErrorCode.DUPLICATE_IMPORTED_NAME, 9, 8, 4));
-  }
-
-  public void test_importConflict_used_notTypeAnnotation_3() throws Exception {
-    prepare_importConflictAB();
-    appSource.setContent(
-        APP,
-        makeCode(
-            "// filler filler filler filler filler filler filler filler filler filler filler",
-            "library test.app;",
-            "import 'A.dart' hide Test;",
-            "import 'B.dart';",
-            "class A extends Test {}",
-            "main() {",
-            "}",
-            ""));
-    compile();
-    assertErrors(errors);
-  }
-
-  public void test_importConflict_used_inCommentRef() throws Exception {
-    prepare_importConflictAB();
-    appSource.setContent(
-        APP,
-        makeCode(
-            "// filler filler filler filler filler filler filler filler filler filler filler",
-            "library test.app;",
-            "import 'A.dart';",
-            "import 'B.dart';",
-            "/** [Test] */",
-            "main() {",
-            "}",
-            ""));
-    compile();
-    assertErrors(errors);
-  }
-
-  /**
-   * <p>
-   * http://code.google.com/p/dart/issues/detail?id=6824
-   */
-  public void test_exportConflict() throws Exception {
-    appSource.setContent(
-        "A.dart",
-        makeCode(
-            "// filler filler filler filler filler filler filler filler filler filler filler",
-            "library lib_a;",
-            "class Test {}",
-            ""));
-    appSource.setContent(
-        "B.dart",
-        makeCode(
-            "// filler filler filler filler filler filler filler filler filler filler filler",
-            "library lib_b;",
-            "class Test {}",
-            ""));
-    appSource.setContent(
-        APP,
-        makeCode(
-            "// filler filler filler filler filler filler filler filler filler filler filler",
-            "library test.app;",
-            "export 'A.dart';",
-            "export 'B.dart';",
-            ""));
-    compile();
-    assertErrors(errors, errEx(APP, ResolverErrorCode.DUPLICATE_EXPORTED_NAME, 4, 1, 16));
-  }
-
-  private void prepare_importConflictAB() {
-    appSource.setContent(
-        "A.dart",
-        makeCode(
-            "// filler filler filler filler filler filler filler filler filler filler filler",
-            "library lib_a;",
-            "class Test {}",
-            ""));
-    appSource.setContent(
-        "B.dart",
-        makeCode(
-            "// filler filler filler filler filler filler filler filler filler filler filler",
-            "library lib_b;",
-            "class Test {}",
-            ""));
-  }
-
-  /**
-   * <p>
-   * http://code.google.com/p/dart/issues/detail?id=5735
-   */
-  public void test_importConflict_hideNoPrefix_importAgainWithPrefix() throws Exception {
-    appSource.setContent(
-        "A.dart",
-        makeCode(
-            "// filler filler filler filler filler filler filler filler filler filler filler",
-            "library lib_a;",
-            "var E = 2.7;",
-            ""));
-    appSource.setContent(
-        "B.dart",
-        makeCode(
-            "// filler filler filler filler filler filler filler filler filler filler filler",
-            "library lib_b;",
-            "export 'A.dart' show E;",
-            "var E = 'E';",
-            ""));
-    appSource.setContent(
-        APP,
-        makeCode(
-            "// filler filler filler filler filler filler filler filler filler filler filler",
-            "library test.app;",
-            "import 'B.dart';",
-            "import 'A.dart' as M show E;",
-            "main() {",
-            "  print(E);",
-            "  print(M.E);",
-            "}",
-            ""));
-    compile();
-    assertErrors(errors);
-  }
-
-  public void test_reportMissingSource() throws Exception {
-    appSource.setContent(
-        APP,
-        makeCode(
-            "// filler filler filler filler filler filler filler filler filler filler filler",
-            "library app;",
-            "part 'noSuchUnit.dart';",
-            ""));
-    compile();
-    // Check that errors where reported (and in correct time).
-    assertErrors(errors, errEx(DartCompilerErrorCode.MISSING_SOURCE, 3, 1, 23));
-  }
-
-  public void test_reportMissingSource_withSchema_file() throws Exception {
-    URI uri = new URI("file:noSuchSource.dart");
-    Source source = new UrlSource(uri) {
-      @Override
-      public String getName() {
-        return null;
-      }
-    };
-    // should not cause exception
-    assertFalse(source.exists());
-  }
-
-  public void test_reportMissingSource_withSchema_dart() throws Exception {
-    URI uri = new URI("dart:noSuchSource");
-    Source source = new UrlSource(uri, new PackageLibraryManager()) {
-      @Override
-      public String getName() {
-        return null;
-      }
-    };
-    // should not cause exception
-    assertFalse(source.exists());
-  }
-  /**
-   * <p>
-   * http://code.google.com/p/dart/issues/detail?id=3532
-   */
-  public void test_includeSameUnitTwice() throws Exception {
-    appSource.setContent(
-        "A.dart",
-        makeCode(
-            "// filler filler filler filler filler filler filler filler filler filler filler",
-            "part of application;",
-            ""));
-    appSource.setContent(
-        APP,
-        makeCode(
-            "// filler filler filler filler filler filler filler filler filler filler filler",
-            "library application;",
-            "part 'A.dart';",
-            "part 'A.dart';",
-            ""));
-    // do compile, no errors expected
-    compile();
-    assertErrors(errors, errEx(DartCompilerErrorCode.UNIT_WAS_ALREADY_INCLUDED, 4, 1, 14));
-  }
-
-  /**
-   * There was bug that we added <code>null</code> into {@link LibraryUnit#getImports()}. Here trick
-   * is that we reference "existing" {@link Source}, which can not be read.
-   * <p>
-   * http://code.google.com/p/dart/issues/detail?id=2693
-   */
-  public void test_ignoreNullLibrary() throws Exception {
-    appSource.setContent("canNotRead.dart", MemoryLibrarySource.IO_EXCEPTION_CONTENT);
-    appSource.setContent(
-        APP,
-        makeCode(
-            "// filler filler filler filler filler filler filler filler filler filler filler",
-            "library app;",
-            "import 'canNotRead.dart';",
-            ""));
-    // use same config as Editor - resolve despite of errors
-    config = new DefaultCompilerConfiguration() {
-      @Override
-      public boolean resolveDespiteParseErrors() {
-        return true;
-      }
-    };
-    // Ignore errors, but we should not get exceptions.
-    compile();
-  }
-
-  /**
-   * <p>
-   * http://code.google.com/p/dart/issues/detail?id=4072
-   */
-  public void test_inaccessibleMethod_fromOtherLibrary_static() throws Exception {
-    appSource.setContent(
-        "A.dart",
-        makeCode(
-            "// filler filler filler filler filler filler filler filler filler filler filler",
-            "library A;",
-            "class A {",
-            "  static _privateStatic() {}",
-            "}",
-            ""));
-    appSource.setContent(
-        APP,
-        makeCode(
-            "// filler filler filler filler filler filler filler filler filler filler filler",
-            "library application;",
-            "import 'A.dart';",
-            "main() {",
-            "  A._privateStatic();",
-            "}",
-            ""));
-    // do compile, check errors
-    compile();
-    assertErrors(
-        errors,
-        errEx(ResolverErrorCode.ILLEGAL_ACCESS_TO_PRIVATE, 5, 5, 14));
-  }
-
-  /**
-   * <p>
-   * http://code.google.com/p/dart/issues/detail?id=4072
-   */
-  public void test_inaccessibleMethod_fromOtherLibrary_instance() throws Exception {
-    appSource.setContent(
-        "A.dart",
-        makeCode(
-            "// filler filler filler filler filler filler filler filler filler filler filler",
-            "library A;",
-            "class A {",
-            "  _privateInstance() {}",
-            "}",
-            ""));
-    appSource.setContent(
-        APP,
-        makeCode(
-            "// filler filler filler filler filler filler filler filler filler filler filler",
-            "library application;",
-            "import 'A.dart';",
-            "main() {",
-            "  A a = new A();",
-            "  a._privateInstance();",
-            "}",
-            ""));
-    // do compile, check errors
-    compile();
-    assertErrors(
-        errors,
-        errEx(TypeErrorCode.ILLEGAL_ACCESS_TO_PRIVATE, 6, 5, 16));
-  }
-
-  /**
-   * <p>
-   * http://code.google.com/p/dart/issues/detail?id=3266
-   */
-  public void test_inaccessibleSuperMethod_fromOtherLibrary() throws Exception {
-    appSource.setContent(
-        "A.dart",
-        makeCode(
-            "// filler filler filler filler filler filler filler filler filler filler filler",
-            "library A;",
-            "class A {",
-            "  _method() {}",
-            "}",
-            ""));
-    appSource.setContent(
-        APP,
-        makeCode(
-            "// filler filler filler filler filler filler filler filler filler filler filler",
-            "library application;",
-            "import 'A.dart';",
-            "class B extends A {",
-            "  test1() {",
-            "    _method();",
-            "  }",
-            "  test2() {",
-            "    super._method();",
-            "  }",
-            "}",
-            ""));
-    // do compile, check errors
-    compile();
-    assertErrors(
-        errors,
-        errEx(ResolverErrorCode.CANNOT_ACCESS_METHOD, 6, 5, 7),
-        errEx(ResolverErrorCode.CANNOT_ACCESS_METHOD, 9, 11, 7));
-  }
-
-  /**
-   * <p>
-   * http://code.google.com/p/dart/issues/detail?id=6822
-   */
-  public void test_useImportPrefix_asVariableName() throws Exception {
-    appSource.setContent(
-        "A.dart",
-        makeCode(
-            "// filler filler filler filler filler filler filler filler filler filler filler",
-            "library A;",
-            ""));
-    appSource.setContent(
-        APP,
-        makeCode(
-            "// filler filler filler filler filler filler filler filler filler filler filler",
-            "library application;",
-            "import 'A.dart' as prf;",
-            "main() {",
-            "  var prf;",
-            "}",
-            ""));
-    // do compile, no errors expected
-    compile();
-    assertErrors(errors);
-  }
-
-  /**
-   * <p>
-   * http://code.google.com/p/dart/issues/detail?id=3340
-   */
-  public void test_useImportPrefix_asTopLevelFieldName() throws Exception {
-    appSource.setContent(
-        "A.dart",
-        makeCode(
-            "// filler filler filler filler filler filler filler filler filler filler filler",
-            "library A;",
-            ""));
-    appSource.setContent(
-        APP,
-        makeCode(
-            "// filler filler filler filler filler filler filler filler filler filler filler",
-            "library application;",
-            "import 'A.dart' as prf;",
-            "var prf;",
-            "main() {",
-            "}",
-            ""));
-    // do compile, no errors expected
-    compile();
-    assertErrors(errors, errEx(ResolverErrorCode.CANNOT_HIDE_IMPORT_PREFIX, 4, 5, 3));
-  }
-
-  public void test_newLibrarySyntax_show() throws Exception {
-    appSource.setContent(
-        "A.dart",
-        makeCode(
-            "// filler filler filler filler filler filler filler filler filler filler filler",
-            "library test.A;",
-            "class TypeA {}",
-            "class TypeB {}",
-            "class TypeC {}",
-            ""));
-    appSource.setContent(
-        APP,
-        makeCode(
-            "// filler filler filler filler filler filler filler filler filler filler filler",
-            "library test.app;",
-            "import 'A.dart' as libA show TypeA, TypeB;",
-            "main() {",
-            "  libA.TypeA v1;",
-            "  libA.TypeB v2;",
-            "  libA.TypeC v3;",
-            "}",
-            ""));
-    // TypeC not listed in "show"
-    compile();
-    assertErrors(errors, errEx(TypeErrorCode.NO_SUCH_TYPE, 7, 3, 10));
-  }
-
-  public void test_newLibrarySyntax_hide() throws Exception {
-    appSource.setContent(
-        "A.dart",
-        makeCode(
-            "// filler filler filler filler filler filler filler filler filler filler filler",
-            "library test.A;",
-            "class TypeA {}",
-            "class TypeB {}",
-            "class TypeC {}",
-            ""));
-    appSource.setContent(
-        APP,
-        makeCode(
-            "// filler filler filler filler filler filler filler filler filler filler filler",
-            "library test.app;",
-            "import 'A.dart' as libA hide TypeC;",
-            "main() {",
-            "  libA.TypeA v1;",
-            "  libA.TypeB v2;",
-            "  libA.TypeC v3;",
-            "}",
-            ""));
-    // TypeC is listed in "hide"
-    compile();
-    assertErrors(errors, errEx(TypeErrorCode.NO_SUCH_TYPE, 7, 3, 10));
-  }
-
-  public void test_newLibrarySyntax_export_show() throws Exception {
-    appSource.setContent(
-        "A.dart",
-        makeCode(
-            "// filler filler filler filler filler filler filler filler filler filler filler",
-            "library test.A;",
-            "class TypeAA {}",
-            "class TypeAB {}",
-            "class TypeAC {}",
-            ""));
-    appSource.setContent(
-        "B.dart",
-        makeCode(
-            "// filler filler filler filler filler filler filler filler filler filler filler",
-            "library test.B;",
-            "export 'A.dart' show TypeAA, TypeAB;",
-            "class TypeBA {}",
-            "class TypeBB {}",
-            "class TypeBC {}",
-            ""));
-    appSource.setContent(
-        APP,
-        makeCode(
-            "// filler filler filler filler filler filler filler filler filler filler filler",
-            "library test.app;",
-            "import 'B.dart' as libB hide TypeAA, TypeBB;",
-            "main() {",
-            "  libB.TypeAA aa;",
-            "  libB.TypeAB ab;",
-            "  libB.TypeAC ac;",
-            "  libB.TypeBA ba;",
-            "  libB.TypeBB bb;",
-            "  libB.TypeBC bc;",
-            "}",
-            ""));
-    compile();
-    assertErrors(
-        errors,
-        errEx(TypeErrorCode.NO_SUCH_TYPE, 5, 3, 11),
-        errEx(TypeErrorCode.NO_SUCH_TYPE, 7, 3, 11),
-        errEx(TypeErrorCode.NO_SUCH_TYPE, 9, 3, 11));
-    assertTrue(errors.toString().contains("libB.TypeAA"));
-    assertTrue(errors.toString().contains("libB.TypeAC"));
-    assertTrue(errors.toString().contains("libB.TypeBB"));
-  }
-
-  public void test_newLibrarySyntax_export2() throws Exception {
-    appSource.setContent(
-        "A.dart",
-        makeCode(
-            "// filler filler filler filler filler filler filler filler filler filler filler",
-            "library libA;",
-            "class SourceString {}",
-            ""));
-    appSource.setContent(
-        "B.dart",
-        makeCode(
-            "// filler filler filler filler filler filler filler filler filler filler filler",
-            "library libB;",
-            "import 'C.dart';",
-            "export 'A.dart' show SourceString;",
-            ""));
-    appSource.setContent(
-        "C.dart",
-        makeCode(
-            "// filler filler filler filler filler filler filler filler filler filler filler",
-            "library libC;",
-            "import 'B.dart';",
-            "foo() {",
-            "  SourceString s;",
-            "}",
-            ""));
-    appSource.setContent(
-        APP,
-        makeCode(
-            "// filler filler filler filler filler filler filler filler filler filler filler",
-            "library app;",
-            "import 'B.dart';",
-            ""));
-    compile();
-    assertErrors(errors);
-  }
-
-  public void test_newLibrarySyntax_export3() throws Exception {
-    appSource.setContent(
-        "A.dart",
-        makeCode(
-            "// filler filler filler filler filler filler filler filler filler filler filler",
-            "library libA;",
-            "class SourceString {}",
-            ""));
-    appSource.setContent(
-        "B.dart",
-        makeCode(
-            "// filler filler filler filler filler filler filler filler filler filler filler",
-            "library libB;",
-            "export 'C.dart';",
-            "export 'A.dart' show SourceString;",
-            ""));
-    appSource.setContent(
-        "C.dart",
-        makeCode(
-            "// filler filler filler filler filler filler filler filler filler filler filler",
-            "library libC;",
-            "import 'B.dart';",
-            "foo() {",
-            "  SourceString s;",
-            "}",
-            ""));
-    appSource.setContent(
-        APP,
-        makeCode(
-            "// filler filler filler filler filler filler filler filler filler filler filler",
-            "library app;",
-            "import 'B.dart';",
-            ""));
-    compile();
-    assertErrors(errors);
-  }
-
-  public void test_newLibrarySyntax_export4() throws Exception {
-    appSource.setContent(
-        "p1.dart",
-        makeCode(
-            "// filler filler filler filler filler filler filler filler filler filler filler",
-            "library lib1;",
-            "export 'p3.dart';",
-            ""));
-    appSource.setContent(
-        "p2.dart",
-        makeCode(
-            "// filler filler filler filler filler filler filler filler filler filler filler",
-            "library lib2;",
-            "export 'p3.dart';",
-            ""));
-    appSource.setContent(
-        "p3.dart",
-        makeCode(
-            "// filler filler filler filler filler filler filler filler filler filler filler",
-            "library lib3;",
-            "class MyClass {}",
-            ""));
-    appSource.setContent(
-        APP,
-        makeCode(
-            "// filler filler filler filler filler filler filler filler filler filler filler",
-            "library app;",
-            "import 'p1.dart' hide MyClass;",
-            "import 'p2.dart';",
-            "MyClass topLevelField;",
-            ""));
-    compile();
-    assertErrors(errors);
-  }
-
-  public void test_newLibrarySyntax_export_hide() throws Exception {
-    appSource.setContent(
-        "A.dart",
-        makeCode(
-            "// filler filler filler filler filler filler filler filler filler filler filler",
-            "library test.A;",
-            "class TypeAA {}",
-            "class TypeAB {}",
-            "class TypeAC {}",
-            ""));
-    appSource.setContent(
-        "B.dart",
-        makeCode(
-            "// filler filler filler filler filler filler filler filler filler filler filler",
-            "library test.B;",
-            "export 'A.dart' hide TypeAC;",
-            "class TypeBA {}",
-            "class TypeBB {}",
-            "class TypeBC {}",
-            ""));
-    appSource.setContent(
-        APP,
-        makeCode(
-            "// filler filler filler filler filler filler filler filler filler filler filler",
-            "library test.app;",
-            "import 'B.dart' as libB hide TypeAA, TypeBB;",
-            "main() {",
-            "  libB.TypeAA aa;",
-            "  libB.TypeAB ab;",
-            "  libB.TypeAC ac;",
-            "  libB.TypeBA ba;",
-            "  libB.TypeBB bb;",
-            "  libB.TypeBC bc;",
-            "}",
-            ""));
-    compile();
-    assertErrors(
-        errors,
-        errEx(TypeErrorCode.NO_SUCH_TYPE, 5, 3, 11),
-        errEx(TypeErrorCode.NO_SUCH_TYPE, 7, 3, 11),
-        errEx(TypeErrorCode.NO_SUCH_TYPE, 9, 3, 11));
-    assertTrue(errors.toString().contains("libB.TypeAA"));
-    assertTrue(errors.toString().contains("libB.TypeAC"));
-    assertTrue(errors.toString().contains("libB.TypeBB"));
-  }
-
-  public void test_newLibrarySyntax_noExport() throws Exception {
-    appSource.setContent(
-        "A.dart",
-        makeCode(
-            "// filler filler filler filler filler filler filler filler filler filler filler",
-            "library test.A;",
-            "class TypeAA {}",
-            "class TypeAB {}",
-            "class TypeAC {}",
-            ""));
-    appSource.setContent(
-        "B.dart",
-        makeCode(
-            "// filler filler filler filler filler filler filler filler filler filler filler",
-            "library test.B;",
-            "import 'A.dart' as libA;",
-            "class TypeBA {}",
-            "class TypeBB {}",
-            "class TypeBC {}",
-            ""));
-    appSource.setContent(
-        APP,
-        makeCode(
-            "// filler filler filler filler filler filler filler filler filler filler filler",
-            "library test.app;",
-            "import 'B.dart' as libB;",
-            "main() {",
-            "  libB.TypeAA aa;",
-            "  libB.TypeAB ab;",
-            "  libB.TypeAC ac;",
-            "  libB.TypeBA ba;",
-            "  libB.TypeBB bb;",
-            "  libB.TypeBC bc;",
-            "}",
-            ""));
-    compile();
-    assertErrors(
-        errors,
-        errEx(TypeErrorCode.NO_SUCH_TYPE, 5, 3, 11),
-        errEx(TypeErrorCode.NO_SUCH_TYPE, 6, 3, 11),
-        errEx(TypeErrorCode.NO_SUCH_TYPE, 7, 3, 11));
-    assertTrue(errors.toString().contains("libB.TypeAA"));
-    assertTrue(errors.toString().contains("libB.TypeAB"));
-    assertTrue(errors.toString().contains("libB.TypeAC"));
-  }
-
-  /**
-   * <p>
-   * http://code.google.com/p/dart/issues/detail?id=7598
-   */
-  public void test_newLibrarySyntax_export_withMetadata() throws Exception {
-    appSource.setContent(
-        "A.dart",
-        makeCode(
-            "// filler filler filler filler filler filler filler filler filler filler filler",
-            "library test.A;",
-            "var a = 0;",
-            ""));
-    appSource.setContent(
-        "B.dart",
-        makeCode(
-            "// filler filler filler filler filler filler filler filler filler filler filler",
-            "library test.B;",
-            "@meta export 'A.dart';",
-            "const meta = 'meta!';",
-            ""));
-    appSource.setContent(
-        APP,
-        makeCode(
-            "// filler filler filler filler filler filler filler filler filler filler filler",
-            "library test.app;",
-            "import 'B.dart';",
-            "main() {",
-            "  print(a);",
-            "}",
-            ""));
-    compile();
-    assertErrors(errors);
-  }
-
-  /**
-   * <p>
-   * http://code.google.com/p/dart/issues/detail?id=4238
-   */
-  public void test_typesPropagation_html_query() throws Exception {
-    appSource.setContent(
-        APP,
-        makeCode(
-            "// filler filler filler filler filler filler filler filler filler filler filler",
-            "library application;",
-            "import 'dart:html';",
-            "main() {",
-            "  var v1 = query('a');",
-            "  var v2 = query('A');",
-            "  var v3 = query('body:active');",
-            "  var v4 = query('button[foo=\"bar\"]');",
-            "  var v5 = query('div.class');",
-            "  var v6 = query('input#id');",
-            "  var v7 = query('select#id');",
-            "  // invocation of method",
-            "  var m1 = document.query('div');",
-            "  // unsupported currently",
-            "  var b1 = query('noSuchTag');",
-            "  var b2 = query('DART_EDITOR_NO_SUCH_TYPE');",
-            "  var b3 = query('body div');",
-            "}",
-            ""));
-    // do compile, no errors expected
-    compile();
-    assertErrors(errors);
-    // validate types
-    DartUnit unit = units.get(APP);
-    assertNotNull(unit);
-    assertInferredElementTypeString(unit, "v1", "AnchorElement", TypeQuality.INFERRED);
-    assertInferredElementTypeString(unit, "v2", "AnchorElement", TypeQuality.INFERRED);
-    assertInferredElementTypeString(unit, "v3", "BodyElement", TypeQuality.INFERRED);
-    assertInferredElementTypeString(unit, "v4", "ButtonElement", TypeQuality.INFERRED);
-    assertInferredElementTypeString(unit, "v5", "DivElement", TypeQuality.INFERRED);
-    assertInferredElementTypeString(unit, "v6", "InputElement", TypeQuality.INFERRED);
-    assertInferredElementTypeString(unit, "v7", "SelectElement", TypeQuality.INFERRED);
-    // invocation of method
-    assertInferredElementTypeString(unit, "m1", "DivElement", TypeQuality.INFERRED);
-    // bad cases, or unsupported now
-    assertInferredElementTypeString(unit, "b1", "Element", TypeQuality.INFERRED);
-    assertInferredElementTypeString(unit, "b2", "Element", TypeQuality.INFERRED);
-    assertInferredElementTypeString(unit, "b3", "Element", TypeQuality.INFERRED);
-  }
-
-  /**
-   * Libraries "dart:io" and "dart:html" can not be used together in single application.
-   * <p>
-   * http://code.google.com/p/dart/issues/detail?id=3839
-   */
-  public void test_consoleWebMix() throws Exception {
-    appSource.setContent(
-        APP,
-        makeCode(
-            "// filler filler filler filler filler filler filler filler filler filler filler",
-            "library application;",
-            "import 'dart:io';",
-            "import 'dart:html';",
-            ""));
-    // do compiled
-    compile();
-    // find expected error
-    boolean found = false;
-    for (DartCompilationError error : errors) {
-      found |= error.getErrorCode() == DartCompilerErrorCode.CONSOLE_WEB_MIX;
-    }
-    assertTrue(found);
-  }
-
-  /**
-   * <p>
-   * http://code.google.com/p/dart/issues/detail?id=3531
-   * <p>
-   * Revised 2012-12-12 - specification has no rule about import prefix and built-in identifier.
-   */
-  public void test_builtInIdentifier_asImportPrefix() throws Exception {
-    appSource.setContent(
-        "A.dart",
-        makeCode(
-            "// filler filler filler filler filler filler filler filler filler filler filler",
-            "library A;",
-            ""));
-    appSource.setContent(
-        APP,
-        makeCode(
-            "// filler filler filler filler filler filler filler filler filler filler filler",
-            "library application;",
-            "import 'A.dart' as abstract;",
-            "import 'A.dart' as as;",
-            "import 'A.dart' as dynamic;",
-            "import 'A.dart' as export;",
-            "import 'A.dart' as external;",
-            "import 'A.dart' as factory;",
-            "import 'A.dart' as get;",
-            "import 'A.dart' as implements;",
-            "import 'A.dart' as import;",
-            "import 'A.dart' as library;",
-            "import 'A.dart' as operator;",
-            "import 'A.dart' as part;",
-            "import 'A.dart' as set;",
-            "import 'A.dart' as static;",
-            "import 'A.dart' as typedef;",
-            "main() {",
-            "  var prf;",
-            "}",
-            ""));
-    // do compile, no errors expected
-    compile();
-    assertEquals(0, errors.size());
-  }
-
-  public void test_implicitlyImportCore() throws Exception {
-    appSource.setContent(
-        APP,
-        makeCode(
-            "// filler filler filler filler filler filler filler filler filler filler filler",
-            "library application;",
-            "import 'dart:core';",
-            ""));
-    compile();
-    ErrorExpectation.assertErrors(errors);
-  }
-
-  /**
-   * Investigation of failing "language/ct_const4_test".
-   */
-  public void test_useConstFromLib() throws Exception {
-    appSource.setContent(
-        "A.dart",
-        makeCode(
-            "// filler filler filler filler filler filler filler filler filler filler filler",
-            "library A;",
-            "final B = 1;",
-            ""));
-    appSource.setContent(
-        APP,
-        makeCode(
-            "// filler filler filler filler filler filler filler filler filler filler filler",
-            "library application;",
-            "import 'A.dart' as mylib;",
-            "final A = mylib.B;",
-            ""));
-    // do compile, no errors expected
-    compile();
-    assertErrors(errors);
-  }
-
-  /**
-   * Part should have one and only one directive - "part of".
-   */
-  public void test_partDirectives_otherThenPartOf() throws Exception {
-    appSource.setContent(
-        "A.dart",
-        makeCode(
-            "// filler filler filler filler filler filler filler filler filler filler filler",
-            "library A;",
-            ""));
-    appSource.setContent(
-        APP,
-        makeCode(
-            "// filler filler filler filler filler filler filler filler filler filler filler",
-            "library application;",
-            "part 'A.dart';",
-            ""));
-    // do compile
-    compile();
-    assertErrors(errors, errEx(DartCompilerErrorCode.ILLEGAL_DIRECTIVES_IN_SOURCED_UNIT, 2, 1, 10));
-  }
-
-  /**
-   * Part should have one and only one directive - "part of".
-   */
-  public void test_partDirectives_otherThenPartOf2() throws Exception {
-    appSource.setContent(
-        "A.dart",
-        makeCode(
-            "// filler filler filler filler filler filler filler filler filler filler filler",
-            "part of application;",
-            "part 'A.dart';",
-            ""));
-    appSource.setContent(
-        APP,
-        makeCode(
-            "// filler filler filler filler filler filler filler filler filler filler filler",
-            "library application;",
-            "part 'A.dart';",
-            ""));
-    // do compile
-    compile();
-    assertErrors(errors, errEx(DartCompilerErrorCode.ILLEGAL_DIRECTIVES_IN_SOURCED_UNIT, 2, 1, 20));
-  }
-
-  /**
-   * Part should have one and only one directive - "part of".
-   */
-  public void test_partDirectives_noPartOf() throws Exception {
-    appSource.setContent(
-        "A.dart",
-        makeCode(
-            "// filler filler filler filler filler filler filler filler filler filler filler",
-            ""));
-    appSource.setContent(
-        APP,
-        makeCode(
-            "// filler filler filler filler filler filler filler filler filler filler filler",
-            "library application;",
-            "part 'A.dart';",
-            ""));
-    // do compile
-    compile();
-    assertErrors(errors, errEx(DartCompilerErrorCode.MISSING_PART_OF_DIRECTIVE, -1, -1, 0));
-  }
-
-  /**
-   * Part should have one and only one directive - "part of".
-   */
-  public void test_partDirectives_wrongNameInPartOf() throws Exception {
-    appSource.setContent(
-        "A.dart",
-        makeCode(
-            "// filler filler filler filler filler filler filler filler filler filler filler",
-            "part of Z;",
-            ""));
-    appSource.setContent(
-        APP,
-        makeCode(
-            "// filler filler filler filler filler filler filler filler filler filler filler",
-            "library application;",
-            "part 'A.dart';",
-            ""));
-    // do compile
-    compile();
-    assertErrors(
-        errors,
-        errEx(DartCompilerErrorCode.WRONG_PART_OF_NAME, 2, 1, 10),
-        errEx(TypeErrorCode.CANNOT_BE_RESOLVED, 2, 9, 1));
-  }
-
-  /**
-   * Internals of Dart use "dart-ext:" import scheme, and these libraries are allowed to use
-   * "native". New import syntax.
-   */
-  public void test_useNative_withDartExt_new() throws Exception {
-    appSource.setContent(
-        APP,
-        makeCode(
-            "// filler filler filler filler filler filler filler filler filler filler filler",
-            "library A;",
-            "import 'dart-ext:test_extension';",
-            "class A {",
-            "  static int ifNull(a, b) native 'TestExtension_IfNull';",
-            "}",
-            ""));
-    // do compile, no errors expected
-    compile();
-    assertErrors(errors);
-  }
-
-  /**
-   * <p>
-   * http://code.google.com/p/dart/issues/detail?id=6077
-   */
-  public void test_dartMirrors_notFullyImplemented() throws Exception {
-    appSource.setContent(
-        APP,
-        makeCode("// filler filler filler filler filler filler filler filler filler filler filler",
-            "import 'dart:mirrors';"));
-    // do compile, no errors expected
-    compile();
-    assertErrors(errors, errEx(DartCompilerErrorCode.MIRRORS_NOT_FULLY_IMPLEMENTED, 2, 1, 22));
-  }
-
-  private void assertAppBuilt() {
-    didWrite(APP, EXTENSION_DEPS);
-  }
-
-  private void compile() {
-    compile(appSource);
-  }
-
-  private void compile(LibrarySource lib) {
-    try {
-      provider.resetReadsAndWrites();
-      errors.clear();
-      DartCompilerListener listener = new DartCompilerListener.Empty() {
-        Set<URI> compilingUris = Sets.newHashSet();
-
-        @Override
-        public void unitAboutToCompile(DartSource source, boolean diet) {
-          compilingUris.add(source.getUri());
-        }
-
-        @Override
-        public void onError(DartCompilationError event) {
-          // ignore deprecated
-          if (event.getErrorCode() == TypeErrorCode.DEPRECATED_ELEMENT) {
-            return;
-          }
-          // Remember errors only between unitAboutToCompile/unitCompiled.
-          Source source = event.getSource();
-          if (source != null && compilingUris.contains(source.getUri())) {
-            errors.add(event);
-          }
-        }
-
-        @Override
-        public void unitCompiled(DartUnit unit) {
-          compilingUris.remove(unit.getSourceInfo().getSource().getUri());
-          units.put(unit.getSourceName(), unit);
-        }
-      };
-      DartCompiler.compileLib(lib, config, provider, listener);
-    } catch (IOException e) {
-      throw new AssertionFailedError("Unexpected IOException: " + e.getMessage());
-    }
-  }
-
-  private void didWrite(String sourceName, String extension) {
-    String spec = sourceName + "/" + extension;
-    assertTrue("Expected write: " + spec, provider.writes.contains(spec));
-  }
-
-  private void didNotWrite(String sourceName, String extension) {
-    String spec = sourceName + "/" + extension;
-    assertFalse("Didn't expect write: " + spec, provider.writes.contains(spec));
-  }
-}
diff --git a/compiler/javatests/com/google/dart/compiler/end2end/inc/IncrementalCompilationTest.java b/compiler/javatests/com/google/dart/compiler/end2end/inc/IncrementalCompilationTest.java
deleted file mode 100644
index ea7e9e1..0000000
--- a/compiler/javatests/com/google/dart/compiler/end2end/inc/IncrementalCompilationTest.java
+++ /dev/null
@@ -1,631 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.end2end.inc;
-
-import static com.google.dart.compiler.DartCompiler.EXTENSION_DEPS;
-import static com.google.dart.compiler.DartCompiler.EXTENSION_TIMESTAMP;
-
-import com.google.common.collect.Lists;
-import com.google.dart.compiler.CompilerTestCase;
-import com.google.dart.compiler.DartCompilationError;
-import com.google.dart.compiler.DartCompiler;
-import com.google.dart.compiler.DartCompilerListener;
-import com.google.dart.compiler.DefaultCompilerConfiguration;
-import com.google.dart.compiler.LibrarySource;
-import com.google.dart.compiler.MockArtifactProvider;
-import com.google.dart.compiler.MockBundleLibrarySource;
-import com.google.dart.compiler.Source;
-import com.google.dart.compiler.util.apache.StringUtils;
-
-import junit.framework.AssertionFailedError;
-
-import java.io.IOException;
-import java.io.Reader;
-import java.io.Writer;
-import java.util.List;
-import java.util.Set;
-import java.util.concurrent.ConcurrentSkipListSet;
-
-// TODO(zundel): update this test not to rely on code generation
-public class IncrementalCompilationTest extends CompilerTestCase {
-
-  private static final String TEST_BASE_PATH = "com/google/dart/compiler/end2end/inc/";
-  private static final String TEST_APP = "my.app.dart";
-
-  static class IncMockArtifactProvider extends MockArtifactProvider {
-    Set<String> reads = new ConcurrentSkipListSet<String>();
-    Set<String> writes = new ConcurrentSkipListSet<String>();
-
-    @Override
-    public Reader getArtifactReader(Source source, String part, String extension) {
-      reads.add(source.getName() + "/" + extension);
-      return super.getArtifactReader(source, part, extension);
-    }
-
-    @Override
-    public Writer getArtifactWriter(Source source, String part, String extension) {
-      writes.add(source.getName() + "/" + extension);
-      return super.getArtifactWriter(source, part, extension);
-    }
-
-    void resetReadsAndWrites() {
-      reads.clear();
-      writes.clear();
-    }
-  }
-
-  private DefaultCompilerConfiguration config;
-  private IncMockArtifactProvider provider;
-
-  private MockBundleLibrarySource myAppSource;
-  private MockBundleLibrarySource someLibSource;
-  private MockBundleLibrarySource someImplLibSource;
-
-  private final List<DartCompilationError> errors = Lists.newArrayList();
-
-  @Override
-  protected void setUp() throws Exception {
-    config = new DefaultCompilerConfiguration() {
-      @Override
-      public boolean incremental() {
-        return true;
-      }
-    };
-    provider = new IncMockArtifactProvider();
-
-    myAppSource = new MockBundleLibrarySource(IncrementalCompilationTest.class.getClassLoader(),
-      TEST_BASE_PATH, TEST_APP);
-    someLibSource = myAppSource.getImportFor("some.lib.dart");
-    someImplLibSource = someLibSource.getImportFor("someimpl.lib.dart");
-  }
-
-  @Override
-  protected void tearDown() {
-    config = null;
-    provider = null;
-    myAppSource = null;
-    someLibSource = null;
-    someImplLibSource = null;
-  }
-
-  public void testRemoveDeps() throws Exception {
-    compile();
-
-    MockBundleLibrarySource myNuke5AppSource = new MockBundleLibrarySource(
-      IncrementalCompilationTest.class.getClassLoader(),
-      TEST_BASE_PATH, "my.nuke5.app.dart", "my.app.dart");
-    myNuke5AppSource.remapSource("mybase.dart", "mybase.no5ref.dart");
-    myNuke5AppSource.remapSource("my.dart", "my.no5ref.dart");
-    myNuke5AppSource.removeSource("myother5.dart");
-
-    compile(myNuke5AppSource);
-  }
-
-  public void testFullCompile() {
-    compile();
-    System.out.println(StringUtils.join(errors, "\n"));
-
-    // Assert that all artifacts are written.
-    didWrite("someimpl.dart", EXTENSION_TIMESTAMP);
-    didWrite("someimpl.lib.dart", EXTENSION_DEPS);
-
-    didWrite("some.dart", EXTENSION_TIMESTAMP);
-    didWrite("some.lib.dart", EXTENSION_DEPS);
-
-    didWrite("my.dart", EXTENSION_TIMESTAMP);
-    didWrite("myother0.dart", EXTENSION_TIMESTAMP);
-    didWrite("myother1.dart", EXTENSION_TIMESTAMP);
-    didWrite("myother2.dart", EXTENSION_TIMESTAMP);
-    didWrite("my.app.dart", EXTENSION_DEPS);
-    didWrite("my.app.dart", EXTENSION_TIMESTAMP);
-  }
-
-  public void testNoOpRecompile() {
-    compile();
-
-    provider.resetReadsAndWrites();
-    compile();
-
-    // Assert we didn't write anything.
-    didNotWrite("someimpl.dart", EXTENSION_TIMESTAMP);
-    didNotWrite("someimpl.lib.dart", EXTENSION_DEPS);
-
-    didNotWrite("some.dart", EXTENSION_TIMESTAMP);
-    didNotWrite("some.lib.dart", EXTENSION_DEPS);
-
-    didNotWrite("my.dart", EXTENSION_TIMESTAMP);
-    didNotWrite("myother0.dart", EXTENSION_TIMESTAMP);
-    didNotWrite("myother1.dart", EXTENSION_TIMESTAMP);
-    didNotWrite("myother2.dart", EXTENSION_TIMESTAMP);
-    didNotWrite("my.app.dart", EXTENSION_DEPS);
-    didNotWrite("my.app.dart", EXTENSION_TIMESTAMP);
-  }
-
-  public void testTouchOneSource() {
-    compile();
-
-    provider.resetReadsAndWrites();
-    myAppSource.touchSource("my.dart");
-    compile();
-
-    // We just bumped the timestamp on my.dart, so only my.dart.js and my.app.js should be changed.
-    // At present, the app's deps and api will be rewritten. This might be optimized later.
-    didWrite("my.dart", EXTENSION_TIMESTAMP);
-    didWrite("my.app.dart", EXTENSION_DEPS);
-
-    // Nothing else should have changed.
-    didNotWrite("someimpl.dart", EXTENSION_TIMESTAMP);
-    didNotWrite("someimpl.lib.dart", EXTENSION_DEPS);
-
-    didNotWrite("some.dart", EXTENSION_TIMESTAMP);
-    didNotWrite("some.lib.dart", EXTENSION_DEPS);
-
-    didNotWrite("myother0.dart", EXTENSION_TIMESTAMP);
-    didNotWrite("myother1.dart", EXTENSION_TIMESTAMP);
-    didNotWrite("myother2.dart", EXTENSION_TIMESTAMP);
-  }
-
-  public void testNormalizationTracking() {
-    compile();
-
-    provider.resetReadsAndWrites();
-    myAppSource.touchSource("myother7.dart");
-    compile();
-
-    // Test against normalization having an effect on hashcodes
-    // SomeInterface2 is an empty interface that can have an extra default constructor added by
-    // the dartc backend normalization process.  By depending on a class that implements the interface,
-    // my.app.dart.deps will transitively depend on the empty interface.  If something changes
-    // with how hashcodes are generated, this test should be updated.
-
-    // We just bumped the timestamp on myother7.dart, so only myother7.dart.js and my.app.js should
-    // be changed. At present, the app's deps and api will be rewritten.
-
-    didWrite("myother7.dart", EXTENSION_TIMESTAMP);
-    didWrite("my.app.dart", EXTENSION_DEPS);
-
-    // Nothing else should have changed.
-    didNotWrite("my.dart", EXTENSION_TIMESTAMP);
-    didNotWrite("someimpl.dart", EXTENSION_TIMESTAMP);
-    didNotWrite("someimpl.lib.dart", EXTENSION_DEPS);
-
-    didNotWrite("some.dart", EXTENSION_TIMESTAMP);
-    didNotWrite("some.lib.dart", EXTENSION_DEPS);
-
-    didNotWrite("myother0.dart", EXTENSION_TIMESTAMP);
-    didNotWrite("myother1.dart", EXTENSION_TIMESTAMP);
-    didNotWrite("myother2.dart", EXTENSION_TIMESTAMP);
-  }
-
-  public void testKnockout_timestamp() {
-    compile();
-
-    provider.resetReadsAndWrites();
-    provider.removeArtifact("my.dart", "", EXTENSION_TIMESTAMP);
-    compile();
-
-    // At present, knocking out a js artifact will force an update of the library's api and
-    // deps. This could be optimized.
-    didWrite("my.dart", EXTENSION_TIMESTAMP);
-
-    // Assert that everything else was left alone.
-    didNotWrite("someimpl.dart", EXTENSION_TIMESTAMP);
-    didNotWrite("someimpl.lib.dart", EXTENSION_DEPS);
-
-    didNotWrite("some.dart", EXTENSION_TIMESTAMP);
-    didNotWrite("some.lib.dart", EXTENSION_DEPS);
-
-    didNotWrite("myother0.dart", EXTENSION_TIMESTAMP);
-    didNotWrite("myother1.dart", EXTENSION_TIMESTAMP);
-    didNotWrite("myother2.dart", EXTENSION_TIMESTAMP);
-  }
-
-  public void testChangeImplementation_methodBody() {
-    compile();
-
-    provider.resetReadsAndWrites();
-    someImplLibSource.remapSource("someimpl.dart", "someimpl.bodychange.dart");
-    compile();
-
-    // Changed someimpl.dart, so it, its library, and the compiled app should be written.
-    didWrite("someimpl.dart", EXTENSION_TIMESTAMP);
-    didWrite("someimpl.lib.dart", EXTENSION_DEPS);
-
-    // We've switched to (unit -> unit) dependency, so should be recompiled too.
-    didWrite("some.dart", EXTENSION_TIMESTAMP);
-    didWrite("some.lib.dart", EXTENSION_DEPS);
-
-    didNotWrite("my.dart", EXTENSION_TIMESTAMP);
-    didNotWrite("myother0.dart", EXTENSION_TIMESTAMP);
-    didNotWrite("myother1.dart", EXTENSION_TIMESTAMP);
-    didNotWrite("myother2.dart", EXTENSION_TIMESTAMP);
-    didNotWrite("my.app.dart", EXTENSION_DEPS);
-  }
-
-  public void testChangeApi_newStaticMethod() {
-    compile();
-
-    provider.resetReadsAndWrites();
-    myAppSource.remapSource("myother0.dart", "myother0.newstaticmethod.dart");
-    compile();
-
-    // Added a new static method to Other0, which should force a recompile of my.dart,
-    // because the latter contains a reference to one of its static methods.
-    didWrite("my.dart", EXTENSION_TIMESTAMP);
-    didWrite("myother0.dart", EXTENSION_TIMESTAMP);
-    didWrite("my.app.dart", EXTENSION_DEPS);
-
-    didNotWrite("someimpl.dart", EXTENSION_TIMESTAMP);
-    didNotWrite("someimpl.lib.dart", EXTENSION_DEPS);
-
-    didNotWrite("some.dart", EXTENSION_TIMESTAMP);
-    didNotWrite("some.lib.dart", EXTENSION_DEPS);
-
-    didNotWrite("myother1.dart", EXTENSION_TIMESTAMP);
-    didNotWrite("myother2.dart", EXTENSION_TIMESTAMP);
-  }
-
-  public void testChangeApi_staticFieldRef() {
-    compile();
-
-    provider.resetReadsAndWrites();
-    myAppSource.remapSource("myother3.dart", "myother3.newstaticfield.dart");
-    compile();
-
-    // Added a new static field to Other0, which should force a recompile of my.dart,
-    // because the latter contains a reference to one of its static methods.
-    didWrite("my.dart", EXTENSION_TIMESTAMP);
-    didWrite("myother3.dart", EXTENSION_TIMESTAMP);
-    didWrite("my.app.dart", EXTENSION_DEPS);
-
-    didNotWrite("someimpl.dart", EXTENSION_TIMESTAMP);
-    didNotWrite("someimpl.lib.dart", EXTENSION_DEPS);
-
-    didNotWrite("some.dart", EXTENSION_TIMESTAMP);
-    didNotWrite("some.lib.dart", EXTENSION_DEPS);
-
-    didNotWrite("myother0.dart", EXTENSION_TIMESTAMP);
-    didNotWrite("myother1.dart", EXTENSION_TIMESTAMP);
-    didNotWrite("myother2.dart", EXTENSION_TIMESTAMP);
-  }
-
-  public void testChangeApi_viaTypeParamBound() {
-    compile();
-
-    provider.resetReadsAndWrites();
-    myAppSource.remapSource("myother4.dart", "myother4.newstaticfield.dart");
-    compile();
-
-    // Added a new static field to Other0, which should force a recompile of my.dart,
-    // because the latter contains a reference to one of its static methods.
-    didWrite("my.dart", EXTENSION_TIMESTAMP);
-    didWrite("myother4.dart", EXTENSION_TIMESTAMP);
-    didWrite("my.app.dart", EXTENSION_DEPS);
-
-    didNotWrite("someimpl.dart", EXTENSION_TIMESTAMP);
-    didNotWrite("someimpl.lib.dart", EXTENSION_DEPS);
-
-    didNotWrite("some.dart", EXTENSION_TIMESTAMP);
-    didNotWrite("some.lib.dart", EXTENSION_DEPS);
-
-    didNotWrite("myother0.dart", EXTENSION_TIMESTAMP);
-    didNotWrite("myother1.dart", EXTENSION_TIMESTAMP);
-    didNotWrite("myother2.dart", EXTENSION_TIMESTAMP);
-  }
-
-  public void testChangeApi_returnTypeChange() {
-    compile();
-
-    provider.resetReadsAndWrites();
-    myAppSource.remapSource("myother0.dart", "myother0.returntypechange.dart");
-    compile();
-
-    // Changed a return type in Other0, which should force a recompile of my.dart,
-    // because the latter contains a reference to one of its static methods.
-    didWrite("my.dart", EXTENSION_TIMESTAMP);
-    didWrite("myother0.dart", EXTENSION_TIMESTAMP);
-    didWrite("my.app.dart", EXTENSION_DEPS);
-
-    didNotWrite("someimpl.dart", EXTENSION_TIMESTAMP);
-    didNotWrite("someimpl.lib.dart", EXTENSION_DEPS);
-
-    didNotWrite("some.dart", EXTENSION_TIMESTAMP);
-    didNotWrite("some.lib.dart", EXTENSION_DEPS);
-
-    didNotWrite("myother1.dart", EXTENSION_TIMESTAMP);
-    didNotWrite("myother2.dart", EXTENSION_TIMESTAMP);
-  }
-
-  public void testChangeApi_globalVarChange() {
-    compile();
-
-    provider.resetReadsAndWrites();
-    myAppSource.remapSource("myother0.dart", "myother0.globalvarchange.dart");
-    compile();
-
-    // Changed a top-level variable type in Other0, which should force a recompile of my.dart,
-    // because the latter contains a reference to one of its static methods.
-    didWrite("my.dart", EXTENSION_TIMESTAMP);
-    didWrite("myother0.dart", EXTENSION_TIMESTAMP);
-    didWrite("my.app.dart", EXTENSION_DEPS);
-  }
-
-  public void testChangeApi_globalFunctionChange() {
-    compile();
-
-    provider.resetReadsAndWrites();
-    myAppSource.remapSource("myother0.dart", "myother0.globalfunctionchange.dart");
-    compile();
-
-    // Changed a return type in Other0, which should force a recompile of my.dart,
-    // because the latter contains a reference to one of its static methods.
-    didWrite("my.dart", EXTENSION_TIMESTAMP);
-    didWrite("myother0.dart", EXTENSION_TIMESTAMP);
-    didWrite("my.app.dart", EXTENSION_DEPS);
-  }
-
-  public void testChangeApi_viaNew() {
-    compile();
-
-    provider.resetReadsAndWrites();
-    myAppSource.remapSource("myother1.dart", "myother1.change.dart");
-    compile();
-
-    // Changed the api of Other1, which should force a recompile of my.dart,
-    // because the latter instantiates one of its classes.
-    didWrite("my.dart", EXTENSION_TIMESTAMP);
-    didWrite("myother1.dart", EXTENSION_TIMESTAMP);
-    didWrite("my.app.dart", EXTENSION_DEPS);
-
-    didNotWrite("someimpl.dart", EXTENSION_TIMESTAMP);
-    didNotWrite("someimpl.lib.dart", EXTENSION_DEPS);
-
-    didNotWrite("some.dart", EXTENSION_TIMESTAMP);
-    didNotWrite("some.lib.dart", EXTENSION_DEPS);
-
-    didNotWrite("myother0.dart", EXTENSION_TIMESTAMP);
-    didNotWrite("myother2.dart", EXTENSION_TIMESTAMP);
-  }
-
-  public void testChangeApi_viaSubclassing() {
-    compile();
-
-    provider.resetReadsAndWrites();
-    myAppSource.remapSource("myother2.dart", "myother2.change.dart");
-    compile();
-
-    // Changed the api of Other2, which should force a recompile of my.dart,
-    // because the latter subclasses one of its classes.
-    didWrite("my.dart", EXTENSION_TIMESTAMP);
-    didWrite("myother2.dart", EXTENSION_TIMESTAMP);
-    didWrite("my.app.dart", EXTENSION_DEPS);
-
-    didNotWrite("someimpl.dart", EXTENSION_TIMESTAMP);
-    didNotWrite("someimpl.lib.dart", EXTENSION_DEPS);
-
-    didNotWrite("some.dart", EXTENSION_TIMESTAMP);
-    didNotWrite("some.lib.dart", EXTENSION_DEPS);
-
-    didNotWrite("myother0.dart", EXTENSION_TIMESTAMP);
-    didNotWrite("myother1.dart", EXTENSION_TIMESTAMP);
-  }
-
-  public void testChangeApi_inLibrary() {
-    compile();
-
-    provider.resetReadsAndWrites();
-    someLibSource.remapSource("some.dart", "some.newmethod.dart");
-    someImplLibSource.remapSource("someimpl.dart", "someimpl.change.dart");
-    compile();
-
-    // We changed both the interface and implementation libraries, so almost everything should have
-    // been recompiled.
-    didWrite("someimpl.dart", EXTENSION_TIMESTAMP);
-    didWrite("someimpl.lib.dart", EXTENSION_DEPS);
-
-    didWrite("some.dart", EXTENSION_TIMESTAMP);
-    didWrite("some.lib.dart", EXTENSION_DEPS);
-
-    didWrite("my.dart", EXTENSION_TIMESTAMP);
-    didWrite("my.app.dart", EXTENSION_DEPS);
-
-    // Except the "others", which have no dependency on the library.
-    didNotWrite("myother0.dart", EXTENSION_TIMESTAMP);
-    didNotWrite("myother1.dart", EXTENSION_TIMESTAMP);
-    didNotWrite("myother2.dart", EXTENSION_TIMESTAMP);
-  }
-
-  public void testChangeApi_inImplLibrary() {
-    compile();
-
-    provider.resetReadsAndWrites();
-    someImplLibSource.remapSource("someimpl.dart", "someimpl.change.dart");
-    compile();
-
-    // Assert that only the interface and implementation library were recompiled.
-    didWrite("someimpl.dart", EXTENSION_TIMESTAMP);
-    didWrite("someimpl.lib.dart", EXTENSION_DEPS);
-
-    didWrite("some.dart", EXTENSION_TIMESTAMP);
-    didWrite("some.lib.dart", EXTENSION_DEPS);
-
-    // The app should remain untouched.
-    didNotWrite("myother0.dart", EXTENSION_TIMESTAMP);
-    didNotWrite("myother1.dart", EXTENSION_TIMESTAMP);
-    didNotWrite("myother2.dart", EXTENSION_TIMESTAMP);
-    didNotWrite("my.dart", EXTENSION_TIMESTAMP);
-    didNotWrite("my.app.dart", EXTENSION_DEPS);
-  }
-
-  public void testChangeApi_inInterface() {
-    compile();
-
-    provider.resetReadsAndWrites();
-    someLibSource.remapSource("some.dart", "some.intfchange.dart");
-    compile();
-
-    didNotWrite("myother0.dart", EXTENSION_TIMESTAMP);
-    didNotWrite("myother1.dart", EXTENSION_TIMESTAMP);
-    didNotWrite("myother2.dart", EXTENSION_TIMESTAMP);
-
-    // Assert we recompiled both some.dart and someimpl.dart, as well as my.dart.
-    // (someimpl.dart is recompiled because its interface in some.dart changed)
-    didWrite("someimpl.dart", EXTENSION_TIMESTAMP);
-    didWrite("someimpl.lib.dart", EXTENSION_DEPS);
-
-    didWrite("some.dart", EXTENSION_TIMESTAMP);
-    didWrite("some.lib.dart", EXTENSION_DEPS);
-
-    didWrite("my.dart", EXTENSION_TIMESTAMP);
-    didWrite("my.app.dart", EXTENSION_DEPS);
-  }
-
-  // TODO(jgw): Bug 5319907.
-  public void disabled_testFieldHole() {
-    compile();
-
-    provider.resetReadsAndWrites();
-    myAppSource.remapSource("myother0.dart", "myother0.fillthehole.dart");
-    compile();
-
-    didNotWrite("someimpl.dart", EXTENSION_TIMESTAMP);
-    didNotWrite("someimpl.lib.dart", EXTENSION_DEPS);
-
-    didNotWrite("some.dart", EXTENSION_TIMESTAMP);
-    didNotWrite("some.lib.dart", EXTENSION_DEPS);
-
-    didNotWrite("myother1.dart", EXTENSION_TIMESTAMP);
-    didNotWrite("myother2.dart", EXTENSION_TIMESTAMP);
-
-    // Both myother0.dart and my.dart should be recompiled.
-    didWrite("my.dart", EXTENSION_TIMESTAMP);
-    didWrite("myother0.dart", EXTENSION_TIMESTAMP);
-    didWrite("my.app.dart", EXTENSION_DEPS);
-  }
-
-  public void testMethodHole() {
-    compile();
-
-    provider.resetReadsAndWrites();
-    myAppSource.remapSource("myother0.dart", "myother0.fillthemethodhole.dart");
-    compile();
-  }
-
-  public void testQualifiedFieldRef() {
-    compile();
-
-    provider.resetReadsAndWrites();
-    myAppSource.remapSource("myother5.dart", "myother5.change.dart");
-    compile();
-
-    // Changed the api of Other5, which should force a recompile of my.dart,
-    // because the latter includes a qualified reference to one of its instance fields.
-    didWrite("my.dart", EXTENSION_TIMESTAMP);
-    didWrite("myother5.dart", EXTENSION_TIMESTAMP);
-    didWrite("my.app.dart", EXTENSION_DEPS);
-
-    didNotWrite("someimpl.dart", EXTENSION_TIMESTAMP);
-    didNotWrite("someimpl.lib.dart", EXTENSION_DEPS);
-
-    didNotWrite("some.dart", EXTENSION_TIMESTAMP);
-    didNotWrite("some.lib.dart", EXTENSION_DEPS);
-
-    didNotWrite("myother0.dart", EXTENSION_TIMESTAMP);
-    didNotWrite("myother1.dart", EXTENSION_TIMESTAMP);
-    didNotWrite("myother2.dart", EXTENSION_TIMESTAMP);
-  }
-
-  public void testQualifiedMethodRef() {
-    compile();
-
-    provider.resetReadsAndWrites();
-    myAppSource.remapSource("myother6.dart", "myother6.change.dart");
-    compile();
-
-    // Changed the api of Other6, which should force a recompile of my.dart,
-    // because the latter includes a qualified reference to one of its instance methods.
-    didWrite("my.dart", EXTENSION_TIMESTAMP);
-    didWrite("myother6.dart", EXTENSION_TIMESTAMP);
-    didWrite("my.app.dart", EXTENSION_DEPS);
-
-    didNotWrite("someimpl.dart", EXTENSION_TIMESTAMP);
-    didNotWrite("someimpl.lib.dart", EXTENSION_DEPS);
-
-    didNotWrite("some.dart", EXTENSION_TIMESTAMP);
-    didNotWrite("some.lib.dart", EXTENSION_DEPS);
-
-    didNotWrite("myother0.dart", EXTENSION_TIMESTAMP);
-    didNotWrite("myother1.dart", EXTENSION_TIMESTAMP);
-    didNotWrite("myother2.dart", EXTENSION_TIMESTAMP);
-  }
-
-  public void testRemoveDepClass() {
-    compile();
-
-    provider.resetReadsAndWrites();
-    myAppSource.remapSource("myother5.dart", "myother5.change.dart");
-    myAppSource.remapSource("myother6.dart", "myother6.removeclass.dart");
-    compile();
-
-    // Changed myother6.dart, which should force a recompile of myother5.dart,
-    // because the latter had a qualified reference to one of its classes.
-    didWrite("myother5.dart", EXTENSION_TIMESTAMP);
-    didWrite("myother6.dart", EXTENSION_TIMESTAMP);
-
-    didWrite("my.dart", EXTENSION_TIMESTAMP);
-    // Because of the previous changes my.app.dart is also recompile.
-    didWrite("my.app.dart", EXTENSION_DEPS);
-
-    // No changes in not related units.
-    didNotWrite("someimpl.dart", EXTENSION_TIMESTAMP);
-    didNotWrite("someimpl.lib.dart", EXTENSION_DEPS);
-
-    didNotWrite("some.dart", EXTENSION_TIMESTAMP);
-    didNotWrite("some.lib.dart", EXTENSION_DEPS);
-
-    didNotWrite("myother0.dart", EXTENSION_TIMESTAMP);
-    didNotWrite("myother1.dart", EXTENSION_TIMESTAMP);
-    didNotWrite("myother2.dart", EXTENSION_TIMESTAMP);
-  }
-
-  public void testMergeFiles() throws Exception {
-    compile();
-
-    MockBundleLibrarySource myMergedAppSource = new MockBundleLibrarySource(
-      IncrementalCompilationTest.class.getClassLoader(),
-      TEST_BASE_PATH, "my.merged.app.dart", "my.app.dart");
-
-    compile(myMergedAppSource);
-  }
-
-  private void compile() {
-    compile(myAppSource);
-  }
-
-  private void compile(LibrarySource lib) {
-    try {
-      errors.clear();
-      DartCompilerListener listener = new DartCompilerListener.Empty() {
-        @Override
-        public void onError(DartCompilationError event) {
-          errors.add(event);
-        }
-      };
-      DartCompiler.compileLib(lib, config, provider, listener);
-    } catch (IOException e) {
-      throw new AssertionFailedError("Unexpected IOException: " + e.getMessage());
-    }
-  }
-
-  private void didWrite(String sourceName, String extension) {
-    String spec = sourceName + "/" + extension;
-    assertTrue("Expected write: " + spec, provider.writes.contains(spec));
-  }
-
-  private void didNotWrite(String sourceName, String extension) {
-    String spec = sourceName + "/" + extension;
-    assertFalse("Didn't expect write: " + spec, provider.writes.contains(spec));
-  }
-}
diff --git a/compiler/javatests/com/google/dart/compiler/end2end/inc/IncrementalCompilationWithPrefixTest.java b/compiler/javatests/com/google/dart/compiler/end2end/inc/IncrementalCompilationWithPrefixTest.java
deleted file mode 100644
index 8d47aa2..0000000
--- a/compiler/javatests/com/google/dart/compiler/end2end/inc/IncrementalCompilationWithPrefixTest.java
+++ /dev/null
@@ -1,147 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.end2end.inc;
-
-import static com.google.dart.compiler.DartCompiler.EXTENSION_DEPS;
-import static com.google.dart.compiler.DartCompiler.EXTENSION_TIMESTAMP;
-
-import com.google.dart.compiler.CompilerTestCase;
-import com.google.dart.compiler.DartCompiler;
-import com.google.dart.compiler.DartCompilerListener;
-import com.google.dart.compiler.DartCompilerListenerTest;
-import com.google.dart.compiler.DefaultCompilerConfiguration;
-import com.google.dart.compiler.LibrarySource;
-import com.google.dart.compiler.MockArtifactProvider;
-import com.google.dart.compiler.MockBundleLibrarySource;
-import com.google.dart.compiler.Source;
-
-import junit.framework.AssertionFailedError;
-
-import java.io.IOException;
-import java.io.Reader;
-import java.io.Writer;
-import java.net.URISyntaxException;
-import java.util.Set;
-import java.util.concurrent.ConcurrentSkipListSet;
-
-public class IncrementalCompilationWithPrefixTest extends CompilerTestCase {
-
-  private static final String TEST_BASE_PATH = "com/google/dart/compiler/end2end/inc/";
-
-  static class IncMockArtifactProvider extends MockArtifactProvider {
-    Set<String> reads = new ConcurrentSkipListSet<String>();
-    Set<String> writes = new ConcurrentSkipListSet<String>();
-
-    @Override
-    public Reader getArtifactReader(Source source, String part, String extension) {
-      reads.add(source.getName() + "/" + extension);
-      return super.getArtifactReader(source, part, extension);
-    }
-
-    @Override
-    public Writer getArtifactWriter(Source source, String part, String extension) {
-      // System.out.println("Writing " + source.getName() + "/" + extension);
-      writes.add(source.getName() + "/" + extension);
-      return super.getArtifactWriter(source, part, extension);
-    }
-
-    void resetReadsAndWrites() {
-      // System.out.println("Clearing reads/writes");
-      reads.clear();
-      writes.clear();
-    }
-  }
-
-  private DefaultCompilerConfiguration config;
-  private IncMockArtifactProvider provider;
-
-  private MockBundleLibrarySource myAppSource;
-  private MockBundleLibrarySource someLibSource;
-
-  @Override
-  protected void setUp() throws Exception {
-    config = new DefaultCompilerConfiguration() {
-      @Override
-      public boolean incremental() {
-        return true;
-      }
-    };
-    provider = new IncMockArtifactProvider();
-  }
-
-  @Override
-  protected void tearDown() {
-    config = null;
-    provider = null;
-    myAppSource = null;
-    someLibSource = null;
-  }
-
-  public void testModifyUnPrefixedLib() {
-    try {
-      myAppSource = new MockBundleLibrarySource(IncrementalCompilationWithPrefixTest.class.getClassLoader(),
-      TEST_BASE_PATH, "my.unprefixed.app.dart");
-      someLibSource = myAppSource.getImportFor("some.prefixable.lib.dart");
-    } catch (URISyntaxException e) {
-      throw new AssertionError(e);
-    }
-
-    compile();
-
-    provider.resetReadsAndWrites();
-    someLibSource.touchSource("some.prefixable.lib.dart");
-    someLibSource.remapSource("some.prefixable.lib.dart", "some.prefixable.modified.lib.dart");
-    compile();
-
-    didWrite("my.unprefixed.app.dart", EXTENSION_TIMESTAMP);
-    didWrite("my.unprefixed.app.dart", EXTENSION_DEPS);
-    didWrite("some.prefixable.lib.dart", EXTENSION_TIMESTAMP);
-    didWrite("some.prefixable.lib.dart", EXTENSION_DEPS);
-  }
-
-  public void testModifyPrefixedLib() {
-    try {
-      myAppSource = new MockBundleLibrarySource(IncrementalCompilationWithPrefixTest.class.getClassLoader(),
-      TEST_BASE_PATH, "my.prefixed.app.dart");
-      someLibSource = myAppSource.getImportFor("some.prefixable.lib.dart");
-    } catch (URISyntaxException e) {
-      throw new AssertionError(e);
-    }
-
-    compile();
-
-    provider.resetReadsAndWrites();
-    someLibSource.touchSource("some.prefixable.lib.dart");
-    someLibSource.remapSource("some.prefixable.lib.dart", "some.prefixable.modified.lib.dart");
-    compile();
-
-    didWrite("my.prefixed.app.dart", EXTENSION_TIMESTAMP);
-    didWrite("my.prefixed.app.dart", EXTENSION_DEPS);
-    didWrite("some.prefixable.lib.dart", EXTENSION_TIMESTAMP);
-    didWrite("some.prefixable.lib.dart", EXTENSION_DEPS);
-  }
-
-  private void compile() {
-    compile(null);
-  }
-
-  private void compile(String srcName, Object... errors) {
-    compile(myAppSource, srcName, errors);
-  }
-
-  private void compile(LibrarySource lib, String srcName, Object... errors) {
-    try {
-      DartCompilerListener listener = new DartCompilerListenerTest(srcName, errors);
-      DartCompiler.compileLib(lib, config, provider, listener);
-    } catch (IOException e) {
-      throw new AssertionFailedError("Unexpected IOException: " + e.getMessage());
-    }
-  }
-
-  private void didWrite(String sourceName, String extension) {
-    String spec = sourceName + "/" + extension;
-    assertTrue("Expected write: " + spec, provider.writes.contains(spec));
-  }
-}
diff --git a/compiler/javatests/com/google/dart/compiler/end2end/inc/MemoryLibrarySource.java b/compiler/javatests/com/google/dart/compiler/end2end/inc/MemoryLibrarySource.java
deleted file mode 100644
index e31466f..0000000
--- a/compiler/javatests/com/google/dart/compiler/end2end/inc/MemoryLibrarySource.java
+++ /dev/null
@@ -1,145 +0,0 @@
-// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-package com.google.dart.compiler.end2end.inc;
-
-import com.google.common.collect.Maps;
-import com.google.dart.compiler.DartSource;
-import com.google.dart.compiler.LibrarySource;
-import com.google.dart.compiler.Source;
-import com.google.dart.compiler.UrlDartSource;
-
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.Reader;
-import java.io.StringReader;
-import java.net.URI;
-import java.util.Map;
-
-/**
- * {@link LibrarySource} which provides content for all {@link Source}s from memory.
- */
-public class MemoryLibrarySource implements LibrarySource {
-  public static final String IO_EXCEPTION_CONTENT = "simulate-IOException";
-  private final String libName;
-  private final Map<String, DartSource> sourceMap;
-  private final Map<String, String> sourceContentMap;
-  private final Map<String, Long> sourceLastModifiedMap;
-
-  public MemoryLibrarySource(String libName) {
-    this.libName = libName;
-    sourceMap = Maps.newHashMap();
-    sourceContentMap = Maps.newHashMap();
-    sourceLastModifiedMap = Maps.newHashMap();
-  }
-
-  private MemoryLibrarySource(String libName, MemoryLibrarySource parent) {
-    this.libName = libName;
-    sourceMap = parent.sourceMap;
-    sourceContentMap = parent.sourceContentMap;
-    sourceLastModifiedMap = parent.sourceLastModifiedMap;
-  }
-
-  @Override
-  public boolean exists() {
-    return true;
-  }
-
-  @Override
-  public String getName() {
-    return libName;
-  }
-
-  @Override
-  public String getUniqueIdentifier() {
-    return libName;
-  }
-
-  @Override
-  public URI getUri() {
-    return URI.create(libName);
-  }
-
-  @Override
-  public long getLastModified() {
-    return sourceLastModifiedMap.get(libName);
-  }
-
-  @Override
-  public Reader getSourceReader() throws IOException {
-    String content = sourceContentMap.get(libName);
-    if (IO_EXCEPTION_CONTENT.equals(content)) {
-      throw new IOException("simulated");
-    }
-    if (content == null) {
-      throw new FileNotFoundException(libName);
-    }
-    return new StringReader(content);
-  }
-
-  @Override
-  public LibrarySource getImportFor(String relPath) throws IOException {
-    if (!sourceContentMap.containsKey(relPath)) {
-      return null;
-    }
-    return new MemoryLibrarySource(relPath, this);
-  }
-
-  @Override
-  public DartSource getSourceFor(final String relPath) {
-    DartSource result;
-    // check cache
-    {
-      result = sourceMap.get(relPath);
-      if (result != null) {
-        return result;
-      }
-    }
-    // prepare content
-    final String content = sourceContentMap.get(relPath);
-    final Long sourceLastModified = sourceLastModifiedMap.get(relPath);
-    // may be does not exist
-    if (content == null) {
-      return null;
-    }
-    // Return fake UrlDateSource with in-memory content.
-    final URI uri = URI.create(relPath);
-    result = new UrlDartSource(uri, relPath, this) {
-      @Override
-      public String getName() {
-        return relPath;
-      }
-
-      @Override
-      public URI getUri() {
-        return uri;
-      }
-
-      @Override
-      public boolean exists() {
-        return content != null;
-      }
-
-      @Override
-      public long getLastModified() {
-        return sourceLastModified.longValue();
-      }
-
-      @Override
-      public Reader getSourceReader() throws IOException {
-        return new StringReader(content);
-      }
-    };
-    sourceMap.put(relPath, result);
-    return result;
-  }
-
-  /**
-   * Sets the given content for the source.
-   */
-  public void setContent(String relPath, String content) {
-    sourceMap.remove(relPath);
-    sourceContentMap.put(relPath, content);
-    sourceLastModifiedMap.put(relPath, System.currentTimeMillis());
-  }
-}
diff --git a/compiler/javatests/com/google/dart/compiler/end2end/inc/my.app.dart b/compiler/javatests/com/google/dart/compiler/end2end/inc/my.app.dart
deleted file mode 100644
index 15aca3f..0000000
--- a/compiler/javatests/com/google/dart/compiler/end2end/inc/my.app.dart
+++ /dev/null
@@ -1,16 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-library myApp;
-
-import "some.lib.dart";
-part "my.dart";
-part "mybase.dart";
-part "myother0.dart";
-part "myother1.dart";
-part "myother2.dart";
-part "myother3.dart";
-part "myother4.dart";
-part "myother5.dart";
-part "myother6.dart";
-part "myother7.dart";
diff --git a/compiler/javatests/com/google/dart/compiler/end2end/inc/my.dart b/compiler/javatests/com/google/dart/compiler/end2end/inc/my.dart
deleted file mode 100644
index f123883..0000000
--- a/compiler/javatests/com/google/dart/compiler/end2end/inc/my.dart
+++ /dev/null
@@ -1,63 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-part of myApp;
-
-var x = 0, y = 1;
-void fn() { /* ... */ }
-
-class Spoo<T> {
-  Spoo() { }
-  Spoo.other() { }
-}
-
-main() {
-  // Static method reference to Other0.
-  var v = Other0.value();
-  
-  // Reference Other1 via new.
-  var o1 = new Other1();
-
-  // Static field reference to Other3.
-  var f = Other3.field;
-
-  // Reference SomeClass via new, and SomeClassImpl transitively.
-  var sc = new SomeClass(1);
-  var msg = sc.message;
-
-  // Reference global var defined in myother0.dart
-  var gv = globalVar;
-
-  // Reference global function defined in myother0.dart
-  var gf = globalFunction();
-}
-
-class Qualifiers extends QualifierBase {
-  void fn() {
-    // Qualified reference to Other5's field.
-    var field = other5.field;
-
-    // Qualified reference to Other6's method.
-    var result = other6.method();
-  }
-}
-
-// Reference Other2 by subclassing it.
-class Foo extends Other2 {
-  foo() {
-    // unqualified reference to superclass method.
-    methodHole();
-
-    // unqualified reference to superclass field.
-    return hole;
-  }
-
-  int bar() {
-    // qualified reference
-    return super.not_hole.contents;
-  }
-}
-
-// Reference Other4 using it as a type parameter bound.
-class Bar<T extends Other4> {
-}
diff --git a/compiler/javatests/com/google/dart/compiler/end2end/inc/my.merged.app.dart b/compiler/javatests/com/google/dart/compiler/end2end/inc/my.merged.app.dart
deleted file mode 100644
index afe2335..0000000
--- a/compiler/javatests/com/google/dart/compiler/end2end/inc/my.merged.app.dart
+++ /dev/null
@@ -1,14 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-library myApp;
-
-import "some.lib.dart";
-part "my.dart";
-part "mybase.dart";
-part "myother0.dart";
-part "myother1.dart";
-part "myother2.dart";
-part "myother34.dart";
-part "myother5.dart";
-part "myother6.dart";
\ No newline at end of file
diff --git a/compiler/javatests/com/google/dart/compiler/end2end/inc/my.no5ref.dart b/compiler/javatests/com/google/dart/compiler/end2end/inc/my.no5ref.dart
deleted file mode 100644
index a35149c..0000000
--- a/compiler/javatests/com/google/dart/compiler/end2end/inc/my.no5ref.dart
+++ /dev/null
@@ -1,51 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-part of myApp;
-
-class Spoo<T> {
-  Spoo() { }
-  Spoo.other() { }
-}
-
-main() {
-  // Static method reference to Other0.
-  var v = Other0.value();
-
-  // Reference Other1 via new.
-  var o1 = new Other1();
-
-  // Static field reference to Other3.
-  var f = Other3.field;
-
-  // Reference SomeClass via new, and SomeClassImpl transitively.
-  var sc = new SomeClass(1);
-  var msg = sc.message;
-}
-
-class Qualifiers extends QualifierBase {
-  void fn() {
-    // Qualified reference to Other6's method.
-    var result = other6.method();
-  }
-}
-
-// Reference Other2 by subclassing it.
-class Foo extends Other2 {
-  foo() {
-    // unqualified reference to superclass method.
-    methodHole();
-
-    // unqualified reference to superclass field.
-    return hole;
-  }
-
-  int bar() {
-    // qualified reference
-    return super.not_hole.contents;
-  }
-}
-
-// Reference Other4 using it as a type parameter bound.
-class Bar<T extends Other4> {
-}
diff --git a/compiler/javatests/com/google/dart/compiler/end2end/inc/my.nuke5.app.dart b/compiler/javatests/com/google/dart/compiler/end2end/inc/my.nuke5.app.dart
deleted file mode 100644
index 6d50f3c..0000000
--- a/compiler/javatests/com/google/dart/compiler/end2end/inc/my.nuke5.app.dart
+++ /dev/null
@@ -1,14 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-library myApp;
-
-import "some.lib.dart";
-part "my.dart";
-part "mybase.dart";
-part "myother0.dart";
-part "myother1.dart";
-part "myother2.dart";
-part "myother3.dart";
-part "myother4.dart";
-part "myother6.dart";
\ No newline at end of file
diff --git a/compiler/javatests/com/google/dart/compiler/end2end/inc/my.prefixed.app.dart b/compiler/javatests/com/google/dart/compiler/end2end/inc/my.prefixed.app.dart
deleted file mode 100644
index e5958dc..0000000
--- a/compiler/javatests/com/google/dart/compiler/end2end/inc/my.prefixed.app.dart
+++ /dev/null
@@ -1,18 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-library myAppPref;
-
-import "some.prefixable.lib.dart" as prefix;
-
-class Prefix {
-  static final int foo = 43;
-
-  static getSource() {
-    return foo;
-  }
-
-  static getImport() {
-    return prefix.Prefix.foo;
-  }
-}
diff --git a/compiler/javatests/com/google/dart/compiler/end2end/inc/my.unprefixed.app.dart b/compiler/javatests/com/google/dart/compiler/end2end/inc/my.unprefixed.app.dart
deleted file mode 100644
index 7b36d57..0000000
--- a/compiler/javatests/com/google/dart/compiler/end2end/inc/my.unprefixed.app.dart
+++ /dev/null
@@ -1,18 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-library myAppUnPref;
-
-import "some.prefixable.lib.dart";
-
-class Unprefix {
-  static final int foo = 43;
-
-  static getSource() {
-    return foo;
-  }
-
-  static getImport() {
-    return Prefix.foo;
-  }
-}
diff --git a/compiler/javatests/com/google/dart/compiler/end2end/inc/mybase.dart b/compiler/javatests/com/google/dart/compiler/end2end/inc/mybase.dart
deleted file mode 100644
index f10a5cf..0000000
--- a/compiler/javatests/com/google/dart/compiler/end2end/inc/mybase.dart
+++ /dev/null
@@ -1,9 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-part of myApp;
-
-class QualifierBase {
-  Other5 other5;
-  Other6 other6;
-}
diff --git a/compiler/javatests/com/google/dart/compiler/end2end/inc/mybase.no5ref.dart b/compiler/javatests/com/google/dart/compiler/end2end/inc/mybase.no5ref.dart
deleted file mode 100644
index ff7209d..0000000
--- a/compiler/javatests/com/google/dart/compiler/end2end/inc/mybase.no5ref.dart
+++ /dev/null
@@ -1,8 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-part of myApp;
-
-class QualifierBase {
-  Other6 other6;
-}
diff --git a/compiler/javatests/com/google/dart/compiler/end2end/inc/myother0.dart b/compiler/javatests/com/google/dart/compiler/end2end/inc/myother0.dart
deleted file mode 100644
index cb6e48b..0000000
--- a/compiler/javatests/com/google/dart/compiler/end2end/inc/myother0.dart
+++ /dev/null
@@ -1,19 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-part of myApp;
-
-class Other0 {
-  static int value() { return 42; }
-
-  int field_;
-
-  Other0() : this.field_ = 42 { }
-  int get field { return field_; }
-}
-
-int globalVar = 42;
-
-int globalFunction() {
-  return 42;
-}
diff --git a/compiler/javatests/com/google/dart/compiler/end2end/inc/myother0.fillthehole.dart b/compiler/javatests/com/google/dart/compiler/end2end/inc/myother0.fillthehole.dart
deleted file mode 100644
index d0f572a..0000000
--- a/compiler/javatests/com/google/dart/compiler/end2end/inc/myother0.fillthehole.dart
+++ /dev/null
@@ -1,25 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-part of myApp;
-
-class Other0 {
-  static int value() { return 42; }
-
-  int field_;
-
-  Other0() : this.field_ = 42 { }
-  int get field { return field_; }
-}
-
-int globalVar = 42;
-
-int globalFunction() {
-  return 42;
-}
-
-// The definition of this var should force a recompile of my.dart/Foo, because
-// it ends up binding to an unqualified reference of one of Foo's superclass
-// fields (hole).
-int hole = 42;
-
diff --git a/compiler/javatests/com/google/dart/compiler/end2end/inc/myother0.fillthemethodhole.dart b/compiler/javatests/com/google/dart/compiler/end2end/inc/myother0.fillthemethodhole.dart
deleted file mode 100644
index b9a35c8..0000000
--- a/compiler/javatests/com/google/dart/compiler/end2end/inc/myother0.fillthemethodhole.dart
+++ /dev/null
@@ -1,25 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-part of myApp;
-
-class Other0 {
-  static int value() { return 42; }
-
-  int field_;
-
-  Other0() : this.field_ = 42 { }
-  int get field { return field_; }
-}
-
-int globalVar = 42;
-
-int globalFunction() {
-  return 42;
-}
-
-// The definition of this class should force a recompile of my.dart/Foo, because
-// it ends up binding to an unqualified reference of one of Foo's superclass
-// methods (methodHole).
-class methodHole {
-}
diff --git a/compiler/javatests/com/google/dart/compiler/end2end/inc/myother0.fillthenothole.dart b/compiler/javatests/com/google/dart/compiler/end2end/inc/myother0.fillthenothole.dart
deleted file mode 100644
index 005d4a9..0000000
--- a/compiler/javatests/com/google/dart/compiler/end2end/inc/myother0.fillthenothole.dart
+++ /dev/null
@@ -1,25 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-part of myApp;
-
-class Other0 {
-  static int value() { return 42; }
-
-  int field_;
-
-  Other0() : this.field_ = 42 { }
-  int get field { return field_; }
-}
-
-int globalVar = 42;
-
-int globalFunction() {
-  return 42;
-}
-
-// The definition of this class should not cause a recompile of my.dart, because
-// my.dart/Foo's reference to 'not_hole' is super-qualified.
-class not_hole {
-  static final int contents = 42;
-}
diff --git a/compiler/javatests/com/google/dart/compiler/end2end/inc/myother0.globalfunctionchange.dart b/compiler/javatests/com/google/dart/compiler/end2end/inc/myother0.globalfunctionchange.dart
deleted file mode 100644
index c0377a3..0000000
--- a/compiler/javatests/com/google/dart/compiler/end2end/inc/myother0.globalfunctionchange.dart
+++ /dev/null
@@ -1,20 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-part of myApp;
-
-class Other0 {
-  static int value() { return 42; }
-
-  int field_;
-
-  Other0() : this.field_ = 42 { }
-  int get field { return field_; }
-}
-
-int globalVar = 42;
-
-// changed return type from int to num
-num globalFunction() {
-  return 42;
-}
diff --git a/compiler/javatests/com/google/dart/compiler/end2end/inc/myother0.globalvarchange.dart b/compiler/javatests/com/google/dart/compiler/end2end/inc/myother0.globalvarchange.dart
deleted file mode 100644
index ad04968..0000000
--- a/compiler/javatests/com/google/dart/compiler/end2end/inc/myother0.globalvarchange.dart
+++ /dev/null
@@ -1,19 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-part of myApp;
-
-class Other0 {
-  static int value() { return 42; }
-
-  int field_;
-
-  Other0() : this.field_ = 42 { }
-  int get field { return field_; }
-}
-
-num globalVar = 42;    // changed return type from int to num
-
-int globalFunction() {
-  return 42;
-}
diff --git a/compiler/javatests/com/google/dart/compiler/end2end/inc/myother0.newstaticmethod.dart b/compiler/javatests/com/google/dart/compiler/end2end/inc/myother0.newstaticmethod.dart
deleted file mode 100644
index 628c947..0000000
--- a/compiler/javatests/com/google/dart/compiler/end2end/inc/myother0.newstaticmethod.dart
+++ /dev/null
@@ -1,20 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-part of myApp;
-
-class Other0 {
-  static int value() { return 42; }
-  static String strValue() { return "42"; }
-
-  int field_;
-
-  Other0() : this.field_ = 42 { }
-  int get field { return field_; }
-}
-
-int globalVar = 42;
-
-int globalFunction() {
-  return 42;
-}
diff --git a/compiler/javatests/com/google/dart/compiler/end2end/inc/myother0.returntypechange.dart b/compiler/javatests/com/google/dart/compiler/end2end/inc/myother0.returntypechange.dart
deleted file mode 100644
index aa88248..0000000
--- a/compiler/javatests/com/google/dart/compiler/end2end/inc/myother0.returntypechange.dart
+++ /dev/null
@@ -1,19 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-part of myApp;
-
-class Other0 {
-  static int value() { return 42; }
-
-  int field_;
-
-  Other0() : this.field_ = 42 { }
-  num get field { return field_; }
-}
-
-int globalVar = 42;
-
-int globalFunction() {
-  return 42;
-}
diff --git a/compiler/javatests/com/google/dart/compiler/end2end/inc/myother1.change.dart b/compiler/javatests/com/google/dart/compiler/end2end/inc/myother1.change.dart
deleted file mode 100644
index dbe9acd..0000000
--- a/compiler/javatests/com/google/dart/compiler/end2end/inc/myother1.change.dart
+++ /dev/null
@@ -1,10 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-part of myApp;
-
-class Other1 {
-  static Function FN;
-
-  Other1() { FN = () { return 42; };}
-}
diff --git a/compiler/javatests/com/google/dart/compiler/end2end/inc/myother1.dart b/compiler/javatests/com/google/dart/compiler/end2end/inc/myother1.dart
deleted file mode 100644
index cba3e1e..0000000
--- a/compiler/javatests/com/google/dart/compiler/end2end/inc/myother1.dart
+++ /dev/null
@@ -1,17 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-part of myApp;
-
-class Other1 {
-
-  static Function FN;
-
-  Other1() {
-
-    if (FN == null) {
-      FN = () { return 42; };
-    }
-  }
-  void newMethod() { }
-}
diff --git a/compiler/javatests/com/google/dart/compiler/end2end/inc/myother2.change.dart b/compiler/javatests/com/google/dart/compiler/end2end/inc/myother2.change.dart
deleted file mode 100644
index f861bbc..0000000
--- a/compiler/javatests/com/google/dart/compiler/end2end/inc/myother2.change.dart
+++ /dev/null
@@ -1,15 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-part of myApp;
-
-class IntBag {
-  int contents;
-}
-
-class Other2 {
-  IntBag hole, not_hole;
-  void methodHole() { }
-
-  Other2() { }
-}
diff --git a/compiler/javatests/com/google/dart/compiler/end2end/inc/myother2.dart b/compiler/javatests/com/google/dart/compiler/end2end/inc/myother2.dart
deleted file mode 100644
index 2ad88e1..0000000
--- a/compiler/javatests/com/google/dart/compiler/end2end/inc/myother2.dart
+++ /dev/null
@@ -1,16 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-part of myApp;
-
-class IntBag {
-  int contents;
-}
-
-class Other2 {
-  IntBag hole, not_hole;
-  void methodHole() { }
-
-  Other2() { }
-  newMethod() { }
-}
diff --git a/compiler/javatests/com/google/dart/compiler/end2end/inc/myother3.dart b/compiler/javatests/com/google/dart/compiler/end2end/inc/myother3.dart
deleted file mode 100644
index e81353c..0000000
--- a/compiler/javatests/com/google/dart/compiler/end2end/inc/myother3.dart
+++ /dev/null
@@ -1,8 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-part of myApp;
-
-class Other3 {
-  static int field;
-}
diff --git a/compiler/javatests/com/google/dart/compiler/end2end/inc/myother3.newstaticfield.dart b/compiler/javatests/com/google/dart/compiler/end2end/inc/myother3.newstaticfield.dart
deleted file mode 100644
index 8394405..0000000
--- a/compiler/javatests/com/google/dart/compiler/end2end/inc/myother3.newstaticfield.dart
+++ /dev/null
@@ -1,9 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-part of myApp;
-
-class Other3 {
-  static int field;
-  static int newField;
-}
diff --git a/compiler/javatests/com/google/dart/compiler/end2end/inc/myother34.dart b/compiler/javatests/com/google/dart/compiler/end2end/inc/myother34.dart
deleted file mode 100644
index 767c0a2..0000000
--- a/compiler/javatests/com/google/dart/compiler/end2end/inc/myother34.dart
+++ /dev/null
@@ -1,11 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-part of myApp;
-
-class Other3 {
-  static int field;
-}
-class Other4 {
-  static int field;
-}
diff --git a/compiler/javatests/com/google/dart/compiler/end2end/inc/myother4.change.dart b/compiler/javatests/com/google/dart/compiler/end2end/inc/myother4.change.dart
deleted file mode 100644
index be9df67..0000000
--- a/compiler/javatests/com/google/dart/compiler/end2end/inc/myother4.change.dart
+++ /dev/null
@@ -1,9 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-part of myApp;
-
-class Other4 {
-  static int field;
-  static int newField;
-}
diff --git a/compiler/javatests/com/google/dart/compiler/end2end/inc/myother4.dart b/compiler/javatests/com/google/dart/compiler/end2end/inc/myother4.dart
deleted file mode 100644
index 3039f16..0000000
--- a/compiler/javatests/com/google/dart/compiler/end2end/inc/myother4.dart
+++ /dev/null
@@ -1,8 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-part of myApp;
-
-class Other4 {
-  static int field;
-}
diff --git a/compiler/javatests/com/google/dart/compiler/end2end/inc/myother4.newstaticfield.dart b/compiler/javatests/com/google/dart/compiler/end2end/inc/myother4.newstaticfield.dart
deleted file mode 100644
index be9df67..0000000
--- a/compiler/javatests/com/google/dart/compiler/end2end/inc/myother4.newstaticfield.dart
+++ /dev/null
@@ -1,9 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-part of myApp;
-
-class Other4 {
-  static int field;
-  static int newField;
-}
diff --git a/compiler/javatests/com/google/dart/compiler/end2end/inc/myother5.change.dart b/compiler/javatests/com/google/dart/compiler/end2end/inc/myother5.change.dart
deleted file mode 100644
index 899983b..0000000
--- a/compiler/javatests/com/google/dart/compiler/end2end/inc/myother5.change.dart
+++ /dev/null
@@ -1,11 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-part of myApp;
-
-class Other5 {
-  int field;
-
-  Other5() { field = 42; }
-  void newMethod() { }
-}
diff --git a/compiler/javatests/com/google/dart/compiler/end2end/inc/myother5.dart b/compiler/javatests/com/google/dart/compiler/end2end/inc/myother5.dart
deleted file mode 100644
index 803faa7..0000000
--- a/compiler/javatests/com/google/dart/compiler/end2end/inc/myother5.dart
+++ /dev/null
@@ -1,10 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-part of myApp;
-
-class Other5 {
-  int field;
-
-  Other5() { field = 42; Unused.unused(); }
-}
diff --git a/compiler/javatests/com/google/dart/compiler/end2end/inc/myother6.change.dart b/compiler/javatests/com/google/dart/compiler/end2end/inc/myother6.change.dart
deleted file mode 100644
index 7ac2378..0000000
--- a/compiler/javatests/com/google/dart/compiler/end2end/inc/myother6.change.dart
+++ /dev/null
@@ -1,14 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-part of myApp;
-
-class Other6 {
-  Other6() { }
-  method() { }
-  void newMethod() { }
-}
-
-class Unused {
-  static void unused() { }
-}
diff --git a/compiler/javatests/com/google/dart/compiler/end2end/inc/myother6.dart b/compiler/javatests/com/google/dart/compiler/end2end/inc/myother6.dart
deleted file mode 100644
index b1b9245..0000000
--- a/compiler/javatests/com/google/dart/compiler/end2end/inc/myother6.dart
+++ /dev/null
@@ -1,13 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-part of myApp;
-
-class Other6 {
-  Other6() { }
-  method() { }
-}
-
-class Unused {
-  static void unused() { }
-}
diff --git a/compiler/javatests/com/google/dart/compiler/end2end/inc/myother6.removeclass.dart b/compiler/javatests/com/google/dart/compiler/end2end/inc/myother6.removeclass.dart
deleted file mode 100644
index 2a17f79..0000000
--- a/compiler/javatests/com/google/dart/compiler/end2end/inc/myother6.removeclass.dart
+++ /dev/null
@@ -1,9 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-part of myApp;
-
-class Other6 {
-  Other6() { }
-  method() { }
-}
diff --git a/compiler/javatests/com/google/dart/compiler/end2end/inc/myother7.dart b/compiler/javatests/com/google/dart/compiler/end2end/inc/myother7.dart
deleted file mode 100644
index 0ca2c06..0000000
--- a/compiler/javatests/com/google/dart/compiler/end2end/inc/myother7.dart
+++ /dev/null
@@ -1,8 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-part of myApp;
-
-class Baz {
-  SomeClass2 sc2;
-}
\ No newline at end of file
diff --git a/compiler/javatests/com/google/dart/compiler/end2end/inc/some.dart b/compiler/javatests/com/google/dart/compiler/end2end/inc/some.dart
deleted file mode 100644
index 0bb2c0d..0000000
--- a/compiler/javatests/com/google/dart/compiler/end2end/inc/some.dart
+++ /dev/null
@@ -1,16 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-part of some_lib;
-
-abstract class SomeClass {
-  factory SomeClass(arg) = SomeClassImpl;
-  get message;
-}
-
-abstract class SomeInterface2 {
-}
-
-// myother7.dart/Baz depends on SomeClass2 which depends on SomeInterface2
-class SomeClass2 implements SomeInterface2 {
-}
diff --git a/compiler/javatests/com/google/dart/compiler/end2end/inc/some.intfchange.dart b/compiler/javatests/com/google/dart/compiler/end2end/inc/some.intfchange.dart
deleted file mode 100644
index a67807e..0000000
--- a/compiler/javatests/com/google/dart/compiler/end2end/inc/some.intfchange.dart
+++ /dev/null
@@ -1,16 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-part of some_lib;
-
-abstract class SomeClass {
-  factory SomeClass(arg) = SomeClassImpl;
-  String get message; // Added return type
-}
-
-abstract class SomeInterface2 {
-}
-
-// myother7.dart/Baz depends on SomeClass2 which depends on SomeInterface2
-class SomeClass2 implements SomeInterface2 {
-}
diff --git a/compiler/javatests/com/google/dart/compiler/end2end/inc/some.lib.dart b/compiler/javatests/com/google/dart/compiler/end2end/inc/some.lib.dart
deleted file mode 100644
index bd976f8..0000000
--- a/compiler/javatests/com/google/dart/compiler/end2end/inc/some.lib.dart
+++ /dev/null
@@ -1,7 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library some_lib;
-import "someimpl.lib.dart";
-part "some.dart";
diff --git a/compiler/javatests/com/google/dart/compiler/end2end/inc/some.newmethod.dart b/compiler/javatests/com/google/dart/compiler/end2end/inc/some.newmethod.dart
deleted file mode 100644
index 783aeaa..0000000
--- a/compiler/javatests/com/google/dart/compiler/end2end/inc/some.newmethod.dart
+++ /dev/null
@@ -1,17 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-part of some_lib;
-
-abstract class SomeClass {
-  factory SomeClass(arg) = SomeClassImpl;
-  get message;
-  newMethod();
-}
-
-abstract class SomeInterface2 {
-}
-
-// myother7.dart/Baz depends on SomeClass2 which depends on SomeInterface2
-class SomeClass2 implements SomeInterface2 {
-}
diff --git a/compiler/javatests/com/google/dart/compiler/end2end/inc/some.prefixable.lib.dart b/compiler/javatests/com/google/dart/compiler/end2end/inc/some.prefixable.lib.dart
deleted file mode 100644
index be5059a..0000000
--- a/compiler/javatests/com/google/dart/compiler/end2end/inc/some.prefixable.lib.dart
+++ /dev/null
@@ -1,9 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library some_lib;
-
-class Prefix {
-  static final int foo = 42;
-}
diff --git a/compiler/javatests/com/google/dart/compiler/end2end/inc/some.prefixable.modified.lib.dart b/compiler/javatests/com/google/dart/compiler/end2end/inc/some.prefixable.modified.lib.dart
deleted file mode 100644
index ac6b16d..0000000
--- a/compiler/javatests/com/google/dart/compiler/end2end/inc/some.prefixable.modified.lib.dart
+++ /dev/null
@@ -1,9 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library some_lib;
-
-class Prefix {
-  static final int foo = 43;
-}
diff --git a/compiler/javatests/com/google/dart/compiler/end2end/inc/someimpl.bodychange.dart b/compiler/javatests/com/google/dart/compiler/end2end/inc/someimpl.bodychange.dart
deleted file mode 100644
index a3fd2fd..0000000
--- a/compiler/javatests/com/google/dart/compiler/end2end/inc/someimpl.bodychange.dart
+++ /dev/null
@@ -1,11 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-part of someimpl_dart;
-
-class SomeClassImpl implements SomeClass {
-  String message_;
-
-  SomeClassImpl(arg) : this.message_ = "what?!" { }
-  String get message { return message_; }
-}
diff --git a/compiler/javatests/com/google/dart/compiler/end2end/inc/someimpl.change.dart b/compiler/javatests/com/google/dart/compiler/end2end/inc/someimpl.change.dart
deleted file mode 100644
index 667978e..0000000
--- a/compiler/javatests/com/google/dart/compiler/end2end/inc/someimpl.change.dart
+++ /dev/null
@@ -1,12 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-part of someimpl_dart;
-
-class SomeClassImpl implements SomeClass {
-  String message_;
-
-  SomeClassImpl(arg) : this.message_ = "w00t!" { }
-  String get message { return message_; }
-  newMethod() { }
-}
diff --git a/compiler/javatests/com/google/dart/compiler/end2end/inc/someimpl.dart b/compiler/javatests/com/google/dart/compiler/end2end/inc/someimpl.dart
deleted file mode 100644
index 85b6861..0000000
--- a/compiler/javatests/com/google/dart/compiler/end2end/inc/someimpl.dart
+++ /dev/null
@@ -1,11 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-part of someimpl_dart;
-
-class SomeClassImpl implements SomeClass {
-  String message_;
-
-  SomeClassImpl(arg) : message_ = "w00t!" { }
-  String get message { return message_; }
-}
diff --git a/compiler/javatests/com/google/dart/compiler/end2end/inc/someimpl.lib.dart b/compiler/javatests/com/google/dart/compiler/end2end/inc/someimpl.lib.dart
deleted file mode 100644
index 409c590..0000000
--- a/compiler/javatests/com/google/dart/compiler/end2end/inc/someimpl.lib.dart
+++ /dev/null
@@ -1,7 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library someimpl_dart;
-import "some.lib.dart";
-part "someimpl.dart";
diff --git a/compiler/javatests/com/google/dart/compiler/parser/AbstractParserTest.java b/compiler/javatests/com/google/dart/compiler/parser/AbstractParserTest.java
deleted file mode 100644
index 85d0f56..0000000
--- a/compiler/javatests/com/google/dart/compiler/parser/AbstractParserTest.java
+++ /dev/null
@@ -1,153 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.parser;
-
-import com.google.dart.compiler.CompilerTestCase;
-import com.google.dart.compiler.ast.DartDirective;
-import com.google.dart.compiler.ast.DartImportDirective;
-import com.google.dart.compiler.ast.DartLibraryDirective;
-import com.google.dart.compiler.ast.DartSourceDirective;
-import com.google.dart.compiler.ast.DartUnit;
-
-import java.net.URL;
-import java.util.Iterator;
-
-/**
- * Tests for the parser, which simply assert that valid source units parse
- * correctly. All tests invoking {@code parseUnit} are designed such that
- * they will throw an exception if anything goes wrong in the parser.
- */
-public abstract class AbstractParserTest extends CompilerTestCase {
-
-  public void testClasses() {
-    parseUnit("ClassesInterfaces.dart");
-  }
-
-  public void testMethodSignatures() {
-    parseUnit("MethodSignatures.dart");
-  }
-
-  public void testFunctionTypes() {
-    parseUnit("FunctionTypes.dart");
-  }
-
-  public void testFormalParameters() {
-    parseUnit("FormalParameters.dart");
-  }
-
-  public void testSuperCalls() {
-    parseUnit("SuperCalls.dart");
-  }
-
-  public void testGenericTypedef() {
-    parseUnit("GenericTypedef.dart");
-  }
-
-  public void testGenericTypes() {
-    parseUnit("GenericTypes.dart");
-  }
-
-  public void testShifting() {
-    parseUnit("Shifting.dart");
-  }
-
-  public void testFunctionInterfaces() {
-    parseUnit("FunctionInterfaces.dart");
-  }
-
-  public void testStringBuffer() {
-    parseUnit("StringBuffer.dart");
-  }
-
-  public void testListObjectLiterals() {
-    parseUnit("ListObjectLiterals.dart");
-  }
-
-  public void testCatchFinally() {
-    parseUnit("CatchFinally.dart");
-  }
-
-  public void testStrings() {
-    parseUnit("Strings.dart");
-  }
-
-  public void testNewWithPrefix() {
-    parseUnit("NewWithPrefix.dart");
-  }
-
-  public void testRedirectedConstructor() {
-    parseUnit("RedirectedConstructor.dart");
-  }
-
-  public void testTopLevel() {
-    parseUnit("TopLevel.dart");
-  }
-
-  public void testDirectives() {
-    DartUnit unit = parseUnit("Directives.dart");
-    if (unit == null) {
-      return;
-    }
-    Iterator<DartDirective> iter = unit.getDirectives().iterator();
-
-    DartDirective directive = iter.next();
-    assertEquals(DartLibraryDirective.class, directive.getClass());
-    assertEquals("a_directives_test", ((DartLibraryDirective) directive).getLibraryName());
-
-    directive = iter.next();
-    assertEquals(DartImportDirective.class, directive.getClass());
-    assertEquals("dart:core", ((DartImportDirective) directive).getLibraryUri().getValue());
-    assertEquals(null, ((DartImportDirective) directive).getPrefix());
-
-    directive = iter.next();
-    assertEquals(DartSourceDirective.class, directive.getClass());
-    assertEquals("ListObjectLiterals.dart", ((DartSourceDirective) directive).getSourceUri().getValue());
-  }
-
-  public void testDirectives2() {
-    DartUnit unit = parseUnit("Directives2.dart");
-    if (unit == null) {
-      return;
-    }
-    Iterator<DartDirective> iter = unit.getDirectives().iterator();
-
-    DartDirective directive = iter.next();
-    assertEquals(DartLibraryDirective.class, directive.getClass());
-    assertEquals("b_directives_test", ((DartLibraryDirective) directive).getLibraryName());
-
-    directive = iter.next();
-    assertEquals(DartImportDirective.class, directive.getClass());
-    assertEquals("dart:core", ((DartImportDirective) directive).getLibraryUri().getValue());
-    assertEquals(null, ((DartImportDirective) directive).getPrefix());
-
-    directive = iter.next();
-    assertEquals(DartSourceDirective.class, directive.getClass());
-    assertEquals("SomeClass.dart", ((DartSourceDirective) directive).getSourceUri().getValue());
-  }
-
-  public abstract void testStringsErrors();
-
-  public void testTiming() {
-    String[] inputs = new String[]{
-        "ClassesInterfaces.dart", "MethodSignatures.dart",
-        "FunctionTypes.dart", "FormalParameters.dart", "SuperCalls.dart",
-        "GenericTypes.dart", "Shifting.dart", "FunctionInterfaces.dart",
-        "StringBuffer.dart", "ListObjectLiterals.dart", "CatchFinally.dart",
-        "Strings.dart",};
-    StringBuilder out = new StringBuilder();
-    for (String input : inputs) {
-      URL url = inputUrlFor(getClass(), input);
-      String source = readUrl(url);
-      for (int i = 0; i < 50; ++i) {
-        out.append(source);
-      }
-    }
-    String megaSource = out.toString();
-    long start = System.currentTimeMillis();
-    parseUnit("Mega.dart", megaSource);
-    System.out.format("%s ms for '%s.%s()'%n", System.currentTimeMillis() - start,
-                      getClass().getName(), getName());
-  }
-}
diff --git a/compiler/javatests/com/google/dart/compiler/parser/BadCommentNegativeTest.dart b/compiler/javatests/com/google/dart/compiler/parser/BadCommentNegativeTest.dart
deleted file mode 100644
index 6f5eae1..0000000
--- a/compiler/javatests/com/google/dart/compiler/parser/BadCommentNegativeTest.dart
+++ /dev/null
@@ -1,4 +0,0 @@
-/*
-*
- //comment
-X Y
\ No newline at end of file
diff --git a/compiler/javatests/com/google/dart/compiler/parser/CPParserTest.java b/compiler/javatests/com/google/dart/compiler/parser/CPParserTest.java
deleted file mode 100644
index 74e3002..0000000
--- a/compiler/javatests/com/google/dart/compiler/parser/CPParserTest.java
+++ /dev/null
@@ -1,66 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.parser;
-
-import com.google.dart.compiler.CompilerTestCase;
-import com.google.dart.compiler.DartCompilerListener;
-import com.google.dart.compiler.Source;
-import com.google.dart.compiler.ast.DartComment;
-import com.google.dart.compiler.ast.DartUnit;
-import com.google.dart.compiler.common.SourceInfo;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Tests for the parser, which simply assert that valid source units parse
- * correctly. All tests invoking {@code parseUnit} are designed such that
- * they will throw an exception if anything goes wrong in the parser.
- */
-public class CPParserTest extends CompilerTestCase {
-
-  private static String[] EXPECTED001 = {"/*\n * Beginning comment\n */",
-    "// line comment", "// another", "/**/", "//", "/*/*nested*/*/",
-  };
-  private static String[] EXPECTED002 = {"/*\n*\n //comment\nX Y"};
-
-  private String source;
-
-  
-  @Override
-  protected DartParser makeParser(Source src, String sourceCode, DartCompilerListener listener) {
-    source = sourceCode;
-    return super.makeParser(src, sourceCode, listener);
-  }
-
-  public void test001() {
-    DartUnit unit = parseUnit("Comments.dart");
-    compareComments(unit.getComments(), EXPECTED001);
-  }
-
-  public void test002() {
-    DartUnit unit = parseUnitErrors("BadCommentNegativeTest.dart",
-                                    "Unexpected token 'ILLEGAL' (expected end of file)", 1, 1);
-    compareComments(unit.getComments(), EXPECTED002);
-  }
-
-  private List<String> extractComments(List<DartComment> cms) {
-    List<String> comments = new ArrayList<String>();
-    for (DartComment cm : cms) {
-      SourceInfo sourceInfo = cm.getSourceInfo();
-      comments.add(source.substring(sourceInfo.getOffset(), sourceInfo.getEnd()));
-    }
-    return comments;
-  }
-
-  private void compareComments(List<DartComment> cms, String[] expected) {
-    List<String> comments = extractComments(cms);
-    assertEquals(expected.length, comments.size());
-    for (int i = 0; i < expected.length; i++) {
-      assertEquals(expected[i], comments.get(i));
-    }
-  }
-
-}
diff --git a/compiler/javatests/com/google/dart/compiler/parser/CatchFinally.dart b/compiler/javatests/com/google/dart/compiler/parser/CatchFinally.dart
deleted file mode 100644
index c7457ea..0000000
--- a/compiler/javatests/com/google/dart/compiler/parser/CatchFinally.dart
+++ /dev/null
@@ -1,85 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-class Foo {
-  static main(arguments) {
-    testCatch();
-    testFinally();
-    testCatchFinally();
-    testMultipleCatch();
-    testMultipleCatchFinally();
-    testRethrow();
-  }
-
-  static testRethrow() {
-    try {
-      throw new Foo();
-    } catch(e, st) {
-      throw;
-    }
-  }
-
-  static testCatch() {
-    var exception;
-    try {
-      throw new Foo();
-    } catch(e, st) {
-      exception = e;
-    }
-  }
-
-  static testFinally() {
-    var exception;
-    try {
-      throw new Foo();
-    } finally {
-      exception = null;
-    }
-  }
-
-  static testCatchFinally() {
-    var exception;
-    try {
-      throw new Foo();
-    } catch(e, st) {
-      exception = e;
-    } finally {
-      exception = null;
-    }
-  }
-
-  static testMultipleCatchFinally() {
-    var exception;
-    try {
-      throw new Foo();
-    } on Foo catch(e, st) {
-      exception = e;
-    } on Bar catch(e) {
-      exception = e;
-    } finally {
-      exception = null;
-    }
-  }
-
-  static testMultipleCatch() {
-    var exception;
-    try {
-      throw new Foo();
-    } catch (e) {
-      exception = e;
-    } on Map catch (e) {
-      exception = e;
-    } on int catch (e) {
-      exception = e;
-    } catch (e, st) {
-      exception = e;
-    } on Map catch (e, st) {
-      exception = e;
-    } on int catch (e, st) {
-      exception = e;
-    } finally {
-      exception = e;
-    }
-  }
-}
diff --git a/compiler/javatests/com/google/dart/compiler/parser/ClassesInterfaces.dart b/compiler/javatests/com/google/dart/compiler/parser/ClassesInterfaces.dart
deleted file mode 100644
index 7faaeac..0000000
--- a/compiler/javatests/com/google/dart/compiler/parser/ClassesInterfaces.dart
+++ /dev/null
@@ -1,118 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-class Object {
-  var x;
-  int foo() {
-    return 42;
-  }
-  bar(int x, int y, z) { }
-}
-
-class Baz extends Kuk implements A, B, C {
-  static final y = 12, z = 42;
-  static final Foo moms = 42, kuks = 42;
-  final Kuk hest;
-  static var foo;
-
-  const Baz();
-  const Baz.named() : this.foo = 1;
-  factory prefix.A.foo() {
-  }
-
-  /* Try a few
-   * syntactic constructs. */
-  void baz() {
-    if (42) if (42) 42; else throw 42;
-    switch (42) { case 42: return 42; default: break;}
-    switch (42) {
-    L1: case 42:
-          L2: for(;;) {}
-          return 42;
-        default:
-          break;
-    }
-    switch (42) {
-        case 42:
-          L2: for(;;) {}
-          return 42;
-    L3: case 43:
-        case 44:
-        case 45:
-        default:
-          break;
-    }
-    switch (42) {
-        case 42:
-          L2: for(;;) {}
-          return 42;
-    L3: case 43:
-          break;
-    L4: case 44:
-          continue L3;
-        case 45:
-          break;
-    }
-    try { } catch (e) { }
-    L0: while (false) try { } catch (e) { } finally { break L0; }
-    int kongy(x,y) { return 42; }  // This is a comment.
-
-    42 is Baz;
-    42 is Bar<Foo, Foo>;
-    42 is !Baz;
-    42 is !Bar<Foo, Foo>;
-  }
-
-  int bar(args) {
-    kongy(args);
-    kongy(1, args);
-  }
-
-  int hest(a) {
-    for (var i = 0; i < a.length; i++) {
-      a.b.c.f().g[i] += foo(i);
-      int kuk = 42;
-      (kuk);
-      id(x) { return x; }
-      int id(x) { return x; }
-      Box<int, double> id(x) { return x; }
-      var f = () { };
-      assert(x == 12);
-      id((x) {});
-      a < b;
-      int x = a < b;
-      id(() {});
-    }
-  }
-
-  Baz.superOnly(x, y, z) : super(x, y, z) {}
-  Baz.superAndInit(x, y, z) : super(x, y, z), this.y = 2 {}
-  Baz.superAndInits(x, y, z) : super(x, y, z), this.y = 2, this.x = 4 {}
-
-  // Try all kinds of formal parameters.
-  void fisk(final a,
-            b,
-            var c,
-            int d,
-            e(),
-            void f(),
-            Map<int, double> g,
-            Map<int, double> h()) {}
-
-  Baz(x, y, z) : super(x, y, z) {}
-}
-
-abstract class Foo implements D, E {
-  bar();
-}
-
-// Test bounds on type parameters
-abstract class Bar<K extends Foo, V> implements Foo {
-}
-
-abstract class Bar<K extends Foo, V extends Foo> implements Foo {
-}
-
-abstract class Bar<K, V extends Foo> implements Foo {
-}
diff --git a/compiler/javatests/com/google/dart/compiler/parser/CommentTest.java b/compiler/javatests/com/google/dart/compiler/parser/CommentTest.java
deleted file mode 100644
index 1cd4ade..0000000
--- a/compiler/javatests/com/google/dart/compiler/parser/CommentTest.java
+++ /dev/null
@@ -1,88 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.parser;
-
-import com.google.common.collect.Lists;
-import com.google.dart.compiler.CompilerTestCase;
-import com.google.dart.compiler.DartCompilerListener;
-import com.google.dart.compiler.Source;
-import com.google.dart.compiler.ast.DartComment;
-import com.google.dart.compiler.ast.DartDeclaration;
-import com.google.dart.compiler.ast.DartNode;
-import com.google.dart.compiler.ast.DartUnit;
-import com.google.dart.compiler.common.SourceInfo;
-
-import java.util.List;
-
-/**
- * Tests to ensure the scanner is correctly recording comments, as defined
- * in the javadoc for <code>DartScanner.recordCommentLocation().</code>
- */
-public class CommentTest extends CompilerTestCase {
-  private String source;
-
-  private static String[] EXPECTED001 = {"/*\n * Beginning comment\n */",
-    "// line comment", "// another", "/**/", "//", "/*/*nested*/*/",
-  };
-  private static String[] EXPECTED002 = {"/*\n*\n //comment\nX Y"};
-
-  public void test001() {
-    DartUnit unit = parseUnit("Comments.dart");
-    compareComments(unit, EXPECTED001);
-  }
-
-  public void test002() {
-    DartUnit unit = parseUnitErrors("BadCommentNegativeTest.dart",
-                    "Unexpected token 'ILLEGAL' (expected end of file)", 1, 1);
-    compareComments(unit, EXPECTED002);
-  }
-
-  public void test003() {
-    DartUnit unit = parseUnit("Comments2.dart");
-    assertDeclComments(unit, "firstMethod", "/** Comments are good. */");
-    assertDeclComments(unit, "secondMethod", null);
-  }
-  
-  @Override
-  protected DartParser makeParser(Source src, String sourceCode, DartCompilerListener listener) {
-    source = sourceCode;
-    return super.makeParser(src, sourceCode, listener);
-  }
-
-  private List<String> extractComments(DartUnit unit) {
-    List<String> comments = Lists.newArrayList();
-    List<DartComment> commentNodes = unit.getComments();
-    for (DartComment commentNode : commentNodes) {
-      SourceInfo sourceInfo = commentNode.getSourceInfo();
-      String comment = source.substring(sourceInfo.getOffset(), sourceInfo.getEnd());
-      comments.add(comment);
-    }
-    return comments;
-  }
-
-  private void compareComments(DartUnit unit, String[] expected) {
-    List<String> comments = extractComments(unit);
-    assertEquals(expected.length, comments.size());
-    for (int i = 0; i < expected.length; i++) {
-      assertEquals(expected[i], comments.get(i));
-    }
-  }
-
-  private void assertDeclComments(DartUnit unit, String name, String comments) {
-    for (DartNode node : unit.getTopLevelNodes()) {
-      if (node instanceof DartDeclaration && node.getElement() != null
-          && name.equals(node.getElement().getOriginalName())) {
-        DartDeclaration<?> decl = (DartDeclaration<?>)node;
-        String nodeComments = null;
-
-        if (decl.getDartDoc() != null) {
-          nodeComments = decl.getDartDoc().toSource();
-        }
-
-        assertEquals(comments, nodeComments);
-      }
-    }
-  }
-}
diff --git a/compiler/javatests/com/google/dart/compiler/parser/Comments.dart b/compiler/javatests/com/google/dart/compiler/parser/Comments.dart
deleted file mode 100644
index 16c1256..0000000
--- a/compiler/javatests/com/google/dart/compiler/parser/Comments.dart
+++ /dev/null
@@ -1,7 +0,0 @@
-/*
- * Beginning comment
- */
-// line comment
-// another
-class X/**/{//
-}/*/*nested*/*/
\ No newline at end of file
diff --git a/compiler/javatests/com/google/dart/compiler/parser/Comments2.dart b/compiler/javatests/com/google/dart/compiler/parser/Comments2.dart
deleted file mode 100644
index ff64636..0000000
--- a/compiler/javatests/com/google/dart/compiler/parser/Comments2.dart
+++ /dev/null
@@ -1,8 +0,0 @@
-/** Comments are good. */
-void firstMethod() {
-  /** This should be ignored. */
-}
-
-void secondMethod() {
-
-}
diff --git a/compiler/javatests/com/google/dart/compiler/parser/DartASTValidator.java b/compiler/javatests/com/google/dart/compiler/parser/DartASTValidator.java
deleted file mode 100755
index 9309162..0000000
--- a/compiler/javatests/com/google/dart/compiler/parser/DartASTValidator.java
+++ /dev/null
@@ -1,635 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.parser;
-
-import com.google.dart.compiler.ast.ASTVisitor;
-import com.google.dart.compiler.ast.DartArrayAccess;
-import com.google.dart.compiler.ast.DartArrayLiteral;
-import com.google.dart.compiler.ast.DartBinaryExpression;
-import com.google.dart.compiler.ast.DartBlock;
-import com.google.dart.compiler.ast.DartBooleanLiteral;
-import com.google.dart.compiler.ast.DartBreakStatement;
-import com.google.dart.compiler.ast.DartCase;
-import com.google.dart.compiler.ast.DartCatchBlock;
-import com.google.dart.compiler.ast.DartClass;
-import com.google.dart.compiler.ast.DartConditional;
-import com.google.dart.compiler.ast.DartContinueStatement;
-import com.google.dart.compiler.ast.DartDefault;
-import com.google.dart.compiler.ast.DartDoWhileStatement;
-import com.google.dart.compiler.ast.DartDoubleLiteral;
-import com.google.dart.compiler.ast.DartEmptyStatement;
-import com.google.dart.compiler.ast.DartExprStmt;
-import com.google.dart.compiler.ast.DartField;
-import com.google.dart.compiler.ast.DartFieldDefinition;
-import com.google.dart.compiler.ast.DartForInStatement;
-import com.google.dart.compiler.ast.DartForStatement;
-import com.google.dart.compiler.ast.DartFunction;
-import com.google.dart.compiler.ast.DartFunctionExpression;
-import com.google.dart.compiler.ast.DartFunctionObjectInvocation;
-import com.google.dart.compiler.ast.DartFunctionTypeAlias;
-import com.google.dart.compiler.ast.DartIdentifier;
-import com.google.dart.compiler.ast.DartIfStatement;
-import com.google.dart.compiler.ast.DartImportDirective;
-import com.google.dart.compiler.ast.DartInitializer;
-import com.google.dart.compiler.ast.DartIntegerLiteral;
-import com.google.dart.compiler.ast.DartLabel;
-import com.google.dart.compiler.ast.DartLibraryDirective;
-import com.google.dart.compiler.ast.DartMapLiteral;
-import com.google.dart.compiler.ast.DartMapLiteralEntry;
-import com.google.dart.compiler.ast.DartMethodDefinition;
-import com.google.dart.compiler.ast.DartMethodInvocation;
-import com.google.dart.compiler.ast.DartNamedExpression;
-import com.google.dart.compiler.ast.DartNativeBlock;
-import com.google.dart.compiler.ast.DartNativeDirective;
-import com.google.dart.compiler.ast.DartNewExpression;
-import com.google.dart.compiler.ast.DartNode;
-import com.google.dart.compiler.ast.DartNullLiteral;
-import com.google.dart.compiler.ast.DartParameter;
-import com.google.dart.compiler.ast.DartParameterizedTypeNode;
-import com.google.dart.compiler.ast.DartParenthesizedExpression;
-import com.google.dart.compiler.ast.DartPropertyAccess;
-import com.google.dart.compiler.ast.DartRedirectConstructorInvocation;
-import com.google.dart.compiler.ast.DartReturnStatement;
-import com.google.dart.compiler.ast.DartSourceDirective;
-import com.google.dart.compiler.ast.DartStringInterpolation;
-import com.google.dart.compiler.ast.DartStringLiteral;
-import com.google.dart.compiler.ast.DartSuperConstructorInvocation;
-import com.google.dart.compiler.ast.DartSuperExpression;
-import com.google.dart.compiler.ast.DartSwitchStatement;
-import com.google.dart.compiler.ast.DartSyntheticErrorExpression;
-import com.google.dart.compiler.ast.DartSyntheticErrorStatement;
-import com.google.dart.compiler.ast.DartThisExpression;
-import com.google.dart.compiler.ast.DartThrowExpression;
-import com.google.dart.compiler.ast.DartTryStatement;
-import com.google.dart.compiler.ast.DartTypeExpression;
-import com.google.dart.compiler.ast.DartTypeNode;
-import com.google.dart.compiler.ast.DartTypeParameter;
-import com.google.dart.compiler.ast.DartUnaryExpression;
-import com.google.dart.compiler.ast.DartUnit;
-import com.google.dart.compiler.ast.DartUnqualifiedInvocation;
-import com.google.dart.compiler.ast.DartVariable;
-import com.google.dart.compiler.ast.DartVariableStatement;
-import com.google.dart.compiler.ast.DartWhileStatement;
-
-import junit.framework.Assert;
-
-import java.util.ArrayList;
-import java.util.List;
-
-public class DartASTValidator extends ASTVisitor<Void> {
-
-  private ArrayList<String> errors = new ArrayList<String>();
-
-  public void assertValid() {
-    if (!errors.isEmpty()) {
-      StringBuilder builder = new StringBuilder();
-      builder.append("Invalid AST structure:");
-      for (String message : errors) {
-        builder.append("\r\n   ");
-        builder.append(message);
-      }
-      Assert.fail(builder.toString());
-    }
-  }
-
-  @Override
-  public void visit(List<? extends DartNode> nodes) {
-    if (nodes != null) {
-      int previousEnd = -1;
-      for (DartNode node : nodes) {
-        int start = node.getSourceInfo().getOffset();
-        if (start <= previousEnd) {
-          errors.add("Node starts (" + start + ") before previous sibling's end (" + previousEnd
-              + ") or nodes are not in source order");
-        }
-        node.accept(this);
-        previousEnd = start + node.getSourceInfo().getLength() - 1;
-      }
-    }
-  }
-
-  @Override
-  public Void visitArrayAccess(DartArrayAccess node) {
-    validate(node);
-    node.visitChildren(this);
-    return null;
-  }
-
-  @Override
-  public Void visitArrayLiteral(DartArrayLiteral node) {
-    validate(node);
-    node.visitChildren(this);
-    return null;
-  }
-
-  @Override
-  public Void visitBinaryExpression(DartBinaryExpression node) {
-    validate(node);
-    node.visitChildren(this);
-    return null;
-  }
-
-  @Override
-  public Void visitBlock(DartBlock node) {
-    validate(node);
-    node.visitChildren(this);
-    return null;
-  }
-
-  @Override
-  public Void visitBooleanLiteral(DartBooleanLiteral node) {
-    validate(node);
-    node.visitChildren(this);
-    return null;
-  }
-
-  @Override
-  public Void visitBreakStatement(DartBreakStatement node) {
-    validate(node);
-    node.visitChildren(this);
-    return null;
-  }
-
-  @Override
-  public Void visitCase(DartCase node) {
-    validate(node);
-    node.visitChildren(this);
-    return null;
-  }
-
-  @Override
-  public Void visitCatchBlock(DartCatchBlock node) {
-    validate(node);
-    node.visitChildren(this);
-    return null;
-  }
-
-  @Override
-  public Void visitClass(DartClass node) {
-    validate(node);
-    node.getName().accept(this);
-    node.visitChildren(this);
-    return null;
-  }
-
-  @Override
-  public Void visitConditional(DartConditional node) {
-    validate(node);
-    node.visitChildren(this);
-    return null;
-  }
-
-  @Override
-  public Void visitContinueStatement(DartContinueStatement node) {
-    validate(node);
-    node.visitChildren(this);
-    return null;
-  }
-
-  @Override
-  public Void visitDefault(DartDefault node) {
-    validate(node);
-    node.visitChildren(this);
-    return null;
-  }
-
-  @Override
-  public Void visitDoubleLiteral(DartDoubleLiteral node) {
-    validate(node);
-    node.visitChildren(this);
-    return null;
-  }
-
-  @Override
-  public Void visitDoWhileStatement(DartDoWhileStatement node) {
-    validate(node);
-    node.visitChildren(this);
-    return null;
-  }
-
-  @Override
-  public Void visitEmptyStatement(DartEmptyStatement node) {
-    validate(node);
-    node.visitChildren(this);
-    return null;
-  }
-
-  @Override
-  public Void visitExprStmt(DartExprStmt node) {
-    validate(node);
-    node.visitChildren(this);
-    return null;
-  }
-
-  @Override
-  public Void visitFieldDefinition(DartFieldDefinition node) {
-    validate(node);
-    node.visitChildren(this);
-    return null;
-  }
-
-  @Override
-  public Void visitField(DartField node) {
-    validate(node);
-    node.visitChildren(this);
-    node.getName().accept(this);
-    return null;
-  }
-
-  @Override
-  public Void visitForInStatement(DartForInStatement node) {
-    validate(node);
-    node.visitChildren(this);
-    return null;
-  }
-
-  @Override
-  public Void visitForStatement(DartForStatement node) {
-    validate(node);
-    node.visitChildren(this);
-    return null;
-  }
-
-  @Override
-  public Void visitFunction(DartFunction node) {
-    validate(node);
-    node.visitChildren(this);
-    return null;
-  }
-
-  @Override
-  public Void visitFunctionExpression(DartFunctionExpression node) {
-    validate(node);
-    DartIdentifier name = node.getName();
-    if (name != null) {
-      name.accept(this);
-    }
-    node.visitChildren(this);
-    return null;
-  }
-
-  @Override
-  public Void visitFunctionObjectInvocation(DartFunctionObjectInvocation node) {
-    validate(node);
-    node.visitChildren(this);
-    return null;
-  }
-
-  @Override
-  public Void visitFunctionTypeAlias(DartFunctionTypeAlias node) {
-    validate(node);
-    node.getName().accept(this);
-    node.visitChildren(this);
-    return null;
-  }
-
-  @Override
-  public Void visitIdentifier(DartIdentifier node) {
-    validate(node);
-    node.visitChildren(this);
-    return null;
-  }
-
-  @Override
-  public Void visitIfStatement(DartIfStatement node) {
-    validate(node);
-    node.visitChildren(this);
-    return null;
-  }
-
-  @Override
-  public Void visitImportDirective(DartImportDirective node) {
-    validate(node);
-    node.visitChildren(this);
-    return null;
-  }
-
-  @Override
-  public Void visitInitializer(DartInitializer node) {
-    validate(node);
-    node.visitChildren(this);
-    return null;
-  }
-
-  @Override
-  public Void visitIntegerLiteral(DartIntegerLiteral node) {
-    validate(node);
-    node.visitChildren(this);
-    return null;
-  }
-
-  @Override
-  public Void visitLabel(DartLabel node) {
-    validate(node);
-    node.getLabel().accept(this);
-    node.visitChildren(this);
-    return null;
-  }
-
-  @Override
-  public Void visitLibraryDirective(DartLibraryDirective node) {
-    validate(node);
-    node.visitChildren(this);
-    return null;
-  }
-
-  @Override
-  public Void visitMapLiteral(DartMapLiteral node) {
-    validate(node);
-    node.visitChildren(this);
-    return null;
-  }
-
-  @Override
-  public Void visitMapLiteralEntry(DartMapLiteralEntry node) {
-    validate(node);
-    node.visitChildren(this);
-    return null;
-  }
-
-  @Override
-  public Void visitMethodDefinition(DartMethodDefinition node) {
-    validate(node);
-    node.getName().accept(this);
-    node.visitChildren(this);
-    return null;
-  }
-
-  @Override
-  public Void visitMethodInvocation(DartMethodInvocation node) {
-    validate(node);
-    node.visitChildren(this);
-    return null;
-  }
-
-  @Override
-  public Void visitNativeBlock(DartNativeBlock node) {
-    validate(node);
-    node.visitChildren(this);
-    return null;
-  }
-
-  @Override
-  public Void visitNativeDirective(DartNativeDirective node) {
-    validate(node);
-    node.visitChildren(this);
-    return null;
-  }
-
-  @Override
-  public Void visitNewExpression(DartNewExpression node) {
-    validate(node);
-    node.visitChildren(this);
-    return null;
-  }
-
-  @Override
-  public Void visitNullLiteral(DartNullLiteral node) {
-    validate(node);
-    node.visitChildren(this);
-    return null;
-  }
-
-  @Override
-  public Void visitParameter(DartParameter node) {
-    validate(node);
-    node.getName().accept(this);
-    node.visitChildren(this);
-    return null;
-  }
-
-  @Override
-  public Void visitParenthesizedExpression(DartParenthesizedExpression node) {
-    validate(node);
-    node.visitChildren(this);
-    return null;
-  }
-
-  @Override
-  public Void visitPropertyAccess(DartPropertyAccess node) {
-    validate(node);
-    node.visitChildren(this);
-    return null;
-  }
-
-  @Override
-  public Void visitReturnStatement(DartReturnStatement node) {
-    validate(node);
-    node.visitChildren(this);
-    return null;
-  }
-
-  @Override
-  public Void visitSourceDirective(DartSourceDirective node) {
-    validate(node);
-    node.visitChildren(this);
-    return null;
-  }
-
-  @Override
-  public Void visitNamedExpression(DartNamedExpression node) {
-    validate(node);
-    node.visitChildren(this);
-    return null;
-  }
-
-  @Override
-  public Void visitStringInterpolation(DartStringInterpolation node) {
-    validate(node);
-    node.visitChildren(this);
-    return null;
-  }
-
-  @Override
-  public Void visitStringLiteral(DartStringLiteral node) {
-    validate(node);
-    node.visitChildren(this);
-    return null;
-  }
-
-  @Override
-  public Void visitSuperConstructorInvocation(
-      DartSuperConstructorInvocation node) {
-    validate(node);
-    node.visitChildren(this);
-    return null;
-  }
-
-  @Override
-  public Void visitSuperExpression(DartSuperExpression node) {
-    validate(node);
-    node.visitChildren(this);
-    return null;
-  }
-
-  @Override
-  public Void visitSwitchStatement(DartSwitchStatement node) {
-    validate(node);
-    node.visitChildren(this);
-    return null;
-  }
-
-  @Override
-  public Void visitSyntheticErrorExpression(DartSyntheticErrorExpression node) {
-    validate(node);
-    node.visitChildren(this);
-    return null;
-  }
-
-  @Override
-  public Void visitSyntheticErrorStatement(DartSyntheticErrorStatement node) {
-    validate(node);
-    node.visitChildren(this);
-    return null;
-  }
-
-  @Override
-  public Void visitThisExpression(DartThisExpression node) {
-    validate(node);
-    node.visitChildren(this);
-    return null;
-  }
-
-  @Override
-  public Void visitThrowExpression(DartThrowExpression node) {
-    validate(node);
-    node.visitChildren(this);
-    return null;
-  }
-
-  @Override
-  public Void visitTryStatement(DartTryStatement node) {
-    validate(node);
-    node.visitChildren(this);
-    return null;
-  }
-
-  @Override
-  public Void visitTypeExpression(DartTypeExpression node) {
-    validate(node);
-    node.visitChildren(this);
-    return null;
-  }
-
-  @Override
-  public Void visitTypeNode(DartTypeNode node) {
-    validate(node);
-    node.visitChildren(this);
-    return null;
-  }
-
-  @Override
-  public Void visitTypeParameter(DartTypeParameter node) {
-    validate(node);
-    node.getName().accept(this);
-    node.visitChildren(this);
-    return null;
-  }
-
-  @Override
-  public Void visitUnaryExpression(DartUnaryExpression node) {
-    validate(node);
-    node.visitChildren(this);
-    return null;
-  }
-
-  @Override
-  public Void visitUnit(DartUnit node) {
-    node.visitChildren(this);
-    return null;
-  }
-
-  @Override
-  public Void visitUnqualifiedInvocation(DartUnqualifiedInvocation node) {
-    validate(node);
-    node.visitChildren(this);
-    return null;
-  }
-
-  @Override
-  public Void visitVariable(DartVariable node) {
-    validate(node);
-    node.getName().accept(this);
-    node.visitChildren(this);
-    return null;
-  }
-
-  @Override
-  public Void visitVariableStatement(DartVariableStatement node) {
-    validate(node);
-    node.visitChildren(this);
-    return null;
-  }
-
-  @Override
-  public Void visitWhileStatement(DartWhileStatement node) {
-    validate(node);
-    node.visitChildren(this);
-    return null;
-  }
-
-  @Override
-  public Void visitRedirectConstructorInvocation(DartRedirectConstructorInvocation node) {
-    validate(node);
-    node.visitChildren(this);
-    return null;
-  }
-
-  private void validate(DartNode node) {
-    DartNode parent = node.getParent();
-    if (parent == null) {
-      errors.add("No parent for " + node.getClass().getName());
-    }
-
-    int nodeStart = node.getSourceInfo().getOffset();
-    int nodeLength = node.getSourceInfo().getLength();
-    if (nodeStart < 0 || nodeLength < 0) {
-      errors.add("No source info for " + node.getClass().getName());
-    }
-
-    if (parent != null) {
-      int nodeEnd = nodeStart + nodeLength;
-      int parentStart = parent.getSourceInfo().getOffset();
-      int parentEnd = parentStart + parent.getSourceInfo().getLength();
-      if (parentStart > nodeStart && !isExceptionForNesting(node)) {
-        errors.add("Invalid source start (" + nodeStart + ") for "
-            + node.getClass().getName() + " inside "
-            + parent.getClass().getName() + " (" + parentStart + ")");
-      }
-      if (nodeEnd > parentEnd && !isExceptionForNesting(node)) {
-        errors.add("Invalid source end (" + nodeEnd + ") for "
-            + node.getClass().getName() + " inside "
-            + parent.getClass().getName() + " (" + parentStart + ")");
-      }
-    }
-
-    if (node instanceof DartSyntheticErrorExpression
-        || node instanceof DartSyntheticErrorExpression) {
-      errors.add("Parser error at (" + nodeStart + ")");
-    }
-  }
-
-  /**
-   * Return {@code true} if the given node is an exception to the rule that nodes must nest lexically
-   * within their parents. The one exception currently recognized is a DartTypeNode whose parent is
-   * a DartParameter within a DartCatchBlock. This exception exists because the type has been moved
-   * outside the parameter (following the 'on' keyword) but we didn't update the AST structure to
-   * reflect this change.
-   *
-   * @param node the node being tested
-   * @return {@code true} if the given node is an exception to the rule that nodes must nest lexically
-   * within their parents
-   */
-  private boolean isExceptionForNesting(DartNode node) {
-    return (node instanceof DartTypeNode) && (node.getParent() instanceof DartParameter) && (node.getParent().getParent() instanceof DartCatchBlock);
-  }
-
-  @Override
-  public Void visitParameterizedTypeNode(DartParameterizedTypeNode node) {
-    validate(node);
-    node.visitChildren(this);
-    return null;
-  }
-}
diff --git a/compiler/javatests/com/google/dart/compiler/parser/DartParserRunner.java b/compiler/javatests/com/google/dart/compiler/parser/DartParserRunner.java
deleted file mode 100644
index 7c49eb9..0000000
--- a/compiler/javatests/com/google/dart/compiler/parser/DartParserRunner.java
+++ /dev/null
@@ -1,209 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.parser;
-
-import com.google.common.collect.Sets;
-import com.google.dart.compiler.DartCompilationError;
-import com.google.dart.compiler.DartCompilerListener;
-import com.google.dart.compiler.DartSource;
-import com.google.dart.compiler.DartSourceTest;
-import com.google.dart.compiler.ErrorSeverity;
-import com.google.dart.compiler.ast.DartUnit;
-
-import junit.framework.TestCase;
-
-import java.io.BufferedReader;
-import java.io.FileReader;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.concurrent.atomic.AtomicReference;
-
-public class DartParserRunner implements DartCompilerListener, Runnable {
-
-  public static final int DEFAULT_TIMEOUT_IN_MILISECONDS = 10 * 1000;
-
-  public static void main(String[] args) {
-    for (String fileName : args) {
-      String source = readSource(fileName);
-      if (source == null) {
-        System.err.println("Unable to read " + fileName);
-        continue;
-      }
-      System.out.println("Parsing " + fileName);
-      DartParserRunner parser = DartParserRunner.parse(fileName, source, Integer.MAX_VALUE, true);
-      for (DartCompilationError error : parser.getErrors()) {
-        System.err.println(error.toString());
-      }
-    }
-  }
-
-  /*
-   * Parses @sourceCode ensuring explicit failure in case of non-termination.
-   */
-  public static DartParserRunner parse(String name, String sourceCode) {
-   return DartParserRunner.parse(name, sourceCode, false);
-  }
-
-  /*
-   * Parses @sourceCode ensuring explicit failure in case of non-termination.
-   */
-  public static DartParserRunner parse(String name, String sourceCode, int timeoutInMs,
-       boolean wantWarnings) {
-   return DartParserRunner.parse(name, sourceCode, false, timeoutInMs, wantWarnings);
-  }
-
-  /*
-   * Parses @sourceCode ensuring explicit failure in case of non-termination.
-   */
-  public static DartParserRunner parse(String name, String sourceCode, boolean apiParsing) {
-    return parse(name, sourceCode, apiParsing, 0, false);
-  }
-
-  /*
-   * Parses @sourceCode ensuring explicit failure in case of non-termination.
-   */
-  public static DartParserRunner parse(String name, String sourceCode, boolean apiParsing,
-        int timeoutInMs, boolean wantWarnings) {
-    DartParserRunner parser  = null;
-    try {
-      parser = new DartParserRunner(name, sourceCode, apiParsing);
-      if (timeoutInMs != 0) {
-        parser.setTimeout(timeoutInMs);
-      }
-      parser.setWantWarnings(wantWarnings);
-      parser.doWork();
-      TestCase.assertFalse("Dart parser failed to terminate.", parser.isAlive());
-      Throwable t = parser.workerException.get();
-      if (t != null) {
-        throw new AssertionError(t);
-      }
-    } catch(Exception e) {
-      throw new Error(e.toString());
-    }
-    return parser;
-  }
-
-  /**
-   * Reads a text file and returns the contents as a String.
-   * 
-   * @param file
-   * @return file contents as a String
-   */
-  private static String readSource(String file) {
-    StringBuilder buf = new StringBuilder();
-    BufferedReader reader = null;
-    try {
-      reader = new BufferedReader(new FileReader(file));
-      String line;
-      while ((line = reader.readLine()) != null) {
-        buf.append(line).append("\n");
-      }
-      return buf.toString();
-    } catch (IOException e) {
-      return null;
-    } finally {
-      if (reader != null) {
-        try {
-          reader.close();
-        } catch (IOException e) {
-        }
-      }
-    }
-  }
-
-  private boolean apiParsing;
-  private DartUnit dartUnit;
-  private List<DartCompilationError> errors = new ArrayList<DartCompilationError>();
-  private String name;
-
-  private Thread parserWorker;
-
-  private String sourceCode;
-
-  private int timeoutInMillis = DEFAULT_TIMEOUT_IN_MILISECONDS;
-
-  private AtomicReference<Throwable> workerException = new AtomicReference<Throwable>();
-
-  private boolean wantWarnings;
-
-  private DartParserRunner(String name, String sourceCode) {
-    this(name, sourceCode, false);
-  }
-
-  private DartParserRunner(String name, String sourceCode, boolean apiParsing) {
-    this.name = name;
-    this.sourceCode = sourceCode;
-    this.parserWorker = new Thread(this);
-    this.apiParsing = apiParsing;
-  }
-
-  public DartUnit getDartUnit() {
-    return dartUnit;
-  }
-
-  @Override
-  public void onError(DartCompilationError event) {
-    if (event.getErrorCode().getErrorSeverity() == ErrorSeverity.WARNING && !wantWarnings) {
-      return;
-    }
-    errors.add(event);
-  }
-
-  public int getErrorCount() {
-    return errors.size();
-  }
-
-  public List<DartCompilationError> getErrors() {
-    return errors;
-  }
-
-  public boolean hasErrors() {
-    return getErrors().size() > 0;
-  }
-
-  @Override
-  public void run() {
-    try {
-      DartSourceTest dartSrc = new DartSourceTest(name, sourceCode, null);
-      dartUnit = (new DartParser(
-          dartSrc,
-          sourceCode,
-          apiParsing,
-          Sets.<String>newHashSet(),
-          this,
-          null)).parseUnit();
-    } catch (Throwable t) {
-      workerException.set(t);
-    }
-  }
-
-  public DartParserRunner setTimeout(int timeoutInMillis) {
-    this.timeoutInMillis = timeoutInMillis;
-    return this;
-  }
-
-  public DartParserRunner setWantWarnings(boolean wantWarnings) {
-    this.wantWarnings = wantWarnings;
-    return this;
-  }
-
-  private void doWork() throws InterruptedException {
-    parserWorker.start();
-    parserWorker.join(timeoutInMillis);
-  }
-
-  private boolean isAlive() {
-    return parserWorker.isAlive();
-  }
-
-  @Override
-  public void unitAboutToCompile(DartSource source, boolean diet) {
-  }
-
-  @Override
-  public void unitCompiled(DartUnit unit) {
-  }
-}
diff --git a/compiler/javatests/com/google/dart/compiler/parser/DietParserTest.java b/compiler/javatests/com/google/dart/compiler/parser/DietParserTest.java
deleted file mode 100644
index 5c40314..0000000
--- a/compiler/javatests/com/google/dart/compiler/parser/DietParserTest.java
+++ /dev/null
@@ -1,26 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.parser;
-
-import com.google.common.collect.Sets;
-import com.google.dart.compiler.DartCompilerListener;
-import com.google.dart.compiler.Source;
-
-/**
- * Tests for the parser, which simply assert that valid source units parse
- * correctly. All tests invoking {@code parseUnit} are designed such that
- * they will throw an exception if anything goes wrong in the parser.
- */
-public class DietParserTest extends AbstractParserTest {
-
-  public void testStringsErrors() {
-    parseUnit("StringsErrorsNegativeTest.dart");
-  }
-  
-  @Override
-  protected DartParser makeParser(Source src, String sourceCode, DartCompilerListener listener) {
-    return new DartParser(src, sourceCode, true, Sets.<String>newHashSet(), listener, null);
-  }
-}
diff --git a/compiler/javatests/com/google/dart/compiler/parser/Directives.dart b/compiler/javatests/com/google/dart/compiler/parser/Directives.dart
deleted file mode 100644
index 403724d..0000000
--- a/compiler/javatests/com/google/dart/compiler/parser/Directives.dart
+++ /dev/null
@@ -1,15 +0,0 @@
-#!/bin/dart
-/*
- * Beginning comment
- */
-
-library a_directives_test;
- 
-import "dart:core";
- 
-part "ListObjectLiterals.dart";
- 
- main() {
-   // something to do here
- }
- 
\ No newline at end of file
diff --git a/compiler/javatests/com/google/dart/compiler/parser/Directives2.dart b/compiler/javatests/com/google/dart/compiler/parser/Directives2.dart
deleted file mode 100644
index 098fb2d..0000000
--- a/compiler/javatests/com/google/dart/compiler/parser/Directives2.dart
+++ /dev/null
@@ -1,9 +0,0 @@
-library b_directives_test;
- 
-import "dart:core";
-part "SomeClass.dart";
- 
- main() {
-   // something to do here
- }
- 
\ No newline at end of file
diff --git a/compiler/javatests/com/google/dart/compiler/parser/ErrorMessageLocationTest.java b/compiler/javatests/com/google/dart/compiler/parser/ErrorMessageLocationTest.java
deleted file mode 100644
index cb1376a..0000000
--- a/compiler/javatests/com/google/dart/compiler/parser/ErrorMessageLocationTest.java
+++ /dev/null
@@ -1,58 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.parser;
-
-import com.google.dart.compiler.DartCompilationError;
-
-import junit.framework.TestCase;
-
-import java.util.List;
-
-/**
- * Test that error messages cover the correct locations in the source code.
- */
-public class ErrorMessageLocationTest extends TestCase {
-  /**
-   * Test that unexpected token highlights the correct location in the file.
-   */
-  public void testUnexpectedTokenErrorMessage() {
-    String sourceCode =
-        "// Empty comment\n" +
-        "class foo while Bar {\n" +
-        "}";
-
-    DartParserRunner runner = DartParserRunner.parse(getName(), sourceCode);
-    List<DartCompilationError> actualErrors = runner.getErrors();
-
-    // Due to error recovery more than a single error is generated
-    DartCompilationError actualError = actualErrors.get(0);
-
-    String errorTokenString = "while";
-    assertEquals(11, actualError.getColumnNumber());
-    assertEquals(errorTokenString.length(), actualError.getLength());
-    assertEquals(2, actualError.getLineNumber());
-    assertEquals(sourceCode.indexOf(errorTokenString), actualError.getStartPosition());
-  }
-
-  public void testExpectedLeftParenErrorMessage1() {
-    String sourceCode =
-        "// comment to change the line\n" +
-        "main () {\n" +
-        "  var x = new PART1.PART2.PART3.PART4();\n" +
-        "}\n";
-
-    DartParserRunner runner = DartParserRunner.parse(getName(), sourceCode);
-    List<DartCompilationError> actualErrors = runner.getErrors();
-
-    // Due to error recovery more than a single error is generated
-    DartCompilationError actualError = actualErrors.get(0);
-
-    String errorTokenString = "PART4";
-    assertEquals(33, actualError.getColumnNumber());
-    assertEquals(errorTokenString.length(), actualError.getLength());
-    assertEquals(3, actualError.getLineNumber());
-    assertEquals(sourceCode.indexOf(errorTokenString), actualError.getStartPosition());
-  }
-}
diff --git a/compiler/javatests/com/google/dart/compiler/parser/FactoryInitializersNegativeTest.dart b/compiler/javatests/com/google/dart/compiler/parser/FactoryInitializersNegativeTest.dart
deleted file mode 100644
index 6fcf52c..0000000
--- a/compiler/javatests/com/google/dart/compiler/parser/FactoryInitializersNegativeTest.dart
+++ /dev/null
@@ -1,12 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-// expect syntax errors: Factory constructors cannot have initializers.
-
-class A {
-  int x;
-  int y;
-  factory A.foo(x,y) : this.x = 1 {
-  }
-}
diff --git a/compiler/javatests/com/google/dart/compiler/parser/FormalParameters.dart b/compiler/javatests/com/google/dart/compiler/parser/FormalParameters.dart
deleted file mode 100644
index c650b86..0000000
--- a/compiler/javatests/com/google/dart/compiler/parser/FormalParameters.dart
+++ /dev/null
@@ -1,10 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-class FormalParameterSyntax {
-  a([x = 42]) { }
-  b([int x = 42]) { }
-  c(x, [y = 42]) { }
-  d(x, [int y = 42]) { }
-}
diff --git a/compiler/javatests/com/google/dart/compiler/parser/FunctionInterfaces.dart b/compiler/javatests/com/google/dart/compiler/parser/FunctionInterfaces.dart
deleted file mode 100644
index ff4f879..0000000
--- a/compiler/javatests/com/google/dart/compiler/parser/FunctionInterfaces.dart
+++ /dev/null
@@ -1,28 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-typedef void VoidCallback1(Event event);
-typedef void VoidCallback2(Event event, int x);
-typedef void VoidCallback3(Event event, int x, y);
-typedef void VoidCallback4(Event event, int x, var y);
-
-typedef Callback1(Event event);
-typedef Callback2(Event event, int x);
-typedef Callback3(Event event, int x, y);
-typedef Callback4(Event event, int x, var y);
-
-typedef int IntCallback1(Event event);
-typedef int IntCallback2(Event event, int x);
-typedef int IntCallback3(Event event, int x, y);
-typedef int IntCallback4(Event event, int x, var y);
-
-typedef Box<int> BoxCallback1(Event event);
-typedef Box<int> BoxCallback2(Event event, int x);
-typedef Box<int> BoxCallback3(Event event, int x, y);
-typedef Box<int> BoxCallback4(Event event, int x, var y);
-
-typedef Box<Box<int>> BoxBoxCallback1(Event event);
-typedef Box<Box<int>> BoxBoxCallback2(Event event, int x);
-typedef Box<Box<int>> BoxBoxCallback3(Event event, int x, y);
-typedef Box<Box<int>> BoxBoxCallback4(Event event, int x, var y);
diff --git a/compiler/javatests/com/google/dart/compiler/parser/FunctionTypes.dart b/compiler/javatests/com/google/dart/compiler/parser/FunctionTypes.dart
deleted file mode 100644
index 0bfdcc8..0000000
--- a/compiler/javatests/com/google/dart/compiler/parser/FunctionTypes.dart
+++ /dev/null
@@ -1,21 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-class FunctionTypeSyntax {
-  Function a;
-  static Function b;
-
-  Function c() { }
-  static Function d() { }
-
-  e(Function f) { }
-  static f(Function f) { }
-
-  g(f()) { }
-  h(void f()) { }
-  j(f(x)) { }
-  k(f(x, y)) { }
-  l(int f(int x, int y)) { }
-  m(int x, int f(x), int y) { }
-}
diff --git a/compiler/javatests/com/google/dart/compiler/parser/GenericTypedef.dart b/compiler/javatests/com/google/dart/compiler/parser/GenericTypedef.dart
deleted file mode 100644
index de23728..0000000
--- a/compiler/javatests/com/google/dart/compiler/parser/GenericTypedef.dart
+++ /dev/null
@@ -1,5 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-typedef T Deserializer<T>(InputDataStream input);
diff --git a/compiler/javatests/com/google/dart/compiler/parser/GenericTypes.dart b/compiler/javatests/com/google/dart/compiler/parser/GenericTypes.dart
deleted file mode 100644
index ba1ca8d..0000000
--- a/compiler/javatests/com/google/dart/compiler/parser/GenericTypes.dart
+++ /dev/null
@@ -1,15 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-class Box<T> {
-  T t;
-  getT() { return t; }
-  setT(T t) { this.t = t; }
-}
-
-class UseBox {
-  Box<Box<Box<prefix.Fisk>>> boxIt(Box<Box<prefix.Fisk>> box) {
-    return new Box<Box<Box<prefix.Fisk>>>(box);
-  }
-}
diff --git a/compiler/javatests/com/google/dart/compiler/parser/LibraryParserTest.java b/compiler/javatests/com/google/dart/compiler/parser/LibraryParserTest.java
deleted file mode 100644
index c17e62f..0000000
--- a/compiler/javatests/com/google/dart/compiler/parser/LibraryParserTest.java
+++ /dev/null
@@ -1,171 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.parser;
-
-import com.google.common.collect.Sets;
-import com.google.dart.compiler.DartCompilerListenerTest;
-import com.google.dart.compiler.DartSource;
-import com.google.dart.compiler.LibrarySource;
-import com.google.dart.compiler.ast.LibraryNode;
-import com.google.dart.compiler.ast.LibraryUnit;
-
-import junit.framework.TestCase;
-
-import java.io.Reader;
-import java.io.StringReader;
-import java.net.URI;
-import java.net.URISyntaxException;
-
-/**
- * Tests for parsing library directives from a dart file.
- */
-public class LibraryParserTest extends TestCase {
-
-  static class TestLibrarySource implements LibrarySource {
-    private final String source;
-
-    public TestLibrarySource(String source) {
-      this.source = source;
-    }
-
-    @Override
-    public String getUniqueIdentifier() {
-      return getName();
-    }
-
-    @Override
-    public URI getUri() {
-      try {
-        return new URI(getName());
-      } catch (URISyntaxException e) {
-        throw new RuntimeException(e);
-      }
-    }
-
-    @Override
-    public Reader getSourceReader() {
-      return new StringReader(source);
-    }
-
-    @Override
-    public String getName() {
-      return "test.dart";
-    }
-
-    @Override
-    public boolean exists() {
-      return true;
-    }
-
-    @Override
-    public long getLastModified() {
-      return 0;
-    }
-
-    @Override
-    public DartSource getSourceFor(String relPath) {
-      return null;
-    }
-
-    @Override
-    public LibrarySource getImportFor(String relPath) {
-      return null;
-    }
-  }
-
-  public void testLibrary() {
-    // "library { import = ['foo.lib', 'bar.lib'] source = ['this.dart', 'that.dart'] }";
-    String text =
-        "library testLibrary;\n" 
-      + "import \"foo.dart\";\n" 
-      + "import \"bar.dart\";\n"
-      + "part \"this.dart\";\n" 
-      + "part \"that.dart\";\n";
-
-    LibraryUnit unit = parse(text);
-
-    assertHasImport(unit, "foo.dart");
-    assertHasImport(unit, "bar.dart");
-    assertHasSource(unit, "this.dart");
-    assertHasSource(unit, "that.dart");
-  }
-
-  public void testNative() {
-      // "library { import = ['foo.lib'] source = ['this.dart'] native = ['impl.js'] }";
-    String text =
-        "library testLibrary;\n" 
-      + "import \"foo.dart\";\n" 
-      + "part \"this.dart\";\n" 
-      + "#native(\"impl.js\");\n";
-      
-    LibraryUnit unit = parse(text);
-
-    assertHasImport(unit, "foo.dart");
-    assertHasSource(unit, "this.dart");
-    assertHasNative(unit, "impl.js");
-  }
-
-  public void testImportPrefix() {
-//      "library { import = [foo:'foo.lib', 'bar.lib'] source = ['this.dart', 'that.dart'] }";
-    String text =
-        "library testLibrary;\n" 
-      + "import \"foo.dart\" as foo;\n" 
-      + "import \"bar.dart\";\n" 
-      + "part \"this.dart\";\n" 
-      + "#native(\"impl.js\");\n";
-    LibraryUnit unit = parse(text);
-
-    assertHasImport(unit, "foo.dart", "foo");
-    assertHasImport(unit, "bar.dart");
-    assertHasSource(unit, "this.dart");
-    assertHasNative(unit, "impl.js");
-  }
-
-  private void assertHasImport(LibraryUnit unit, String name) {
-    assertHas(unit.getImportPaths(), name);
-  }
-
-  private void assertHasImport(LibraryUnit unit, String name, String prefix) {
-    assertHas(unit.getImportPaths(), name, prefix);
-  }
-
-  private void assertHasSource(LibraryUnit unit, String name) {
-    assertHas(unit.getSourcePaths(), name);
-  }
-
-  private void assertHasNative(LibraryUnit unit, String name) {
-    assertHas(unit.getNativePaths(), name);
-  }
-
-  private void assertHas(Iterable<LibraryNode> nodes, String name) {
-    assertHas(nodes, name, null);
-  }
-
-  private void assertHas(Iterable<LibraryNode> nodes, String name, String prefix) {
-    for (LibraryNode node : nodes) {
-      if (node.getText().equals(name)) {
-        if ((prefix != null) && !node.getPrefix().equals(prefix)) {
-          break;
-        }
-        return;
-      }
-    }
-    fail("Missing " + ((prefix != null) ? (prefix + " : ") : "") + name);
-  }
-
-  private LibraryUnit parse(String text, Object... errors) {
-    TestLibrarySource source = new TestLibrarySource(text);
-    DartCompilerListenerTest listener = new DartCompilerListenerTest(source.getName(), errors);
-    LibraryUnit unit = new DartParser(
-        source,
-        text,
-        false,
-        Sets.<String>newHashSet(),
-        listener,
-        null).preProcessLibraryDirectives(source);
-    listener.checkAllErrorsReported();
-    return unit;
-  }
-}
diff --git a/compiler/javatests/com/google/dart/compiler/parser/ListObjectLiterals.dart b/compiler/javatests/com/google/dart/compiler/parser/ListObjectLiterals.dart
deleted file mode 100644
index 0e3b301..0000000
--- a/compiler/javatests/com/google/dart/compiler/parser/ListObjectLiterals.dart
+++ /dev/null
@@ -1,32 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-class ListObjectLiterals {
-  foo() {
-    var a = [a, b, [c + 42, x], 1, 2, 3];
-    var b = { 'a':1, 'b':c + 42, 'd':[0, 1, 2], 'e':{ 'foo':42, 'bar':49 }};
-
-    var c = [a, b, ];
-    var d = {'a':1, 'b':2, 'c':3};
-
-    var e = [ ];
-    var f = { };
-    var g = [];
-    var h = {};
-
-    var i = const [];
-    var j = const <int>[];
-    var k = <int>[];
-    var l = const [1,2,3];
-    var m = const <int>[1,2,3];
-    var n = <int>[1,2,3];
-
-    var o = const {};
-    var p = const <String, int>{};
-    var q = <String, int>{};
-    var r = const {'a':1, 'b':2, 'c':3};
-    var s = const <int> {'a':1, 'b':2, 'c':3 };
-    var t = {'a':1, 'b':2, 'c':3};
-  }
-}
diff --git a/compiler/javatests/com/google/dart/compiler/parser/MethodSignatures.dart b/compiler/javatests/com/google/dart/compiler/parser/MethodSignatures.dart
deleted file mode 100644
index 6a2b414..0000000
--- a/compiler/javatests/com/google/dart/compiler/parser/MethodSignatures.dart
+++ /dev/null
@@ -1,20 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-abstract class MethodSignatureSyntax {
-  a();
-  b(x);
-  c(int x);
-  d(var x);
-  e(final x);
-
-  f(x, y);
-  g(var x, y);
-  h(final x, y);
-  j(var x, var y);
-  k(final x, final y);
-
-  l(int x, y);
-  m(int x, int y);
-}
diff --git a/compiler/javatests/com/google/dart/compiler/parser/NegativeParserTest.java b/compiler/javatests/com/google/dart/compiler/parser/NegativeParserTest.java
deleted file mode 100644
index e1c94ca..0000000
--- a/compiler/javatests/com/google/dart/compiler/parser/NegativeParserTest.java
+++ /dev/null
@@ -1,1053 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-package com.google.dart.compiler.parser;
-
-import com.google.common.base.Joiner;
-import com.google.dart.compiler.CompilerTestCase;
-import com.google.dart.compiler.ast.DartClass;
-import com.google.dart.compiler.ast.DartIdentifier;
-import com.google.dart.compiler.ast.DartMethodDefinition;
-import com.google.dart.compiler.ast.DartNode;
-import com.google.dart.compiler.ast.DartUnit;
-
-import static com.google.dart.compiler.common.ErrorExpectation.assertErrors;
-import static com.google.dart.compiler.common.ErrorExpectation.errEx;
-
-import java.util.List;
-import java.util.Set;
-
-/**
- * Negative Parser/Syntax tests.
- */
-public class NegativeParserTest extends CompilerTestCase {
-  public void test_deprecatedGetterSyntax() {
-    parseExpectErrors("get foo() {}", errEx(ParserErrorCode.DEPRECATED_GETTER, 1, 5, 3));
-  }
-
-  public void test_deprecatedStrictEQ() {
-    parseExpectErrors(makeCode(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "main() {",
-        "  1 === 2;",
-        "}",
-        ""), errEx(ParserErrorCode.DEPRECATED_STRICT_EQ, 3, 5, 3));
-  }
-
-  public void test_deprecatedStrictNE() {
-    parseExpectErrors(makeCode(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "main() {",
-        "  1 !== 2;",
-        "}",
-        ""), errEx(ParserErrorCode.DEPRECATED_STRICT_NE, 3, 5, 3));
-  }
-
-  public void test_deprecatedAbstract() {
-    parseExpectWarnings(makeCode(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "abstract class A {",
-        "  abstract m();",
-        "}",
-        ""), errEx(ParserErrorCode.DEPRECATED_ABSTRACT_METHOD, 3, 3, 8));
-  }
-  
-  public void testFieldInitializerInRedirectionConstructor1() {
-    parseExpectErrors(
-        "class A { A(x) { } A.foo() : this(5), y = 5; var y; }",
-        errEx(ParserErrorCode.REDIRECTING_CONSTRUCTOR_OTHER, 1, 39, 5),
-        errEx(ParserErrorCode.REDIRECTING_CONSTRUCTOR_ITSELF, 1, 30, 7));
-  }
-  
-  public void test_deprecatedFunctionLiteral() {
-    parseExpectWarnings(
-        makeCode(
-            "// filler filler filler filler filler filler filler filler filler filler",
-            "main() {",
-            "  var x = f() => 42;",
-            "  var y = int g() => 87;",
-            "}",
-            ""),
-        errEx(ParserErrorCode.DEPRECATED_FUNCTION_LITERAL, 3, 11, 1),
-        errEx(ParserErrorCode.DEPRECATED_FUNCTION_LITERAL, 4, 11, 3));
-  }
-  
-  public void testFieldInitializerInRedirectionConstructor2() {
-    parseExpectErrors(
-        "class A { A(x) { } A.foo() : y = 5, this(5); var y; }",
-        errEx(ParserErrorCode.REDIRECTING_CONSTRUCTOR_OTHER, 1, 30, 5),
-        errEx(ParserErrorCode.REDIRECTING_CONSTRUCTOR_ITSELF, 1, 37, 7));
-  }
-
-  public void testFieldInitializerInRedirectionConstructor3() {
-    parseExpectErrors(
-        "class A { A.foo(x) { } A() : y = 5, this.foo(5); var y; }",
-        errEx(ParserErrorCode.REDIRECTING_CONSTRUCTOR_OTHER, 1, 30, 5),
-        errEx(ParserErrorCode.REDIRECTING_CONSTRUCTOR_ITSELF, 1, 37, 11));
-  }
-
-  public void testFieldInitializerInRedirectionConstructor4() {
-    parseExpectErrors(
-        "class A { A(x) { } A.foo(this.y, this.z) : this(5); var y; var z;}",
-        errEx(ParserErrorCode.REDIRECTING_CONSTRUCTOR_PARAM, 1, 26, 6),
-        errEx(ParserErrorCode.REDIRECTING_CONSTRUCTOR_PARAM, 1, 34, 6),
-        errEx(ParserErrorCode.REDIRECTING_CONSTRUCTOR_ITSELF, 1, 44, 7));
-  }
-
-  public void testFieldInitializerInRedirectionConstructor5() {
-    parseExpectErrors(
-        "class A { A(x) { } A.foo(this.y) : this(5), z = 7; var y; var z;}",
-        errEx(ParserErrorCode.REDIRECTING_CONSTRUCTOR_PARAM, 1, 26, 6),
-        errEx(ParserErrorCode.REDIRECTING_CONSTRUCTOR_OTHER, 1, 45, 5),
-        errEx(ParserErrorCode.REDIRECTING_CONSTRUCTOR_ITSELF, 1, 36, 7));
-  }
-
-  public void testSuperInRedirectionConstructor1() {
-    parseExpectErrors(
-        "class A { A(x) { } A.foo() : this(5), super(); var y; }",
-        errEx(ParserErrorCode.REDIRECTING_CONSTRUCTOR_OTHER, 1, 39, 7),
-        errEx(ParserErrorCode.REDIRECTING_CONSTRUCTOR_ITSELF, 1, 30, 7));
-  }
-
-  public void testSuperInRedirectionConstructor2() {
-    parseExpectErrors(
-        "class A { A(x) { } A.foo() : super(), this(5); var y; }",
-        errEx(ParserErrorCode.REDIRECTING_CONSTRUCTOR_OTHER, 1, 30, 7),
-        errEx(ParserErrorCode.REDIRECTING_CONSTRUCTOR_ITSELF, 1, 39, 7));
-  }
-
-  public void testMultipleRedirectionConstructors() {
-    parseExpectErrors(
-        "class A { A(x) { } A.foo() : this(1), this(2); }",
-        errEx(ParserErrorCode.REDIRECTING_CONSTRUCTOR_MULTIPLE, 1, 30, 7),
-        errEx(ParserErrorCode.REDIRECTING_CONSTRUCTOR_MULTIPLE, 1, 39, 7));
-  }
-
-  /**
-   * May be parsing errors, but not exceptions.
-   * <p>
-   * http://code.google.com/p/dart/issues/detail?id=4040
-   */
-  public void test_incompleteArguments() {
-    parseSource(makeCode(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "main() {",
-        "  f(a: 0,",
-        "}",
-        ""));
-  }
-
-  public void testSuperMultipleInvocationsTest() {
-    String source =
-        makeCode(
-            "class A {",
-            "    int a;",
-            "    A(this.a);",
-            "    A.foo(int x, int y);",
-            "}",
-            "",
-            "class B extends A {",
-            "    int b1;",
-            "    int b2;",
-            "    B(int x) : this.b1 = x, super(x), this.b2 = x, super.foo(x, x);",
-            "}");
-    parseExpectErrors(
-        source,
-        errEx(ParserErrorCode.SUPER_CONSTRUCTOR_MULTIPLE, 10, 29, 8),
-        errEx(ParserErrorCode.SUPER_CONSTRUCTOR_MULTIPLE, 10, 52, 15));
-  }
-
-  public void testIncompleteClassDeclaration_noLBrace() {
-    String sourceCode =
-        makeCode(
-            "class Baz",
-            "class Foo<T> implements Bar<T> {",
-            "  Foo(T head, Bar<T> tail);",
-            "}");
-    DartUnit unit =
-        parseSourceUnitErrors(
-            sourceCode,
-            ParserErrorCode.EXPECTED_CLASS_DECLARATION_LBRACE.getMessage(),
-            2,
-            1);
-    // check structure of AST, top level Baz and Foo expected
-    assertEquals(2, unit.getTopLevelNodes().size());
-    assertEquals(
-        makeCode(
-            "// unit Test.dart",
-            "class Baz {",
-            "}",
-            "",
-            "class Foo<T> implements Bar<T> {",
-            "",
-            "  Foo(T head, Bar<T> tail) ;",
-            "}",
-            ""),
-        unit.toSource());
-  }
-
-  /**
-   * Language specification requires that factory should be declared in class. However declaring
-   * factory on top level should not cause exceptions in compiler. To ensure this we parse top level
-   * factory into normal {@link DartMethodDefinition}.
-   * <p>
-   * http://code.google.com/p/dart/issues/detail?id=345
-   */
-  public void test_badTopLevelFactory() {
-    DartUnit unit =
-        parseSourceUnitErrors(
-            "factory foo() {}",
-            ParserErrorCode.FACTORY_CANNOT_BE_TOP_LEVEL.getMessage(),
-            1,
-            1);
-    DartMethodDefinition factory = (DartMethodDefinition) unit.getTopLevelNodes().get(0);
-    assertNotNull(factory);
-    // this factory has name, which is allowed for normal method
-    assertEquals(true, factory.getName() instanceof DartIdentifier);
-    assertEquals("foo", ((DartIdentifier) factory.getName()).getName());
-  }
-
-  public void test_defaultParameterValue_inClosureTypedef() {
-    parseExpectErrors(
-        "typedef void f(int a, [int b = 12345, inc c]);",
-        errEx(ParserErrorCode.DEFAULT_VALUE_CAN_NOT_BE_SPECIFIED_IN_TYPEDEF, 1, 32, 5));
-  }
-
-  public void test_defaultParameterValue_inClosure() {
-    parseExpectErrors(
-        "class A {void f(void cb(int a, [int b = 12345, int c])) {}}",
-        errEx(ParserErrorCode.DEFAULT_VALUE_CAN_NOT_BE_SPECIFIED_IN_CLOSURE, 1, 41, 5));
-  }
-
-  public void test_optionalPositionalParameterValue_inSetter() {
-    parseExpectErrors(
-        "class A { set f([int b]); }",
-        errEx(ParserErrorCode.OPTIONAL_POSITIONAL_PARAMETER_NOT_ALLOWED, 1, 18, 5));
-  }
-  
-  public void test_namedParameterValue_inSetter() {
-    parseExpectErrors(
-        "class A { set f({int b}); }",
-        errEx(ParserErrorCode.NAMED_PARAMETER_NOT_ALLOWED, 1, 18, 5));
-  }
-
-  public void test_missingEndOfOptionalParameters() {
-    parseExpectErrors(
-        "class A {void m(var p1, [var p2 = const []) {} }",
-        errEx(ParserErrorCode.MISSING_OPTIONAL_PARAMETER_END, 1, 43, 1));
-  }
-
-  public void test_optionalPositionalParameterValue_inOperator() {
-    parseExpectErrors(
-        "class A { operator []=(int a, [int b]); }",
-        errEx(ParserErrorCode.OPTIONAL_POSITIONAL_PARAMETER_NOT_ALLOWED, 1, 32, 5));
-  }
-  
-  public void test_namedParameterValue_inOperator() {
-    parseExpectErrors(
-        "class A { operator []=(int a, {int b}); }",
-        errEx(ParserErrorCode.NAMED_PARAMETER_NOT_ALLOWED, 1, 32, 5));
-  }
-
-  /**
-   * If keyword "extends" is mistyped in type parameters declaration, we should report about this
-   * and then recover correctly.
-   * <p>
-   * http://code.google.com/p/dart/issues/detail?id=341
-   */
-  public void test_parseTypeParameter_expectedExtends_mistypedExtends() throws Exception {
-    DartParserRunner parserRunner =
-        parseSource(Joiner.on("\n").join(
-            "class A {",
-            "}",
-            "class B<X ex> {",
-            "}",
-            "class C<X extneds A> {",
-            "}",
-            "class D<X extneds A, Y extends A> {",
-            "}"));
-    // check expected errors
-    assertErrors(
-        parserRunner.getErrors(),
-        errEx(ParserErrorCode.EXPECTED_EXTENDS, 3, 11, 2),
-        errEx(ParserErrorCode.EXPECTED_EXTENDS, 5, 11, 7),
-        errEx(ParserErrorCode.EXPECTED_EXTENDS, 7, 11, 7));
-    // check structure of AST
-    DartUnit dartUnit = parserRunner.getDartUnit();
-    String expected =
-        Joiner.on("\n").join(
-            "// unit " + getName(),
-            "class A {",
-            "}",
-            "",
-            "class B<X> {",
-            "}",
-            "",
-            "class C<X extends A> {",
-            "}",
-            "",
-            "class D<X extends A, Y extends A> {",
-            "}");
-    String actual = dartUnit.toSource().trim();
-    if (!expected.equals(actual)) {
-      System.err.println("Expected:\n" + expected);
-      System.err.println("\nActual:\n" + actual);
-    }
-    assertEquals(expected, actual);
-  }
-
-  /**
-   * Type parameters declaration is not finished.
-   * <p>
-   * http://code.google.com/p/dart/issues/detail?id=341
-   */
-  public void test_parseTypeParameter_unfinishedTypeParameters() throws Exception {
-    DartParserRunner parserRunner =
-        parseSource(Joiner.on("\n").join(
-            "class ClassWithLongEnoughName {",
-            "}",
-            "class B<X {",
-            "}",
-            "class C {",
-            "}"));
-    // check expected errors
-    assertErrors(
-        parserRunner.getErrors(),
-        errEx(ParserErrorCode.EXPECTED_EXTENDS, 3, 11, 1),
-        errEx(ParserErrorCode.EXPECTED_TOKEN, 4, 1, 1),
-        errEx(ParserErrorCode.EXPECTED_CLASS_DECLARATION_LBRACE, 5, 1, 5));
-    // check structure of AST
-    DartUnit dartUnit = parserRunner.getDartUnit();
-    assertEquals(
-        Joiner.on("\n").join(
-            "// unit " + getName(),
-            "class ClassWithLongEnoughName {",
-            "}",
-            "",
-            "class B<X> {",
-            "}",
-            "",
-            "class C {",
-            "}"),
-        dartUnit.toSource().trim());
-  }
-
-  /**
-   * Type parameters declaration is not finished, next top level element beginning encountered. May
-   * be use just types new class declaration before existing one.
-   * <p>
-   * http://code.google.com/p/dart/issues/detail?id=341
-   */
-  public void test_parseTypeParameter_nextTopLevelInTheMiddle() throws Exception {
-    DartParserRunner parserRunner =
-        parseSource(Joiner.on("\n").join(
-            "class ClassWithLongEnoughName {",
-            "}",
-            "class B<X",
-            "class C {",
-            "}"));
-    // check expected errors
-    assertErrors(parserRunner.getErrors(),
-        errEx(ParserErrorCode.EXPECTED_TOKEN, 4, 1, 5));
-
-    // check structure of AST
-    DartUnit dartUnit = parserRunner.getDartUnit();
-    assertEquals(
-        Joiner.on("\n").join(
-            "// unit " + getName(),
-            "class ClassWithLongEnoughName {",
-            "}",
-            "",
-            "class B<X> {",
-            "}",
-            "",
-            "class C {",
-            "}"),
-        dartUnit.toSource().trim());
-  }
-
-  /**
-   * Function signatures require the name to be an identifier; especially true at the top level.
-   * <p>
-   * http://code.google.com/p/dart/issues/detail?id=839
-   */
-  public void testTopLevelFunctionNotIdentifier() {
-    parseExpectErrors(
-        "foo.baz() {}",
-        errEx(ParserErrorCode.FUNCTION_NAME_EXPECTED_IDENTIFIER, 1, 1, 7));
-  }
-
-  public void testInvalidStringInterpolation() {
-    parseExpectErrors(
-        Joiner.on("\n").join(
-            "void main() {",
-            "  print(\"1 ${42} 2 ${} 3\");",
-            "  print(\"1 ${42} 2 ${10;} 3\");",
-            "  print(\"1 ${42} 2 ${10,20} 3\");",
-            "  print(\"1 ${42} 2 ${10 20} 3\");",
-            "  print(\"$\");",
-            "  print(\"$",
-            "}"),
-        errEx(ParserErrorCode.UNEXPECTED_TOKEN, 2, 22, 1),
-        errEx(ParserErrorCode.EXPECTED_TOKEN, 2, 23, 3),
-        errEx(ParserErrorCode.EXPECTED_TOKEN, 3, 24, 1),
-        errEx(ParserErrorCode.UNEXPECTED_TOKEN_IN_STRING_INTERPOLATION, 3, 25, 1),
-        errEx(ParserErrorCode.EXPECTED_TOKEN, 4, 24, 1),
-        errEx(ParserErrorCode.UNEXPECTED_TOKEN_IN_STRING_INTERPOLATION, 4, 25, 2),
-        errEx(ParserErrorCode.UNEXPECTED_TOKEN_IN_STRING_INTERPOLATION, 4, 27, 1),
-        errEx(ParserErrorCode.EXPECTED_TOKEN, 5, 25, 2),
-        errEx(ParserErrorCode.UNEXPECTED_TOKEN_IN_STRING_INTERPOLATION, 5, 27, 1),
-        errEx(ParserErrorCode.UNEXPECTED_TOKEN_IN_STRING_INTERPOLATION, 6, 11, 0),
-        errEx(ParserErrorCode.UNEXPECTED_TOKEN_IN_STRING_INTERPOLATION, 7, 11, 0),
-        errEx(ParserErrorCode.UNEXPECTED_TOKEN_IN_STRING_INTERPOLATION, 7, 11, 1),
-        errEx(ParserErrorCode.UNEXPECTED_TOKEN_IN_STRING_INTERPOLATION, 8, 1, 1),
-        errEx(ParserErrorCode.INCOMPLETE_STRING_LITERAL, 8, 1, 1),
-        errEx(ParserErrorCode.EXPECTED_COMMA_OR_RIGHT_PAREN, 8, 2, 0));
-  }
-
-  public void testDeprecatedFactoryInInterface() {
-    parseExpectWarnings(
-        "interface foo factory bar {}",
-        errEx(ParserErrorCode.DEPRECATED_INTERFACE, 1, 1, 9),
-        errEx(ParserErrorCode.DEPRECATED_USE_OF_FACTORY_KEYWORD, 1, 15, 7));
-  }
-
-  public void test_deprecatedRawString() {
-    parseExpectWarnings(
-        "String s() { return @'s'; }",
-        errEx(ParserErrorCode.DEPRECATED_RAW_STRING, 1, 21, 1));
-  }
-
-  public void test_useExtendsInTypedef() {
-    parseExpectErrors(Joiner.on("\n").join(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "typedef ParameterizedFun1<T, U extends bool, V>(T t, U u);",
-        ""));
-  }
-
-  public void test_abstractTopLevel_class() {
-    parseExpectErrors(Joiner.on("\n").join(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "abstract class A {",
-        "}"));
-  }
-
-  public void test_abstractTopLevel_interface() {
-    parseExpectErrors(
-        Joiner.on("\n").join(
-            "// filler filler filler filler filler filler filler filler filler filler",
-            "abstract interface A {",
-            "}"),
-        errEx(ParserErrorCode.DEPRECATED_INTERFACE, 2, 10, 9),
-        errEx(ParserErrorCode.ABSTRACT_TOP_LEVEL_ELEMENT, 2, 1, 8));
-  }
-  
-  public void test_deprecatedInterface() {
-    parseExpectErrors(
-        Joiner.on("\n").join(
-            "// filler filler filler filler filler filler filler filler filler filler",
-            "interface A {",
-            "}"),
-            errEx(ParserErrorCode.DEPRECATED_INTERFACE, 2, 1, 9));
-  }
-
-  public void test_abstractTopLevel_typedef() {
-    parseExpectErrors(
-        "abstract typedef void f();",
-        errEx(ParserErrorCode.ABSTRACT_TOP_LEVEL_ELEMENT, 1, 1, 8));
-  }
-
-  public void test_abstractTopLevel_method() {
-    parseExpectErrors(
-        "abstract void foo() {}",
-        errEx(ParserErrorCode.ABSTRACT_TOP_LEVEL_ELEMENT, 1, 1, 8));
-  }
-
-  public void test_incompleteExpressionInInterpolation() {
-    parseExpectErrors(
-        "var s = 'fib(3) = ${fib(3}';",
-        errEx(ParserErrorCode.EXPECTED_COMMA_OR_RIGHT_PAREN, 1, 26, 1));
-  }
-
-  public void test_interfaceMethodWithBody() {
-    parseExpectErrors(
-        Joiner.on("\n").join(
-            "// filler filler filler filler filler filler filler filler filler filler",
-            "interface A {",
-            "  foo() {",
-            "  }",
-            "}"),
-        errEx(ParserErrorCode.DEPRECATED_INTERFACE, 2, 1, 9),
-        errEx(ParserErrorCode.INTERFACE_METHOD_WITH_BODY, 3, 3, 3));
-  }
-
-  /**
-   * The Language Specification in the section 6.1 states: "It is a compile-time error to preface a
-   * function declaration with the built-in identifier static."
-   */
-  public void test_staticFunction_topLevel() {
-    parseExpectErrors(
-        Joiner.on("\n").join(
-            "// filler filler filler filler filler filler filler filler filler filler",
-            "static foo() {",
-            "}"),
-        errEx(ParserErrorCode.TOP_LEVEL_CANNOT_BE_STATIC, 2, 1, 6));
-  }
-
-  /**
-   * The Language Specification in the section 6.1 states: "It is a compile-time error to preface a
-   * function declaration with the built-in identifier static."
-   */
-  public void test_staticFunction_local() {
-    DartParserRunner parserRunner =
-        parseExpectErrors(
-            Joiner.on("\n").join(
-                "// filler filler filler filler filler filler filler filler filler filler",
-                "topLevelMethodWithLongEnoughNameToForceWrapping() {",
-                "  static int localFunction() {",
-                "  }",
-                "}"),
-            errEx(ParserErrorCode.LOCAL_CANNOT_BE_STATIC, 3, 3, 6));
-    // Check that "static" was ignored and "int" parsed as return type.
-    assertEquals(
-        makeCode(
-            "// unit " + getName(),
-            "",
-            "topLevelMethodWithLongEnoughNameToForceWrapping() {",
-            "  int localFunction() {",
-            "  };",
-            "}"),
-        parserRunner.getDartUnit().toSource());
-  }
-
-  public void test_positionalArgument_afterNamed() {
-    parseExpectErrors(
-        Joiner.on("\n").join(
-            "// filler filler filler filler filler filler filler filler filler filler",
-            "f(r1, [n1, n2]) {}",
-            "foo() {",
-            "  f(-1, n1: 1, 2);",
-            "}"),
-        errEx(ParserErrorCode.POSITIONAL_AFTER_NAMED_ARGUMENT, 4, 16, 1));
-  }
-
-  public void test_unaryPlus() {
-    parseExpectErrors(
-        Joiner.on("\n").join(
-            "// filler filler filler filler filler filler filler filler filler filler",
-            "var a = 1;",
-            "var b = -1;",
-            "var c = +1;",
-            "var d = -a;",
-            "var e = +a;",
-            "var f = + 1;",
-            ""),
-        errEx(ParserErrorCode.NO_UNARY_PLUS_OPERATOR, 6, 9, 1),
-        errEx(ParserErrorCode.NO_SPACE_AFTER_PLUS, 7, 9, 1));
-  }
-
-  public void test_formalParameters_const() throws Exception {
-    parseExpectErrors(
-        Joiner.on("\n").join(
-            "func_const(const x) {}",
-            "func_constTyped(const int $) {}"),
-        errEx(ParserErrorCode.FORMAL_PARAMETER_IS_CONST, 1, 12, 5),
-        errEx(ParserErrorCode.FORMAL_PARAMETER_IS_CONST, 2, 17, 5));
-  }
-
-  /**
-   * Test with variants of function declarations and function literal invocations.
-   */
-  public void test_functionDeclaration_functionLiteral() {
-    DartParserRunner parserRunner =
-        parseExpectErrors(Joiner.on("\n").join(
-            "// filler filler filler filler filler filler filler filler filler filler",
-            "foo() {",
-            "  f0(p){}", // declaration of function as statement
-            "  int f1(p){}", // declaration of function as statement, has type
-            "  var res = (p){}(1);", // invocation of function literal in assignment
-            "  (p){}(2);", // invocation of function literal in statement, no name
-            "  f3(p) => 4;", // function with => arrow ends with ';'
-            "  (5);", // this is separate statement, not invocation of previous function
-            "  join(promises, (p) => 6);", // function with => arrow as argument
-            "  join(promises, (p) {return 7;});", // function with block as argument
-            "}",
-            ""));
-    assertEquals(
-        makeCode(
-            "// unit " + getName(),
-            "",
-            "foo() {",
-            "  f0(p) {",
-            "  };",
-            "  int f1(p) {",
-            "  };",
-            "  var res = (p) {",
-            "  }(1);",
-            "  (p) {",
-            "  }(2);",
-            "  f3(p) {",
-            "    return 4;",
-            "  };",
-            "  (5);",
-            "  join(promises, (p) {",
-            "    return 6;",
-            "  });",
-            "  join(promises, (p) {",
-            "    return 7;",
-            "  });",
-            "}"),
-        parserRunner.getDartUnit().toSource());
-  }
-
-  /**
-   * Test for {@link DartUnit#getTopDeclarationNames()}.
-   */
-  public void test_getTopDeclarationNames() throws Exception {
-    DartParserRunner parserRunner =
-        parseSource(Joiner.on("\n").join(
-            "// filler filler filler filler filler filler filler filler filler filler",
-            "class MyClass {}",
-            "class MyInterface {}",
-            "topLevelMethod() {}",
-            "int get topLevelGetter {return 0;}",
-            "void set topLevelSetter(int v) {}",
-            "typedef void MyTypeDef();",
-            ""));
-    DartUnit unit = parserRunner.getDartUnit();
-    // Check top level declarations.
-    Set<String> names = unit.getTopDeclarationNames();
-    assertEquals(6, names.size());
-    assertTrue(names.contains("MyClass"));
-    assertTrue(names.contains("MyInterface"));
-    assertTrue(names.contains("topLevelMethod"));
-    assertTrue(names.contains("topLevelGetter"));
-    assertTrue(names.contains("topLevelSetter"));
-    assertTrue(names.contains("MyTypeDef"));
-  }
-
-  /**
-   * Test for {@link DartUnit#getTopDeclarationNames()} and qualified top-level method name.
-   * <p>
-   * http://code.google.com/p/dart/issues/detail?id=1738
-   */
-  public void test_getTopDeclarationNames_badName() throws Exception {
-    DartParserRunner parserRunner =
-        parseSource(Joiner.on("\n").join(
-            "// filler filler filler filler filler filler filler filler filler filler",
-            "void my.method() {}",
-            ""));
-    DartUnit unit = parserRunner.getDartUnit();
-    // We have top-level node...
-    List<DartNode> topLevelNodes = unit.getTopLevelNodes();
-    assertEquals(1, topLevelNodes.size());
-    // ...but it has wrong name, so ignored.
-    Set<String> names = unit.getTopDeclarationNames();
-    assertEquals(0, names.size());
-  }
-
-  /**
-   * Test for {@link DartUnit#getDeclarationNames()}.
-   */
-  public void test_getDeclarationNames() throws Exception {
-    DartParserRunner parserRunner =
-        parseSource(Joiner.on("\n").join(
-            "// filler filler filler filler filler filler filler filler filler filler",
-            "class MyClass<TypeVar> {",
-            "  myMethod(int pA, int pB) {",
-            "    int varA;",
-            "    try {",
-            "    } catch(var ex) {",
-            "    }",
-            "  }",
-            "}",
-            "topLevelMethod() {}",
-            "int get topLevelGetter {return 0;}",
-            "void set topLevelSetter(int setterParam) {}",
-            "typedef void MyTypeDef();",
-            ""));
-    DartUnit unit = parserRunner.getDartUnit();
-    // Check all declarations.
-    Set<String> names = unit.getDeclarationNames();
-    assertEquals(12, names.size());
-    assertTrue(names.contains("MyClass"));
-    assertTrue(names.contains("TypeVar"));
-    assertTrue(names.contains("myMethod"));
-    assertTrue(names.contains("pA"));
-    assertTrue(names.contains("pB"));
-    assertTrue(names.contains("varA"));
-    assertTrue(names.contains("ex"));
-    assertTrue(names.contains("topLevelMethod"));
-    assertTrue(names.contains("topLevelGetter"));
-    assertTrue(names.contains("topLevelSetter"));
-    assertTrue(names.contains("setterParam"));
-    assertTrue(names.contains("MyTypeDef"));
-  }
-
-  /**
-   * There was bug in diet parser, it did not understand new "arrow" syntax of function definition.
-   */
-  public void test_dietParser_functionArrow() {
-    DartParserRunner parserRunner =
-        DartParserRunner.parse(
-            getName(),
-            Joiner.on("\n").join(
-                "class ClassWithVeryLongNameEnoughToForceLineWrapping {",
-                "  foo() => return 0;",
-                "}",
-                ""),
-            true);
-    assertErrors(parserRunner.getErrors());
-    assertEquals(
-        Joiner.on("\n").join(
-            "// unit " + getName(),
-            "class ClassWithVeryLongNameEnoughToForceLineWrapping {",
-            "",
-            "  foo() {",
-            "  }",
-            "}"),
-        parserRunner.getDartUnit().toSource().trim());
-  }
-
-  /**
-   * "get" is valid name for method, it can cause warning, but not parsing failure.
-   */
-  public void test_methodNamed_get() {
-    parseExpectErrors(Joiner.on("\n").join(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "class A {",
-        "  void get() {}",
-        "}",
-        ""));
-  }
-
-  /**
-   * "set" is valid name for method, it can cause warning, but not parsing failure.
-   */
-  public void test_methodNamed_set() {
-    parseExpectErrors(Joiner.on("\n").join(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "class A {",
-        "  void set() {}",
-        "}",
-        ""));
-  }
-
-  /**
-   * "operator" is valid name for method, it can cause warning, but not parsing failure.
-   */
-  public void test_methodNamed_operator() {
-    parseExpectErrors(Joiner.on("\n").join(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "class A {",
-        "  void operator() {}",
-        "}",
-        ""));
-  }
-
-  /**
-   * We can parse operator "call" declaration.
-   */
-  public void test_operator_call() {
-    parseExpectErrors(Joiner.on("\n").join(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "class A {",
-        "  operator call() {}",
-        "}",
-        ""));
-  }
-
-  /**
-   * We can parse operator "equals" declaration.
-   */
-  public void test_operator_equals() {
-    DartParserRunner runner = parseExpectErrors(Joiner.on("\n").join(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "class A {",
-        "  operator ==(other) => false;",
-        "}",
-        ""));
-    DartClass clazz = (DartClass) runner.getDartUnit().getTopLevelNodes().get(0);
-    DartMethodDefinition method = (DartMethodDefinition) clazz.getMembers().get(0);
-    assertTrue(method.getModifiers().isOperator());
-  }
-
-  /**
-   * "native" can be specified only for classes.
-   */
-  public void test_native_inInterace() {
-    parseExpectErrors(
-        Joiner.on("\n").join(
-            "// filler filler filler filler filler filler filler filler filler filler",
-            "interface A native 'N' {",
-            "}",
-            ""),
-        errEx(ParserErrorCode.DEPRECATED_INTERFACE, 2, 1, 9),
-        errEx(ParserErrorCode.NATIVE_ONLY_CLASS, 2, 13, 6));
-  }
-
-  /**
-   * "native" can be specified only for classes without "extends".
-   */
-  public void test_native_classWithExtends() {
-    parseExpectErrors(
-        Joiner.on("\n").join(
-            "// filler filler filler filler filler filler filler filler filler filler",
-            "class A {",
-            "}",
-            "class B extends A native 'N' {",
-            "}",
-            ""),
-        errEx(ParserErrorCode.NATIVE_ONLY_CORE_LIB, 4, 19, 6));
-  }
-
-  /**
-   * "native" can be specified only in "corelib".
-   */
-  public void test_native_onlyCoreLib() {
-    parseExpectErrors(
-        Joiner.on("\n").join(
-            "// filler filler filler filler filler filler filler filler filler filler",
-            "class A native 'N' {",
-            "}",
-            ""),
-        errEx(ParserErrorCode.NATIVE_ONLY_CORE_LIB, 2, 9, 6));
-  }
-
-  /**
-   * "native" can be specified only in "corelib".
-   */
-  public void test_native_onlyCoreLib_factory() {
-    parseExpectErrors(
-        Joiner.on("\n").join(
-            "// filler filler filler filler filler filler filler filler filler filler",
-            "class A {",
-            "  factory A() native;",
-            "}",
-            ""),
-        errEx(ParserErrorCode.NATIVE_ONLY_CORE_LIB, 3, 15, 6));
-  }
-
-  /**
-   * "native" can be specified only in "corelib".
-   */
-  public void test_native_onlyCoreLib_method() {
-    parseExpectErrors(
-        Joiner.on("\n").join(
-            "// filler filler filler filler filler filler filler filler filler filler",
-            "class A {",
-            "  factory A() native;",
-            "}",
-            ""),
-        errEx(ParserErrorCode.NATIVE_ONLY_CORE_LIB, 3, 15, 6));
-  }
-
-  /**
-   * The spec in the section 10.28 says:
-   * <p>
-   * It is a compile-time error if a built-in identifier is used as the declared name of a class,
-   * interface, type variable or type alias.
-   * <p>
-   * http://code.google.com/p/dart/issues/detail?id=3477
-   */
-  public void test_builtInIdentifier_asClassName() {
-    parseExpectErrors(
-        Joiner.on("\n").join(
-            "// filler filler filler filler filler filler filler filler filler filler",
-            "class abstract {}",
-            "class as {}",
-            "class dynamic {}",
-            "class export {}",
-            "class external {}",
-            "class factory {}",
-            "class get {}",
-            "class implements {}",
-            "class import {}",
-            "class library {}",
-            "class operator {}",
-            "class part {}",
-            "class set {}",
-            "class static {}",
-            "class typedef {}",
-            ""),
-            errEx(ParserErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE_NAME, 2, 7, 8), // abstract
-            errEx(ParserErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE_NAME, 3, 7, 2), // as
-            errEx(ParserErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE_NAME, 4, 7, 7), // dynamic
-            errEx(ParserErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE_NAME, 5, 7, 6), // export
-            errEx(ParserErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE_NAME, 6, 7, 8), // external
-            errEx(ParserErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE_NAME, 7, 7, 7), // factory
-            errEx(ParserErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE_NAME, 8, 7, 3), // get
-            errEx(ParserErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE_NAME, 9, 7, 10), // implements
-            errEx(ParserErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE_NAME, 10, 7, 6), // import
-            errEx(ParserErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE_NAME, 11, 7, 7), // library
-            errEx(ParserErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE_NAME, 12, 7, 8), // operator
-            errEx(ParserErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE_NAME, 13, 7, 4), // part
-            errEx(ParserErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE_NAME, 14, 7, 3), // set
-            errEx(ParserErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE_NAME, 15, 7, 6), // static
-            errEx(ParserErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE_NAME, 16, 7, 7)); // typedef
-  }
-
-  /**
-   * The spec in the section 10.28 says:
-   * <p>
-   * It is a compile-time error if a built-in identifier is used as the declared name of a class,
-   * interface, type variable or type alias.
-   * <p>
-   * http://code.google.com/p/dart/issues/detail?id=3477
-   */
-  public void test_builtInIdentifier_asTypevariableName() {
-    parseExpectErrors(
-        Joiner.on("\n").join(
-            "// filler filler filler filler filler filler filler filler filler filler",
-            "class C01<abstract> {}",
-            "class C02<as> {}",
-            "class C03<dynamic> {}",
-            "class C04<export> {}",
-            "class C05<external> {}",
-            "class C06<factory> {}",
-            "class C07<get> {}",
-            "class C08<implements> {}",
-            "class C09<import> {}",
-            "class C10<library> {}",
-            "class C11<operator> {}",
-            "class C12<part> {}",
-            "class C13<set> {}",
-            "class C14<static> {}",
-            "class C15<typedef> {}",
-            ""),
-        errEx(ParserErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE_VARIABLE_NAME, 2, 11, 8), // abstract
-        errEx(ParserErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE_VARIABLE_NAME, 3, 11, 2), // as
-        errEx(ParserErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE_VARIABLE_NAME, 4, 11, 7), // dynamic
-        errEx(ParserErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE_VARIABLE_NAME, 5, 11, 6), // export
-        errEx(ParserErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE_VARIABLE_NAME, 6, 11, 8), // external
-        errEx(ParserErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE_VARIABLE_NAME, 7, 11, 7), // factory
-        errEx(ParserErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE_VARIABLE_NAME, 8, 11, 3), // get
-        errEx(ParserErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE_VARIABLE_NAME, 9, 11, 10), // implements
-        errEx(ParserErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE_VARIABLE_NAME, 10, 11, 6), // import
-        errEx(ParserErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE_VARIABLE_NAME, 11, 11, 7), // library
-        errEx(ParserErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE_VARIABLE_NAME, 12, 11, 8), // operator
-        errEx(ParserErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE_VARIABLE_NAME, 13, 11, 4), // part
-        errEx(ParserErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE_VARIABLE_NAME, 14, 11, 3), // set
-        errEx(ParserErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE_VARIABLE_NAME, 15, 11, 6), // static
-        errEx(ParserErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE_VARIABLE_NAME, 16, 11, 7)); // typedef
-  }
-
-  /**
-   * The spec in the section 10.28 says:
-   * <p>
-   * It is a compile-time error if a built-in identifier is used as the declared name of a class,
-   * interface, type variable or type alias.
-   * <p>
-   * http://code.google.com/p/dart/issues/detail?id=3477
-   */
-  public void test_builtInIdentifier_asTypedefName() {
-    parseExpectErrors(
-        Joiner.on("\n").join(
-            "// filler filler filler filler filler filler filler filler filler filler",
-            "typedef abstract();",
-            "typedef as();",
-            "typedef dynamic();",
-            "typedef export();",
-            "typedef external();",
-            "typedef factory();",
-            "typedef get();",
-            "typedef implements();",
-            "typedef import();",
-            "typedef library();",
-            "typedef operator();",
-            "typedef part();",
-            "typedef set();",
-            "typedef static();",
-            "typedef typedef();",
-            ""),
-        errEx(ParserErrorCode.BUILT_IN_IDENTIFIER_AS_TYPEDEF_NAME, 2, 9, 8), // abstract
-        errEx(ParserErrorCode.BUILT_IN_IDENTIFIER_AS_TYPEDEF_NAME, 3, 9, 2), // as
-        errEx(ParserErrorCode.BUILT_IN_IDENTIFIER_AS_TYPEDEF_NAME, 4, 9, 7), // dynamic
-        errEx(ParserErrorCode.BUILT_IN_IDENTIFIER_AS_TYPEDEF_NAME, 5, 9, 6), // export
-        errEx(ParserErrorCode.BUILT_IN_IDENTIFIER_AS_TYPEDEF_NAME, 6, 9, 8), // external
-        errEx(ParserErrorCode.BUILT_IN_IDENTIFIER_AS_TYPEDEF_NAME, 7, 9, 7), // factory
-        errEx(ParserErrorCode.BUILT_IN_IDENTIFIER_AS_TYPEDEF_NAME, 8, 9, 3), // get
-        errEx(ParserErrorCode.BUILT_IN_IDENTIFIER_AS_TYPEDEF_NAME, 9, 9, 10), // implements
-        errEx(ParserErrorCode.BUILT_IN_IDENTIFIER_AS_TYPEDEF_NAME, 10, 9, 6), // import
-        errEx(ParserErrorCode.BUILT_IN_IDENTIFIER_AS_TYPEDEF_NAME, 11, 9, 7), // library
-        errEx(ParserErrorCode.BUILT_IN_IDENTIFIER_AS_TYPEDEF_NAME, 12, 9, 8), // operator
-        errEx(ParserErrorCode.BUILT_IN_IDENTIFIER_AS_TYPEDEF_NAME, 13, 9, 4), // part
-        errEx(ParserErrorCode.BUILT_IN_IDENTIFIER_AS_TYPEDEF_NAME, 14, 9, 3), // set
-        errEx(ParserErrorCode.BUILT_IN_IDENTIFIER_AS_TYPEDEF_NAME, 15, 9, 6), // static
-        errEx(ParserErrorCode.BUILT_IN_IDENTIFIER_AS_TYPEDEF_NAME, 16, 9, 7)); // typedef
-  }
-
-  /**
-   * There is ambiguity in parsing function expression inside of initializer.
-   * <p>
-   * But we should be able to parse when function expression is inside of "new expression".
-   * <p>
-   * http://code.google.com/p/dart/issues/detail?id=2339
-   */
-  public void test_functionExpression_inInitializer_newExpression() {
-    parseExpectErrors(
-        Joiner.on("\n").join(
-            "// filler filler filler filler filler filler filler filler filler filler",
-            "class A {",
-            "  A(var p) {}",
-            "}",
-            "class B {",
-            "  var f;",
-            "  B() : f = new A(() => 42) {",
-            "  }",
-            "}",
-            ""));
-  }
-
-  /**
-   * There is ambiguity in parsing function expression inside of initializer.
-   * <p>
-   * But we should be able to parse when function expression is inside of "const expression".
-   * <p>
-   * http://code.google.com/p/dart/issues/detail?id=2339
-   */
-  public void test_functionExpression_inInitializer_constExpression() {
-    parseExpectErrors(
-        Joiner.on("\n").join(
-            "// filler filler filler filler filler filler filler filler filler filler",
-            "class A {",
-            "  const A(var p) {}",
-            "}",
-            "class B {",
-            "  var f;",
-            "  B() : f = const A(() => 42) {",
-            "  }",
-            "}",
-            ""));
-  }
-
-  /**
-   * There is ambiguity in parsing function expression inside of initializer.
-   * <p>
-   * But we should be able to parse when function expression is inside of "method invocation".
-   * <p>
-   * http://code.google.com/p/dart/issues/detail?id=2339
-   */
-  public void test_functionExpression_inInitializer_methodInvocation() {
-    parseExpectErrors(
-        Joiner.on("\n").join(
-            "// filler filler filler filler filler filler filler filler filler filler",
-            "foo(var p) {}",
-            "class B {",
-            "  var f;",
-            "  B() : f = foo(() => 42) {",
-            "  }",
-            "}",
-            ""));
-  }
-
-  public void test_qualifiedType_inForIn() {
-    parseExpectErrors(Joiner.on("\n").join(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "foo() {",
-        "  for (pref.A a in elements) {",
-        "  }",
-        "}",
-        ""));
-  }
-}
diff --git a/compiler/javatests/com/google/dart/compiler/parser/NewWithPrefix.dart b/compiler/javatests/com/google/dart/compiler/parser/NewWithPrefix.dart
deleted file mode 100644
index a2faa2a..0000000
--- a/compiler/javatests/com/google/dart/compiler/parser/NewWithPrefix.dart
+++ /dev/null
@@ -1,27 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-class NewWithPrefix {
-  foo() {
-    var a = new prefix.Set<String>.named();
-    a = new prefix.Set<String>();
-    a = const prefix.Set<String>.named();
-    a = const prefix.Set<String>();
-
-    a = new prefix.Set.named();
-    a = new prefix.Set();
-    a = const prefix.Set.named();
-    a = const prefix.Set();
-
-    a = new Set<String>.named();
-    a = new Set<String>();
-    a = const Set<String>.named();
-    a = const Set<String>();
-
-    a = new Set.named();
-    a = new Set();
-    a = const Set.named();
-    a = const Set();
-  }
-}
diff --git a/compiler/javatests/com/google/dart/compiler/parser/ParserEventsTest.java b/compiler/javatests/com/google/dart/compiler/parser/ParserEventsTest.java
deleted file mode 100644
index f53afbd..0000000
--- a/compiler/javatests/com/google/dart/compiler/parser/ParserEventsTest.java
+++ /dev/null
@@ -1,782 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.parser;
-
-import static com.google.dart.compiler.parser.ParserEventsTest.Mark.ArrayLiteral;
-import static com.google.dart.compiler.parser.ParserEventsTest.Mark.BinaryExpression;
-import static com.google.dart.compiler.parser.ParserEventsTest.Mark.Block;
-import static com.google.dart.compiler.parser.ParserEventsTest.Mark.BreakStatement;
-import static com.google.dart.compiler.parser.ParserEventsTest.Mark.CatchClause;
-import static com.google.dart.compiler.parser.ParserEventsTest.Mark.CatchParameter;
-import static com.google.dart.compiler.parser.ParserEventsTest.Mark.ClassBody;
-import static com.google.dart.compiler.parser.ParserEventsTest.Mark.ClassMember;
-import static com.google.dart.compiler.parser.ParserEventsTest.Mark.CompilationUnit;
-import static com.google.dart.compiler.parser.ParserEventsTest.Mark.ConditionalExpression;
-import static com.google.dart.compiler.parser.ParserEventsTest.Mark.ConstExpression;
-import static com.google.dart.compiler.parser.ParserEventsTest.Mark.ConstructorName;
-import static com.google.dart.compiler.parser.ParserEventsTest.Mark.ContinueStatement;
-import static com.google.dart.compiler.parser.ParserEventsTest.Mark.DoStatement;
-import static com.google.dart.compiler.parser.ParserEventsTest.Mark.EmptyStatement;
-import static com.google.dart.compiler.parser.ParserEventsTest.Mark.Expression;
-import static com.google.dart.compiler.parser.ParserEventsTest.Mark.ExpressionList;
-import static com.google.dart.compiler.parser.ParserEventsTest.Mark.ExpressionStatement;
-import static com.google.dart.compiler.parser.ParserEventsTest.Mark.FieldInitializerOrRedirectedConstructor;
-import static com.google.dart.compiler.parser.ParserEventsTest.Mark.FinalDeclaration;
-import static com.google.dart.compiler.parser.ParserEventsTest.Mark.ForInitialization;
-import static com.google.dart.compiler.parser.ParserEventsTest.Mark.ForStatement;
-import static com.google.dart.compiler.parser.ParserEventsTest.Mark.FormalParameterList;
-import static com.google.dart.compiler.parser.ParserEventsTest.Mark.FunctionDeclaration;
-import static com.google.dart.compiler.parser.ParserEventsTest.Mark.FunctionLiteral;
-import static com.google.dart.compiler.parser.ParserEventsTest.Mark.FunctionTypeInterface;
-import static com.google.dart.compiler.parser.ParserEventsTest.Mark.Identifier;
-import static com.google.dart.compiler.parser.ParserEventsTest.Mark.IfStatement;
-import static com.google.dart.compiler.parser.ParserEventsTest.Mark.Initializer;
-import static com.google.dart.compiler.parser.ParserEventsTest.Mark.Label;
-import static com.google.dart.compiler.parser.ParserEventsTest.Mark.Literal;
-import static com.google.dart.compiler.parser.ParserEventsTest.Mark.MapLiteral;
-import static com.google.dart.compiler.parser.ParserEventsTest.Mark.MapLiteralEntry;
-import static com.google.dart.compiler.parser.ParserEventsTest.Mark.MethodName;
-import static com.google.dart.compiler.parser.ParserEventsTest.Mark.NativeBody;
-import static com.google.dart.compiler.parser.ParserEventsTest.Mark.NewExpression;
-import static com.google.dart.compiler.parser.ParserEventsTest.Mark.OperatorName;
-import static com.google.dart.compiler.parser.ParserEventsTest.Mark.ParenthesizedExpression;
-import static com.google.dart.compiler.parser.ParserEventsTest.Mark.PostfixExpression;
-import static com.google.dart.compiler.parser.ParserEventsTest.Mark.QualifiedIdentifier;
-import static com.google.dart.compiler.parser.ParserEventsTest.Mark.ReturnStatement;
-import static com.google.dart.compiler.parser.ParserEventsTest.Mark.SelectorExpression;
-import static com.google.dart.compiler.parser.ParserEventsTest.Mark.SpreadExpression;
-import static com.google.dart.compiler.parser.ParserEventsTest.Mark.StringInterpolation;
-import static com.google.dart.compiler.parser.ParserEventsTest.Mark.StringSegment;
-import static com.google.dart.compiler.parser.ParserEventsTest.Mark.SuperExpression;
-import static com.google.dart.compiler.parser.ParserEventsTest.Mark.SuperInitializer;
-import static com.google.dart.compiler.parser.ParserEventsTest.Mark.SwitchMember;
-import static com.google.dart.compiler.parser.ParserEventsTest.Mark.SwitchStatement;
-import static com.google.dart.compiler.parser.ParserEventsTest.Mark.ThisExpression;
-import static com.google.dart.compiler.parser.ParserEventsTest.Mark.ThrowStatement;
-import static com.google.dart.compiler.parser.ParserEventsTest.Mark.TopLevelElement;
-import static com.google.dart.compiler.parser.ParserEventsTest.Mark.TryStatement;
-import static com.google.dart.compiler.parser.ParserEventsTest.Mark.TypeAnnotation;
-import static com.google.dart.compiler.parser.ParserEventsTest.Mark.TypeArguments;
-import static com.google.dart.compiler.parser.ParserEventsTest.Mark.TypeExpression;
-import static com.google.dart.compiler.parser.ParserEventsTest.Mark.TypeFunctionOrVarable;
-import static com.google.dart.compiler.parser.ParserEventsTest.Mark.TypeParameter;
-import static com.google.dart.compiler.parser.ParserEventsTest.Mark.UnaryExpression;
-import static com.google.dart.compiler.parser.ParserEventsTest.Mark.VarDeclaration;
-import static com.google.dart.compiler.parser.ParserEventsTest.Mark.VariableDeclaration;
-import static com.google.dart.compiler.parser.ParserEventsTest.Mark.WhileStatement;
-
-import com.google.common.collect.Sets;
-import com.google.dart.compiler.DartCompilerListener;
-import com.google.dart.compiler.Source;
-import com.google.dart.compiler.metrics.CompilerMetrics;
-
-import java.util.HashSet;
-import java.util.LinkedHashSet;
-import java.util.Set;
-
-public class ParserEventsTest extends AbstractParserTest {
-
-  /**
-   * A collection of marks representing interesting parser states. Copied from
-   * com.google.dart.tools.core.internal.completion.
-   * <p>
-   * TODO(messick) Find a way to share the implementation of Mark.
-   */
-  static enum Mark {
-    // some elements are roots of the kind-of relationships, they must be first
-    Block,
-    Expression,
-    Literal(Expression),
-    FormalParameterList,
-    Statement,
-    // all others are alphabetical
-    ArrayLiteral(Literal),
-    BinaryExpression(Expression),
-    BreakStatement(Statement),
-    CatchClause,
-    CatchParameter,
-    ClassBody(Block),
-    ClassMember,
-    CompilationUnit,
-    ConditionalExpression(Expression),
-    FinalDeclaration,
-    ConstExpression(Expression),
-    ConstructorName,
-    ContinueStatement(Statement),
-    DoStatement(Statement),
-    EmptyStatement(Statement),
-    ExpressionList,
-    ExpressionStatement(Statement),
-    FieldInitializerOrRedirectedConstructor,
-    ForInitialization,
-     ForStatement(Statement),
-    FunctionDeclaration,
-    FunctionLiteral(Literal),
-    FunctionTypeInterface,
-    Identifier(Expression),
-    IfStatement(Statement),
-    Initializer,
-    TypeExpression(Expression),
-    Label,
-    MapLiteral(Literal),
-    MapLiteralEntry,
-    MethodName,
-    NativeBody,
-    NewExpression(Expression),
-    OperatorName,
-    ParenthesizedExpression(Expression),
-    PostfixExpression(Expression),
-    QualifiedIdentifier,
-    ReturnStatement(Statement),
-    SelectorExpression(Expression),
-    SpreadExpression(Expression),
-    StringInterpolation,
-    StringSegment,
-    SuperExpression(Expression),
-    SuperInitializer,
-    SwitchMember,
-    SwitchStatement(Statement),
-    ThisExpression(Expression),
-    ThrowStatement(Statement),
-    TopLevelElement,
-    TryStatement(Statement),
-    TypeAnnotation,
-    TypeArguments,
-    TypeFunctionOrVarable,
-    TypeParameter,
-    UnaryExpression(Expression),
-    VarDeclaration,
-    VariableDeclaration,
-    WhileStatement(Statement);
-
-    public final Mark kind;
-
-    private Mark() {
-      kind = null;
-    }
-
-    private Mark(Mark kind) {
-      this.kind = kind;
-    }
-
-    /**
-     * Return <code>true</code> if this Mark has a kind-of relation to the given Mark.
-     *
-     * @param other the Mark to test for a kind-of relation
-     * @return <code>true</code> if the test succeeds
-     */
-    public boolean isKindOf(Mark other) {
-      if (this == other) {
-        return true;
-      }
-      if (kind == null) {
-        return false;
-      }
-      return kind.isKindOf(other);
-    }
-  }
-
-  private static class ParserEventRecorder extends DartParser {
-    private LinkedHashSet<Mark> marks;
-
-    @Override
-    protected void rollback() {
-      super.rollback();
-      Mark lastMark = null;
-      for (Mark mark: marks) {
-        lastMark = mark;
-      }
-      if (lastMark != null) {
-        marks.remove(lastMark);
-      }
-    }
-
-    public ParserEventRecorder(Source source,
-        String sourceCode,
-        boolean isDietParse,
-        Set<String> prefixes,
-        DartCompilerListener listener,
-        CompilerMetrics compilerMetrics) {
-      super(source, sourceCode, isDietParse, prefixes, listener, compilerMetrics);
-      marks = new LinkedHashSet<Mark>();
-    }
-
-    @SuppressWarnings({"unchecked", "rawtypes"})
-    public HashSet<Mark> copyMarks() {
-      return (HashSet) marks.clone();
-    }
-
-    @Override
-    protected void beginArrayLiteral() {
-      super.beginArrayLiteral();
-      recordMark(ArrayLiteral);
-    }
-
-    @Override
-    protected void beginBinaryExpression() {
-      super.beginBinaryExpression();
-      recordMark(BinaryExpression);
-    }
-
-    @Override
-    protected void beginBlock() {
-      super.beginBlock();
-      recordMark(Block);
-    }
-
-    @Override
-    protected void beginBreakStatement() {
-      super.beginBreakStatement();
-      recordMark(BreakStatement);
-    }
-
-    @Override
-    protected void beginCatchClause() {
-      super.beginCatchClause();
-      recordMark(CatchClause);
-    }
-
-    @Override
-    protected void beginCatchParameter() {
-      super.beginFormalParameter();
-      recordMark(CatchParameter);
-    }
-
-    @Override
-    protected void beginClassBody() {
-      super.beginClassBody();
-      recordMark(ClassBody);
-    }
-
-    @Override
-    protected void beginClassMember() {
-      super.beginClassMember();
-      recordMark(ClassMember);
-    }
-
-    @Override
-    protected void beginCompilationUnit() {
-      super.beginCompilationUnit();
-      recordMark(CompilationUnit);
-    }
-
-    @Override
-    protected void beginConditionalExpression() {
-      super.beginConditionalExpression();
-      recordMark(ConditionalExpression);
-    }
-
-    @Override
-    protected void beginConstExpression() {
-      super.beginConstExpression();
-      recordMark(ConstExpression);
-    }
-
-    @Override
-    protected void beginConstructor() {
-      super.beginConstructor();
-      recordMark(ConstructorName);
-    }
-
-    @Override
-    protected void beginContinueStatement() {
-      super.beginContinueStatement();
-      recordMark(ContinueStatement);
-    }
-
-    @Override
-    protected void beginDoStatement() {
-      super.beginDoStatement();
-      recordMark(DoStatement);
-    }
-
-    @Override
-    protected void beginEmptyStatement() {
-      super.beginEmptyStatement();
-      recordMark(EmptyStatement);
-    }
-
-    @Override
-    protected void beginEntryPoint() {
-      super.beginEntryPoint();
-      // TODO(messick): add recording
-    }
-
-    @Override
-    protected void beginExpression() {
-      super.beginExpression();
-      recordMark(Expression);
-    }
-
-    @Override
-    protected void beginExpressionList() {
-      super.beginExpressionList();
-      recordMark(ExpressionList);
-    }
-
-    @Override
-    protected void beginExpressionStatement() {
-      super.beginExpressionStatement();
-      recordMark(ExpressionStatement);
-    }
-
-    @Override
-    protected void beginFieldInitializerOrRedirectedConstructor() {
-      super.beginFieldInitializerOrRedirectedConstructor();
-      recordMark(FieldInitializerOrRedirectedConstructor);
-    }
-
-    @Override
-    protected void beginFinalDeclaration() {
-      super.beginFinalDeclaration();
-      recordMark(FinalDeclaration);
-    }
-
-    @Override
-    protected void beginForInitialization() {
-      super.beginForInitialization();
-      recordMark(ForInitialization);
-    }
-
-    @Override
-    protected void beginFormalParameterList() {
-      super.beginFormalParameterList();
-      recordMark(FormalParameterList);
-    }
-
-    @Override
-    protected void beginForStatement() {
-      super.beginForStatement();
-      recordMark(ForStatement);
-    }
-
-    @Override
-    protected void beginFunctionDeclaration() {
-      super.beginFunctionDeclaration();
-      recordMark(FunctionDeclaration);
-    }
-
-    @Override
-    protected void beginFunctionLiteral() {
-      super.beginFunctionLiteral();
-      recordMark(FunctionLiteral);
-    }
-
-    @Override
-    protected void beginFunctionTypeInterface() {
-      super.beginFunctionTypeInterface();
-      recordMark(FunctionTypeInterface);
-    }
-
-    @Override
-    protected void beginIdentifier() {
-      super.beginIdentifier();
-      recordMark(Identifier);
-    }
-
-    @Override
-    protected void beginIfStatement() {
-      super.beginIfStatement();
-      recordMark(IfStatement);
-    }
-
-    @Override
-    protected void beginInitializer() {
-      super.beginInitializer();
-      recordMark(Initializer);
-    }
-
-    @Override
-    protected void beginTypeExpression() {
-      super.beginTypeExpression();
-      recordMark(TypeExpression);
-    }
-
-    @Override
-    protected void beginLabel() {
-      super.beginLabel();
-      recordMark(Label);
-    }
-
-    @Override
-    protected void beginLiteral() {
-      super.beginLiteral();
-      recordMark(Literal);
-    }
-
-    @Override
-    protected void beginMapLiteral() {
-      super.beginMapLiteral();
-      recordMark(MapLiteral);
-    }
-
-    @Override
-    protected void beginMapLiteralEntry() {
-      super.beginMapLiteralEntry();
-      recordMark(MapLiteralEntry);
-    }
-
-    @Override
-    protected void beginMethodName() {
-      super.beginMethodName();
-      recordMark(MethodName);
-    }
-
-    @Override
-    protected void beginNativeBody() {
-      super.beginNativeBody();
-      recordMark(NativeBody);
-    }
-
-    @Override
-    protected void beginNewExpression() {
-      super.beginNewExpression();
-      recordMark(NewExpression);
-    }
-
-    @Override
-    protected void beginOperatorName() {
-      super.beginOperatorName();
-      recordMark(OperatorName);
-    }
-
-    @Override
-    protected void beginParameter() {
-      super.beginParameter();
-      // TODO(messick): add recording
-    }
-
-    @Override
-    protected void beginParameterName() {
-      super.beginParameterName();
-      // TODO(messick): add recording
-    }
-
-    @Override
-    protected void beginParenthesizedExpression() {
-      super.beginParenthesizedExpression();
-      recordMark(ParenthesizedExpression);
-    }
-
-    @Override
-    protected void beginPostfixExpression() {
-      super.beginPostfixExpression();
-      recordMark(PostfixExpression);
-    }
-
-    @Override
-    protected void beginQualifiedIdentifier() {
-      super.beginQualifiedIdentifier();
-      recordMark(QualifiedIdentifier);
-    }
-
-    @Override
-    protected void beginReturnStatement() {
-      super.beginReturnStatement();
-      recordMark(ReturnStatement);
-    }
-
-    @Override
-    protected void beginReturnType() {
-      super.beginReturnType();
-      // TODO(messick): add recording
-    }
-
-    @Override
-    protected void beginSelectorExpression() {
-      super.beginSelectorExpression();
-      recordMark(SelectorExpression);
-    }
-
-    @Override
-    protected void beginSpreadExpression() {
-      super.beginSpreadExpression();
-      recordMark(SpreadExpression);
-    }
-
-    @Override
-    protected void beginStringInterpolation() {
-      super.beginStringInterpolation();
-      recordMark(StringInterpolation);
-    }
-
-    @Override
-    protected void beginStringSegment() {
-      super.beginStringSegment();
-      recordMark(StringSegment);
-    }
-
-    @Override
-    protected void beginSuperExpression() {
-      super.beginSuperExpression();
-      recordMark(SuperExpression);
-    }
-
-    @Override
-    protected void beginSuperInitializer() {
-      super.beginSuperInitializer();
-      recordMark(SuperInitializer);
-    }
-
-    @Override
-    protected void beginSwitchMember() {
-      super.beginSwitchMember();
-      recordMark(SwitchMember);
-    }
-
-    @Override
-    protected void beginSwitchStatement() {
-      super.beginSwitchStatement();
-      recordMark(SwitchStatement);
-    }
-
-    @Override
-    protected void beginThisExpression() {
-      super.beginThisExpression();
-      recordMark(ThisExpression);
-    }
-
-    @Override
-    protected void beginThrowExpression() {
-      super.beginThrowExpression();
-      recordMark(ThrowStatement);
-    }
-
-    @Override
-    protected void beginTopLevelElement() {
-      super.beginTopLevelElement();
-      recordMark(TopLevelElement);
-    }
-
-    @Override
-    protected void beginTryStatement() {
-      super.beginTryStatement();
-      recordMark(TryStatement);
-    }
-
-    @Override
-    protected void beginTypeAnnotation() {
-      super.beginTypeAnnotation();
-      recordMark(TypeAnnotation);
-    }
-
-    @Override
-    protected void beginTypeArguments() {
-      super.beginTypeArguments();
-      recordMark(TypeArguments);
-    }
-
-    @Override
-    protected void beginTypeFunctionOrVariable() {
-      super.beginTypeFunctionOrVariable();
-      recordMark(TypeFunctionOrVarable);
-    }
-
-    @Override
-    protected void beginTypeParameter() {
-      super.beginTypeParameter();
-      recordMark(TypeParameter);
-    }
-
-    @Override
-    protected void beginUnaryExpression() {
-      super.beginUnaryExpression();
-      recordMark(UnaryExpression);
-    }
-
-    @Override
-    protected void beginVarDeclaration() {
-      super.beginVarDeclaration();
-      recordMark(VarDeclaration);
-    }
-
-    @Override
-    protected void beginVariableDeclaration() {
-      super.beginVariableDeclaration();
-      recordMark(VariableDeclaration);
-    }
-
-    @Override
-    protected void beginWhileStatement() {
-      super.beginWhileStatement();
-      recordMark(WhileStatement);
-    }
-
-    private void recordMark(Mark mark) {
-      marks.add(mark);
-    }
-  }
-
-  private ParserEventRecorder recorder = null;
-
-  @Override
-  public void testListObjectLiterals() {
-    parseUnit("ListObjectLiterals.dart");
-  }
-
-  @Override
-  public void testCatchFinally() {
-    parseUnit("CatchFinally.dart");
-  }
-
-  @Override
-  public void testClasses() {
-    parseUnit("ClassesInterfaces.dart");
-    compareMarks(ReturnStatement, TopLevelElement, Block,
-        ForStatement, ClassBody, FunctionLiteral, ParenthesizedExpression, TypeExpression,
-        MethodName, ConditionalExpression, BinaryExpression, FormalParameterList,
-        FunctionDeclaration, BreakStatement, PostfixExpression, SuperInitializer, TypeAnnotation,
-        ClassMember, VarDeclaration, SwitchMember, CompilationUnit, Expression,
-        TypeFunctionOrVarable, TypeParameter, ExpressionList, Identifier,
-        IfStatement, QualifiedIdentifier, SwitchStatement,
-        SelectorExpression, ForInitialization, CatchClause, CatchParameter,
-        FieldInitializerOrRedirectedConstructor, ContinueStatement, Label, TryStatement, Literal,
-        SpreadExpression, VariableDeclaration, TypeArguments, ExpressionStatement, ThrowStatement,
-        WhileStatement, Initializer);
-  }
-
-  @Override
-  public void testFormalParameters() {
-    parseUnit("FormalParameters.dart");
-    compareMarks(TopLevelElement, ClassMember, CompilationUnit,
-        BinaryExpression, NativeBody, Identifier, TypeAnnotation, ClassBody,
-        Literal, Block, PostfixExpression, MethodName, Expression, QualifiedIdentifier,
-        FormalParameterList, ConditionalExpression);
-  }
-
-  @Override
-  public void testFunctionInterfaces() {
-    parseUnit("FunctionInterfaces.dart");
-    compareMarks(TypeAnnotation, TopLevelElement, CompilationUnit,
-        FormalParameterList, QualifiedIdentifier, Identifier, FunctionTypeInterface);
-  }
-
-  @Override
-  public void testFunctionTypes() {
-    parseUnit("FunctionTypes.dart");
-    compareMarks(Identifier, TypeAnnotation, MethodName, CompilationUnit, ClassMember,
-        TopLevelElement, NativeBody, QualifiedIdentifier, FormalParameterList, ClassBody, Block,
-        VariableDeclaration);
-  }
-
-  @Override
-  public void testGenericTypes() {
-    parseUnit("GenericTypes.dart");
-    compareMarks(NativeBody, MethodName, ClassBody, ExpressionStatement, FormalParameterList,
-        Literal, ReturnStatement, Expression, TypeParameter,
-        PostfixExpression, TopLevelElement, ConditionalExpression, ThisExpression, ConstructorName,
-        NewExpression, QualifiedIdentifier, CompilationUnit, Block,
-        Identifier, VariableDeclaration, BinaryExpression, ClassMember, TypeAnnotation);
-  }
-
-  @Override
-  public void testMethodSignatures() {
-    parseUnit("MethodSignatures.dart");
-    compareMarks(TopLevelElement, ClassMember, TypeAnnotation,
-        CompilationUnit, MethodName, QualifiedIdentifier, Identifier,
-        ClassBody, FormalParameterList);
-  }
-
-  @Override
-  public void testNewWithPrefix() {
-    parseUnit("NewWithPrefix.dart");
-    compareMarks(VarDeclaration, ClassMember, ConstructorName,
-        ConditionalExpression, ConstExpression, Literal, NewExpression, Identifier, TypeAnnotation,
-        PostfixExpression, FormalParameterList, QualifiedIdentifier, TopLevelElement,
-        BinaryExpression, NativeBody, ClassBody, ExpressionStatement, MethodName, CompilationUnit,
-        VariableDeclaration, Block, Expression);
-  }
-
-  @Override
-  public void testRedirectedConstructor() {
-    parseUnit("RedirectedConstructor.dart");
-    compareMarks(BinaryExpression, CompilationUnit, FormalParameterList, ConditionalExpression,
-        Expression, PostfixExpression, ClassBody, ThisExpression,
-        Initializer, TopLevelElement, NativeBody, Block, MethodName, SuperInitializer, Literal,
-        ClassMember, Identifier, QualifiedIdentifier, FieldInitializerOrRedirectedConstructor,
-        TypeAnnotation, VariableDeclaration);
-  }
-
-  @Override
-  public void testShifting() {
-    parseUnit("Shifting.dart");
-    compareMarks(Expression, ClassBody, TypeFunctionOrVarable, VariableDeclaration,
-        CompilationUnit, ConditionalExpression, Identifier, ClassMember,
-        Block, QualifiedIdentifier, NativeBody, OperatorName, TypeAnnotation, TypeArguments,
-        PostfixExpression, BinaryExpression, FormalParameterList, TopLevelElement, Literal,
-        ReturnStatement);
-  }
-
-  @Override
-  public void testStringBuffer() {
-    parseUnit("StringBuffer.dart");
-    compareMarks(ClassBody, ConstructorName, TypeAnnotation,
-        TypeFunctionOrVarable, NativeBody, SelectorExpression, TopLevelElement, Block,
-        NewExpression, MethodName, Literal, Expression, CompilationUnit, Identifier,
-        ThrowStatement, PostfixExpression, BinaryExpression, ClassMember, VariableDeclaration,
-        ConditionalExpression, ExpressionStatement, ReturnStatement, IfStatement,
-        QualifiedIdentifier, FormalParameterList, FunctionLiteral);
-  }
-
-  @Override
-  public void testStrings() {
-    parseUnit("Strings.dart");
-    compareMarks(Expression, MethodName, ExpressionStatement, Block, ConditionalExpression,
-        ClassBody, TopLevelElement, VariableDeclaration, CompilationUnit, ClassMember,
-        PostfixExpression, BinaryExpression, VarDeclaration, Identifier, Literal,
-        FormalParameterList, NativeBody);
-  }
-
-  @Override
-  public void testStringsErrors() {
-    parseUnitErrors("StringsErrorsNegativeTest.dart",
-        "Unexpected token 'ILLEGAL'", 7, 13,
-        "Unexpected token 'ILLEGAL'", 9, 9,
-        "Unexpected token 'ILLEGAL'", 11, 9);
-    compareMarks(NativeBody, TopLevelElement, PostfixExpression, ClassMember, CompilationUnit,
-        VariableDeclaration, Identifier, BinaryExpression, ClassBody,
-        ConditionalExpression, Literal, Expression, MethodName, ExpressionStatement, Block,
-        FormalParameterList, VarDeclaration);
-  }
-
-  @Override
-  public void testSuperCalls() {
-    parseUnit("SuperCalls.dart");
-    compareMarks(ExpressionStatement, ClassMember, SelectorExpression,
-        VariableDeclaration, BinaryExpression, Literal, Identifier, SuperExpression,
-        FormalParameterList, TopLevelElement, PostfixExpression, NativeBody, ClassBody, MethodName,
-        CompilationUnit, Expression, VarDeclaration, Block, ConditionalExpression);
-  }
-
-  @Override
-  public void testTiming() {
-    // do nothing except stop broken superclass method from printing to console
-  }
-
-  @Override
-  public void testTopLevel() {
-    parseUnit("TopLevel.dart");
-    compareMarks(ArrayLiteral, CompilationUnit, PostfixExpression, NativeBody, Literal, Identifier,
-        ClassMember, Block, MethodName, TopLevelElement, TypeAnnotation, Expression,
-        QualifiedIdentifier, ConditionalExpression, BinaryExpression, VariableDeclaration,
-        FormalParameterList);
-  }
-  
-  @Override
-  protected DartParser makeParser(Source src, String sourceCode, DartCompilerListener listener) {
-    recorder = new ParserEventRecorder(src, sourceCode, false, Sets.<String>newHashSet(), listener, null);
-    return recorder;
-  }
-
-  private void compareMarks(Mark... expectedMarks) {
-    HashSet<Mark> recordedMarks = recorder.copyMarks();
-    for (Mark m : expectedMarks) {
-      assertNotNull("Missing mark: " + m.name(), recordedMarks.remove(m));
-    }
-    for (Mark m : recordedMarks) {
-      fail("Unexpected mark: " + m.name());
-    }
-  }
-}
diff --git a/compiler/javatests/com/google/dart/compiler/parser/ParserRecoveryTest.java b/compiler/javatests/com/google/dart/compiler/parser/ParserRecoveryTest.java
deleted file mode 100644
index b615cdf..0000000
--- a/compiler/javatests/com/google/dart/compiler/parser/ParserRecoveryTest.java
+++ /dev/null
@@ -1,1694 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.parser;
-
-import com.google.common.base.Joiner;
-import com.google.dart.compiler.ast.DartArrayLiteral;
-import com.google.dart.compiler.ast.DartBinaryExpression;
-import com.google.dart.compiler.ast.DartBooleanLiteral;
-import com.google.dart.compiler.ast.DartBreakStatement;
-import com.google.dart.compiler.ast.DartClass;
-import com.google.dart.compiler.ast.DartContinueStatement;
-import com.google.dart.compiler.ast.DartDoWhileStatement;
-import com.google.dart.compiler.ast.DartExprStmt;
-import com.google.dart.compiler.ast.DartFieldDefinition;
-import com.google.dart.compiler.ast.DartForInStatement;
-import com.google.dart.compiler.ast.DartForStatement;
-import com.google.dart.compiler.ast.DartFunctionTypeAlias;
-import com.google.dart.compiler.ast.DartIdentifier;
-import com.google.dart.compiler.ast.DartIfStatement;
-import com.google.dart.compiler.ast.DartImportDirective;
-import com.google.dart.compiler.ast.DartIntegerLiteral;
-import com.google.dart.compiler.ast.DartLibraryDirective;
-import com.google.dart.compiler.ast.DartMapLiteral;
-import com.google.dart.compiler.ast.DartMethodDefinition;
-import com.google.dart.compiler.ast.DartPropertyAccess;
-import com.google.dart.compiler.ast.DartReturnStatement;
-import com.google.dart.compiler.ast.DartSourceDirective;
-import com.google.dart.compiler.ast.DartStatement;
-import com.google.dart.compiler.ast.DartSwitchStatement;
-import com.google.dart.compiler.ast.DartThrowExpression;
-import com.google.dart.compiler.ast.DartTryStatement;
-import com.google.dart.compiler.ast.DartTypeNode;
-import com.google.dart.compiler.ast.DartUnit;
-import com.google.dart.compiler.ast.DartUnqualifiedInvocation;
-import com.google.dart.compiler.ast.DartVariable;
-import com.google.dart.compiler.ast.DartVariableStatement;
-import com.google.dart.compiler.ast.DartWhileStatement;
-
-import java.math.BigInteger;
-import java.util.List;
-
-public class ParserRecoveryTest extends AbstractParserTest {
-
-  @Override
-  public void testStringsErrors() {
-    // Implemented elsewhere
-  }
-
-  public void test_incompleteFunctionExpression() {
-    DartParserRunner parserRunner = parseSource(Joiner.on("\n").join(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "main() {",
-        "  var v = (AAA a, BB)",
-        "}"));
-    DartUnit unit = parserRunner.getDartUnit();
-    assertEquals(
-        Joiner.on("\n").join(
-            "// unit test_incompleteFunctionExpression",
-            "",
-            "main() {",
-            "  var v = (AAA a, BB) {",
-            "  };",
-            "}",
-            ""),
-        unit.toString());
-  }
-
-  public void test_incompleteFunctionExpression_qualifiedType() {
-    DartParserRunner parserRunner = parseSource(Joiner.on("\n").join(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "main() {",
-        "  var v = (pref.AAA a, BB)",
-        "}"));
-    DartUnit unit = parserRunner.getDartUnit();
-    assertEquals(
-        Joiner.on("\n").join(
-            "// unit test_incompleteFunctionExpression_qualifiedType",
-            "",
-            "main() {",
-            "  var v = (pref.AAA a, BB) {",
-            "  };",
-            "}",
-            ""),
-        unit.toString());
-  }
-  
-  public void test_incompleteFunctionExpression_typeArguments() {
-    DartParserRunner parserRunner = parseSource(Joiner.on("\n").join(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "main() {",
-        "  var v = (AAA<T1, T2<T3, T4>, T5> a, BB)",
-        "}"));
-    DartUnit unit = parserRunner.getDartUnit();
-    assertEquals(
-        Joiner.on("\n").join(
-            "// unit test_incompleteFunctionExpression_typeArguments",
-            "",
-            "main() {",
-            "  var v = (AAA<T1, T2<T3, T4>, T5> a, BB) {",
-            "  };",
-            "}",
-            ""),
-            unit.toString());
-  }
-
-  public void testVarOnMethodDefinition() {
-    // This syntax is illegal, and should produce errors, but since it is a common error,
-    // we want to make sure it produce a valid AST for editor users
-    DartUnit unit = parseUnit("phony_var_on_method.dart",
-        Joiner.on("\n").join(
-            "var f1() { return 1;}",  // Error, use of var on a method
-            "class A { ",
-            "  var f2() { return 1;}",  // Error, use of var on a method
-            "  f3() { return 2; }",
-            "}"),
-            ParserErrorCode.VAR_IS_NOT_ALLOWED_ON_A_METHOD_DEFINITION, 1, 1,
-            ParserErrorCode.VAR_IS_NOT_ALLOWED_ON_A_METHOD_DEFINITION, 3, 3);
-    DartMethodDefinition f1 = (DartMethodDefinition)unit.getTopLevelNodes().get(0);
-    assertEquals("f1", ((DartIdentifier)(f1.getName())).getName());
-    DartClass A = (DartClass)unit.getTopLevelNodes().get(1);
-    DartMethodDefinition f2 = (DartMethodDefinition)(A.getMembers().get(0));
-    assertEquals("f2", ((DartIdentifier)(f2.getName())).getName());
-    // Make sure that parsing continue
-    DartMethodDefinition f3 = (DartMethodDefinition)(A.getMembers().get(1));
-    assertEquals("f3", ((DartIdentifier)(f3.getName())).getName());
-  }
-
-  public void testFinalOnMethodDefinition() {
-    // This syntax is illegal, and should produce errors, but since it is a common error,
-    // we want to make sure it produce a valid AST for editor users
-    DartUnit unit = parseUnit("phony_final_on_method.dart",
-        Joiner.on("\n").join(
-            "final f1() {return 1;}",  // Error, use of final on a method
-            "class A { ",
-            "  final f2() {return 1;}",  // Error, use of final on a method
-            "  f3() { return 2; }",
-            "  final String f4() { return 1; }",  // Error, use of final on a method
-            "}"),
-            ParserErrorCode.FINAL_IS_NOT_ALLOWED_ON_A_METHOD_DEFINITION, 1, 1,
-            ParserErrorCode.FINAL_IS_NOT_ALLOWED_ON_A_METHOD_DEFINITION, 3, 3,
-            ParserErrorCode.FINAL_IS_NOT_ALLOWED_ON_A_METHOD_DEFINITION, 5, 9);
-    DartMethodDefinition f1 = (DartMethodDefinition)unit.getTopLevelNodes().get(0);
-    assertEquals("f1", ((DartIdentifier)(f1.getName())).getName());
-    DartClass A = (DartClass)unit.getTopLevelNodes().get(1);
-    DartMethodDefinition f2 = (DartMethodDefinition)(A.getMembers().get(0));
-    assertEquals("f2", ((DartIdentifier)(f2.getName())).getName());
-    DartMethodDefinition f3 = (DartMethodDefinition)(A.getMembers().get(1));
-    assertEquals("f3", ((DartIdentifier)(f3.getName())).getName());
-    DartMethodDefinition f4 = (DartMethodDefinition)(A.getMembers().get(2));
-    assertEquals("f4", ((DartIdentifier)(f4.getName())).getName());
-  }
-
-  public void testRecoverToTopLevel1() {
-    DartUnit unit = parseUnitUnspecifiedErrors("phony_recover_to_toplevel1.dart",
-        Joiner.on("\n").join(
-            "class A {",
-            "  var a;",
-            "",  // error - missing right brace
-            "class B { ",  // error recover should pick up class B
-            "  var b;",
-            "}"));
-    // Make sure class B is still around
-    DartClass A = (DartClass)unit.getTopLevelNodes().get(0);
-    assertEquals("A", A.getName().getName());
-    DartFieldDefinition A_a = (DartFieldDefinition)A.getMembers().get(0);
-    assertEquals("a", A_a.getFields().get(0).getName().getName());
-    DartClass B = (DartClass)unit.getTopLevelNodes().get(1);
-    assertEquals("B", B.getName().getName());
-    DartFieldDefinition B_b = (DartFieldDefinition)B.getMembers().get(0);
-    assertEquals("b", B_b.getFields().get(0).getName().getName());
-  }
-
-  public void testRecoverToTopLevel2() {
-    DartUnit unit = parseUnitUnspecifiedErrors("phony_recover_to_toplevel2.dart",
-        Joiner.on("\n").join(
-            "class A {",
-            "  var a;",
-            "  var incomplete",  // error - missing semicolon
-            "", // error - missing closing brace
-            "class B { ",  // error recover should pick up class B
-            "  var b;",
-            "}"));
-    // Make sure class B is still around
-    DartClass A = (DartClass)unit.getTopLevelNodes().get(0);
-    assertEquals("A", A.getName().getName());
-    DartFieldDefinition A_a = (DartFieldDefinition)A.getMembers().get(0);
-    assertEquals("a", A_a.getFields().get(0).getName().getName());
-    DartClass B = (DartClass)unit.getTopLevelNodes().get(1);
-    assertEquals("B", B.getName().getName());
-    DartFieldDefinition B_b = (DartFieldDefinition)B.getMembers().get(0);
-    assertEquals("b", B_b.getFields().get(0).getName().getName());
-  }
-
-  public void testRecoverToTopLevel3() {
-    DartUnit unit = parseUnitUnspecifiedErrors("phony_recover_to_toplevel3.dart",
-        Joiner.on("\n").join(
-            "class A {",
-            "  var a;",
-            "  var incomplete = ",  // error - missing value
-            "", // error - missing closing brace
-            "class B { ",  // error recover should pick up class B
-            "  var b;",
-            "}"));
-    // Make sure class B is still around
-    DartClass A = (DartClass)unit.getTopLevelNodes().get(0);
-    assertEquals("A", A.getName().getName());
-    DartFieldDefinition A_a = (DartFieldDefinition)A.getMembers().get(0);
-    assertEquals("a", A_a.getFields().get(0).getName().getName());
-    DartClass B = (DartClass)unit.getTopLevelNodes().get(1);
-    assertEquals("B", B.getName().getName());
-    DartFieldDefinition B_b = (DartFieldDefinition)B.getMembers().get(0);
-    assertEquals("b", B_b.getFields().get(0).getName().getName());
-  }
-
-  public void testRecoverToTopLevel4() {
-    DartUnit unit = parseUnitUnspecifiedErrors("phony_recover_to_toplevel4.dart",
-        Joiner.on("\n").join(
-            "class A {",
-            "  var a;",
-            "  incomplete()",  // error - missing body
-            "", // error - missing right brace
-            "class B { ",  // error recover should pick up class B
-            "  var b;",
-            "}"));
-    // Make sure class B is still around
-    DartClass A = (DartClass)unit.getTopLevelNodes().get(0);
-    assertEquals("A", A.getName().getName());
-    DartFieldDefinition A_a = (DartFieldDefinition)A.getMembers().get(0);
-    assertEquals("a", A_a.getFields().get(0).getName().getName());
-    DartClass B = (DartClass)unit.getTopLevelNodes().get(1);
-    assertEquals("B", B.getName().getName());
-    DartFieldDefinition B_b = (DartFieldDefinition)B.getMembers().get(0);
-    assertEquals("b", B_b.getFields().get(0).getName().getName());
-  }
-
-  public void testRecoverToTopLevel5() {
-    DartUnit unit = parseUnitUnspecifiedErrors("phony_recover_to_toplevel5.dart",
-        Joiner.on("\n").join(
-            "class A {",
-            "  var a;",
-            "  incomplete()",  // error - missing body
-            "}",
-            "class B { ",  // error recover should pick up class B
-            "  var b;",
-            "}"));
-    // Make sure class B is still around
-    DartClass A = (DartClass)unit.getTopLevelNodes().get(0);
-    assertEquals("A", A.getName().getName());
-    DartFieldDefinition A_a = (DartFieldDefinition)A.getMembers().get(0);
-    assertEquals("a", A_a.getFields().get(0).getName().getName());
-    DartClass B = (DartClass)unit.getTopLevelNodes().get(1);
-    assertEquals("B", B.getName().getName());
-    DartFieldDefinition B_b = (DartFieldDefinition)B.getMembers().get(0);
-    assertEquals("b", B_b.getFields().get(0).getName().getName());
-  }
-
-  public void testRecoverToTopLevel6() {
-    DartUnit unit = parseUnitUnspecifiedErrors("phony_recover_to_toplevel6.dart",
-        Joiner.on("\n").join(
-            "class A {",
-            "  var a;",
-            "  method() { instance.field",  // error - missing semicolon, missing rbrace
-            "}",
-            "class B { ",  // error recover should pick up class B
-            "  var b;",
-            "}"));
-    // Make sure class B is still around
-    DartClass A = (DartClass)unit.getTopLevelNodes().get(0);
-    assertEquals("A", A.getName().getName());
-    DartFieldDefinition A_a = (DartFieldDefinition)A.getMembers().get(0);
-    assertEquals("a", A_a.getFields().get(0).getName().getName());
-    DartClass B = (DartClass)unit.getTopLevelNodes().get(1);
-    assertEquals("B", B.getName().getName());
-    DartFieldDefinition B_b = (DartFieldDefinition)B.getMembers().get(0);
-    assertEquals("b", B_b.getFields().get(0).getName().getName());
-  }
-
-  public void testRecoverToTopLevel7() {
-    DartUnit unit = parseUnitUnspecifiedErrors("phony_recover_to_toplevel7.dart",
-        Joiner.on("\n").join(
-            "class A {",
-            "  var a;",
-            "  method() { instance.field",  // error - missing semicolon, missing rbrace
-            "", // error missing rbrace
-            "class B { ",  // error recover should pick up class B
-            "  var b;",
-            "}"));
-    // Make sure class B is still around
-    DartClass A = (DartClass)unit.getTopLevelNodes().get(0);
-    assertEquals("A", A.getName().getName());
-    DartFieldDefinition A_a = (DartFieldDefinition)A.getMembers().get(0);
-    assertEquals("a", A_a.getFields().get(0).getName().getName());
-    DartClass B = (DartClass)unit.getTopLevelNodes().get(1);
-    assertEquals("B", B.getName().getName());
-    DartFieldDefinition B_b = (DartFieldDefinition)B.getMembers().get(0);
-    assertEquals("b", B_b.getFields().get(0).getName().getName());
-  }
-
-  public void testRecoverToTopLevel8() {
-    DartUnit unit = parseUnitUnspecifiedErrors("phony_recover_to_toplevel8.dart",
-        Joiner.on("\n").join(
-            "class A {",
-            "  var a;",
-            "  method() {",
-            "    B instance ;",
-            "    instance.",  // error - missing semicolon, missing rbrace
-            "", // error missing rbrace
-            "class B { ",  // error recover should pick up class B
-            "  var b;",
-            "}"));
-    // Make sure class B is still around
-    DartClass A = (DartClass)unit.getTopLevelNodes().get(0);
-    assertEquals("A", A.getName().getName());
-    DartFieldDefinition A_a = (DartFieldDefinition)A.getMembers().get(0);
-    assertEquals("a", A_a.getFields().get(0).getName().getName());
-    DartClass B = (DartClass)unit.getTopLevelNodes().get(1);
-    assertEquals("B", B.getName().getName());
-    DartFieldDefinition B_b = (DartFieldDefinition)B.getMembers().get(0);
-    assertEquals("b", B_b.getFields().get(0).getName().getName());
-  }
-
-  public void testRecoverToTopLevel9() {
-    DartUnit unit = parseUnitUnspecifiedErrors("phony_recover_to_toplevel9.dart",
-        Joiner.on("\n").join(
-            "class A ", // missing braces
-            "class B { ",  // error recovery should pick up class B
-            "  var b;",
-            "}"));
-    // Make sure class B is still around
-    DartClass A = (DartClass)unit.getTopLevelNodes().get(0);
-    assertEquals("A", A.getName().getName());
-    DartClass B = (DartClass)unit.getTopLevelNodes().get(1);
-    assertEquals("B", B.getName().getName());
-    DartFieldDefinition B_b = (DartFieldDefinition)B.getMembers().get(0);
-    assertEquals("b", B_b.getFields().get(0).getName().getName());
-  }
-
-  public void testRecoverToTopLevel10() {
-    DartUnit unit = parseUnitUnspecifiedErrors("phony_recover_to_toplevel10.dart",
-        Joiner.on("\n").join(
-            "class A ", // missing opening brace
-            "  var a;",
-            "}",
-            "class B { ",  // error recovery should pick up class B
-            "  var b;",
-            "}"));
-    // Make sure class B is still around
-    DartClass A = (DartClass)unit.getTopLevelNodes().get(0);
-    assertEquals("A", A.getName().getName());
-    // In this case, the parser chooses to promote 'var a' to a top level element
-    DartClass B = (DartClass)unit.getTopLevelNodes().get(2);
-    assertEquals("B", B.getName().getName());
-    DartFieldDefinition B_b = (DartFieldDefinition)B.getMembers().get(0);
-    assertEquals("b", B_b.getFields().get(0).getName().getName());
-  }
-
-  public void testReservedWordClass() {
-    DartUnit unit = parseUnitUnspecifiedErrors("phony_reserved_word_class",
-        Joiner.on("\n").join(
-            "class foo {}",
-            "main() {",
-            "  int class = 10;",
-            "  print(\"class = $class\");",
-            "}",
-            "class bar {}"));
-    DartClass foo = (DartClass)unit.getTopLevelNodes().get(0);
-    assertEquals("foo", foo.getName().getName());
-    DartMethodDefinition mainMethod = (DartMethodDefinition)unit.getTopLevelNodes().get(1);
-    assertEquals("main", ((DartIdentifier)mainMethod.getName()).getName());
-    // The recovery on 'int class' closes the main method, assuming int class = 10 is a
-    // new toplevel so 'print' ends up as a bogus top level node.
-    DartClass bar = (DartClass)unit.getTopLevelNodes().get(3);
-    assertEquals("bar", bar.getName().getName());
-  }
-
-  public void testBadOperatorRecovery() {
-    DartUnit unit = parseUnit("phony_bad_operator_recovery",
-        Joiner.on("\n").join(
-            "class foo {",
-            "  operator / (arg) {}",
-            "  operator /= (arg) {}",
-            "  operator ][ (arg) {}",
-            "  operator === (arg) {}",
-            "  operator + (arg) {}",
-            "}"),
-            ParserErrorCode.OPERATOR_IS_NOT_USER_DEFINABLE, 3, 12,
-            ParserErrorCode.OPERATOR_IS_NOT_USER_DEFINABLE, 4, 12,
-            ParserErrorCode.OPERATOR_IS_NOT_USER_DEFINABLE, 5, 12);
-    DartClass foo =  (DartClass)unit.getTopLevelNodes().get(0);
-    assertEquals("foo", foo.getName().getName());
-    DartMethodDefinition opDiv = (DartMethodDefinition)foo.getMembers().get(0);
-    assertEquals("/", ((DartIdentifier)opDiv.getName()).getName());
-    DartMethodDefinition opAssignDiv = (DartMethodDefinition)foo.getMembers().get(1);
-    assertEquals("/=", ((DartIdentifier)opAssignDiv.getName()).getName());
-    DartMethodDefinition opNonsense = (DartMethodDefinition)foo.getMembers().get(2);
-    assertEquals("][", ((DartIdentifier)opNonsense.getName()).getName());
-    DartMethodDefinition opEquiv = (DartMethodDefinition)foo.getMembers().get(3);
-    assertEquals("===", ((DartIdentifier)opEquiv.getName()).getName());
-    DartMethodDefinition opPlus = (DartMethodDefinition)foo.getMembers().get(4);
-    assertEquals("+", ((DartIdentifier)opPlus.getName()).getName());
-  }
-
-  public void testPropertyAccessInArgumentListRecovery1() {
-    DartUnit unit = parseUnitUnspecifiedErrors("phony_property_access1.dart",
-        Joiner.on("\n").join(
-            "var before;",
-            "var bad = new B(null, foo.);",
-            "var after;"));
-    DartFieldDefinition before = (DartFieldDefinition)unit.getTopLevelNodes().get(0);
-    assertEquals("before", before.getFields().get(0).getName().getName());
-    DartFieldDefinition bad = (DartFieldDefinition)unit.getTopLevelNodes().get(1);
-    assertEquals("bad", bad.getFields().get(0).getName().getName());
-    DartFieldDefinition after = (DartFieldDefinition)unit.getTopLevelNodes().get(2);
-    assertEquals("after", after.getFields().get(0).getName().getName());
-  }
-
-  public void testPropertyAccessInArgumentListRecovery2() {
-    DartUnit unit = parseUnitUnspecifiedErrors("phony_property_access2.dart",
-        Joiner.on("\n").join(
-            "var before;",
-            "var bad = new B(null, foo.,);",
-            "var after;"));
-    DartFieldDefinition before = (DartFieldDefinition)unit.getTopLevelNodes().get(0);
-    assertEquals("before", before.getFields().get(0).getName().getName());
-    DartFieldDefinition bad = (DartFieldDefinition)unit.getTopLevelNodes().get(1);
-    assertEquals("bad", bad.getFields().get(0).getName().getName());
-    DartFieldDefinition after = (DartFieldDefinition)unit.getTopLevelNodes().get(2);
-    assertEquals("after", after.getFields().get(0).getName().getName());
-  }
-
-  public void testPropertyAccessInArgumentListRecovery3() {
-    DartUnit unit = parseUnitUnspecifiedErrors("phony_property_access3.dart",
-        Joiner.on("\n").join(
-            "var before;",
-            "var bad = new B(null,, foo);",
-            "var after;"));
-    DartFieldDefinition before = (DartFieldDefinition)unit.getTopLevelNodes().get(0);
-    assertEquals("before", before.getFields().get(0).getName().getName());
-    DartFieldDefinition bad = (DartFieldDefinition)unit.getTopLevelNodes().get(1);
-    assertEquals("bad", bad.getFields().get(0).getName().getName());
-    DartFieldDefinition after = (DartFieldDefinition)unit.getTopLevelNodes().get(2);
-    assertEquals("after", after.getFields().get(0).getName().getName());
-  }
-
-  public void testPropertyAccessInArgumentListRecovery4() {
-    DartUnit unit = parseUnitUnspecifiedErrors("phony_property_access4.dart",
-        Joiner.on("\n").join(
-            "var before;",
-            "var bad = new B(null,+, foo);",
-            "var after;"));
-    DartFieldDefinition before = (DartFieldDefinition)unit.getTopLevelNodes().get(0);
-    assertEquals("before", before.getFields().get(0).getName().getName());
-    DartFieldDefinition bad = (DartFieldDefinition)unit.getTopLevelNodes().get(1);
-    assertEquals("bad", bad.getFields().get(0).getName().getName());
-    DartFieldDefinition after = (DartFieldDefinition)unit.getTopLevelNodes().get(2);
-    assertEquals("after", after.getFields().get(0).getName().getName());
-  }
-
-  public void testPropertyAccessInInitializerListRecovery1() {
-    DartUnit unit = parseUnitUnspecifiedErrors("phony_property_access1.dart",
-        Joiner.on("\n").join(
-            "class A {",
-            "  var before;",
-            "  A() : before = foo. ;",
-            "  var after;",
-            "}"));
-    DartClass A = (DartClass)unit.getTopLevelNodes().get(0);
-    DartFieldDefinition before = (DartFieldDefinition)A.getMembers().get(0);
-    assertEquals("before", before.getFields().get(0).getName().getName());
-    DartMethodDefinition bad = (DartMethodDefinition)A.getMembers().get(1);
-    assertEquals("A", ((DartIdentifier)bad.getName()).getName());
-    DartFieldDefinition after = (DartFieldDefinition)A.getMembers().get(2);
-    assertEquals("after", after.getFields().get(0).getName().getName());
-  }
-
-  public void testPropertyAccessInFormalParameterList1() {
-    DartUnit unit = parseUnitUnspecifiedErrors("phony_property_access_parameter1.dart",
-        Joiner.on("\n").join(
-                "var before;",
-                "typedef void bad(bar.);",
-            "var after;"));
-        DartFieldDefinition before = (DartFieldDefinition)unit.getTopLevelNodes().get(0);
-        assertEquals("before", before.getFields().get(0).getName().getName());
-        DartFunctionTypeAlias bad = (DartFunctionTypeAlias)unit.getTopLevelNodes().get(1);
-        assertEquals("bad", bad.getName().getName());
-        DartFieldDefinition after = (DartFieldDefinition)unit.getTopLevelNodes().get(2);
-        assertEquals("after", after.getFields().get(0).getName().getName());
-  }
-
-  public void testPropertyAccessInFormalParameterList2() {
-    DartUnit unit = parseUnitUnspecifiedErrors("phony_property_access_parameter2.dart",
-        Joiner.on("\n").join(
-            "var before;",
-            "typedef void bad(bar.,baz);",
-        "var after;"));
-    DartFieldDefinition before = (DartFieldDefinition)unit.getTopLevelNodes().get(0);
-    assertEquals("before", before.getFields().get(0).getName().getName());
-    DartFunctionTypeAlias bad = (DartFunctionTypeAlias)unit.getTopLevelNodes().get(1);
-    assertEquals("bad", bad.getName().getName());
-    DartFieldDefinition after = (DartFieldDefinition)unit.getTopLevelNodes().get(2);
-    assertEquals("after", after.getFields().get(0).getName().getName());
-  }
-
-  public void testPropertyAccessInFormalParameterList3() {
-    DartUnit unit = parseUnitUnspecifiedErrors("phony_property_access_parameter3.dart",
-        Joiner.on("\n").join(
-            "var before;",
-            "typedef void bad(foo, [bar.]);", // incomplete property access
-        "var after;"));
-    DartFieldDefinition before = (DartFieldDefinition)unit.getTopLevelNodes().get(0);
-    assertEquals("before", before.getFields().get(0).getName().getName());
-    DartFunctionTypeAlias bad = (DartFunctionTypeAlias)unit.getTopLevelNodes().get(1);
-    assertEquals("bad", bad.getName().getName());
-    DartFieldDefinition after = (DartFieldDefinition)unit.getTopLevelNodes().get(2);
-    assertEquals("after", after.getFields().get(0).getName().getName());
-  }
-
-
-  public void testPropertyAccessInFormalParameterList4() {
-    DartUnit unit = parseUnitUnspecifiedErrors("phony_property_access_parameter4.dart",
-        Joiner.on("\n").join(
-            "var before;",
-            "typedef void bad(int bar.);", // a property access is not valid here
-            "var after;"));
-    DartFieldDefinition before = (DartFieldDefinition)unit.getTopLevelNodes().get(0);
-    assertEquals("before", before.getFields().get(0).getName().getName());
-    DartFunctionTypeAlias bad = (DartFunctionTypeAlias)unit.getTopLevelNodes().get(1);
-    assertEquals("bad", bad.getName().getName());
-    DartFieldDefinition after = (DartFieldDefinition)unit.getTopLevelNodes().get(2);
-    assertEquals("after", after.getFields().get(0).getName().getName());
-  }
-
-  public void testPropertyAccessInFormalParameterList5() {
-    DartUnit unit = parseUnitUnspecifiedErrors("phony_property_access_parameter5.dart",
-        Joiner.on("\n").join(
-            "var before;",
-            "var bad = (bar.) {};", // incomplete property access
-            "var after;"));
-    DartFieldDefinition before = (DartFieldDefinition)unit.getTopLevelNodes().get(0);
-    assertEquals("before", before.getFields().get(0).getName().getName());
-    DartFieldDefinition bad = (DartFieldDefinition)unit.getTopLevelNodes().get(1);
-    assertEquals("bad", bad.getFields().get(0).getName().getName());
-    DartFieldDefinition after = (DartFieldDefinition)unit.getTopLevelNodes().get(2);
-    assertEquals("after", after.getFields().get(0).getName().getName());
-  }
-
-  public void testPropertyAccessInFormalParameterList6() {
-    DartUnit unit = parseUnitUnspecifiedErrors("phony_property_access_parameter6.dart",
-        Joiner.on("\n").join(
-            "var before;",
-            "void bad(foo.);", // incomplete property access
-            "var after;"));
-    DartFieldDefinition before = (DartFieldDefinition)unit.getTopLevelNodes().get(0);
-    assertEquals("before", before.getFields().get(0).getName().getName());
-    DartMethodDefinition bad = (DartMethodDefinition)unit.getTopLevelNodes().get(1);
-    assertEquals("bad", ((DartIdentifier)bad.getName()).getName());
-    DartFieldDefinition after = (DartFieldDefinition)unit.getTopLevelNodes().get(2);
-    assertEquals("after", after.getFields().get(0).getName().getName());
-  }
-
-  public void testRecoverInBlock1() {
-    DartUnit unit = parseUnitUnspecifiedErrors("phony_recover_in_block1.dart",
-        Joiner.on("\n").join(
-            "var before;",
-            "bad() { foo( }", // unterminated invocation
-            "var after;"));
-    DartFieldDefinition before = (DartFieldDefinition)unit.getTopLevelNodes().get(0);
-    assertEquals("before", before.getFields().get(0).getName().getName());
-    DartMethodDefinition bad = (DartMethodDefinition)unit.getTopLevelNodes().get(1);
-    assertEquals("bad", ((DartIdentifier)bad.getName()).getName());
-    DartUnqualifiedInvocation invocation = (DartUnqualifiedInvocation)
-        ((DartExprStmt)bad.getFunction().getBody().getStatements().get(0)).getExpression();
-    assertEquals("foo", invocation.getTarget().getName());
-    DartFieldDefinition after = (DartFieldDefinition)unit.getTopLevelNodes().get(2);
-    assertEquals("after", after.getFields().get(0).getName().getName());
-  }
-
-  public void testRecoverInBlock2() {
-    DartUnit unit = parseUnitUnspecifiedErrors("phony_recover_in_block2.dart",
-        Joiner.on("\n").join(
-            "var before;",
-            "bad() { foo }", // unterminated statement
-            "var after;"));
-    DartFieldDefinition before = (DartFieldDefinition)unit.getTopLevelNodes().get(0);
-    assertEquals("before", before.getFields().get(0).getName().getName());
-    DartMethodDefinition bad = (DartMethodDefinition)unit.getTopLevelNodes().get(1);
-    assertEquals("bad", ((DartIdentifier)bad.getName()).getName());
-    DartIdentifier ident = (DartIdentifier)
-        ((DartExprStmt)bad.getFunction().getBody().getStatements().get(0)).getExpression();
-    assertEquals("foo", ident.getName());
-    DartFieldDefinition after = (DartFieldDefinition)unit.getTopLevelNodes().get(2);
-    assertEquals("after", after.getFields().get(0).getName().getName());
-  }
-
-  public void testRecoverInBlock3() {
-    DartUnit unit = parseUnitUnspecifiedErrors("phony_recover_in_block3.dart",
-        Joiner.on("\n").join(
-            "var before;",
-            "bad() { foo. }", // unterminated statement
-            "var after;"));
-    DartFieldDefinition before = (DartFieldDefinition)unit.getTopLevelNodes().get(0);
-    assertEquals("before", before.getFields().get(0).getName().getName());
-    DartMethodDefinition bad = (DartMethodDefinition)unit.getTopLevelNodes().get(1);
-    assertEquals("bad", ((DartIdentifier)bad.getName()).getName());
-    DartPropertyAccess prop = (DartPropertyAccess)
-    ((DartExprStmt)bad.getFunction().getBody().getStatements().get(0)).getExpression();
-assertEquals("foo", ((DartIdentifier)prop.getQualifier()).getName());
-    DartFieldDefinition after = (DartFieldDefinition)unit.getTopLevelNodes().get(2);
-    assertEquals("after", after.getFields().get(0).getName().getName());
-  }
-
-  public void testRecoverInBlock4() {
-    DartUnit unit = parseUnitUnspecifiedErrors("phony_recover_in_block4.dart",
-        Joiner.on("\n").join(
-            "var before;",
-            "bad() { var foo = }", // unterminated variable decl
-            "var after;"));
-    DartFieldDefinition before = (DartFieldDefinition)unit.getTopLevelNodes().get(0);
-    assertEquals("before", before.getFields().get(0).getName().getName());
-    DartMethodDefinition bad = (DartMethodDefinition)unit.getTopLevelNodes().get(1);
-    assertEquals("bad", ((DartIdentifier)bad.getName()).getName());
-    DartVariable foo = ((DartVariableStatement)bad.getFunction().getBody().getStatements().get(0))
-        .getVariables().get(0);
-    assertEquals("foo", foo.getVariableName());
-    DartFieldDefinition after = (DartFieldDefinition)unit.getTopLevelNodes().get(2);
-    assertEquals("after", after.getFields().get(0).getName().getName());
-  }
-
-  public void testRecoverInBlock5() {
-    DartUnit unit = parseUnitUnspecifiedErrors("phony_recover_in_block5.dart",
-        Joiner.on("\n").join(
-            "var before;",
-            "bad() { foo(bar. }", // unterminated invocation
-            "var after;"));
-    DartFieldDefinition before = (DartFieldDefinition)unit.getTopLevelNodes().get(0);
-    assertEquals("before", before.getFields().get(0).getName().getName());
-    DartMethodDefinition bad = (DartMethodDefinition)unit.getTopLevelNodes().get(1);
-    assertEquals("bad", ((DartIdentifier)bad.getName()).getName());
-    DartUnqualifiedInvocation invocation = (DartUnqualifiedInvocation)
-        ((DartExprStmt)bad.getFunction().getBody().getStatements().get(0)).getExpression();
-    assertEquals("foo", invocation.getTarget().getName());
-    DartPropertyAccess arg0 = (DartPropertyAccess)invocation.getArguments().get(0);
-    assertEquals("bar", ((DartIdentifier)arg0.getQualifier()).getName());
-    DartFieldDefinition after = (DartFieldDefinition)unit.getTopLevelNodes().get(2);
-    assertEquals("after", after.getFields().get(0).getName().getName());
-  }
-
-  public void testRecoverInBlock6() {
-    DartUnit unit = parseUnitUnspecifiedErrors("phony_recover_in_block6.dart",
-        Joiner.on("\n").join(
-            "var before;",
-            "bad() { foo + }", // incomplete expression
-            "var after;"));
-    DartFieldDefinition before = (DartFieldDefinition)unit.getTopLevelNodes().get(0);
-    assertEquals("before", before.getFields().get(0).getName().getName());
-    DartMethodDefinition bad = (DartMethodDefinition)unit.getTopLevelNodes().get(1);
-    assertEquals("bad", ((DartIdentifier)bad.getName()).getName());
-    DartBinaryExpression expr = (DartBinaryExpression)
-    ((DartExprStmt)bad.getFunction().getBody().getStatements().get(0)).getExpression();
-    assertEquals("foo", ((DartIdentifier)expr.getArg1()).getName());
-    DartFieldDefinition after = (DartFieldDefinition)unit.getTopLevelNodes().get(2);
-    assertEquals("after", after.getFields().get(0).getName().getName());
- }
-
-  public void testPropertyAccessInExpressionList1() {
-    DartUnit unit = parseUnitUnspecifiedErrors("phony_property_access_expression_list1.dart",
-        Joiner.on("\n").join(
-                "method() {",
-                "  var before;",
-                "  for (var i=0;i < 2;before, foo.,after) {}",
-                "  var after;",
-                "}"));
-    DartMethodDefinition method = (DartMethodDefinition) unit.getTopLevelNodes().get(0);
-    DartVariable before = ((DartVariableStatement) method.getFunction().getBody().getStatements()
-        .get(0)).getVariables().get(0);
-    assertEquals("before", before.getName().getName());
-    DartForStatement forStatement = (DartForStatement) method.getFunction().getBody()
-        .getStatements().get(1);
-    DartBinaryExpression increment = (DartBinaryExpression) forStatement.getIncrement();
-    DartBinaryExpression i1 = (DartBinaryExpression) increment.getArg1();
-    DartIdentifier beforeIdent = (DartIdentifier) i1.getArg1();
-    assertEquals("before", beforeIdent.getName());
-    DartPropertyAccess foo = (DartPropertyAccess) i1.getArg2();
-    assertEquals("foo", ((DartIdentifier) foo.getQualifier()).getName());
-    DartIdentifier afterIdent = (DartIdentifier) increment.getArg2();
-    assertEquals("after", afterIdent.getName());
-    DartVariable after = ((DartVariableStatement) method.getFunction().getBody().getStatements()
-        .get(2)).getVariables().get(0);
-    assertEquals("after", after.getName().getName());
-  }
-
-  public void testPropertyAccessInExpressionList2() {
-    DartUnit unit = parseUnitUnspecifiedErrors("phony_property_access_expression_list2.dart",
-        Joiner.on("\n").join(
-            "method() {",
-            "  var before;",
-            "  for (var i=0;i < 2; foo.) {}",
-            "  var after;",
-        "}"));
-    DartMethodDefinition method = (DartMethodDefinition) unit.getTopLevelNodes().get(0);
-    DartVariable before = ((DartVariableStatement) method.getFunction().getBody().getStatements()
-        .get(0)).getVariables().get(0);
-    assertEquals("before", before.getName().getName());
-    DartForStatement forStatement = (DartForStatement) method.getFunction().getBody()
-        .getStatements().get(1);
-    DartPropertyAccess foo = (DartPropertyAccess) forStatement.getIncrement();
-    assertEquals("foo", ((DartIdentifier) foo.getQualifier()).getName());
-    DartVariable after = ((DartVariableStatement) method.getFunction().getBody().getStatements()
-        .get(2)).getVariables().get(0);
-    assertEquals("after", after.getName().getName());
-  }
-
-  public void testPropertyAccessInArrayLiteral1() {
-    DartUnit unit = parseUnitUnspecifiedErrors("phony_property_access_array_literal1.dart",
-        Joiner.on("\n").join(
-            "var before;",
-            "var bad = [foo.];",
-            "var after;"));
-    DartFieldDefinition before = (DartFieldDefinition)unit.getTopLevelNodes().get(0);
-    assertEquals("before", before.getFields().get(0).getName().getName());
-    DartFieldDefinition bad = (DartFieldDefinition)unit.getTopLevelNodes().get(1);
-    assertEquals("bad", bad.getFields().get(0).getName().getName());
-    DartArrayLiteral literal = (DartArrayLiteral)bad.getFields().get(0).getValue();
-    DartPropertyAccess foo = (DartPropertyAccess)literal.getExpressions().get(0);
-    assertEquals("foo", ((DartIdentifier)foo.getQualifier()).getName());
-    DartFieldDefinition after = (DartFieldDefinition)unit.getTopLevelNodes().get(2);
-    assertEquals("after", after.getFields().get(0).getName().getName());
-  }
-
-  public void testPropertyAccessInArrayLiteral2() {
-    DartUnit unit = parseUnitUnspecifiedErrors("phony_property_access_array_literal2.dart",
-        Joiner.on("\n").join(
-            "var before;",
-            "var bad = [foo.,];",
-            "var after;"));
-    DartFieldDefinition before = (DartFieldDefinition)unit.getTopLevelNodes().get(0);
-    assertEquals("before", before.getFields().get(0).getName().getName());
-    DartFieldDefinition bad = (DartFieldDefinition)unit.getTopLevelNodes().get(1);
-    assertEquals("bad", bad.getFields().get(0).getName().getName());
-    DartArrayLiteral literal = (DartArrayLiteral)bad.getFields().get(0).getValue();
-    DartPropertyAccess foo = (DartPropertyAccess)literal.getExpressions().get(0);
-    assertEquals("foo", ((DartIdentifier)foo.getQualifier()).getName());
-    DartFieldDefinition after = (DartFieldDefinition)unit.getTopLevelNodes().get(2);
-    assertEquals("after", after.getFields().get(0).getName().getName());
-  }
-
-  public void testPropertyAccessInArrayLiteral3() {
-    DartUnit unit = parseUnitUnspecifiedErrors("phony_property_access_array_literal2.dart",
-        Joiner.on("\n").join(
-            "var before;",
-            "var bad = [foo. + ];",
-            "var after;"));
-    DartFieldDefinition before = (DartFieldDefinition)unit.getTopLevelNodes().get(0);
-    assertEquals("before", before.getFields().get(0).getName().getName());
-    DartFieldDefinition bad = (DartFieldDefinition)unit.getTopLevelNodes().get(1);
-    assertEquals("bad", bad.getFields().get(0).getName().getName());
-    DartArrayLiteral literal = (DartArrayLiteral)bad.getFields().get(0).getValue();
-    DartPropertyAccess foo = (DartPropertyAccess)literal.getExpressions().get(0);
-    assertEquals("foo", ((DartIdentifier)foo.getQualifier()).getName());
-    DartFieldDefinition after = (DartFieldDefinition)unit.getTopLevelNodes().get(2);
-    assertEquals("after", after.getFields().get(0).getName().getName());
-  }
-
-  public void testPropertyAccessInMapLiteral1() {
-    DartUnit unit = parseUnitUnspecifiedErrors("phony_property_access_map_literal1.dart",
-        Joiner.on("\n").join(
-            "var before;",
-            "var bad = {\"key\" : foo.};",
-            "var after;"));
-    DartFieldDefinition before = (DartFieldDefinition)unit.getTopLevelNodes().get(0);
-    assertEquals("before", before.getFields().get(0).getName().getName());
-    DartFieldDefinition bad = (DartFieldDefinition)unit.getTopLevelNodes().get(1);
-    assertEquals("bad", bad.getFields().get(0).getName().getName());
-    DartMapLiteral literal = (DartMapLiteral)bad.getFields().get(0).getValue();
-    DartPropertyAccess foo = (DartPropertyAccess)literal.getEntries().get(0).getValue();
-    assertEquals("foo", ((DartIdentifier)foo.getQualifier()).getName());
-    DartFieldDefinition after = (DartFieldDefinition)unit.getTopLevelNodes().get(2);
-    assertEquals("after", after.getFields().get(0).getName().getName());
-  }
-
-  public void testPropertyAccessInMapLiteral2() {
-    DartUnit unit = parseUnitUnspecifiedErrors("phony_property_access_map_literal2.dart",
-        Joiner.on("\n").join(
-            "var before;",
-            "var bad = {\"key\" : foo.,};",
-            "var after;"));
-    DartFieldDefinition before = (DartFieldDefinition)unit.getTopLevelNodes().get(0);
-    assertEquals("before", before.getFields().get(0).getName().getName());
-    DartFieldDefinition bad = (DartFieldDefinition)unit.getTopLevelNodes().get(1);
-    assertEquals("bad", bad.getFields().get(0).getName().getName());
-    DartMapLiteral literal = (DartMapLiteral)bad.getFields().get(0).getValue();
-    DartPropertyAccess foo = (DartPropertyAccess)literal.getEntries().get(0).getValue();
-    assertEquals("foo", ((DartIdentifier)foo.getQualifier()).getName());
-    DartFieldDefinition after = (DartFieldDefinition)unit.getTopLevelNodes().get(2);
-    assertEquals("after", after.getFields().get(0).getName().getName());
-  }
-
-  public void testPropertyAccessInMapLiteral3() {
-    DartUnit unit = parseUnitUnspecifiedErrors("phony_property_access_map_literal3.dart",
-        Joiner.on("\n").join(
-            "var before;",
-            "var bad = {\"key\" : foo. +};",
-            "var after;"));
-    DartFieldDefinition before = (DartFieldDefinition)unit.getTopLevelNodes().get(0);
-    assertEquals("before", before.getFields().get(0).getName().getName());
-    DartFieldDefinition bad = (DartFieldDefinition)unit.getTopLevelNodes().get(1);
-    assertEquals("bad", bad.getFields().get(0).getName().getName());
-    DartMapLiteral literal = (DartMapLiteral)bad.getFields().get(0).getValue();
-    DartPropertyAccess foo = (DartPropertyAccess)literal.getEntries().get(0).getValue();
-    assertEquals("foo", ((DartIdentifier)foo.getQualifier()).getName());
-    DartFieldDefinition after = (DartFieldDefinition)unit.getTopLevelNodes().get(2);
-    assertEquals("after", after.getFields().get(0).getName().getName());
-  }
-
-  public void testRecoveryDirective1() {
-    DartUnit unit = parseUnit("phony_recovery_directive1.dart",
-        Joiner.on("\n").join(
-            "library a;",
-            "library b;"),
-            ParserErrorCode.DIRECTIVE_OUT_OF_ORDER, 2, 1,
-            ParserErrorCode.ONLY_ONE_LIBRARY_DIRECTIVE, 2, 10);
-    DartLibraryDirective a = (DartLibraryDirective)unit.getDirectives().get(0);
-    assertEquals("a", a.getLibraryName());
-    DartLibraryDirective b = (DartLibraryDirective)unit.getDirectives().get(1);
-    assertEquals("b", b.getLibraryName());
-  }
-
-  public void testRecoveryDirective2() {
-    DartUnit unit = parseUnit("phony_recovery_directive2.dart",
-        Joiner.on("\n").join(
-            "import 'a';",
-            "library b;"),
-            ParserErrorCode.DIRECTIVE_OUT_OF_ORDER, 2, 1);
-    DartImportDirective a = (DartImportDirective)unit.getDirectives().get(0);
-    assertEquals("a", a.getLibraryUri().getValue());
-    DartLibraryDirective b = (DartLibraryDirective)unit.getDirectives().get(1);
-    assertEquals("b", b.getLibraryName());
-  }
-
-  public void testRecoveryDirective3() {
-    DartUnit unit = parseUnit("phony_recovery_directive3.dart",
-        Joiner.on("\n").join(
-            "part 'a';",
-            "import 'b';"),
-            ParserErrorCode.DIRECTIVE_OUT_OF_ORDER, 2, 1);
-    DartSourceDirective a = (DartSourceDirective)unit.getDirectives().get(0);
-    assertEquals("a", a.getSourceUri().getValue());
-    DartImportDirective b = (DartImportDirective)unit.getDirectives().get(1);
-    assertEquals("b", b.getLibraryUri().getValue());
-  }
-
-  public void testRecoveryDirective4() {
-    DartUnit unit = parseUnit("phony_recovery_directive4.dart",
-        Joiner.on("\n").join(
-            "import 'a'", // missing semicolon
-            "import 'b';"),
-            ParserErrorCode.EXPECTED_TOKEN, 1, 8);
-    DartImportDirective a = (DartImportDirective)unit.getDirectives().get(0);
-    assertEquals("a", a.getLibraryUri().getValue());
-    DartImportDirective b = (DartImportDirective)unit.getDirectives().get(1);
-    assertEquals("b", b.getLibraryUri().getValue());
-  }
-
-  public void testRecoveryDirective6() {
-    DartUnit unit = parseUnit("phony_recovery_directive6.dart",
-        Joiner.on("\n").join(
-            "import 'a'", // missing semicolon
-            "class b {}"),
-            ParserErrorCode.EXPECTED_TOKEN, 1, 8);
-    DartImportDirective a = (DartImportDirective)unit.getDirectives().get(0);
-    assertEquals("a", a.getLibraryUri().getValue());
-    DartClass b = (DartClass)unit.getTopLevelNodes().get(0);
-    assertEquals("b", b.getClassName());
-  }
-
-
-  public void testPropertyAccessInTypeArgsRecovery1() {
-    DartUnit unit = parseUnitUnspecifiedErrors("phony_property_access_type_args1.dart",
-        Joiner.on("\n").join(
-            "var before;",
-            "List<foo.> bad;",
-            "var after;"));
-    DartFieldDefinition before = (DartFieldDefinition)unit.getTopLevelNodes().get(0);
-    assertEquals("before", before.getFields().get(0).getName().getName());
-    DartFieldDefinition bad = (DartFieldDefinition)unit.getTopLevelNodes().get(1);
-    assertEquals("bad", bad.getFields().get(0).getName().getName());
-    DartTypeNode badTypeNode = bad.getTypeNode().getTypeArguments().get(0);
-    assertEquals("foo", ((DartIdentifier)((DartPropertyAccess)badTypeNode.getIdentifier()).getQualifier()).getName());
-    DartFieldDefinition after = (DartFieldDefinition)unit.getTopLevelNodes().get(2);
-    assertEquals("after", after.getFields().get(0).getName().getName());
-  }
-
-  public void testPropertyAccessInTypeArgsRecovery2() {
-    DartUnit unit = parseUnitUnspecifiedErrors("phony_property_access_type_args2.dart",
-        Joiner.on("\n").join(
-            "var before;",
-            "List<foo. +> bad;",
-            "var after;"));
-    DartFieldDefinition before = (DartFieldDefinition)unit.getTopLevelNodes().get(0);
-    assertEquals("before", before.getFields().get(0).getName().getName());
-//    DartFieldDefinition bad = (DartFieldDefinition)unit.getTopLevelNodes().get(1);
-//    assertEquals("bad", bad.getFields().get(0).getName().getName());
-//    DartTypeNode badTypeNode = bad.getTypeNode().getTypeArguments().get(0);
-//    assertEquals("foo", ((DartIdentifier)((DartPropertyAccess)badTypeNode.getIdentifier()).getQualifier()).getName());
-    DartFieldDefinition after = (DartFieldDefinition)unit.getTopLevelNodes().get(2);
-    assertEquals("after", after.getFields().get(0).getName().getName());
-  }
-
-  public void testPropertyAccessInTypeParametersRecovery1() {
-    DartUnit unit = parseUnitUnspecifiedErrors("phony_property_access_type_param1.dart",
-        Joiner.on("\n").join(
-            "var before;",
-            "class bad<T extends foo.> {}",
-            "var after;"));
-    DartFieldDefinition before = (DartFieldDefinition)unit.getTopLevelNodes().get(0);
-    assertEquals("before", before.getFields().get(0).getName().getName());
-    DartClass bad = (DartClass)unit.getTopLevelNodes().get(1);
-    assertEquals("bad", bad.getClassName());
-    DartTypeNode badTypeNode = bad.getTypeParameters().get(0).getBound();
-    assertEquals("foo", ((DartIdentifier)((DartPropertyAccess)badTypeNode.getIdentifier()).getQualifier()).getName());
-    DartFieldDefinition after = (DartFieldDefinition)unit.getTopLevelNodes().get(2);
-    assertEquals("after", after.getFields().get(0).getName().getName());
-  }
-
-  public void testPropertyAccessInTypeParametersRecovery2() {
-    DartUnit unit = parseUnitUnspecifiedErrors("phony_property_access_type_param2.dart",
-        Joiner.on("\n").join(
-            "var before;",
-            "class bad<T extends foo. +> {}",
-            "var after;"));
-    DartFieldDefinition before = (DartFieldDefinition)unit.getTopLevelNodes().get(0);
-    assertEquals("before", before.getFields().get(0).getName().getName());
-    DartClass bad = (DartClass)unit.getTopLevelNodes().get(1);
-    assertEquals("bad", bad.getClassName());
-    DartTypeNode badTypeNode = bad.getTypeParameters().get(0).getBound();
-    assertEquals("foo", ((DartIdentifier)((DartPropertyAccess)badTypeNode.getIdentifier()).getQualifier()).getName());
-    DartFieldDefinition after = (DartFieldDefinition)unit.getTopLevelNodes().get(2);
-    assertEquals("after", after.getFields().get(0).getName().getName());
-  }
-
-  public void testPropertyAccessInTypeParametersRecovery3() {
-    DartUnit unit = parseUnitUnspecifiedErrors("phony_property_access_type_param3.dart",
-        Joiner.on("\n").join(
-            "var before;",
-            "class bad<foo +> {}",
-            "var after;"));
-    DartFieldDefinition before = (DartFieldDefinition)unit.getTopLevelNodes().get(0);
-    assertEquals("before", before.getFields().get(0).getName().getName());
-    DartClass bad = (DartClass)unit.getTopLevelNodes().get(1);
-    assertEquals("bad", bad.getClassName());
-    assertEquals("foo", bad.getTypeParameters().get(0).getName().getName());
-    DartFieldDefinition after = (DartFieldDefinition)unit.getTopLevelNodes().get(2);
-    assertEquals("after", after.getFields().get(0).getName().getName());
-  }
-
-  public void testInvalidIdentifier1() {
-    DartUnit unit = parseUnit("phony_invalid_identifier.dart",
-        Joiner.on("\n").join(
-            "var before;",
-            "class void {}",
-            "var after;"),
-            ParserErrorCode.INVALID_IDENTIFIER, 2, 7);
-    DartFieldDefinition before = (DartFieldDefinition)unit.getTopLevelNodes().get(0);
-    assertEquals("before", before.getFields().get(0).getName().getName());
-
-    DartFieldDefinition after = (DartFieldDefinition)unit.getTopLevelNodes().get(1);
-    assertEquals("after", after.getFields().get(0).getName().getName());
-  }
-
-  public void testRecoveryClassRbrace1() {
-    DartUnit unit = parseUnitUnspecifiedErrors("phony_recovery_class_rbrace1.dart",
-        Joiner.on("\n").join(
-            "var before;",
-            "class A {",
-            "  int bad =,",  // incomplete field definition
-            "}",
-            "int after;")); // use 'int' instead of 'var' because it is harder to recover to
-    DartFieldDefinition before = (DartFieldDefinition)unit.getTopLevelNodes().get(0);
-    assertEquals("before", before.getFields().get(0).getName().getName());
-    DartClass A = (DartClass)unit.getTopLevelNodes().get(1);
-    assertEquals("A", A.getClassName());
-    DartFieldDefinition bad = (DartFieldDefinition)A.getMembers().get(0);
-    assertEquals("bad", bad.getFields().get(0).getName().getName());
-    DartFieldDefinition after = (DartFieldDefinition)unit.getTopLevelNodes().get(2);
-    assertEquals("after", after.getFields().get(0).getName().getName());
-    assertEquals("int", ((DartIdentifier)after.getTypeNode().getIdentifier()).getName());
-  }
-
-  public void testRecoveryClassRbrace2() {
-    DartUnit unit = parseUnitUnspecifiedErrors("phony_recovery_class_rbrace2.dart",
-        Joiner.on("\n").join(
-            "var before;",
-            "class A {",
-            "  int bad( arg a,",  // incomplete method definition
-            "}",
-            "int after;")); // use 'int' instead of 'var' because it is harder to recover to
-    DartFieldDefinition before = (DartFieldDefinition)unit.getTopLevelNodes().get(0);
-    assertEquals("before", before.getFields().get(0).getName().getName());
-    DartClass A = (DartClass)unit.getTopLevelNodes().get(1);
-    assertEquals("A", A.getClassName());
-    DartMethodDefinition bad = (DartMethodDefinition)A.getMembers().get(0);
-    assertEquals("bad", ((DartIdentifier)bad.getName()).getName());
-    DartFieldDefinition after = (DartFieldDefinition)unit.getTopLevelNodes().get(2);
-    assertEquals("after", after.getFields().get(0).getName().getName());
-    assertEquals("int", ((DartIdentifier)after.getTypeNode().getIdentifier()).getName());
-  }
-
-  public void testRecoveryClassRbrace3() {
-    DartUnit unit = parseUnitUnspecifiedErrors("phony_recovery_class_rbrace3.dart",
-        Joiner.on("\n").join(
-            "var before;",
-            "class A {",
-            "  int bad( arg a, ; complete garbage follows",  // incomplete method definition
-            "}",
-            "int after;")); // use 'int' instead of 'var' because it is harder to recover to
-    DartFieldDefinition before = (DartFieldDefinition)unit.getTopLevelNodes().get(0);
-    assertEquals("before", before.getFields().get(0).getName().getName());
-    DartClass A = (DartClass)unit.getTopLevelNodes().get(1);
-    assertEquals("A", A.getClassName());
-    DartMethodDefinition bad = (DartMethodDefinition)A.getMembers().get(0);
-    assertEquals("bad", ((DartIdentifier)bad.getName()).getName());
-    DartFieldDefinition after = (DartFieldDefinition)unit.getTopLevelNodes().get(2);
-    assertEquals("after", after.getFields().get(0).getName().getName());
-    assertEquals("int", ((DartIdentifier)after.getTypeNode().getIdentifier()).getName());
-  }
-
-  public void testRecoveryClassRbrace4() {
-    DartUnit unit = parseUnitUnspecifiedErrors("phony_recovery_class_rbrace4.dart",
-        Joiner.on("\n").join(
-            "var before;",
-            "class A {",
-            "  int bad(arg a) { junk }; ",  // trailing semicolon
-            "}",
-            "int after;")); // use 'int' instead of 'var' because it is harder to recover to
-    DartFieldDefinition before = (DartFieldDefinition)unit.getTopLevelNodes().get(0);
-    assertEquals("before", before.getFields().get(0).getName().getName());
-    DartClass A = (DartClass)unit.getTopLevelNodes().get(1);
-    assertEquals("A", A.getClassName());
-    DartMethodDefinition bad = (DartMethodDefinition)A.getMembers().get(0);
-    assertEquals("bad", ((DartIdentifier)bad.getName()).getName());
-    DartFieldDefinition after = (DartFieldDefinition)unit.getTopLevelNodes().get(2);
-    assertEquals("after", after.getFields().get(0).getName().getName());
-    assertEquals("int", ((DartIdentifier)after.getTypeNode().getIdentifier()).getName());
-  }
-
-  public void testRecoveryClassRbrace5() {
-    DartUnit unit = parseUnitUnspecifiedErrors("phony_recovery_class_rbrace5.dart",
-        Joiner.on("\n").join(
-            "var before;",
-            "class A {",
-            "  var bad = int foo(arg a) { =  junk }; ",  // jibberish value with trailing semicolon
-            "}",
-            "int after;")); // use 'int' instead of 'var' because it is harder to recover to
-    DartFieldDefinition before = (DartFieldDefinition)unit.getTopLevelNodes().get(0);
-    assertEquals("before", before.getFields().get(0).getName().getName());
-    DartClass A = (DartClass)unit.getTopLevelNodes().get(1);
-    assertEquals("A", A.getClassName());
-    DartFieldDefinition bad = (DartFieldDefinition)A.getMembers().get(0);
-    assertEquals("bad", bad.getFields().get(0).getName().getName());
-    DartFieldDefinition after = (DartFieldDefinition)unit.getTopLevelNodes().get(2);
-    assertEquals("after", after.getFields().get(0).getName().getName());
-    assertEquals("int", ((DartIdentifier)after.getTypeNode().getIdentifier()).getName());
-  }
-
-  public void testRecoveryClassRbrace6() {
-    DartUnit unit = parseUnitUnspecifiedErrors("phony_recovery_class_rbrace6.dart",
-        Joiner.on("\n").join(
-            "var before;",
-            "class A {",
-            "  bad() ",  // incomplete method
-            "}",
-            "int after;")); // use 'int' instead of 'var' because it is harder to recover to
-    DartFieldDefinition before = (DartFieldDefinition)unit.getTopLevelNodes().get(0);
-    assertEquals("before", before.getFields().get(0).getName().getName());
-    DartClass A = (DartClass)unit.getTopLevelNodes().get(1);
-    assertEquals("A", A.getClassName());
-    DartMethodDefinition bad = (DartMethodDefinition)A.getMembers().get(0);
-    assertEquals("bad", ((DartIdentifier)bad.getName()).getName());
-    DartFieldDefinition after = (DartFieldDefinition)unit.getTopLevelNodes().get(2);
-    assertEquals("after", after.getFields().get(0).getName().getName());
-    assertEquals("int", ((DartIdentifier)after.getTypeNode().getIdentifier()).getName());
-  }
-
-  public void testRecoveryClassRbrace7() {
-    DartUnit unit = parseUnitUnspecifiedErrors("phony_recovery_class_rbrace7.dart",
-        Joiner.on("\n").join(
-            "var before;",
-            "class A {",
-            "  bad() }",  // incomplete method
-            "}",
-            "int after;")); // use 'int' instead of 'var' because it is harder to recover to
-    DartFieldDefinition before = (DartFieldDefinition)unit.getTopLevelNodes().get(0);
-    assertEquals("before", before.getFields().get(0).getName().getName());
-    DartClass A = (DartClass)unit.getTopLevelNodes().get(1);
-    assertEquals("A", A.getClassName());
-    DartMethodDefinition bad = (DartMethodDefinition)A.getMembers().get(0);
-    assertEquals("bad", ((DartIdentifier)bad.getName()).getName());
-    DartFieldDefinition after = (DartFieldDefinition)unit.getTopLevelNodes().get(2);
-    assertEquals("after", after.getFields().get(0).getName().getName());
-    assertEquals("int", ((DartIdentifier)after.getTypeNode().getIdentifier()).getName());
-  }
-
-  public void testRecoveryClassRbrace8() {
-    DartUnit unit = parseUnitUnspecifiedErrors("phony_recovery_class_rbrace8.dart",
-        Joiner.on("\n").join(
-            "var before;",
-            "class A {",
-            "  bad( }",  // incomplete method
-            "}",
-            "int after;")); // use 'int' instead of 'var' because it is harder to recover to
-    DartFieldDefinition before = (DartFieldDefinition)unit.getTopLevelNodes().get(0);
-    assertEquals("before", before.getFields().get(0).getName().getName());
-    DartClass A = (DartClass)unit.getTopLevelNodes().get(1);
-    assertEquals("A", A.getClassName());
-    DartMethodDefinition bad = (DartMethodDefinition)A.getMembers().get(0);
-    assertEquals("bad", ((DartIdentifier)bad.getName()).getName());
-    DartFieldDefinition after = (DartFieldDefinition)unit.getTopLevelNodes().get(2);
-    assertEquals("after", after.getFields().get(0).getName().getName());
-    assertEquals("int", ((DartIdentifier)after.getTypeNode().getIdentifier()).getName());
-  }
-
-  public void testRecoveryClassRbrace9() {
-    DartUnit unit = parseUnitUnspecifiedErrors("phony_recovery_class_rbrace9.dart",
-        Joiner.on("\n").join(
-            "var before;",
-            "class A {",
-            "  bad",  // incomplete declaration
-            "}",
-            "int after;")); // use 'int' instead of 'var' because it is harder to recover to
-    DartFieldDefinition before = (DartFieldDefinition)unit.getTopLevelNodes().get(0);
-    assertEquals("before", before.getFields().get(0).getName().getName());
-    DartClass A = (DartClass)unit.getTopLevelNodes().get(1);
-    assertEquals("A", A.getClassName());
-    DartMethodDefinition bad = (DartMethodDefinition)A.getMembers().get(0);
-    assertNotNull(bad);
-   // assertEquals("bad", ((DartIdentifier)bad.getName()).getName());
-    DartFieldDefinition after = (DartFieldDefinition)unit.getTopLevelNodes().get(2);
-    assertEquals("after", after.getFields().get(0).getName().getName());
-    assertEquals("int", ((DartIdentifier)after.getTypeNode().getIdentifier()).getName());
-  }
-
-  public void testRecoveryClassRbrace10() {
-    DartUnit unit = parseUnitUnspecifiedErrors("phony_recovery_class_rbrace10.dart",
-        Joiner.on("\n").join(
-            "var before;",
-            "class A {",
-            "  void",  // incomplete declaration
-            "}",
-            "int after;")); // use 'int' instead of 'var' because it is harder to recover to
-    DartFieldDefinition before = (DartFieldDefinition)unit.getTopLevelNodes().get(0);
-    assertEquals("before", before.getFields().get(0).getName().getName());
-    DartClass A = (DartClass)unit.getTopLevelNodes().get(1);
-    assertEquals("A", A.getClassName());
-    DartFieldDefinition after = (DartFieldDefinition)unit.getTopLevelNodes().get(2);
-    assertEquals("after", after.getFields().get(0).getName().getName());
-    assertEquals("int", ((DartIdentifier)after.getTypeNode().getIdentifier()).getName());
-  }
-
-  public void testRecoveryClassRbrace11() {
-    DartUnit unit = parseUnitUnspecifiedErrors("phony_recovery_class_rbrace11.dart",
-        Joiner.on("\n").join(
-            "var before;",
-            "class A {",
-            "  const",  // incomplete declaration
-            "}",
-            "int after;")); // use 'int' instead of 'var' because it is harder to recover to
-    DartFieldDefinition before = (DartFieldDefinition)unit.getTopLevelNodes().get(0);
-    assertEquals("before", before.getFields().get(0).getName().getName());
-    DartClass A = (DartClass)unit.getTopLevelNodes().get(1);
-    assertEquals("A", A.getClassName());
-    DartFieldDefinition after = (DartFieldDefinition)unit.getTopLevelNodes().get(2);
-    assertEquals("after", after.getFields().get(0).getName().getName());
-    assertEquals("int", ((DartIdentifier)after.getTypeNode().getIdentifier()).getName());
-  }
-
-  public void testRecoveryClassRbrace12() {
-    DartUnit unit = parseUnitUnspecifiedErrors("phony_recovery_class_rbrace12.dart",
-        Joiner.on("\n").join(
-            "var before;",
-            "class A {",
-            "  ;;;;",  // stray semicolons
-            "}",
-            "int after;")); // use 'int' instead of 'var' because it is harder to recover to
-    DartFieldDefinition before = (DartFieldDefinition)unit.getTopLevelNodes().get(0);
-    assertEquals("before", before.getFields().get(0).getName().getName());
-    DartClass A = (DartClass)unit.getTopLevelNodes().get(1);
-    assertEquals("A", A.getClassName());
-    DartFieldDefinition after = (DartFieldDefinition)unit.getTopLevelNodes().get(2);
-    assertEquals("after", after.getFields().get(0).getName().getName());
-    assertEquals("int", ((DartIdentifier)after.getTypeNode().getIdentifier()).getName());
-  }
-
-  public void testRecoveryBeforeIf1() {
-    DartUnit unit = parseUnitUnspecifiedErrors(
-        "phony_recovery_before_if1.dart",
-        Joiner.on("\n").join("method() {",
-            "  var before;",
-            "  bad.",
-            "  if (false) {}",
-            "  int after;", // use 'int' instead of 'var' because it is harder to recover to
-            "}"));
-    DartMethodDefinition method = (DartMethodDefinition) unit.getTopLevelNodes().get(0);
-    List<DartStatement> statements = method.getFunction().getBody().getStatements();
-    DartVariable before = ((DartVariableStatement) statements.get(0)).getVariables().get(0);
-    assertEquals("before", before.getName().getName());
-    DartPropertyAccess bad = (DartPropertyAccess) ((DartExprStmt) statements.get(1)).getExpression();
-    assertEquals("bad", ((DartIdentifier) bad.getQualifier()).getName());
-    DartIfStatement ifStatement = (DartIfStatement) statements.get(2);
-    assertEquals(false, ((DartBooleanLiteral)ifStatement.getCondition()).getValue());
-    DartVariable after = ((DartVariableStatement) statements.get(3)).getVariables().get(0);
-    assertEquals("after", after.getName().getName());
-  }
-
-  public void testRecoveryBeforeIf2() {
-    DartUnit unit = parseUnitUnspecifiedErrors(
-        "phony_recovery_before_if2.dart",
-        Joiner.on("\n").join("method() {",
-            "  var before;",
-            "  bad",
-            "  if (false) {}",
-            "  int after;", // use 'int' instead of 'var' because it is harder to recover to
-            "}"));
-    DartMethodDefinition method = (DartMethodDefinition) unit.getTopLevelNodes().get(0);
-    List<DartStatement> statements = method.getFunction().getBody().getStatements();
-    DartVariable before = ((DartVariableStatement) statements.get(0)).getVariables().get(0);
-    assertEquals("before", before.getName().getName());
-    DartIdentifier bad = (DartIdentifier) ((DartExprStmt) statements.get(1)).getExpression();
-    assertEquals("bad", bad.getName());
-    DartIfStatement ifStatement = (DartIfStatement) statements.get(2);
-    assertEquals(false, ((DartBooleanLiteral)ifStatement.getCondition()).getValue());
-    DartVariable after = ((DartVariableStatement) statements.get(3)).getVariables().get(0);
-    assertEquals("after", after.getName().getName());
-  }
-
-  public void testRecoveryBeforeSwitch1() {
-    DartUnit unit = parseUnitUnspecifiedErrors(
-        "phony_recovery_before_switch1.dart",
-        Joiner.on("\n").join("method() {",
-            "  var before;",
-            "  bad.",
-            "  switch (false) {}",
-            "  int after;", // use 'int' instead of 'var' because it is harder to recover to
-            "}"));
-    DartMethodDefinition method = (DartMethodDefinition) unit.getTopLevelNodes().get(0);
-    List<DartStatement> statements = method.getFunction().getBody().getStatements();
-    DartVariable before = ((DartVariableStatement) statements.get(0)).getVariables().get(0);
-    assertEquals("before", before.getName().getName());
-    DartPropertyAccess bad = (DartPropertyAccess) ((DartExprStmt) statements.get(1)).getExpression();
-    assertEquals("bad", ((DartIdentifier) bad.getQualifier()).getName());
-    DartSwitchStatement switchStatement = (DartSwitchStatement) statements.get(2);
-    assertEquals(false, ((DartBooleanLiteral)switchStatement.getExpression()).getValue());
-    DartVariable after = ((DartVariableStatement) statements.get(3)).getVariables().get(0);
-    assertEquals("after", after.getName().getName());
-  }
-
-  public void testRecoveryBeforeSwitch2() {
-    DartUnit unit = parseUnitUnspecifiedErrors(
-        "phony_recovery_before_switch2.dart",
-        Joiner.on("\n").join("method() {",
-            "  var before;",
-            "  bad",
-            "  switch (false) {}",
-            "  int after;", // use 'int' instead of 'var' because it is harder to recover to
-            "}"));
-    DartMethodDefinition method = (DartMethodDefinition) unit.getTopLevelNodes().get(0);
-    List<DartStatement> statements = method.getFunction().getBody().getStatements();
-    DartVariable before = ((DartVariableStatement) statements.get(0)).getVariables().get(0);
-    assertEquals("before", before.getName().getName());
-    DartIdentifier bad = (DartIdentifier) ((DartExprStmt) statements.get(1)).getExpression();
-    assertEquals("bad", bad.getName());
-    DartSwitchStatement switchStatement = (DartSwitchStatement) statements.get(2);
-    assertEquals(false, ((DartBooleanLiteral)switchStatement.getExpression()).getValue());
-    DartVariable after = ((DartVariableStatement) statements.get(3)).getVariables().get(0);
-    assertEquals("after", after.getName().getName());
-  }
-
-  public void testRecoveryBeforeWhile1() {
-    DartUnit unit = parseUnitUnspecifiedErrors(
-        "phony_recovery_before_while1.dart",
-        Joiner.on("\n").join("method() {",
-            "  var before;",
-            "  bad.",
-            "  while (false) {}",
-            "  int after;", // use 'int' instead of 'var' because it is harder to recover to
-            "}"));
-    DartMethodDefinition method = (DartMethodDefinition) unit.getTopLevelNodes().get(0);
-    List<DartStatement> statements = method.getFunction().getBody().getStatements();
-    DartVariable before = ((DartVariableStatement) statements.get(0)).getVariables().get(0);
-    assertEquals("before", before.getName().getName());
-    DartPropertyAccess bad = (DartPropertyAccess) ((DartExprStmt) statements.get(1)).getExpression();
-    assertEquals("bad", ((DartIdentifier) bad.getQualifier()).getName());
-    DartWhileStatement whileStatement = (DartWhileStatement) statements.get(2);
-    assertEquals(false, ((DartBooleanLiteral)whileStatement.getCondition()).getValue());
-    DartVariable after = ((DartVariableStatement) statements.get(3)).getVariables().get(0);
-    assertEquals("after", after.getName().getName());
-  }
-
-  public void testRecoveryBeforeWhile2() {
-    DartUnit unit = parseUnitUnspecifiedErrors(
-        "phony_recovery_before_while2.dart",
-        Joiner.on("\n").join("method() {",
-            "  var before;",
-            "  bad",
-            "  while (false) {}",
-            "  int after;", // use 'int' instead of 'var' because it is harder to recover to
-            "}"));
-    DartMethodDefinition method = (DartMethodDefinition) unit.getTopLevelNodes().get(0);
-    List<DartStatement> statements = method.getFunction().getBody().getStatements();
-    DartVariable before = ((DartVariableStatement) statements.get(0)).getVariables().get(0);
-    assertEquals("before", before.getName().getName());
-    DartIdentifier bad = ((DartIdentifier)((DartExprStmt) statements.get(1)).getExpression());
-    assertEquals("bad", bad.getName());
-    DartWhileStatement whileStatement = (DartWhileStatement) statements.get(2);
-    assertEquals(false, ((DartBooleanLiteral)whileStatement.getCondition()).getValue());
-    DartVariable after = ((DartVariableStatement) statements.get(3)).getVariables().get(0);
-    assertEquals("after", after.getName().getName());
-  }
-
-  public void testRecoveryBeforeDo1() {
-    DartUnit unit = parseUnitUnspecifiedErrors(
-        "phony_recovery_before_do1.dart",
-        Joiner.on("\n").join("method() {",
-            "  var before;",
-            "  bad.",
-            "  do {} while (false);",
-            "  int after;", // use 'int' instead of 'var' because it is harder to recover to
-            "}"));
-    DartMethodDefinition method = (DartMethodDefinition) unit.getTopLevelNodes().get(0);
-    List<DartStatement> statements = method.getFunction().getBody().getStatements();
-    DartVariable before = ((DartVariableStatement) statements.get(0)).getVariables().get(0);
-    assertEquals("before", before.getName().getName());
-    DartPropertyAccess bad = (DartPropertyAccess) ((DartExprStmt) statements.get(1)).getExpression();
-    assertEquals("bad", ((DartIdentifier) bad.getQualifier()).getName());
-    DartDoWhileStatement doStatement = (DartDoWhileStatement) statements.get(2);
-    assertEquals(false, ((DartBooleanLiteral)doStatement.getCondition()).getValue());
-    DartVariable after = ((DartVariableStatement) statements.get(3)).getVariables().get(0);
-    assertEquals("after", after.getName().getName());
-  }
-
-  public void testRecoveryBeforeDo2() {
-    DartUnit unit = parseUnitUnspecifiedErrors(
-        "phony_recovery_before_do2.dart",
-        Joiner.on("\n").join("method() {",
-            "  var before;",
-            "  bad",
-            "  do {} while (false);",
-            "  int after;", // use 'int' instead of 'var' because it is harder to recover to
-            "}"));
-    DartMethodDefinition method = (DartMethodDefinition) unit.getTopLevelNodes().get(0);
-    List<DartStatement> statements = method.getFunction().getBody().getStatements();
-    DartVariable before = ((DartVariableStatement) statements.get(0)).getVariables().get(0);
-    assertEquals("before", before.getName().getName());
-    DartIdentifier bad = (DartIdentifier) ((DartExprStmt) statements.get(1)).getExpression();
-    assertEquals("bad", bad.getName());
-    DartDoWhileStatement doStatement = (DartDoWhileStatement) statements.get(2);
-    assertEquals(false, ((DartBooleanLiteral)doStatement.getCondition()).getValue());
-    DartVariable after = ((DartVariableStatement) statements.get(3)).getVariables().get(0);
-    assertEquals("after", after.getName().getName());
-  }
-
-  public void testRecoveryBeforeFor1() {
-    DartUnit unit = parseUnitUnspecifiedErrors(
-        "phony_recovery_before_for1.dart",
-        Joiner.on("\n").join("method() {",
-            "  var before;",
-            "  bad.",
-            "  for(var i in []) {}",
-            "  int after;", // use 'int' instead of 'var' because it is harder to recover to
-            "}"));
-    DartMethodDefinition method = (DartMethodDefinition) unit.getTopLevelNodes().get(0);
-    List<DartStatement> statements = method.getFunction().getBody().getStatements();
-    DartVariable before = ((DartVariableStatement) statements.get(0)).getVariables().get(0);
-    assertEquals("before", before.getName().getName());
-    DartPropertyAccess bad = (DartPropertyAccess) ((DartExprStmt) statements.get(1)).getExpression();
-    assertEquals("bad", ((DartIdentifier) bad.getQualifier()).getName());
-    DartForInStatement forInStatement = (DartForInStatement) statements.get(2);
-    assertEquals("i", forInStatement.getVariableStatement()
-        .getVariables().get(0).getName().getName());
-    DartVariable after = ((DartVariableStatement) statements.get(3)).getVariables().get(0);
-    assertEquals("after", after.getName().getName());
-  }
-
-  public void testRecoveryBeforeFor2() {
-    DartUnit unit = parseUnitUnspecifiedErrors(
-        "phony_recovery_before_for2.dart",
-        Joiner.on("\n").join("method() {",
-            "  var before;",
-            "  bad.",
-            "  for(var i = 0 ; i < 1 ; i++) {}",
-            "  int after;", // use 'int' instead of 'var' because it is harder to recover to
-            "}"));
-    DartMethodDefinition method = (DartMethodDefinition) unit.getTopLevelNodes().get(0);
-    List<DartStatement> statements = method.getFunction().getBody().getStatements();
-    DartVariable before = ((DartVariableStatement) statements.get(0)).getVariables().get(0);
-    assertEquals("before", before.getName().getName());
-    DartPropertyAccess bad = (DartPropertyAccess) ((DartExprStmt) statements.get(1)).getExpression();
-    assertEquals("bad", ((DartIdentifier) bad.getQualifier()).getName());
-    DartForStatement forStatement = (DartForStatement) statements.get(2);
-    assertEquals("i", ((DartVariableStatement)forStatement.getInit())
-        .getVariables().get(0).getName().getName());
-    DartVariable after = ((DartVariableStatement) statements.get(3)).getVariables().get(0);
-    assertEquals("after", after.getName().getName());
-  }
-
-  public void testRecoveryBeforeVar1() {
-    DartUnit unit = parseUnitUnspecifiedErrors(
-        "phony_recovery_before_var1.dart",
-        Joiner.on("\n").join("method() {",
-            "  var before;",
-            "  bad.",
-            "  var after;",
-            "}"));
-    DartMethodDefinition method = (DartMethodDefinition) unit.getTopLevelNodes().get(0);
-    List<DartStatement> statements = method.getFunction().getBody().getStatements();
-    DartVariable before = ((DartVariableStatement) statements.get(0)).getVariables().get(0);
-    assertEquals("before", before.getName().getName());
-    DartPropertyAccess bad = (DartPropertyAccess) ((DartExprStmt) statements.get(1)).getExpression();
-    assertEquals("bad", ((DartIdentifier) bad.getQualifier()).getName());
-    DartVariable after = ((DartVariableStatement) statements.get(2)).getVariables().get(0);
-    assertEquals("after", after.getName().getName());
-  }
-
-  public void testRecoveryBeforeVar2() {
-    DartUnit unit = parseUnitUnspecifiedErrors(
-        "phony_recovery_before_var2.dart",
-        Joiner.on("\n").join("method() {",
-            "  var before;",
-            "  bad",
-            "  var after;",
-            "}"));
-    DartMethodDefinition method = (DartMethodDefinition) unit.getTopLevelNodes().get(0);
-    List<DartStatement> statements = method.getFunction().getBody().getStatements();
-    DartVariable before = ((DartVariableStatement) statements.get(0)).getVariables().get(0);
-    assertEquals("before", before.getName().getName());
-    DartIdentifier bad = (DartIdentifier) ((DartExprStmt) statements.get(1)).getExpression();
-    assertEquals("bad", bad.getName());
-    DartVariable after = ((DartVariableStatement) statements.get(2)).getVariables().get(0);
-    assertEquals("after", after.getName().getName());
-  }
-
-  public void testRecoveryBeforeFinal1() {
-    DartUnit unit = parseUnitUnspecifiedErrors(
-        "phony_recovery_before_final1.dart",
-        Joiner.on("\n").join("method() {",
-            "  var before;",
-            "  bad.",
-            "  final int after;",
-            "}"));
-    DartMethodDefinition method = (DartMethodDefinition) unit.getTopLevelNodes().get(0);
-    List<DartStatement> statements = method.getFunction().getBody().getStatements();
-    DartVariable before = ((DartVariableStatement) statements.get(0)).getVariables().get(0);
-    assertEquals("before", before.getName().getName());
-    DartPropertyAccess bad = (DartPropertyAccess) ((DartExprStmt) statements.get(1)).getExpression();
-    assertEquals("bad", ((DartIdentifier) bad.getQualifier()).getName());
-    DartVariable after = ((DartVariableStatement) statements.get(2)).getVariables().get(0);
-    assertEquals("after", after.getName().getName());
-    assertTrue(((DartVariableStatement)statements.get(2)).getModifiers().isFinal());
-  }
-
-  public void testRecoveryBeforeFinal2() {
-    DartUnit unit = parseUnitUnspecifiedErrors(
-        "phony_recovery_before_final2.dart",
-        Joiner.on("\n").join("method() {",
-            "  var before;",
-            "  bad",
-            "  final int after;",
-            "}"));
-    DartMethodDefinition method = (DartMethodDefinition) unit.getTopLevelNodes().get(0);
-    List<DartStatement> statements = method.getFunction().getBody().getStatements();
-    DartVariable before = ((DartVariableStatement) statements.get(0)).getVariables().get(0);
-    assertEquals("before", before.getName().getName());
-    DartIdentifier bad = (DartIdentifier) ((DartExprStmt) statements.get(1)).getExpression();
-    assertEquals("bad", bad.getName());
-    DartVariable after = ((DartVariableStatement) statements.get(2)).getVariables().get(0);
-    assertEquals("after", after.getName().getName());
-    assertTrue(((DartVariableStatement)statements.get(2)).getModifiers().isFinal());
-  }
-
-  public void testRecoveryBeforeTry1() {
-    DartUnit unit = parseUnitUnspecifiedErrors(
-        "phony_recovery_before_try1.dart",
-        Joiner.on("\n").join("method() {",
-            "  var before;",
-            "  bad.",
-            "  try {}",
-            "  int after;",
-            "}"));
-    DartMethodDefinition method = (DartMethodDefinition) unit.getTopLevelNodes().get(0);
-    List<DartStatement> statements = method.getFunction().getBody().getStatements();
-    DartVariable before = ((DartVariableStatement) statements.get(0)).getVariables().get(0);
-    assertEquals("before", before.getName().getName());
-    DartPropertyAccess bad = (DartPropertyAccess) ((DartExprStmt) statements.get(1)).getExpression();
-    assertEquals("bad", ((DartIdentifier) bad.getQualifier()).getName());
-    DartTryStatement tryStatement = (DartTryStatement) statements.get(2);
-    assertEquals(0, tryStatement.getTryBlock().getStatements().size());
-    DartVariable after = ((DartVariableStatement) statements.get(3)).getVariables().get(0);
-    assertEquals("after", after.getName().getName());
-  }
-
-  public void testRecoveryBeforeTry2() {
-    DartUnit unit = parseUnitUnspecifiedErrors(
-        "phony_recovery_before_try1.dart",
-        Joiner.on("\n").join("method() {",
-            "  var before;",
-            "  bad",
-            "  try {}",
-            "  int after;",
-            "}"));
-    DartMethodDefinition method = (DartMethodDefinition) unit.getTopLevelNodes().get(0);
-    List<DartStatement> statements = method.getFunction().getBody().getStatements();
-    DartVariable before = ((DartVariableStatement) statements.get(0)).getVariables().get(0);
-    assertEquals("before", before.getName().getName());
-    DartIdentifier bad = (DartIdentifier) ((DartExprStmt) statements.get(1)).getExpression();
-    assertEquals("bad", bad.getName());
-    DartTryStatement tryStatement = (DartTryStatement) statements.get(2);
-    assertEquals(0, tryStatement.getTryBlock().getStatements().size());
-    DartVariable after = ((DartVariableStatement) statements.get(3)).getVariables().get(0);
-    assertEquals("after", after.getName().getName());
-  }
-
-  public void testRecoveryBeforeContinue1() {
-    DartUnit unit = parseUnitUnspecifiedErrors(
-        "phony_recovery_before_continue1.dart",
-        Joiner.on("\n").join("method() {",
-            "  var before;",
-            "  bad.",
-            "  continue;",  // Not really legal here, but the parser doesn't know.
-            "  int after;",
-            "}"));
-    DartMethodDefinition method = (DartMethodDefinition) unit.getTopLevelNodes().get(0);
-    List<DartStatement> statements = method.getFunction().getBody().getStatements();
-    DartVariable before = ((DartVariableStatement) statements.get(0)).getVariables().get(0);
-    assertEquals("before", before.getName().getName());
-    DartPropertyAccess bad = (DartPropertyAccess) ((DartExprStmt) statements.get(1)).getExpression();
-    assertEquals("bad", ((DartIdentifier) bad.getQualifier()).getName());
-    DartContinueStatement continueStatement = (DartContinueStatement) statements.get(2);
-    assertNull(continueStatement.getTargetName());
-    DartVariable after = ((DartVariableStatement) statements.get(3)).getVariables().get(0);
-    assertEquals("after", after.getName().getName());
-  }
-
-  public void testRecoveryBeforeContinue2() {
-    DartUnit unit = parseUnitUnspecifiedErrors(
-        "phony_recovery_before_continue2.dart",
-        Joiner.on("\n").join("method() {",
-            "  var before;",
-            "  bad",
-            "  continue;",  // Not really legal here, but the parser doesn't know.
-            "  int after;",
-            "}"));
-    DartMethodDefinition method = (DartMethodDefinition) unit.getTopLevelNodes().get(0);
-    List<DartStatement> statements = method.getFunction().getBody().getStatements();
-    DartVariable before = ((DartVariableStatement) statements.get(0)).getVariables().get(0);
-    assertEquals("before", before.getName().getName());
-    DartIdentifier bad = (DartIdentifier) ((DartExprStmt) statements.get(1)).getExpression();
-    assertEquals("bad", bad.getName());
-    DartContinueStatement continueStatement = (DartContinueStatement) statements.get(2);
-    assertNull(continueStatement.getTargetName());
-    DartVariable after = ((DartVariableStatement) statements.get(3)).getVariables().get(0);
-    assertEquals("after", after.getName().getName());
-  }
-
-  public void testRecoveryBeforeBreak1() {
-    DartUnit unit = parseUnitUnspecifiedErrors(
-        "phony_recovery_before_break1.dart",
-        Joiner.on("\n").join("method() {",
-            "  var before;",
-            "  bad.",
-            "  break;",  // Not really legal here, but the parser doesn't know.
-            "  int after;",
-            "}"));
-    DartMethodDefinition method = (DartMethodDefinition) unit.getTopLevelNodes().get(0);
-    List<DartStatement> statements = method.getFunction().getBody().getStatements();
-    DartVariable before = ((DartVariableStatement) statements.get(0)).getVariables().get(0);
-    assertEquals("before", before.getName().getName());
-    DartPropertyAccess bad = (DartPropertyAccess) ((DartExprStmt) statements.get(1)).getExpression();
-    assertEquals("bad", ((DartIdentifier) bad.getQualifier()).getName());
-    DartBreakStatement breakStatement = (DartBreakStatement) statements.get(2);
-    assertNull(breakStatement.getTargetName());
-    DartVariable after = ((DartVariableStatement) statements.get(3)).getVariables().get(0);
-    assertEquals("after", after.getName().getName());
-  }
-
-  public void testRecoveryBeforeBreak2() {
-    DartUnit unit = parseUnitUnspecifiedErrors(
-        "phony_recovery_before_break2.dart",
-        Joiner.on("\n").join("method() {",
-            "  var before;",
-            "  bad",
-            "  break;",  // Not really legal here, but the parser doesn't know.
-            "  int after;",
-            "}"));
-    DartMethodDefinition method = (DartMethodDefinition) unit.getTopLevelNodes().get(0);
-    List<DartStatement> statements = method.getFunction().getBody().getStatements();
-    DartVariable before = ((DartVariableStatement) statements.get(0)).getVariables().get(0);
-    assertEquals("before", before.getName().getName());
-    DartIdentifier bad = (DartIdentifier) ((DartExprStmt) statements.get(1)).getExpression();
-    assertEquals("bad", bad.getName());
-    DartBreakStatement breakStatement = (DartBreakStatement) statements.get(2);
-    assertNull(breakStatement.getTargetName());
-    DartVariable after = ((DartVariableStatement) statements.get(3)).getVariables().get(0);
-    assertEquals("after", after.getName().getName());
-  }
-
-  public void testRecoveryBeforeReturn1() {
-    DartUnit unit = parseUnitUnspecifiedErrors(
-        "phony_recovery_before_break1.dart",
-        Joiner.on("\n").join(
-            "int method() {",
-            "  var before;",
-            "  bad.",
-            "  return 1;",
-            "  int after;",  // Never reached, but the parser doesn't know.
-            "}"));
-    DartMethodDefinition method = (DartMethodDefinition) unit.getTopLevelNodes().get(0);
-    List<DartStatement> statements = method.getFunction().getBody().getStatements();
-    DartVariable before = ((DartVariableStatement) statements.get(0)).getVariables().get(0);
-    assertEquals("before", before.getName().getName());
-    DartPropertyAccess bad = (DartPropertyAccess) ((DartExprStmt) statements.get(1)).getExpression();
-    assertEquals("bad", ((DartIdentifier) bad.getQualifier()).getName());
-    DartReturnStatement returnStatement = (DartReturnStatement) statements.get(2);
-    assertEquals(BigInteger.valueOf(1), ((DartIntegerLiteral)returnStatement.getValue()).getValue());
-    DartVariable after = ((DartVariableStatement) statements.get(3)).getVariables().get(0);
-    assertEquals("after", after.getName().getName());
-  }
-
-  public void testRecoveryBeforeReturn2() {
-    DartUnit unit = parseUnitUnspecifiedErrors(
-        "phony_recovery_before_break1.dart",
-        Joiner.on("\n").join(
-            "int method() {",
-            "  var before;",
-            "  bad",
-            "  return 1;",
-            "  int after;",  // Never reached, but the parser doesn't know.
-            "}"));
-    DartMethodDefinition method = (DartMethodDefinition) unit.getTopLevelNodes().get(0);
-    List<DartStatement> statements = method.getFunction().getBody().getStatements();
-    DartVariable before = ((DartVariableStatement) statements.get(0)).getVariables().get(0);
-    assertEquals("before", before.getName().getName());
-    DartIdentifier bad = (DartIdentifier) ((DartExprStmt) statements.get(1)).getExpression();
-    assertEquals("bad", bad.getName());
-    DartReturnStatement returnStatement = (DartReturnStatement) statements.get(2);
-    assertEquals(BigInteger.valueOf(1), ((DartIntegerLiteral)returnStatement.getValue()).getValue());
-    DartVariable after = ((DartVariableStatement) statements.get(3)).getVariables().get(0);
-    assertEquals("after", after.getName().getName());
-  }
-
-  public void testRecoveryBeforeThrow1() {
-    DartUnit unit = parseUnitUnspecifiedErrors(
-        "phony_recovery_before_break1.dart",
-        Joiner.on("\n").join(
-            "int method() {",
-            "  var before;",
-            "  bad.",
-            "  throw new Exception();",
-            "  int after;",  // Never reached, but the parser doesn't know.
-            "}"));
-    DartMethodDefinition method = (DartMethodDefinition) unit.getTopLevelNodes().get(0);
-    List<DartStatement> statements = method.getFunction().getBody().getStatements();
-    DartVariable before = ((DartVariableStatement) statements.get(0)).getVariables().get(0);
-    assertEquals("before", before.getName().getName());
-    DartPropertyAccess bad = (DartPropertyAccess) ((DartExprStmt) statements.get(1)).getExpression();
-    assertEquals("bad", ((DartIdentifier) bad.getQualifier()).getName());
-    DartThrowExpression throwStatement = (DartThrowExpression) ((DartExprStmt) statements.get(2)).getExpression();
-    assertNotNull(throwStatement);
-    DartVariable after = ((DartVariableStatement) statements.get(3)).getVariables().get(0);
-    assertEquals("after", after.getName().getName());
-  }
-
-  public void testRecoveryBeforeThrow2() {
-    DartUnit unit = parseUnitUnspecifiedErrors(
-        "phony_recovery_before_break2.dart",
-        Joiner.on("\n").join(
-            "int method() {",
-            "  var before;",
-            "  bad",
-            "  throw new Exception();",
-            "  int after;",  // Never reached, but the parser doesn't know.
-            "}"));
-    DartMethodDefinition method = (DartMethodDefinition) unit.getTopLevelNodes().get(0);
-    List<DartStatement> statements = method.getFunction().getBody().getStatements();
-    DartVariable before = ((DartVariableStatement) statements.get(0)).getVariables().get(0);
-    assertEquals("before", before.getName().getName());
-    DartIdentifier bad = (DartIdentifier)((DartExprStmt) statements.get(1)).getExpression();
-    assertEquals("bad", bad.getName());
-    DartThrowExpression throwStatement = (DartThrowExpression) ((DartExprStmt) statements.get(2)).getExpression();
-    assertNotNull(throwStatement);
-    DartVariable after = ((DartVariableStatement) statements.get(3)).getVariables().get(0);
-    assertEquals("after", after.getName().getName());
-  }
-}
diff --git a/compiler/javatests/com/google/dart/compiler/parser/ParserRoundTripTest.java b/compiler/javatests/com/google/dart/compiler/parser/ParserRoundTripTest.java
deleted file mode 100644
index 88d1ba0..0000000
--- a/compiler/javatests/com/google/dart/compiler/parser/ParserRoundTripTest.java
+++ /dev/null
@@ -1,74 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.parser;
-
-import com.google.dart.compiler.CompilerTestCase;
-import com.google.dart.compiler.ast.DartToSourceVisitor;
-import com.google.dart.compiler.ast.DartUnit;
-
-/**
- * Tests, for each of the parser test examples, that {@link DartToSourceVisitor} produces
- * something parseable. It's an imperfect test, as it doesn't account for semantic changes,
- * but it catches a lot of common problems.
- */
-public class ParserRoundTripTest extends CompilerTestCase {
-
-  public void testClasses() {
-    roundTrip("ClassesInterfaces.dart");
-  }
-
-  public void testMethodSignatures() {
-    roundTrip("MethodSignatures.dart");
-  }
-
-  public void testFunctionTypes() {
-    roundTrip("FunctionTypes.dart");
-  }
-
-  public void testFormalParameters() {
-    roundTrip("FormalParameters.dart");
-  }
-
-  public void testSuperCalls() {
-    roundTrip("SuperCalls.dart");
-  }
-
-  public void testGenericTypes() {
-    roundTrip("GenericTypes.dart");
-  }
-
-  public void testShifting() {
-    roundTrip("Shifting.dart");
-  }
-
-  public void testFunctionInterfaces() {
-    roundTrip("FunctionInterfaces.dart");
-  }
-
-  public void testStringBuffer() {
-    roundTrip("StringBuffer.dart");
-  }
-
-  public void testListObjectLiterals() {
-    roundTrip("ListObjectLiterals.dart");
-  }
-
-  public void testCatchFinally() {
-    roundTrip("CatchFinally.dart");
-  }
-
-  public void testStrings() {
-    roundTrip("Strings.dart");
-  }
-
-  /**
-   * Ensures that a unit can be parsed, re-serialized, and re-parsed without error.
-   */
-  private void roundTrip(String path) {
-    DartUnit unit = parseUnit(path);
-    String src = unit.toSource();
-    parseUnit(path, src);
-  }
-}
diff --git a/compiler/javatests/com/google/dart/compiler/parser/ParserTests.java b/compiler/javatests/com/google/dart/compiler/parser/ParserTests.java
deleted file mode 100644
index 4cb0ea7..0000000
--- a/compiler/javatests/com/google/dart/compiler/parser/ParserTests.java
+++ /dev/null
@@ -1,36 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.parser;
-
-import junit.extensions.TestSetup;
-import junit.framework.Test;
-import junit.framework.TestSuite;
-
-public class ParserTests extends TestSetup {
-
-  public ParserTests(TestSuite test) {
-    super(test);
-  }
-
-  public static Test suite() {
-    TestSuite suite = new TestSuite("Dart parser test suite.");
-
-    suite.addTestSuite(SyntaxTest.class);
-    //diet-parsing is used only for incremental compilation which is turned off
-    //(and this test causes intermittent timeouts)
-    //suite.addTestSuite(DietParserTest.class);
-    suite.addTestSuite(CPParserTest.class);
-    suite.addTestSuite(ParserRoundTripTest.class);
-    suite.addTestSuite(LibraryParserTest.class);
-    suite.addTestSuite(NegativeParserTest.class);
-    suite.addTestSuite(ValidatingSyntaxTest.class);
-    suite.addTestSuite(CommentTest.class);
-    suite.addTestSuite(ErrorMessageLocationTest.class);
-    suite.addTestSuite(ParserEventsTest.class);
-    suite.addTestSuite(TruncatedSourceParserTest.class);
-    suite.addTestSuite(ParserRecoveryTest.class);
-    return new ParserTests(suite);
-  }
-}
diff --git a/compiler/javatests/com/google/dart/compiler/parser/QualifiedReturnTypeA.dart b/compiler/javatests/com/google/dart/compiler/parser/QualifiedReturnTypeA.dart
deleted file mode 100644
index 2e2439c..0000000
--- a/compiler/javatests/com/google/dart/compiler/parser/QualifiedReturnTypeA.dart
+++ /dev/null
@@ -1,2 +0,0 @@
-class A {
-}
diff --git a/compiler/javatests/com/google/dart/compiler/parser/QualifiedReturnTypeB.dart b/compiler/javatests/com/google/dart/compiler/parser/QualifiedReturnTypeB.dart
deleted file mode 100644
index 6920e83..0000000
--- a/compiler/javatests/com/google/dart/compiler/parser/QualifiedReturnTypeB.dart
+++ /dev/null
@@ -1,8 +0,0 @@
-library test;
-import "QualifiedReturnTypeA.dart" as pref;
-
-class A {
-  pref.A foo() {
-    return new pref.A();
-  }
-}
diff --git a/compiler/javatests/com/google/dart/compiler/parser/RedirectedConstructor.dart b/compiler/javatests/com/google/dart/compiler/parser/RedirectedConstructor.dart
deleted file mode 100644
index 5095a5c..0000000
--- a/compiler/javatests/com/google/dart/compiler/parser/RedirectedConstructor.dart
+++ /dev/null
@@ -1,34 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-class Simple {
-    int x;
-    Simple(this.x) { }
-    Simple.foo(x,y) : this(x + y);
-    Simple.bar(x,y,z) : this.foo(x + y, z);
-}
-
-class Point {
-  final num x;
-  final num y;
-  Point() : this.coord(0, 0); // Redirects to Point.coord.
-  Point.coord(this.x, this.y) {}
-}
-
-class A {
-  var x;
-  A() : this.named(499);
-  A.named(this.x) {}
-}
-
-class B extends A {
-  B() : super() {}
-}
-
-class C {
-  int x;
-  const C() : this.x = 123;
-  C.foo() : this();
-}
-
diff --git a/compiler/javatests/com/google/dart/compiler/parser/Shifting.dart b/compiler/javatests/com/google/dart/compiler/parser/Shifting.dart
deleted file mode 100644
index c345c66..0000000
--- a/compiler/javatests/com/google/dart/compiler/parser/Shifting.dart
+++ /dev/null
@@ -1,10 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-class Shifting {
-  operator >>(other) {
-    Box<Box<prefix.Fisk>> foo = null;
-    return other >> 1;
-  }
-}
diff --git a/compiler/javatests/com/google/dart/compiler/parser/StringBuffer.dart b/compiler/javatests/com/google/dart/compiler/parser/StringBuffer.dart
deleted file mode 100644
index 618b469..0000000
--- a/compiler/javatests/com/google/dart/compiler/parser/StringBuffer.dart
+++ /dev/null
@@ -1,89 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-/**
- * The StringBuffer class is useful for concatenating strings
- * efficiently. Only on a call to [toString] are the strings
- * concatenated to a single String.
- */
-class StringBuffer implements OutputStream {
-  /**
-   * Creates the string buffer with an initial content.
-   */
-  StringBuffer([String content = ""]) {
-    clear();
-    append(content);
-  }
-
-  /// From OutputStream. Appends [str] to the buffer.
-  void writeString(String str) {
-    append(str);
-  }
-
-  /// From OutputStream. Appends the [charCode] to the buffer.
-  void writeCharCode(int charCode) {
-    throw "StringBuffer.writeCharCode Unimplemented";
-  }
-
-  void writeByte(int value) {
-    throw "StringBuffer.writeByte unimplemented";
-  }
-
-  void writeByteArray(Array<int> buffer, int offset, int length) {
-    throw "StringBuffer.writeByteArray unimplemented";
-  }
-
-  void close() {}
-  void flush() {}
-
-
-  /**
-   * Returns the length of the buffer.
-   */
-  int get length {
-    return length_;
-  }
-
-  /**
-   * Appends [str] to the buffer.
-   */
-  void append(String str) {
-    if (str == null || str.isEmpty) return;
-    buffer_.add(str);
-    length_ += str.length;
-  }
-
-  /**
-   * Appends all items in [strings] to the buffer.
-   */
-  void appendAll(Collection<String> strings) {
-    strings.forEach((str) { append(str); });
-  }
-
-  /**
-   * Clears the string buffer.
-   */
-  void clear() {
-    buffer_ = new GrowableArray<String>(4);
-    length_ = 0;
-  }
-
-  /**
-   * Returns the contents of buffer as a concatenated string.
-   */
-  String toString() {
-    if (buffer_.length == 0) return "";
-    if (buffer_.length == 1) return buffer_[0];
-    String result = StringBase.concatAll(_buffer);
-    buffer_.clear();
-    buffer_.add(result);
-    // Since we track the length at each append operation, there is no
-    // need to update it in this function.
-    return result;
-  }
-
-  GrowableArray<String> buffer_;
-  int length_;
-  final bool closed = false;
-}
diff --git a/compiler/javatests/com/google/dart/compiler/parser/Strings.dart b/compiler/javatests/com/google/dart/compiler/parser/Strings.dart
deleted file mode 100644
index 9d2b19d..0000000
--- a/compiler/javatests/com/google/dart/compiler/parser/Strings.dart
+++ /dev/null
@@ -1,33 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-class StringsTests {
-  method() {
-    var x;
-    x = "a simple constant";
-    x = 'a simple constant';
-
-    x = "an escaped quote \".";
-    x = 'an escaped quote \'.';
-
-    x = "a new \n line";
-    x = 'a new \n line';
-
-    x = """
-    multiline 1
-    multiline 2
-    """;
-    x = '''
-    multiline 1
-    multiline 2
-    ''';
-
-    x = """multiline 1
-    multiline 2
-    """;
-    x = '''multiline 1
-    multiline 2
-    ''';
-  }
-}
diff --git a/compiler/javatests/com/google/dart/compiler/parser/StringsErrorsNegativeTest.dart b/compiler/javatests/com/google/dart/compiler/parser/StringsErrorsNegativeTest.dart
deleted file mode 100644
index e038c41..0000000
--- a/compiler/javatests/com/google/dart/compiler/parser/StringsErrorsNegativeTest.dart
+++ /dev/null
@@ -1,14 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-class StringsWithErrorsTest {
-  errors() {
-    var x = "unterminated string
-    ; // added to avoid a cascading failure
-    x = 'another unterminated string
-    ; // added to avoid a cascading failure
-    x = r'unterminated raw string
-    ; // added to avoid a cascading failure
-  }
-}
diff --git a/compiler/javatests/com/google/dart/compiler/parser/SuperCalls.dart b/compiler/javatests/com/google/dart/compiler/parser/SuperCalls.dart
deleted file mode 100644
index d5f7fdf..0000000
--- a/compiler/javatests/com/google/dart/compiler/parser/SuperCalls.dart
+++ /dev/null
@@ -1,29 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-class SuperCallSyntax {
-  method() {
-    super.foo();
-    super.foo(1);
-    super.foo(1, 2);
-
-    super.foo().x;
-    super.foo()[42];
-    super.foo().x++;
-
-    super.foo()();
-    super.foo(1, 2)(3, 4);
-
-    var v1 = super.foo();
-    var v2 = super.foo(1);
-    var v3 = super.foo(1, 2);
-
-    var v4 = super.foo().x;
-    var v5 = super.foo()[42];
-    var v6 = super.foo().x++;
-
-    var v7 = super.foo()();
-    var v8 = super.foo(1, 2)(3, 4);
-  }
-}
diff --git a/compiler/javatests/com/google/dart/compiler/parser/SyntaxTest.java b/compiler/javatests/com/google/dart/compiler/parser/SyntaxTest.java
deleted file mode 100644
index d86da20..0000000
--- a/compiler/javatests/com/google/dart/compiler/parser/SyntaxTest.java
+++ /dev/null
@@ -1,1741 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.parser;
-
-import com.google.common.base.Joiner;
-import com.google.dart.compiler.DartCompilerListener;
-import com.google.dart.compiler.DartSourceTest;
-import com.google.dart.compiler.ast.DartAnnotation;
-import com.google.dart.compiler.ast.DartArrayLiteral;
-import com.google.dart.compiler.ast.DartAssertStatement;
-import com.google.dart.compiler.ast.DartBinaryExpression;
-import com.google.dart.compiler.ast.DartBooleanLiteral;
-import com.google.dart.compiler.ast.DartCascadeExpression;
-import com.google.dart.compiler.ast.DartClass;
-import com.google.dart.compiler.ast.DartClassTypeAlias;
-import com.google.dart.compiler.ast.DartComment;
-import com.google.dart.compiler.ast.DartExprStmt;
-import com.google.dart.compiler.ast.DartExpression;
-import com.google.dart.compiler.ast.DartField;
-import com.google.dart.compiler.ast.DartFieldDefinition;
-import com.google.dart.compiler.ast.DartFunctionExpression;
-import com.google.dart.compiler.ast.DartIdentifier;
-import com.google.dart.compiler.ast.DartImportDirective;
-import com.google.dart.compiler.ast.DartIntegerLiteral;
-import com.google.dart.compiler.ast.DartMapLiteral;
-import com.google.dart.compiler.ast.DartMethodDefinition;
-import com.google.dart.compiler.ast.DartNode;
-import com.google.dart.compiler.ast.DartParameter;
-import com.google.dart.compiler.ast.DartPropertyAccess;
-import com.google.dart.compiler.ast.DartStatement;
-import com.google.dart.compiler.ast.DartStringInterpolation;
-import com.google.dart.compiler.ast.DartStringLiteral;
-import com.google.dart.compiler.ast.DartTryStatement;
-import com.google.dart.compiler.ast.DartTypeExpression;
-import com.google.dart.compiler.ast.DartTypeNode;
-import com.google.dart.compiler.ast.DartUnaryExpression;
-import com.google.dart.compiler.ast.DartUnit;
-import com.google.dart.compiler.ast.DartVariable;
-import com.google.dart.compiler.ast.DartVariableStatement;
-import com.google.dart.compiler.ast.NodeList;
-
-import static com.google.dart.compiler.common.ErrorExpectation.assertErrors;
-import static com.google.dart.compiler.common.ErrorExpectation.errEx;
-
-import java.util.List;
-
-public class SyntaxTest extends AbstractParserTest {
-
-  public void test_parseClass_withBeforeExtends() throws Exception {
-    parseUnit("test.dart", Joiner.on("\n").join(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "class A with B extends C {}",
-        ""),
-        ParserErrorCode.WITH_BEFORE_EXTENDS, 2, 9);
-  }
-  
-  public void test_parseClass_implementsBeforeExtends() throws Exception {
-    parseUnit("test.dart", Joiner.on("\n").join(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "class A implements B extends C {}",
-        ""),
-        ParserErrorCode.IMPLEMENTS_BEFORE_EXTENDS, 2, 9);
-  }
-
-  public void test_parseClass_multipleExtends() throws Exception {
-    parseUnit("test.dart", Joiner.on("\n").join(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "class A extends B extends C {}",
-        ""),
-        ParserErrorCode.MULTIPLE_EXTENDS_CLAUSES, 2, 19);
-  }
-  
-  public void test_parseClass_implementsBeforeWith() throws Exception {
-    parseUnit("test.dart", Joiner.on("\n").join(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "class A extends B implements C with D {}",
-        ""),
-        ParserErrorCode.IMPLEMENTS_BEFORE_WITH, 2, 19);
-  }
-
-  public void test_parseClass_multipleWith() throws Exception {
-    parseUnit("test.dart", Joiner.on("\n").join(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "class A extends B with C with D {}",
-        ""),
-        ParserErrorCode.MULTIPLE_WITH_CLAUSES, 2, 26);
-  }
-
-  public void test_parseClass_multipleImplements() throws Exception {
-    parseUnit("test.dart", Joiner.on("\n").join(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "class A implements B implements C {}",
-        ""),
-        ParserErrorCode.MULTIPLE_IMPLEMENTS_CLAUSES, 2, 22);
-  }
-
-  public void test_parseClass_withWithoutExtends() throws Exception {
-    parseUnit("test.dart", Joiner.on("\n").join(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "class A with B, C {}",
-        ""),
-        ParserErrorCode.WITH_WITHOUT_EXTENDS, 2, 9);
-  }
-  
-  public void test_parseClass_with() throws Exception {
-    parseUnit("test.dart", Joiner.on("\n").join(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "class A extends B with C, D {}",
-        ""));
-    DartClass clazz = findNode(DartClass.class, "class A");
-    NodeList<DartTypeNode> mixins = clazz.getMixins();
-    assertEquals(2, mixins.size());
-    assertEquals("C", mixins.get(0).toString());
-    assertEquals("D", mixins.get(1).toString());
-  }
-
-  public void test_parseTypedefMixin() throws Exception {
-    parseUnit(
-        "test.dart",
-        Joiner.on("\n").join(
-            "// filler filler filler filler filler filler filler filler filler filler",
-            "typedef C = A with B;",
-            ""));
-    DartClassTypeAlias typedef = findNode(DartClassTypeAlias.class, "typedef C");
-    assertEquals("A", typedef.getSuperclass().toString());
-    {
-      NodeList<DartTypeNode> mixins = typedef.getMixins();
-      assertEquals(1, mixins.size());
-      assertEquals("B", mixins.get(0).toString());
-    }
-  }
-  
-  public void test_parseTypedefMixin_abstract() throws Exception {
-    parseUnit(
-        "test.dart",
-        Joiner.on("\n").join(
-            "// filler filler filler filler filler filler filler filler filler filler",
-            "typedef C = abstract A with B;",
-            ""));
-    DartClassTypeAlias typedef = findNode(DartClassTypeAlias.class, "typedef C");
-    assertTrue(typedef.getModifiers().isAbstract());
-  }
-
-  /**
-   * <p>
-   * http://code.google.com/p/dart/issues/detail?id=6881
-   */
-  public void test_uri_adjacent() {
-    parseUnit("test.dart", Joiner.on("\n").join(
-        "import 'myLib' '.dart';",
-        ""));
-  }
-  /**
-   * <p>
-   * http://code.google.com/p/dart/issues/detail?id=6881
-   */
-  public void test_uri_interpolation() {
-    parseUnit("test.dart", Joiner.on("\n").join(
-        "import 'my$x' '.dart';",
-        "var a = 'Lib';",
-        ""),
-        ParserErrorCode.URI_CANNOT_USE_INTERPOLATION, 1, 8);
-  }
-
-  public void test_exportDirective_combinators() {
-    parseUnit("test.dart", Joiner.on("\n").join(
-        "library lib;",
-        "export 'a.dart' show A, B hide C, D;"));
-  }
-
-  public void test_exportDirective_noCombinators() {
-    parseUnit("test.dart", Joiner.on("\n").join(
-        "library lib;",
-        "export 'a.dart';"));
-  }
-
-  public void test_hasParseErrors_true() {
-    DartUnit unit = parseSource("garbage").getDartUnit();
-    assertTrue(unit.hasParseErrors());
-  }
-  
-  public void test_hasParseErrors_false() {
-    DartUnit unit = parseSource("// empty").getDartUnit();
-    assertFalse(unit.hasParseErrors());
-  }
-  
-  public void test_importDirective_noUri() {
-    DartUnit unit = parseUnit("test.dart", Joiner.on("\n").join(
-        "library lib;",
-        "import;"),
-        ParserErrorCode.EXPECTED_TOKEN, 2, 7);
-    DartImportDirective dir = (DartImportDirective) unit.getDirectives().get(1);
-    assertEquals("import ;\n", dir.toSource());
-  }
-
-  public void test_switch_noLBrace() {
-    parseUnit("test.dart", Joiner.on("\n").join(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "main() {",
-        "  switch (0)",
-        "}",
-        ""),
-        ParserErrorCode.EXPECTED_TOKEN, 3, 12);
-  }
-  
-  /**
-   * <p>
-   * http://code.google.com/p/dart/issues/detail?id=6825
-   */
-  public void test_annotation_forExport() {
-    parseUnit(
-        "test.dart",
-        Joiner.on("\n").join(
-            "// filler filler filler filler filler filler filler filler filler filler",
-            "library Test;",
-            "",
-            "@meta @meta2 export 'Lib.dart';",
-            ""));
-  }
-
-  /**
-   * There was bug that class instead of case in switch caused infinite parsing loop.
-   * <p>
-   * http://code.google.com/p/dart/issues/detail?id=7999
-   */
-  public void test_switch_class_inCase() {
-    DartParserRunner runner = parseSource(Joiner.on("\n").join(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "void main() {",
-        "  print((e) {",
-        "    switch (e) {",
-        "      case 'Up': cursor.(); break;",
-        "      class LoopClass { var myData; }",
-        "      case 'Down':",
-        "    }",
-        "  }); ",
-        "}",
-        ""));
-    assertTrue(runner.getErrorCount() > 0);
-  }
-
-  /**
-   * There was bug that handling missing identifier (method name) after "cursor." in switch caused
-   * infinite parsing loop.
-   * <p>
-   * http://code.google.com/p/dart/issues/detail?id=6908
-   */
-  public void test_switch_noMethodName_inCase() {
-    DartParserRunner runner = parseSource(Joiner.on("\n").join(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "void main() {",
-        "  print((e) {",
-        "    switch (e) {",
-        "      case 'Up': cursor.();",
-        "      case 'Down':",
-        "    }",
-        "  }); ",
-        "}",
-        ""));
-    assertErrors(runner.getErrors(),
-        errEx(ParserErrorCode.INVALID_IDENTIFIER, 5, 24, 1));
-  }
-
-  public void test_getter() {
-    parseUnit("getter.dart", Joiner.on("\n").join(
-        "class G {",
-        "  // Old getter syntax",
-        "  int get g1 => 1;",
-        "  // New getter syntax",
-        "  int get g2 => 2;",
-        "}"));
-  }
-
-  public void test_identifier_as() {
-    parseUnit("identifier.dart", Joiner.on("\n").join(
-        "class G {",
-        "  int as = 0;",
-        "}"));
-  }
-  
-  public void test_patch() {
-    DartUnit unit = parseUnit("patch.dart", Joiner.on("\n").join(
-        "patch class A {",
-        "}"));
-    assertEquals(1, unit.getTopLevelNodes().size());
-  }
-
-  public void test_index_literalMap() {
-    parseUnit("test.dart", Joiner.on('\n').join(
-        "main() {",
-        "  try { {'1' : 1, '2' : 2}['1']++; } catch(e) {}",
-        "}"));
-  }
-
-  public void test_redirectingFactoryConstructor_const() {
-    parseUnit("redirecting.dart", Joiner.on("\n").join(
-        "class B {",
-        "  const factory B.n(int x) = A.m;",
-        "}"));
-  }
-
-  public void test_redirectingFactoryConstructor_nonConst() {
-    parseUnit("redirecting.dart", Joiner.on("\n").join(
-        "class B {",
-        "  factory B.n(int x) = A.m;",
-        "}"));
-  }
-
-  public void test_setter() {
-    parseUnit("setter.dart", Joiner.on("\n").join(
-        "class G {",
-        "  void set g1(int v) {}",
-        "}"));
-  }
-
-  public void test_cascade() {
-    parseUnit(
-        "cascade.dart",
-        Joiner.on("\n").join(
-            "// filler filler filler filler filler filler filler filler filler filler",
-            "class C {",
-            "  var f = g..m1()..m2()..f.a;",
-            "  var f = g..[3].x()..y()();",
-            "}"));
-    // test that cascaded invocations have reasonable SourceInfo
-    assertNodeSourceInfo("..m1()");
-    assertNodeSourceInfo("..m2()");
-  }
-
-//  public void test_cascade2() {
-//    DartUnit unit = parseUnit("cascade.dart", Joiner.on("\n").join(
-//        "class A {",
-//        "  B b;",
-//        "}",
-//        "",
-//        "class B {",
-//        "  void m() {}",
-//        "}",
-//        "",
-//        "main() {",
-//        "  A a;",
-//        "  a..b.m()..b.m();",
-//        "}"));
-//    assertNotNull(unit);
-//  }
-
-  public void test_assertStatement() {
-    DartUnit unit = parseUnit("function.dart", Joiner.on("\n").join(
-        "main() {",
-        "  assert(true);",
-        "}"
-    ));
-    assertNotNull(unit);
-    assertEquals(1, unit.getTopLevelNodes().size());
-    DartMethodDefinition function = (DartMethodDefinition) unit.getTopLevelNodes().get(0);
-    assertNotNull(function);
-    DartStatement statement = function.getFunction().getBody().getStatements().get(0);
-    assertTrue(statement instanceof DartAssertStatement);
-    DartExpression expression = ((DartAssertStatement) statement).getCondition();
-    assertTrue(expression instanceof DartBooleanLiteral);
-  }
-  
-  public void test_cascade_withConditionalInside() {
-    DartUnit unit = parseUnit("function.dart", Joiner.on("\n").join(
-        "class A {",
-        "  var name;",
-        "  foo() {}",
-        "}",
-        "",
-        "",
-        "",
-        "main() {",
-        "  A a = new A();",
-        "  a",
-        "    ..name = true ? 'true' : 'false'",
-        "    ..foo();",
-        "}"
-        ));
-    assertNotNull(unit);
-    assertEquals(2, unit.getTopLevelNodes().size());
-    DartMethodDefinition function = (DartMethodDefinition) unit.getTopLevelNodes().get(1);
-    assertNotNull(function);
-    DartStatement statement = function.getFunction().getBody().getStatements().get(1);
-    assertTrue(statement instanceof DartExprStmt);
-    DartCascadeExpression cascade = (DartCascadeExpression) ((DartExprStmt) statement).getExpression();
-    NodeList<DartExpression> cascadeSections = cascade.getCascadeSections();
-    assertEquals(2, cascadeSections.size());
-    assertEquals("..name = true ? \"true\" : \"false\"", cascadeSections.get(0).toString());
-    assertEquals("..foo()", cascadeSections.get(1).toString());
-  }
-  
-  public void test_functionExpression_asStatement() {
-    DartUnit unit = parseUnit("function.dart", Joiner.on("\n").join(
-        "main() {",
-        "  () {};",
-        "}"
-        ));
-    assertNotNull(unit);
-    assertEquals(1, unit.getTopLevelNodes().size());
-    DartMethodDefinition function = (DartMethodDefinition) unit.getTopLevelNodes().get(0);
-    assertNotNull(function);
-    DartStatement statement = function.getFunction().getBody().getStatements().get(0);
-    assertTrue(statement instanceof DartExprStmt);
-    DartExpression expression = ((DartExprStmt) statement).getExpression();
-    assertTrue(expression instanceof DartFunctionExpression);
-  }
-
-  public void test_functionExpression_inIsExpression() {
-    DartUnit unit = parseUnit("function.dart", Joiner.on("\n").join(
-        "main() {",
-        "  (p) {} is String;",
-        "}"
-    ));
-    assertNotNull(unit);
-    assertEquals(1, unit.getTopLevelNodes().size());
-    DartMethodDefinition function = (DartMethodDefinition) unit.getTopLevelNodes().get(0);
-    assertNotNull(function);
-    DartStatement statement = function.getFunction().getBody().getStatements().get(0);
-    assertTrue(statement instanceof DartExprStmt);
-    DartExpression expression = ((DartExprStmt) statement).getExpression();
-    assertTrue(expression instanceof DartBinaryExpression);
-    DartExpression lhs = ((DartBinaryExpression) expression).getArg1();
-    assertTrue(lhs instanceof DartFunctionExpression);
-  }
-
-  public void test_const() {
-    DartUnit unit = parseUnit(getName() + ".dart", makeCode(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "const T1 = 1;",
-        "final T2 = 1;",
-        "class A {",
-        "  const F1 = 2;",
-        "  static final F2 = 2;",
-        "}"));
-    // T1
-    {
-      DartFieldDefinition fieldDefinition = (DartFieldDefinition) unit.getTopLevelNodes().get(0);
-      DartField field = fieldDefinition.getFields().get(0);
-      assertEquals("T1", field.getName().getName());
-      assertEquals(true, field.getModifiers().isConstant());
-      assertEquals(false, field.getModifiers().isStatic());
-      assertEquals(true, field.getModifiers().isFinal());
-    }
-    // T2
-    {
-      DartFieldDefinition fieldDefinition = (DartFieldDefinition) unit.getTopLevelNodes().get(1);
-      DartField field = fieldDefinition.getFields().get(0);
-      assertEquals("T2", field.getName().getName());
-      assertEquals(false, field.getModifiers().isConstant());
-      assertEquals(false, field.getModifiers().isStatic());
-      assertEquals(true, field.getModifiers().isFinal());
-    }
-    // A
-    {
-      DartClass classA = (DartClass) unit.getTopLevelNodes().get(2);
-      // F1
-      {
-        DartFieldDefinition fieldDefinition = (DartFieldDefinition) classA.getMembers().get(0);
-        DartField field = fieldDefinition.getFields().get(0);
-        assertEquals("F1", field.getName().getName());
-        assertEquals(true, field.getModifiers().isConstant());
-        assertEquals(false, field.getModifiers().isStatic());
-        assertEquals(true, field.getModifiers().isFinal());
-      }
-      // F2
-      {
-        DartFieldDefinition fieldDefinition = (DartFieldDefinition) classA.getMembers().get(1);
-        DartField field = fieldDefinition.getFields().get(0);
-        assertEquals("F2", field.getName().getName());
-        assertEquals(false, field.getModifiers().isConstant());
-        assertEquals(true, field.getModifiers().isStatic());
-        assertEquals(true, field.getModifiers().isFinal());
-      }
-    }
-  }
-
-  public void test_constructor_named() {
-    DartUnit unit = parseUnit("test.dart", makeCode(
-        "class A {",
-        "  A.named() {}",
-        "}",
-        "",
-        "class B {",
-        "  factory B() = A.named;",
-        "}"));
-    assertNotNull(unit);
-    DartNode classB = unit.getTopLevelNodes().get(1);
-    assertTrue(classB instanceof DartClass);
-    DartNode member = ((DartClass) classB).getMembers().get(0);
-    assertTrue(member instanceof DartMethodDefinition);
-    DartTypeNode typeName = ((DartMethodDefinition) member).getRedirectedTypeName();
-    assertTrue(typeName.getIdentifier() instanceof DartIdentifier);
-    DartExpression constructorName = ((DartMethodDefinition) member).getRedirectedConstructorName();
-    assertTrue(constructorName instanceof DartIdentifier);
-  }
-
-  /**
-   * There was bug when "identA.identB" always considered as constructor declaration. But it can be
-   * constructor only if "identA" is name of enclosing class.
-   * <p>
-   * http://code.google.com/p/dart/issues/detail?id=513
-   */
-  public void testQualifiedReturnType() {
-    DartUnit unit = parseUnit("QualifiedReturnTypeB.dart");
-    assertEquals(
-        Joiner.on("\n").join(
-            "// unit QualifiedReturnTypeB.dart",
-            "library test;",
-            "import \"QualifiedReturnTypeA.dart\" as pref;",
-            "class A {",
-            "",
-            "  pref.A foo() {",
-            "    return new pref.A();",
-            "  }",
-            "}"),
-        unit.toSource().trim());
-    DartClass classB = (DartClass) unit.getTopLevelNodes().get(0);
-    DartMethodDefinition fooMethod = (DartMethodDefinition) classB.getMembers().get(0);
-    DartTypeNode fooReturnType = fooMethod.getFunction().getReturnTypeNode();
-    assertEquals(true, fooReturnType.getIdentifier() instanceof DartPropertyAccess);
-  }
-
-  @Override
-  public void testStrings() {
-    DartUnit unit = parseUnit("Strings.dart");
-
-    // Inspect the first method and check that the strings were
-    // parsed correctly
-    List<DartNode> nodes = unit.getTopLevelNodes();
-    assertEquals(1, nodes.size());
-    DartClass clazz = (DartClass) nodes.get(0);
-    List<DartNode> members = clazz.getMembers();
-    assertEquals(1, members.size());
-    DartMethodDefinition m = (DartMethodDefinition) members.get(0);
-    assertEquals("method", m.getName().toString());
-    List<DartStatement> body = m.getFunction().getBody().getStatements();
-
-    String[] expectedStrings = new String[] {
-        "a simple constant",
-        "a simple constant",
-        "an escaped quote \".",
-        "an escaped quote \'.",
-        "a new \n line",
-        "a new \n line",
-        "    multiline 1\n    multiline 2\n    ",
-        "    multiline 1\n    multiline 2\n    ",
-        "multiline 1\n    multiline 2\n    ",
-        "multiline 1\n    multiline 2\n    "};
-    assertEquals(expectedStrings.length + 1, body.size());
-    assertTrue(body.get(0) instanceof DartVariableStatement);
-    for (int i = 0; i < expectedStrings.length; i++) {
-      DartStatement s = body.get(i + 1);
-      assertTrue(s instanceof DartExprStmt);
-      DartExprStmt es = (DartExprStmt) s;
-      DartExpression e = es.getExpression();
-      assertTrue(e instanceof DartBinaryExpression);
-      e = ((DartBinaryExpression) e).getArg2();
-      assertTrue(e instanceof DartStringLiteral);
-      assertEquals(expectedStrings[i], ((DartStringLiteral) e).getValue());
-    }
-  }
-
-  @Override
-  public void testStringsErrors() {
-    parseUnitErrors("StringsErrorsNegativeTest.dart",
-        "Unexpected token 'ILLEGAL'", 7, 13,
-        "Unexpected token 'ILLEGAL'", 9, 9,
-        "Unexpected token 'ILLEGAL'", 11, 9);
-  }
-
-  public void testNullAssign() {
-    String sourceCode = "= 123;";
-    try {
-      DartSourceTest dartSrc = new DartSourceTest(getName(), sourceCode, null);
-      DartParser parser = makeParser(dartSrc, sourceCode, new DartCompilerListener.Empty());
-      parser.parseExpression();
-    }
-    catch(Exception e) {
-      fail("unexpected exception " + e);
-    }
-  }
-
-  public void testFactoryInitializerError() {
-    parseUnitErrors("FactoryInitializersNegativeTest.dart",
-                    "Unexpected token ':' (expected '{')", 10, 22,
-                    "Unexpected token '{' (expected ';')", 10, 35);
-  }
-
-  public void testTryCatch () {
-    DartUnit unit = parseUnit("TryCatch.dart");
-
-    List<DartNode> nodes = unit.getTopLevelNodes();
-    assertEquals(7, nodes.size());
-
-    DartTryStatement tryCatch;
-    DartMethodDefinition a = (DartMethodDefinition) nodes.get(2);
-    assertEquals("a", ((DartIdentifier)a.getName()).getName());
-    tryCatch = (DartTryStatement) a.getFunction().getBody().getStatements().get(0);
-    assertEquals(1, tryCatch.getCatchBlocks().size());
-    assertNotNull(tryCatch.getFinallyBlock());
-
-    DartMethodDefinition b = (DartMethodDefinition) nodes.get(3);
-    assertEquals("b", ((DartIdentifier)b.getName()).getName());
-    tryCatch = (DartTryStatement) b.getFunction().getBody().getStatements().get(0);
-    assertEquals(1, tryCatch.getCatchBlocks().size());
-    assertNull(tryCatch.getFinallyBlock());
-
-    DartMethodDefinition c = (DartMethodDefinition) nodes.get(4);
-    assertEquals("c", ((DartIdentifier)c.getName()).getName());
-    tryCatch = (DartTryStatement) c.getFunction().getBody().getStatements().get(0);
-    assertEquals(0, tryCatch.getCatchBlocks().size());
-    assertNotNull(tryCatch.getFinallyBlock());
-
-    DartMethodDefinition d = (DartMethodDefinition) nodes.get(5);
-    assertEquals("d", ((DartIdentifier)d.getName()).getName());
-    tryCatch = (DartTryStatement) d.getFunction().getBody().getStatements().get(0);
-    assertEquals(2, tryCatch.getCatchBlocks().size());
-    assertNull(tryCatch.getFinallyBlock());
-
-    DartMethodDefinition e = (DartMethodDefinition) nodes.get(6);
-    assertEquals("e", ((DartIdentifier)e.getName()).getName());
-    tryCatch = (DartTryStatement) e.getFunction().getBody().getStatements().get(0);
-    assertEquals(2, tryCatch.getCatchBlocks().size());
-    assertNotNull(tryCatch.getFinallyBlock());
-
-    parseUnitErrors("TryCatchNegative.dart",
-      ParserErrorCode.CATCH_OR_FINALLY_EXPECTED, 8, 3);
-  }
-
-//  public void test_tryOn_catch() {
-//    parseUnit("tryOn.dart", "f() {try {} catch (e) {}}");
-//  }
-
-//  public void test_tryOn_catchStack() {
-//    parseUnit("tryOn.dart", "f() {try {} catch (e, s) {}}");
-//  }
-
-//  public void test_tryOn_on1Catch1() {
-//    parseUnit("tryOn.dart", Joiner.on("\n").join(
-//        "class Object {}",
-//        "class E {}",
-//        "f() {try {} on E catch (e) {}}"));
-//  }
-
-//  public void test_tryOn_on2Catch2() {
-//    parseUnit("tryOn.dart", Joiner.on("\n").join(
-//        "class Object {}",
-//        "class E1 {}",
-//        "class E2 {}",
-//        "f() {try {} on E1 catch (e1) {} on E2 catch (e2) {}}"));
-//  }
-
-//  public void test_tryOn_on2Catch3() {
-//    parseUnit("tryOn.dart", Joiner.on("\n").join(
-//        "class Object {}",
-//        "class E1 {}",
-//        "class E2 {}",
-//        "f() {try {} on E1 catch (e1) {} on E2 catch (e2) {} catch (e3) {}}"));
-//  }
-
-//  public void test_tryOn_on2Catch2Finally() {
-//    parseUnit("tryOn.dart", Joiner.on("\n").join(
-//        "class Object {}",
-//        "class E1 {}",
-//        "class E2 {}",
-//        "f() {try {} on E1 catch (e1) {} on E2 catch (e2) {} finally {}}"));
-//  }
-
-  public void testArrayLiteral() {
-    DartUnit unit = parseUnit("phony_array_literal.dart", "var x = <int>[1,2,3];");
-    List<DartNode> nodes = unit.getTopLevelNodes();
-    assertEquals(1, nodes.size());
-    DartFieldDefinition f = (DartFieldDefinition)nodes.get(0);
-    DartField fieldX = f.getFields().get(0);
-    DartArrayLiteral array = (DartArrayLiteral) fieldX.getValue();
-    assertEquals(3, array.getExpressions().size());
-    assertEquals(1, ((DartIntegerLiteral)array.getExpressions().get(0)).getValue().intValue());
-    assertEquals(2, ((DartIntegerLiteral)array.getExpressions().get(1)).getValue().intValue());
-    assertEquals(3, ((DartIntegerLiteral)array.getExpressions().get(2)).getValue().intValue());
-  }
-
-  public void testAs() {
-    DartUnit unit = parseUnit("phony_cast.dart", "var x = 3 as int;");
-    List<DartNode> nodes = unit.getTopLevelNodes();
-    assertEquals(1, nodes.size());
-    DartFieldDefinition f = (DartFieldDefinition)nodes.get(0);
-    DartField fieldX = f.getFields().get(0);
-    DartBinaryExpression cast = (DartBinaryExpression) fieldX.getValue();
-    assertTrue(cast.getArg1() instanceof DartIntegerLiteral);
-    assertEquals(Token.AS, cast.getOperator());
-    assertTrue(cast.getArg2() instanceof DartTypeExpression);
-  }
-
-  public void testMapLiteral() {
-    DartUnit unit = parseUnit("phony_map_literal.dart", "var x = <int>{'a':1,'b':2,'c':3};");
-    List<DartNode> nodes = unit.getTopLevelNodes();
-    assertEquals(1, nodes.size());
-    DartFieldDefinition f = (DartFieldDefinition)nodes.get(0);
-    DartField fieldX = f.getFields().get(0);
-    DartMapLiteral map = (DartMapLiteral) fieldX.getValue();
-    assertEquals(3, map.getEntries().size());
-    assertEquals(1, ((DartIntegerLiteral) (map.getEntries().get(0)).getValue()).getValue()
-        .intValue());
-  }
-  public void testNestedParameterizedTypes1() {
-    // token >>> is handled specially
-    DartUnit unit = parseUnit ("phony_param_type1.dart",
-                               Joiner.on("\n").join(
-                                   "class A<K> {",
-                                   "  A<A<A<K>>> member;",
-                                   "}"));
-    List<DartNode> nodes = unit.getTopLevelNodes();
-    assertEquals(1, nodes.size());
-  }
-
-  public void testNestedParameterizedTypes2() {
-    // token >> is handled specially
-    DartUnit unit = parseUnit ("phony_param_type1.dart",
-                               Joiner.on("\n").join(
-                                   "class A<K> {",
-                                   "  A<A<K>> member;",
-                                   "}"));
-    List<DartNode> nodes = unit.getTopLevelNodes();
-    assertEquals(1, nodes.size());
-  }
-
-  public void testMethodDefinition1() {
-    DartUnit unit = parseUnit ("phony_method_definition1.dart",
-                               Joiner.on("\n").join(
-                                   "class A {",
-                                   "  pref.A foo() {",
-                                   "    return new pref.A();",
-                                   "  }",
-                                   "}"));
-                           List<DartNode> nodes = unit.getTopLevelNodes();
-                           assertEquals(1, nodes.size());
-  }
-
-  public void testMultipleLabels() {
-    parseUnit ("multiple_labels.dart",
-      Joiner.on("\n").join(
-        "class A {",
-        "  void foo() {",
-        "    a: b: foo();",
-        "  }",
-        "}"));
-  }
-
-  public void testAdjacentStrings1() {
-    DartUnit unit = parseUnit ("phony_adjacent_strings_1.dart",
-                               Joiner.on("\n").join(
-                                   "var a = \"\" \"\";",
-                                   "var b = \"1\" \"2\" \"3\";"));
-    List<DartNode> nodes = unit.getTopLevelNodes();
-    assertEquals(2, nodes.size());
-    DartStringLiteral varA = (DartStringLiteral)((DartFieldDefinition)nodes.get(0))
-        .getFields().get(0).getValue();
-    assertEquals("", varA.getValue());
-    DartStringLiteral varB = (DartStringLiteral)((DartFieldDefinition)nodes.get(1))
-        .getFields().get(0).getValue();
-    assertEquals("123", varB.getValue());
-
-  }
-
-  public void testAdjacentStrings2() {
-    DartUnit unit = parseUnit ("phony_adjacent_strings_2.dart",
-                               Joiner.on("\n").join(
-                               "var c = \"hello\" \"${world}\";",
-                               "var d = \"${hello}\" \"world\";",
-                               "var e = \"${hello}\" \"${world}\";"));
-    List<DartNode> nodes = unit.getTopLevelNodes();
-    assertEquals(3, nodes.size());
-    DartStringInterpolation varC = (DartStringInterpolation)((DartFieldDefinition)nodes.get(0))
-        .getFields().get(0).getValue();
-
-    List<DartStringLiteral> strings = varC.getStrings();
-    assertEquals(3, strings.size());
-    assertEquals("hello", strings.get(0).getValue());
-    assertEquals("", strings.get(1).getValue());
-    assertEquals("", strings.get(2).getValue());
-    List<DartExpression> expressions = varC.getExpressions();
-    assertEquals(2, expressions.size());
-    assertEquals("", ((DartStringLiteral)expressions.get(0)).getValue());
-    DartIdentifier expr = (DartIdentifier)expressions.get(1);
-    assertEquals("world", expr.getName());
-
-    DartStringInterpolation varD = (DartStringInterpolation)((DartFieldDefinition)nodes.get(1))
-        .getFields().get(0).getValue();
-    strings = varD.getStrings();
-    assertEquals(3, strings.size());
-    assertEquals("", strings.get(0).getValue());
-    assertEquals("", strings.get(1).getValue());
-    assertEquals("world", strings.get(2).getValue());
-    expressions = varD.getExpressions();
-    assertEquals(2, expressions.size());
-    expr = (DartIdentifier)expressions.get(0);
-    assertEquals("hello", expr.getName());
-    assertEquals("", ((DartStringLiteral)expressions.get(1)).getValue());
-
-    DartStringInterpolation varE = (DartStringInterpolation)((DartFieldDefinition)nodes.get(2))
-        .getFields().get(0).getValue();
-    strings = varE.getStrings();
-    assertEquals(4, strings.size());
-    assertEquals("", strings.get(0).getValue());
-    assertEquals("", strings.get(1).getValue());
-    assertEquals("", strings.get(2).getValue());
-    assertEquals("", strings.get(3).getValue());
-    expressions = varE.getExpressions();
-    assertEquals(3, expressions.size());
-    expr = (DartIdentifier)expressions.get(0);
-    assertEquals("hello", expr.getName());
-    assertEquals("", ((DartStringLiteral)expressions.get(1)).getValue());
-    expr = (DartIdentifier)expressions.get(2);
-    assertEquals("world", expr.getName());
-  }
-
-  public void testAdjacentStrings3() {
-    DartUnit unit = parseUnit ("phony_adjacent_strings_2.dart",
-                               Joiner.on("\n").join(
-                               "var f = \"hello\" \"${world}\" \"!\";",
-                               "var g = \"${hello}\" \"world\" \"!\";"));
-    List<DartNode> nodes = unit.getTopLevelNodes();
-    assertEquals(2, nodes.size());
-    DartStringInterpolation varF = (DartStringInterpolation)((DartFieldDefinition)nodes.get(0))
-        .getFields().get(0).getValue();
-
-    List<DartStringLiteral> strings = varF.getStrings();
-    assertEquals(4, strings.size());
-    assertEquals("hello", strings.get(0).getValue());
-    assertEquals("", strings.get(1).getValue());
-    assertEquals("", strings.get(2).getValue());
-    assertEquals("!", strings.get(3).getValue());
-    List<DartExpression> expressions = varF.getExpressions();
-    assertEquals(3, expressions.size());
-    assertEquals("", ((DartStringLiteral)expressions.get(0)).getValue());
-    DartIdentifier expr = (DartIdentifier)expressions.get(1);
-    assertEquals("world", expr.getName());
-    assertEquals("", ((DartStringLiteral)expressions.get(2)).getValue());
-
-    DartStringInterpolation varG = (DartStringInterpolation)((DartFieldDefinition)nodes.get(1))
-        .getFields().get(0).getValue();
-    strings = varG.getStrings();
-    assertEquals(4, strings.size());
-    assertEquals("", strings.get(0).getValue());
-    assertEquals("", strings.get(1).getValue());
-    assertEquals("world", strings.get(2).getValue());
-    assertEquals("!", strings.get(3).getValue());
-    expressions = varG.getExpressions();
-    assertEquals(3, expressions.size());
-    expr = (DartIdentifier)expressions.get(0);
-    assertEquals("hello", expr.getName());
-    assertEquals("", ((DartStringLiteral)expressions.get(1)).getValue());
-    assertEquals("", ((DartStringLiteral)expressions.get(2)).getValue());
-  }
-
-  public void testPseudokeywordMethodsAndFields() {
-    DartUnit unit = parseUnit("phony_pseudokeyword_methods.dart",
-        Joiner.on("\n").join(
-            "class A { ",
-            "  int get;",
-            "  var set;",
-            "  final operator;",
-            "}",
-            "class B {",
-            "  var get = 1;",
-            "  int set = 1;",
-            "  final int operator = 1;",
-            "}",
-            "class C {",
-            "  var get = 1;",
-            "  int set = 1;",
-            "  final operator = 1;",
-            "}",
-            "class D {",
-            "  int get = 1;",
-            "  final int set = 1;",
-            "  var operator = 1;",
-            "}",
-            "class E {",
-            "  int get() { }",
-            "  void set() { }",
-            "  operator() { }",
-            "}",
-            "class F {",
-            "  operator - () { }",
-            "  operator + (arg) { }",
-            "  operator [] (arg) { }",
-            "  operator []= (arg, arg){ }",
-            "}"));
-
-    DartClass A = (DartClass)unit.getTopLevelNodes().get(0);
-    DartFieldDefinition A_get = (DartFieldDefinition)A.getMembers().get(0);
-    assertEquals("get", A_get.getFields().get(0).getName().getName());
-    DartFieldDefinition A_set = (DartFieldDefinition)A.getMembers().get(1);
-    assertEquals("set", A_set.getFields().get(0).getName().getName());
-    DartFieldDefinition A_operator = (DartFieldDefinition)A.getMembers().get(2);
-    assertEquals("operator", A_operator.getFields().get(0).getName().getName());
-    DartClass B = (DartClass)unit.getTopLevelNodes().get(1);
-    DartFieldDefinition B_get = (DartFieldDefinition)B.getMembers().get(0);
-    assertEquals("get", B_get.getFields().get(0).getName().getName());
-    DartFieldDefinition B_set = (DartFieldDefinition)B.getMembers().get(1);
-    assertEquals("set", B_set.getFields().get(0).getName().getName());
-    DartFieldDefinition B_operator = (DartFieldDefinition)B.getMembers().get(2);
-    assertEquals("operator", B_operator.getFields().get(0).getName().getName());
-    DartClass C = (DartClass)unit.getTopLevelNodes().get(2);
-    DartFieldDefinition C_get = (DartFieldDefinition)C.getMembers().get(0);
-    assertEquals("get", C_get.getFields().get(0).getName().getName());
-    DartFieldDefinition C_set = (DartFieldDefinition)C.getMembers().get(1);
-    assertEquals("set", C_set.getFields().get(0).getName().getName());
-    DartFieldDefinition C_operator = (DartFieldDefinition)C.getMembers().get(2);
-    assertEquals("operator", C_operator.getFields().get(0).getName().getName());
-    DartClass D = (DartClass)unit.getTopLevelNodes().get(3);
-    DartFieldDefinition D_get = (DartFieldDefinition)D.getMembers().get(0);
-    assertEquals("get", D_get.getFields().get(0).getName().getName());
-    DartFieldDefinition D_set = (DartFieldDefinition)D.getMembers().get(1);
-    assertEquals("set", D_set.getFields().get(0).getName().getName());
-    DartFieldDefinition D_operator = (DartFieldDefinition)D.getMembers().get(2);
-    assertEquals("operator", D_operator.getFields().get(0).getName().getName());
-    DartClass E = (DartClass)unit.getTopLevelNodes().get(4);
-    DartMethodDefinition E_get = (DartMethodDefinition)E.getMembers().get(0);
-    assertEquals("get", ((DartIdentifier)E_get.getName()).getName());
-    DartMethodDefinition E_set = (DartMethodDefinition)E.getMembers().get(1);
-    assertEquals("set", ((DartIdentifier)E_set.getName()).getName());
-    DartMethodDefinition E_operator = (DartMethodDefinition)E.getMembers().get(2);
-    assertEquals("operator", ((DartIdentifier)E_operator.getName()).getName());
-    DartClass F = (DartClass)unit.getTopLevelNodes().get(5);
-    DartMethodDefinition F_negate = (DartMethodDefinition)F.getMembers().get(0);
-    assertEquals("-", ((DartIdentifier)F_negate.getName()).getName());
-    DartMethodDefinition F_plus = (DartMethodDefinition)F.getMembers().get(1);
-    assertEquals("+", ((DartIdentifier)F_plus.getName()).getName());
-    DartMethodDefinition F_access = (DartMethodDefinition)F.getMembers().get(2);
-    assertEquals("[]", ((DartIdentifier)F_access.getName()).getName());
-    DartMethodDefinition F_access_assign = (DartMethodDefinition)F.getMembers().get(3);
-    assertEquals("[]=", ((DartIdentifier)F_access_assign.getName()).getName());
-  }
-
-//  public void test_string_raw_deprecated() {
-//    parseUnit("test.dart", "var s = @'abc${d}efg';", ParserErrorCode.DEPRECATED_RAW_STRING, 1, 9);
-//  }
-
-  public void test_string_raw() {
-    String expectedValue = "abc${d}efg";
-    DartUnit unit = parseUnit("test.dart", "var s = r'" + expectedValue + "';");
-    List<DartNode> nodes = unit.getTopLevelNodes();
-    assertEquals(1, nodes.size());
-    DartFieldDefinition definition = (DartFieldDefinition) nodes.get(0);
-    DartField field = definition.getFields().get(0);
-    DartExpression expression = field.getValue();
-    assertTrue(expression instanceof DartStringLiteral);
-    assertEquals(expectedValue, ((DartStringLiteral) expression).getValue());
-  }
-
-  public void test_super_operator() {
-    DartUnit unit = parseUnit("phony_super.dart", Joiner.on("\n").join(
-        "class A {",
-        "  void m() {",
-        "    --super;",
-        "  }",
-        "}"));
-    List<DartNode> nodes = unit.getTopLevelNodes();
-    assertEquals(1, nodes.size());
-    DartClass A = (DartClass) nodes.get(0);
-    DartMethodDefinition m = (DartMethodDefinition) A.getMembers().get(0);
-    DartExprStmt statement = (DartExprStmt) m.getFunction().getBody().getStatements().get(0);
-    DartUnaryExpression value = (DartUnaryExpression) statement.getExpression();
-    assertEquals(Token.SUB, value.getOperator());
-    DartUnaryExpression inner = (DartUnaryExpression) value.getArg();
-    assertEquals(Token.SUB, inner.getOperator());
-  }
-
-  /**
-   * Typedef and interface are top level keywords that are also valid as identifiers.
-   *
-   * This test helps insure that the error recovery logic in the parser that detects
-   * top level keywords out of place doesn't break this functionality.
-   */
-  public void testTopLevelKeywordsAsIdent() {
-    parseUnit("phony_pseudokeyword_methods.dart",
-        Joiner.on("\n").join(
-            "var interface;",
-            "bool interface;",
-            "final interface;",
-            "interface() { }",
-            "String interface() { }",
-            "interface();",
-            "var typedef;",
-            "bool typedef;",
-            "final typedef;",
-            "typedef() { }",
-            "String typedef() { }",
-            "typedef();",
-            "class A { ",
-            "  var interface;",
-            "  bool interface;",
-            "  final interface;",
-            "  interface() { }",
-            "  String interface() { }",
-            "  interface();",
-            "  var typedef;",
-            "  bool typedef;",
-            "  final typedef;",
-            "  typedef() { }",
-            "  String typedef() { }",
-            "  typedef();",
-            "}",
-            "method() {",
-            "  var interface;",
-            "  bool interface;",
-            "  final interface;",
-            "  interface() { }",
-            "  String interface() { }",
-            "  interface();",
-            "  var typedef;",
-            "  bool typedef;",
-            "  final typedef;",
-            "  typedef() { }",
-            "  String typedef() { }",
-            "  typedef();",
-            "}"));
-  }
-
-  /**
-   * We should be able to parse "static(abstract) => 42" top-level function.
-   * <p>
-   * http://code.google.com/p/dart/issues/detail?id=1197
-   */
-  public void test_staticAsFunctionName() {
-    DartUnit unit = parseUnit(
-        getName(),
-        Joiner.on("\n").join(
-            "// filler filler filler filler filler filler filler filler filler filler",
-            "static(abstract) => 42;",
-            ""));
-    assertEquals(1, unit.getTopLevelNodes().size());
-    DartMethodDefinition method = (DartMethodDefinition) unit.getTopLevelNodes().get(0);
-    assertEquals("static", method.getName().toSource());
-    assertEquals("abstract", method.getFunction().getParameters().get(0).getName().toSource());
-  }
-
-  /**
-   * The token 'super' is valid by itself (not as a qualifier or assignment selector) in only some
-   * cases.
-   */
-  public void testLoneSuperExpression1() {
-    parseUnit("phony_lone_super_expression1.dart",
-              Joiner.on("\n").join(
-            "class A {",
-            "  method() {",
-            "    super;",
-            "    super ? true : false;",
-            "    true ? true : super;",
-            "    true ? super : false;",
-            "    if (super && true) { }",
-            "    if (super || false) { }",
-            "  }",
-            "}"),
-            ParserErrorCode.SUPER_IS_NOT_VALID_ALONE_OR_AS_A_BOOLEAN_OPERAND, 3, 5,
-            ParserErrorCode.SUPER_IS_NOT_VALID_ALONE_OR_AS_A_BOOLEAN_OPERAND, 4, 5,
-            ParserErrorCode.SUPER_IS_NOT_VALID_ALONE_OR_AS_A_BOOLEAN_OPERAND, 5, 19,
-            ParserErrorCode.SUPER_IS_NOT_VALID_ALONE_OR_AS_A_BOOLEAN_OPERAND, 6, 12,
-            ParserErrorCode.SUPER_IS_NOT_VALID_AS_A_BOOLEAN_OPERAND, 7, 9,
-            ParserErrorCode.SUPER_IS_NOT_VALID_AS_A_BOOLEAN_OPERAND, 8, 9);
-  }
-
-  public void testLoneSuperExpression2() throws Exception {
-    parseUnit("phony_lone_super_expression1.dart",
-        Joiner.on("\n").join(
-            "// filler filler filler filler filler filler filler filler filler filler",
-            "class Object {}",
-            "class A {",
-            "  method() {",
-            "    if (1 + super) { }", // error
-            "    if (super + 1) { }",  // ok
-            "    if (1 == super) { }", // error
-            "    if (super == 1) { }",  // ok
-            "    if (1 | super) { }", // error
-            "    if (super | 1) { }",  // ok
-            "    if (1 < super) { }", // error
-            "    if (super < 1) { }",  // ok
-            "    if (1 << super) { }", // error
-            "    if (super << 1) { }",  // ok
-            "    if (1 * super) { }", // error
-            "    if (super * 1) { }",  // ok
-            "    var f = -super;", // ok
-            "  }",
-            "}"),
-            ParserErrorCode.SUPER_CANNOT_BE_USED_AS_THE_SECOND_OPERAND, 5, 13,
-            ParserErrorCode.SUPER_CANNOT_BE_USED_AS_THE_SECOND_OPERAND, 7, 14,
-            ParserErrorCode.SUPER_CANNOT_BE_USED_AS_THE_SECOND_OPERAND, 9, 13,
-            ParserErrorCode.SUPER_CANNOT_BE_USED_AS_THE_SECOND_OPERAND, 11, 13,
-            ParserErrorCode.SUPER_CANNOT_BE_USED_AS_THE_SECOND_OPERAND, 13, 14,
-            ParserErrorCode.SUPER_CANNOT_BE_USED_AS_THE_SECOND_OPERAND, 15, 13);
-  }
-
-  public void testBreakOutsideLoop() throws Exception {
-    parseUnit("phony_lone_super_expression1.dart",
-        Joiner.on("\n").join(
-            "class A {",
-            "  method() {",
-            "    while (true) { break; }", // ok
-            "    break;",  // bad
-            "    L1: break L1;", // ok
-            "    while (true) { continue; }", // ok
-            "    continue;", // bad
-            "    L2: continue L2;", // bad
-            "    while (true) { int f() { break; }; }", // bad
-            "  }",
-            "}"),
-            ParserErrorCode.BREAK_OUTSIDE_OF_LOOP, 4, 10,
-            ParserErrorCode.CONTINUE_OUTSIDE_OF_LOOP, 7, 13,
-            ParserErrorCode.CONTINUE_OUTSIDE_OF_LOOP, 8, 18,
-            ParserErrorCode.BREAK_OUTSIDE_OF_LOOP, 9, 35);
-  }
-
-  public void testContinueNoLabelInsideCase() throws Exception {
-    parseUnit("phony_lone_super_expression1.dart",
-        Joiner.on("\n").join(
-            "class A {",
-            "  method() {",
-            "    switch(1) {",
-            "      case 1: continue;", // error
-            "    }",
-            "    while (1) {",
-            "      switch(1) {",
-            "        case 1: continue;", // ok, refers to the while loop.
-            "      }",
-            "    }",
-            "    L: switch(1) {",
-            "     case 1: var result = () { continue L; };", // bad
-            "    }",
-            "  }",
-            "}"),
-            ParserErrorCode.CONTINUE_IN_CASE_MUST_HAVE_LABEL, 4, 23,
-            ParserErrorCode.CONTINUE_OUTSIDE_OF_LOOP, 12, 41);
-  }
-
-  public void testRedundantAbruptlyTermainatedCaseStatement() throws Exception {
-    parseUnit("phony_reduntant_abruptly_terminated_case_statement.dart",
-        Joiner.on("\n").join(
-            "func () {",
-            "  switch (0) {",
-            "   case 0: ",
-            "     return 0; ",
-            "     break;", // warn dead code
-            "   case 1: ",
-            "     return 1; ",
-            "     var foo = 1;", // warn dead code
-            "   case 2:",
-            "     return 2;",
-            "     var bar = 2;", // warn dead code
-            "     break;",    // no warning here
-            "   default:",
-            "     return -1;",
-            "     var baz = -1;", // warn dead code
-            "     break;",  // no warning here
-            "  }",
-            "}"),
-            ParserErrorCode.UNREACHABLE_CODE_IN_CASE, 5, 6,
-            ParserErrorCode.UNREACHABLE_CODE_IN_CASE, 8, 6,
-            ParserErrorCode.UNREACHABLE_CODE_IN_CASE, 11, 6,
-            ParserErrorCode.UNREACHABLE_CODE_IN_CASE, 15, 6);
-  }
-
-  public void testCornerCaseLabelInSwitch() throws Exception {
-    // The parser used to just accept this statement.
-    parseUnit("phony_reduntant_abruptly_terminated_case_statement.dart",
-        Joiner.on("\n").join(
-            "func () {",
-            "  switch (0) {",
-            "  label1: ",  // no case, default or statement follows.
-            "  }",
-            "}"),
-            ParserErrorCode.LABEL_NOT_FOLLOWED_BY_CASE_OR_DEFAULT, 3, 9);
-  }
-
-  public void testBogusEscapedNewline() throws Exception {
-    parseUnit("phony_bogus_escaped_newline.dart",
-        Joiner.on("\n").join(
-            "class A {",
-            "  var foo = \"not really multiline\\\n",
-            "\";",
-            "}"),
-            ParserErrorCode.ESCAPED_NEWLINE,  2, 35,
-            ParserErrorCode.UNEXPECTED_TOKEN,  2, 13,
-            ParserErrorCode.EXPECTED_TOKEN,  4, 1);
-  }
-
-  public void testLabelledCaseStatements() throws Exception {
-    parseUnit("phony_labelled_case_statements.dart",
-        Joiner.on("\n").join(
-            "method() {",
-            "  switch(1) {",
-            "  A: case 0:",
-            "  B: C: case 1:",
-            "    break;",
-            "  }",
-            "}"));
-  }
-
-  public void testRedirectingConstructorBody() throws Exception {
-    parseUnit("phony_test_redirecting_constructor_body.dart",
-        Joiner.on("\n").join(
-            "class A {",
-            "  A.c() {}",  // OK
-            "  A.d() : this.c();", // OK
-            "  A(): this.b() {}", // body not allowed
-            "}"),
-            ParserErrorCode.REDIRECTING_CONSTRUCTOR_CANNOT_HAVE_A_BODY, 4, 18);
-  }
-
-  public void test_missingFactoryBody() throws Exception {
-    parseUnit("phony_test_missing_factory_body.dart",
-        Joiner.on("\n").join(
-            "class A {",
-            "  factory A.c();",  // error - no body
-            "  A() {}",
-            "}"),
-            ParserErrorCode.EXPECTED_FUNCTION_STATEMENT_BODY, 2, 16);
-  }
-
-  public void test_factoryAbstractStatic() throws Exception {
-  parseUnit("phony_test_factory_not_abstract.dart",
-      Joiner.on("\n").join(
-        "class A {",
-        "  A() {}",
-        "  factory A.named1() { return new A();}",
-        "  static factory A.named2() { return new A();}",
-        "}"),
-        ParserErrorCode.FACTORY_CANNOT_BE_STATIC, 4, 10);
-  }
-
-  public void test_factoryInInterface() throws Exception {
-    parseUnit("phony_test_factory_in_interface.dart",
-        Joiner.on("\n").join(
-            "interface A {",
-            "  factory A();",
-            "}"),
-            ParserErrorCode.DEPRECATED_INTERFACE, 1, 1,
-            ParserErrorCode.FACTORY_MEMBER_IN_INTERFACE, 2, 3,
-            ParserErrorCode.EXPECTED_FUNCTION_STATEMENT_BODY, 2, 14);
-  }
-
-  public void test_localVariable_const() {
-    DartUnit unit = parseUnit("constVar.dart", makeCode(
-        "main() {",
-        "  const v = 1;",
-        "}"));
-    assertNotNull(unit);
-    DartNode firstNode = unit.getTopLevelNodes().get(0);
-    assertTrue(firstNode instanceof DartMethodDefinition);
-    DartStatement statement = ((DartMethodDefinition) firstNode).getFunction().getBody().getStatements().get(0);
-    assertTrue(((DartVariableStatement) statement).getModifiers().isConstant());
-  }
-
-  public void test_localVariable_final_prefixedType() {
-    DartUnit unit = parseUnit("finalVar.dart", makeCode(
-        "main() {",
-        "  final p.T v = 1;",
-        "}"));
-    assertNotNull(unit);
-    DartNode firstNode = unit.getTopLevelNodes().get(0);
-    assertTrue(firstNode instanceof DartMethodDefinition);
-    DartStatement statement = ((DartMethodDefinition) firstNode).getFunction().getBody().getStatements().get(0);
-    DartVariableStatement variableStatement = (DartVariableStatement) statement;
-    assertTrue(variableStatement.getModifiers().isFinal());
-    assertEquals("v", variableStatement.getVariables().get(0).getVariableName());
-  }
-
-  public void test_metadata_identifier() {
-    String code = makeCode(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "const int annotation = 0;",
-        "class A {",
-        "  m0() {}",
-        "  @annotation",
-        "  m1() {}",
-        "}",
-        "");
-    DartUnit unit = parseUnit(getName() + ".dart", code);
-    DartClass classA = (DartClass) unit.getTopLevelNodes().get(1);
-
-    DartMethodDefinition method0 = (DartMethodDefinition) classA.getMembers().get(0);
-    assertEquals("m0", method0.getName().toSource());
-    assertEquals(0, method0.getMetadata().size());
-
-    DartMethodDefinition method1 = (DartMethodDefinition) classA.getMembers().get(1);
-    assertEquals("m1", method1.getName().toSource());
-    assertEquals(1, method1.getMetadata().size());
-    DartAnnotation metadata = method1.getMetadata().get(0);
-    assertNotNull(metadata);
-    DartExpression name = metadata.getName();
-    assertTrue(name instanceof DartIdentifier);
-    assertEquals("annotation", name.toSource());
-    assertEquals(0, metadata.getArguments().size());
-  }
-
-  public void test_metadata_localVariable() {
-    String code = makeCode(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "const annotation = 0;",
-        "class A {",
-        "  test() {",
-        "    @annotation",
-        "    var v = 0;",
-        "  }",
-        "}",
-        "");
-    DartUnit unit = parseUnit(getName() + ".dart", code);
-    DartClass classA = (DartClass) unit.getTopLevelNodes().get(1);
-
-    DartMethodDefinition method = (DartMethodDefinition) classA.getMembers().get(0);
-    assertEquals("test", method.getName().toSource());
-    assertEquals(0, method.getMetadata().size());
-
-    DartVariableStatement statement = (DartVariableStatement) method.getFunction().getBody().getStatements().get(0);
-    DartVariable variable = statement.getVariables().get(0);
-    assertEquals("v", variable.getName().toSource());
-    assertEquals(1, variable.getMetadata().size());
-    DartAnnotation metadata = variable.getMetadata().get(0);
-    assertNotNull(metadata);
-    DartExpression name = metadata.getName();
-    assertTrue(name instanceof DartIdentifier);
-    assertEquals("annotation", name.toSource());
-    assertEquals(0, metadata.getArguments().size());
-  }
-
-  public void test_metadata_constructor() {
-    String code = makeCode(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "class A {",
-        "  const A();",
-        "}",
-        "",
-        "class B {",
-        "  m0() {}",
-        "  @A()",
-        "  m1() {}",
-        "}",
-        "");
-    DartUnit unit = parseUnit(getName() + ".dart", code);
-    DartClass classB = (DartClass) unit.getTopLevelNodes().get(1);
-
-    DartMethodDefinition method0 = (DartMethodDefinition) classB.getMembers().get(0);
-    assertEquals("m0", method0.getName().toSource());
-    assertEquals(0, method0.getMetadata().size());
-
-    DartMethodDefinition method1 = (DartMethodDefinition) classB.getMembers().get(1);
-    assertEquals("m1", method1.getName().toSource());
-    assertEquals(1, method1.getMetadata().size());
-  }
-
-  public void test_metadata_deprecated() {
-    String code = makeCode(
-        "class A {",
-        "  m0() {}",
-        "  @deprecated",
-        "  m1() {}",
-        "}",
-        "");
-    DartUnit unit = parseUnit(getName() + ".dart", code);
-    // A
-    {
-      DartClass classA = (DartClass) unit.getTopLevelNodes().get(0);
-      // m0()
-      {
-        DartMethodDefinition method = (DartMethodDefinition) classA.getMembers().get(0);
-        assertEquals("m0", method.getName().toSource());
-        assertEquals(false, method.getObsoleteMetadata().isDeprecated());
-      }
-      // m1()
-      {
-        DartMethodDefinition method = (DartMethodDefinition) classA.getMembers().get(1);
-        assertEquals("m1", method.getName().toSource());
-        assertEquals(true, method.getObsoleteMetadata().isDeprecated());
-      }
-    }
-  }
-
-  public void test_metadata_override() {
-    String code = makeCode(
-        "class A {",
-        "  m0() {}",
-        "  @override",
-        "  m1() {}",
-        "  /** Leading DartDoc comment */",
-        "  @override",
-        "  m2() {}",
-        "  @override",
-        "  /** Trailing DartDoc comment */",
-        "  m3() {}",
-        "}",
-        "");
-    DartUnit unit = parseUnit(getName() + ".dart", code);
-    // A
-    {
-      DartClass classA = (DartClass) unit.getTopLevelNodes().get(0);
-      // m0()
-      {
-        DartMethodDefinition method = (DartMethodDefinition) classA.getMembers().get(0);
-        assertEquals("m0", method.getName().toSource());
-        assertEquals(false, method.getObsoleteMetadata().isOverride());
-        assertNull(method.getDartDoc());
-      }
-      // m1()
-      {
-        DartMethodDefinition method = (DartMethodDefinition) classA.getMembers().get(1);
-        assertEquals("m1", method.getName().toSource());
-        assertEquals(true, method.getObsoleteMetadata().isOverride());
-        assertNull(method.getDartDoc());
-      }
-      // m2()
-      {
-        DartMethodDefinition method = (DartMethodDefinition) classA.getMembers().get(2);
-        assertEquals("m2", method.getName().toSource());
-        assertEquals(true, method.getObsoleteMetadata().isOverride());
-        {
-          DartComment dartDoc = method.getDartDoc();
-          assertNotNull(dartDoc);
-          assertEquals("/** Leading DartDoc comment */", getNodeSource(code, dartDoc));
-        }
-      }
-      // m3()
-      {
-        DartMethodDefinition method = (DartMethodDefinition) classA.getMembers().get(3);
-        assertEquals("m3", method.getName().toSource());
-        assertEquals(true, method.getObsoleteMetadata().isOverride());
-        {
-          DartComment dartDoc = method.getDartDoc();
-          assertNotNull(dartDoc);
-          assertEquals("/** Trailing DartDoc comment */", getNodeSource(code, dartDoc));
-        }
-      }
-    }
-  }
-
-  public void test_operators_valid() throws Exception {
-    parseUnit("operators.dart",
-        Joiner.on("\n").join(
-            "class C {",
-            "  operator <(v) {}",
-            "  operator >(v) {}",
-            "  operator <=(v) {}",
-            "  operator >=(v) {}",
-            "  operator ==(v) {}",
-            "  operator -() {}",
-            "  operator -(v) {}",
-            "  operator +(v) {}",
-            "  operator /(v) {}",
-            "  operator ~/(v) {}",
-            "  operator *(v) {}",
-            "  operator %(v) {}",
-            "  operator |(v) {}",
-            "  operator ^(v) {}",
-            "  operator &(v) {}",
-            "  operator <<(v) {}",
-            "  operator >>(v) {}",
-            "  operator [](i) {}",
-            "  operator []=(i, v) {}",
-            "  operator ~() {}",
-            "}"));
-  }
-
-  public void test_positionalDefaultValue() throws Exception {
-    parseUnit("phony_test_abstract_var.dart",
-        Joiner.on("\n").join(
-            "method(arg=1) {",
-            "}"),
-            ParserErrorCode.DEFAULT_POSITIONAL_PARAMETER, 1, 8);
-  }
-
-  public void test_abstractInInterface() throws Exception {
-    parseUnit("phony_test_abstract_in_interface.dart",
-        Joiner.on("\n").join(
-            "interface A {",
-            "  var foo;",
-            "  bar();",
-            "}"),
-            ParserErrorCode.DEPRECATED_INTERFACE, 1, 1);
-  }
-
-  public void test_voidParameterField() throws Exception {
-    parseUnit("phony_test_abstract_in_interface.dart",
-        Joiner.on("\n").join(
-            "method(void arg) { }",
-            "void field;",
-            "class C {",
-            "  method(void arg) { }",
-            "  void field;",
-            "}"),
-            ParserErrorCode.VOID_PARAMETER, 1, 8,
-            ParserErrorCode.VOID_FIELD, 2, 1,
-            ParserErrorCode.VOID_PARAMETER, 4, 10,
-            ParserErrorCode.VOID_FIELD, 5, 3);
-  }
-
-  public void test_topLevelVariable_const() {
-    DartUnit unit = parseUnit("constVar.dart", "const v = 1;");
-    assertNotNull(unit);
-    DartNode firstNode = unit.getTopLevelNodes().get(0);
-    assertTrue(firstNode instanceof DartFieldDefinition);
-    DartField field = ((DartFieldDefinition) firstNode).getFields().get(0);
-    assertTrue(field.getModifiers().isConstant());
-  }
-
-  public void test_unexpectedTypeArgument() throws Exception {
-    // This is valid code that was previously rejected.
-    // Invoking a named constructor in a prefixed library should work.
-    parseUnit("phony_test_unexpected_type_argument.dart",
-        Joiner.on("\n").join(
-            "method() {",
-            "  new prefix.Type.named<T>();",
-            "}"));
-  }
-
-  public void test_staticOperator() throws Exception {
-    parseUnit("phony_static_operator.dart",
-        Joiner.on("\n").join(
-            "class C {",
-            "  static operator +(arg) {}",
-            "}"),
-            ParserErrorCode.OPERATOR_CANNOT_BE_STATIC, 2, 10);
-  }
-
-  public void test_nonFinalStaticMemberInInterface() throws Exception {
-    parseUnit("phony_non_final_static_member_in_interface.dart",
-        Joiner.on("\n").join(
-            "interface I {",
-            "  static foo();",
-            "  static var bar;",
-            "}"),
-            ParserErrorCode.DEPRECATED_INTERFACE, 1, 1,
-            ParserErrorCode.NON_FINAL_STATIC_MEMBER_IN_INTERFACE, 2, 3,
-            ParserErrorCode.NON_FINAL_STATIC_MEMBER_IN_INTERFACE, 3, 3);
-  }
-
-  public void test_invalidOperatorChaining() throws Exception {
-    parseUnit("phony_invalid_operator_chaining.dart",
-        Joiner.on("\n").join(
-            "method() {",
-            "  if (a < b < c) {}",
-            "  if (a is b is c) {}",
-            "}"),
-            ParserErrorCode.INVALID_OPERATOR_CHAINING, 2, 11,
-            ParserErrorCode.INVALID_OPERATOR_CHAINING, 3, 12);
-  }
-
-  public void test_expectedArrayOrMapLiteral() throws Exception {
-    parseUnit("phony_expected_array_or_map_literal.dart",
-        Joiner.on("\n").join(
-            "method() {",
-            "  var a = <int>;",
-            "}"),
-            ParserErrorCode.EXPECTED_ARRAY_OR_MAP_LITERAL, 2, 9,
-            ParserErrorCode.EXPECTED_TOKEN, 2, 15);
-  }
-
-  public void test_abstractMethod_withoutModifier() {
-    parseUnit("test.dart", Joiner.on("\n").join(
-        "class C {",
-        "  m(a, b, c);",
-        "}"));
-  }
-
-  public void test_argumentDefinitionTest() {
-    parseUnit("test.dart", Joiner.on("\n").join(
-        "class C {",
-        "  m([p = 0]) {",
-        "    return ?p;",
-        "  }",
-        "}"));
-  }
-
-  public void test_assignToNonAssignable() throws Exception {
-    parseUnit("phony_assign_to_non_assignable.dart",
-        Joiner.on("\n").join(
-            "method() {",
-            "  1 + 2 = 3;",
-            "}"),
-            ParserErrorCode.ILLEGAL_ASSIGNMENT_TO_NON_ASSIGNABLE, 2, 7);
-  }
-
-  public void test_forComplexVariable() throws Exception {
-    parseUnit("phony_for_complex_variable.dart",
-        Joiner.on("\n").join(
-            "method() {",
-            "  for (foo + 1 in a) { }",
-            "}"),
-            ParserErrorCode.FOR_IN_WITH_COMPLEX_VARIABLE, 2, 8);
-  }
-
-  public void test_forMultipleVariable() throws Exception {
-    parseUnit("phony_for_multiple_variable.dart",
-        Joiner.on("\n").join(
-            "method() {",
-            "  for (var foo, bar in a) { }",
-            "}"),
-            ParserErrorCode.FOR_IN_WITH_MULTIPLE_VARIABLES, 2, 17);
-  }
-
-  public void test_formalParameters_field() throws Exception {
-    DartUnit unit = parseUnit("formalParameters.dart",
-        Joiner.on("\n").join(
-            "class A {",
-            "  final foo;",
-            "  A(this.foo) {}",
-            "}"));
-    DartClass classNode = (DartClass) unit.getTopLevelNodes().get(0);
-    DartMethodDefinition methodNode = (DartMethodDefinition) classNode.getMembers().get(1);
-    DartParameter parameterNode = methodNode.getFunction().getParameters().get(0);
-    assertTrue(parameterNode.getName() instanceof DartPropertyAccess);
-    DartPropertyAccess accessNode = (DartPropertyAccess) parameterNode.getName();
-    assertEquals(4, accessNode.getQualifier().getSourceInfo().getLength());
-  }
-
-  public void test_formalParameters_named() throws Exception {
-    parseUnit("formalParameters.dart",
-        Joiner.on("\n").join(
-            "method({var a : 1, var b : 2}) {",
-            "}"));
-  }
-
-  public void test_formalParameters_named_missingRightBracket() throws Exception {
-    parseUnit("formalParameters.dart",
-        Joiner.on("\n").join(
-            "method({var a : 1) {",
-            "}"),
-            ParserErrorCode.MISSING_NAMED_PARAMETER_END, 1, 18);
-  }
-
-  public void test_formalParameters_named_wrongSeparator() throws Exception {
-    parseUnit("formalParameters.dart",
-        Joiner.on("\n").join(
-            "method({var a = 1}) {",
-            "}"),
-            ParserErrorCode.INVALID_SEPARATOR_FOR_NAMED, 1, 13);
-  }
-
-  public void test_formalParameters_optional() throws Exception {
-    parseUnit("formalParameters.dart",
-        Joiner.on("\n").join(
-            "method([var a = 1, var b = 2]) {",
-            "}"));
-  }
-
-  public void test_formalParameters_optional_missingRightBrace() throws Exception {
-    parseUnit("formalParameters.dart",
-        Joiner.on("\n").join(
-            "method([var a = 1) {",
-            "}"),
-            ParserErrorCode.MISSING_OPTIONAL_PARAMETER_END, 1, 18);
-  }
-
-  public void test_formalParameters_optional_wrongSeparator() throws Exception {
-    parseUnit("formalParameters.dart",
-        Joiner.on("\n").join(
-            "method([var a : 1]) {",
-            "}"),
-            ParserErrorCode.INVALID_SEPARATOR_FOR_OPTIONAL, 1, 13);
-  }
-
-  public void test_formalParameters_positional() throws Exception {
-    parseUnit("formalParameters.dart",
-        Joiner.on("\n").join(
-            "method(var a, var b) {",
-            "}"));
-  }
-
-  public void test_formalParameters_positional_named() throws Exception {
-    parseUnit("formalParameters.dart",
-        Joiner.on("\n").join(
-            "method(var a, var b, {var c : 3, var d : 4}) {",
-            "}"));
-  }
-
-  public void test_formalParameters_positional_optional() throws Exception {
-    parseUnit("formalParameters.dart",
-        Joiner.on("\n").join(
-            "method(var a, var b, [var c = 3, var d = 4]) {",
-            "}"));
-  }
-
-  public void test_forVariableInitializer() throws Exception {
-    parseUnit("phony_for_multiple_variable.dart",
-        Joiner.on("\n").join(
-            "method() {",
-            "  for (var foo = 1 in a) { }",
-            "}"),
-            ParserErrorCode.FOR_IN_WITH_VARIABLE_INITIALIZER, 2, 18);
-  }
-  
-  public void test_forIn_withConst() throws Exception {
-    parseUnit("test.dart",
-        Joiner.on("\n").join(
-            "main() {",
-            "  for (const v in a) { }",
-            "}"));
-  }
-
-  public void test_varInFunctionType() throws Exception {
-    parseUnit("phony_var_in_function_type.dart",
-            "typedef func(var arg());",
-            ParserErrorCode.FUNCTION_TYPED_PARAMETER_IS_VAR, 1, 18);
-  }
-
-  public void test_finalInFunctionType() throws Exception {
-    parseUnit("phony_var_in_function_type.dart",
-            "typedef func(final arg());",
-            ParserErrorCode.FUNCTION_TYPED_PARAMETER_IS_FINAL, 1, 20);
-  }
-
-  public void test_export_withoutLibraryDirective() {
-    parseUnit("test.dart", Joiner.on("\n").join(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "export 'Lib.dart';",
-        ""),
-        ParserErrorCode.EXPORT_WITHOUT_LIBRARY_DIRECTIVE, 2, 1);
-  }
-  
-  public void test_unicodeNormalizedFormC_inString() throws Exception {
-    byte bytes[] = new byte[] {
-        (byte) 0x76,
-        (byte) 0x61,
-        (byte) 0x72,
-        (byte) 0x20,
-        (byte) 0x73,
-        (byte) 0x3D,
-        (byte) 0x27,
-        (byte) 0x41,
-        (byte) 0xCC,
-        (byte) 0x8A,
-        (byte) 0x27,
-        (byte) 0x3B};
-    String source = new String(bytes, "UTF-8");
-    DartParserRunner parserRunner = parseSource(source);
-    assertErrors(
-        parserRunner.getErrors(),
-        errEx(ParserErrorCode.INVALID_UNICODE_NORMALIZATION, 1, 8, 1));
-  }
-}
diff --git a/compiler/javatests/com/google/dart/compiler/parser/TerminationTest.java b/compiler/javatests/com/google/dart/compiler/parser/TerminationTest.java
deleted file mode 100644
index df093bd..0000000
--- a/compiler/javatests/com/google/dart/compiler/parser/TerminationTest.java
+++ /dev/null
@@ -1,125 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.parser;
-
-import com.google.dart.compiler.CompilerTestCase;
-
-public class TerminationTest extends CompilerTestCase {
-
-  public void testNestedStatement() {
-    assertTrue(DartParserRunner.parse("testNestedStatement",
-      "class A { String foo foo; }").hasErrors());
-  }
-
-  public void testTypeParameterList() {
-    assertTrue(DartParserRunner.parse("testTypeParameterList",
-      "class A <X Y> { }").hasErrors());
-  }
-
-  public void testTypeParameterList2() {
-    assertTrue(DartParserRunner.parse("testTypeParameterList2",
-      "class A <X  ").hasErrors());
-  }
-
-  public void testVarDecl() {
-    assertTrue(DartParserRunner.parse("testParseVarDecl",
-      "class A  { int a b  ").hasErrors());
-  }
-
-  public void testInterfaceList() {
-    assertTrue(DartParserRunner.parse("testInterfaceList",
-      "class A implemented B C { } ").hasErrors());
-  }
-
-  public void testInvalidChainning() {
-    assertTrue(DartParserRunner.parse("testInvalidChainning",
-      "class A { f() { var a; if (a is A is A){}}}").hasErrors());
-  }
-
-  public void testTypeInitializerList() {
-    assertTrue(DartParserRunner.parse("testTypeInitializerList",
-      "class A { A() : x(1) y(1) {} } ").hasErrors());
-  }
-
-  public void testVarDeclInit() {
-    assertTrue(DartParserRunner.parse("testVarDeclInit",
-      "class A { a = 1, b = 2 c = 3; } ").hasErrors());
-  }
-
-  public void testStaticConstDeclList() {
-    assertTrue(DartParserRunner.parse("testStaticConstDeclList",
-      "class A { static const int a = 1, b = 2 c = 3 ; } ").hasErrors());
-  }
-
-  public void testExpressionList() {
-    assertTrue(DartParserRunner.parse("testExpressionList",
-      "class A { A() { for(i;;i++,i++ i++) { } } } ").hasErrors());
-  }
-
-  public void testExpressionList2() {
-    assertTrue(DartParserRunner.parse("testExpressionList",
-      "class A { A() { for(i;;i++,i++  class B {} ").hasErrors());
-  }
-
-  public void testArguments() {
-    assertTrue(DartParserRunner.parse("testArguments",
-      "class A { int foo() { var f = new A(1,2 3 ; } }").hasErrors());
-  }
-
-  public void testMapLiteral() {
-    assertTrue(DartParserRunner.parse("testMapLiteral",
-      "class A { int foo() { var f = {a: 1, b: 2  ; ").hasErrors());
-  }
-
-  public void testMapLiteral2() {
-    assertTrue(DartParserRunner.parse("testMapLiteral2",
-      "class A { int foo() { var f = {a: 1, b ").hasErrors());
-  }
-
-  public void testMapLiteral3() {
-    assertTrue(DartParserRunner.parse("testMapLiteral3",
-      "class A { int foo() { var f = {a: 1, b: 2 c:3 ; ").hasErrors());
-  }
-
-  public void testStringInterpolation() {
-    assertTrue(DartParserRunner.parse("testStringInterpolation",
-      "class A { int foo() { int a; s=\"x${a}   ${ \"  ").hasErrors());
-  }
-
-  public void testStringInterpolation2() {
-    assertTrue(DartParserRunner.parse("testStringInterpolation2",
-      "class A { int foo() { int a; s=\"x${a}  ").hasErrors());
-  }
-
-  public void testTryTypeSpecification() {
-    assertTrue(DartParserRunner.parse("testTryTypeSpecification",
-      "class A <a<b<c  { }  ").hasErrors());
-  }
-
-  public void testTryCatch() {
-    assertTrue(DartParserRunner.parse("testTryCatch",
-      "class A  { int foo() { try {} catch(int e) {} catch   ").hasErrors());
-  }
-
-  public void testSwitchCase() {
-    assertTrue(DartParserRunner.parse("testSwitchCase",
-      "class A  { int foo() { int a; switch(a) { case 1: break; case 2: break; ").hasErrors());
-  }
-
-  public void testInitVarList() {
-    assertTrue(DartParserRunner.parse("testInitVarList",
-      "class A  { int foo() { int a = 1, b = 2 , ").hasErrors());
-  }
-
-  public void testArrayInit() {
-    assertTrue(DartParserRunner.parse("testArrayInit",
-      "class A { foo(){ a = [1, 2      ").hasErrors());
-  }
-
-  public void testMalformedDietSource() {
-    assertTrue(DartParserRunner.parse("testMalformedDietSource",
-      "class A { foo() { { { } { } ", true).hasErrors());
-  }
-}
diff --git a/compiler/javatests/com/google/dart/compiler/parser/TerminationTests.java b/compiler/javatests/com/google/dart/compiler/parser/TerminationTests.java
deleted file mode 100644
index 1060c5c..0000000
--- a/compiler/javatests/com/google/dart/compiler/parser/TerminationTests.java
+++ /dev/null
@@ -1,22 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.parser;
-
-import junit.extensions.TestSetup;
-import junit.framework.Test;
-import junit.framework.TestSuite;
-
-public class TerminationTests extends TestSetup {
-
-  public TerminationTests(TestSuite test) {
-    super(test);
-  }
-
-  public static Test suite() {
-    TestSuite suite = new TestSuite("Dart Parser termination tests suite.");
-    suite.addTestSuite(TerminationTest.class);
-    return new TerminationTests(suite);
-  }
-}
diff --git a/compiler/javatests/com/google/dart/compiler/parser/TopLevel.dart b/compiler/javatests/com/google/dart/compiler/parser/TopLevel.dart
deleted file mode 100644
index 1f70a2f..0000000
--- a/compiler/javatests/com/google/dart/compiler/parser/TopLevel.dart
+++ /dev/null
@@ -1,13 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-var a, b;
-List<int> c;
-final List<int> bar = [1, 2];
-
-void foo() {}
-
-List<int> bar() {}
-
-foobar() {}
diff --git a/compiler/javatests/com/google/dart/compiler/parser/TruncatedSourceParserTest.java b/compiler/javatests/com/google/dart/compiler/parser/TruncatedSourceParserTest.java
deleted file mode 100644
index 0263d62..0000000
--- a/compiler/javatests/com/google/dart/compiler/parser/TruncatedSourceParserTest.java
+++ /dev/null
@@ -1,162 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.parser;
-
-import com.google.dart.compiler.DartCompilationError;
-import com.google.dart.compiler.DartCompilerListenerTest;
-import com.google.dart.compiler.DartSourceTest;
-import com.google.dart.compiler.ast.DartUnit;
-
-public class TruncatedSourceParserTest extends AbstractParserTest {
-
-  private static final int RESULTS_TIMEOUT_SECONDS = 10;
-  private static enum ParseState {
-    INIT, STARTED_PARSE, STOP,
-  }
-
-  /**
-   * Performs parsing in a separate thread such that the test can detect infinite loop.
-   */
-  private class ParserThread extends Thread {
-    private final Object lock = new Object();
-    private final String srcName;
-    private ParseState state = ParseState.INIT;
-    private String srcCode;
-    private DartUnit result;
-
-    /**
-     * Listener that ignores errors because this is a stress test
-     */
-    private DartCompilerListenerTest listener = new DartCompilerListenerTest("") {
-      @Override
-      public void checkAllErrorsReported() {
-      }
-
-      @Override
-      public void onError(DartCompilationError event) {
-      }
-    };
-
-    public ParserThread(String srcName) {
-      super("Parsing " + srcName);
-      this.srcName = srcName;
-    }
-
-    /**
-     * Queue the specified source to be parsed on a separate thread. Wait up to 10 seconds for the
-     * result
-     *
-     * @return <code>true</code> if finished parsing
-     */
-    public boolean parse(String srcCode) {
-      assert (srcCode != null);
-      assert (state == ParseState.INIT);
-      synchronized (lock) {
-        this.srcCode = srcCode;
-        result = null;
-        state = ParseState.STARTED_PARSE;
-        lock.notifyAll();
-        try {
-          lock.wait(RESULTS_TIMEOUT_SECONDS * 1000);
-        } catch (InterruptedException e) {
-          // Fall through
-        }
-        return state == ParseState.INIT;
-      }
-    }
-
-    /**
-     * Parse source code in the background
-     */
-    @Override
-    public void run() {
-      while (true) {
-        DartSourceTest src;
-        synchronized (lock) {
-          while (state == ParseState.INIT) {
-            try {
-              lock.wait();
-            } catch (InterruptedException e) {
-              // Fall through
-            }
-          }
-          if (state == ParseState.STOP) {
-            return;
-          }
-          src = new DartSourceTest(srcName, srcCode, null);
-        }
-        DartUnit unit = makeParser(src, srcCode, listener).parseUnit();
-        synchronized (lock) {
-          if (state == ParseState.STOP) {
-            return;
-          }
-          state = ParseState.INIT;
-          result = unit;
-          lock.notifyAll();
-        }
-      }
-    }
-
-    /**
-     * Signal the background thread to terminate
-     */
-    public void stopParsing() {
-      synchronized (lock) {
-        state = ParseState.STOP;
-        lock.notify();
-      }
-    }
-  }
-
-  @Override
-  public void testStringsErrors() {
-    parseUnit("StringsErrorsNegativeTest.dart");
-  }
-
-  @Override
-  public void testTiming() {
-    // Skip
-  }
-
-  @Override
-  protected DartUnit parseUnit(String srcName, String srcCode, Object... errors) {
-    if ("true".equals(System.getProperty("analysis_skip_TruncatedSourceParserTest"))) {
-      return null;
-    }
-    if (errors.length > 0) {
-      throw new RuntimeException("Expected errors not implemented");
-    }
-    // System.out.print(srcName);
-    ParserThread thread = new ParserThread(srcName);
-    thread.start();
-    int eol = 0;
-    for (int index = 0; index < srcCode.length(); index++) {
-      if (eol == index) {
-        eol++;
-        while (eol < srcCode.length()) {
-          char ch = srcCode.charAt(eol);
-          if (ch == '\r' || ch == '\n') {
-            break;
-          }
-          eol++;
-        }
-      }
-      String modifiedSrcCode = srcCode.substring(0, index);
-      if (!thread.parse(modifiedSrcCode)) {
-        // System.out.println();
-        fail("Failed to finish parsing " + srcName + "\n" + modifiedSrcCode);
-      }
-      modifiedSrcCode += srcCode.substring(eol);
-      if (!thread.parse(modifiedSrcCode)) {
-        // System.out.println();
-        fail("Failed to finish parsing " + srcName + "\n" + modifiedSrcCode);
-      }
-      // System.out.print('.');
-    }
-    thread.stopParsing();
-    // System.out.println();
-    return thread.result;
-  }
-}
diff --git a/compiler/javatests/com/google/dart/compiler/parser/TryCatch.dart b/compiler/javatests/com/google/dart/compiler/parser/TryCatch.dart
deleted file mode 100644
index 4708733..0000000
--- a/compiler/javatests/com/google/dart/compiler/parser/TryCatch.dart
+++ /dev/null
@@ -1,46 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-abstract class TestException1 {
-  int foo();
-}
-
-abstract class TestException2 {
-  int bar();
-}
-
-a() {
-  try {
-  } catch (e) {
-  } finally {
-  }
-}
-
-b() {
-  try {
-  } catch (e) {
-  }
-}
-
-c() {
-  try {
-  } finally {
-  }
-}
-
-d() {
-  try  {
-  } on TestException1 catch (e) {
-  } on TestException2 catch (e) {
-  }
-}
-
-e() {
-  try  {
-  } on TestException1 catch (e) {
-  } on TestException2 catch (e) {
-  } finally {
-  }
-}
-
diff --git a/compiler/javatests/com/google/dart/compiler/parser/TryCatchNegative.dart b/compiler/javatests/com/google/dart/compiler/parser/TryCatchNegative.dart
deleted file mode 100644
index 9e3ecee..0000000
--- a/compiler/javatests/com/google/dart/compiler/parser/TryCatchNegative.dart
+++ /dev/null
@@ -1,9 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-a() {
-  try {
-    var i = 1;
-  } // expect catch or finally here.
-}
diff --git a/compiler/javatests/com/google/dart/compiler/parser/ValidatingSyntaxTest.java b/compiler/javatests/com/google/dart/compiler/parser/ValidatingSyntaxTest.java
deleted file mode 100755
index 5960da8..0000000
--- a/compiler/javatests/com/google/dart/compiler/parser/ValidatingSyntaxTest.java
+++ /dev/null
@@ -1,94 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.parser;
-
-import com.google.dart.compiler.ast.DartBinaryExpression;
-import com.google.dart.compiler.ast.DartClass;
-import com.google.dart.compiler.ast.DartExprStmt;
-import com.google.dart.compiler.ast.DartExpression;
-import com.google.dart.compiler.ast.DartMethodDefinition;
-import com.google.dart.compiler.ast.DartNode;
-import com.google.dart.compiler.ast.DartStatement;
-import com.google.dart.compiler.ast.DartStringLiteral;
-import com.google.dart.compiler.ast.DartUnit;
-import com.google.dart.compiler.ast.DartVariableStatement;
-
-import java.util.List;
-
-/**
- * Tests for the parser, which simply assert that valid source units parse
- * correctly. All tests invoking {@link #parseUnit} are designed such that they
- * will throw an exception if anything goes wrong in the parser.
- */
-public class ValidatingSyntaxTest extends AbstractParserTest {
-
-  @Override
-  public void testStrings() {
-    DartUnit unit = parseUnit("Strings.dart");
-
-    // Inspect the first method and check that the strings were
-    // parsed correctly
-    List<DartNode> nodes = unit.getTopLevelNodes();
-    assertEquals(1, nodes.size());
-    DartClass clazz = (DartClass) nodes.get(0);
-    List<DartNode> members = clazz.getMembers();
-    assertEquals(1, members.size());
-    DartMethodDefinition m = (DartMethodDefinition) members.get(0);
-    assertEquals("method", m.getName().toString());
-    List<DartStatement> body = m.getFunction().getBody().getStatements();
-
-    String[] expectedStrings = new String[] {
-        "a simple constant",
-        "a simple constant",
-        "an escaped quote \".",
-        "an escaped quote \'.",
-        "a new \n line",
-        "a new \n line",
-        "    multiline 1\n    multiline 2\n    ",
-        "    multiline 1\n    multiline 2\n    ",
-        "multiline 1\n    multiline 2\n    ",
-        "multiline 1\n    multiline 2\n    "};
-    assertEquals(expectedStrings.length + 1, body.size());
-    assertTrue(body.get(0) instanceof DartVariableStatement);
-    for (int i = 0; i < expectedStrings.length; i++) {
-      DartStatement s = body.get(i + 1);
-      assertTrue(s instanceof DartExprStmt);
-      DartExprStmt es = (DartExprStmt) s;
-      DartExpression e = es.getExpression();
-      assertTrue(e instanceof DartBinaryExpression);
-      e = ((DartBinaryExpression) e).getArg2();
-      assertTrue(e instanceof DartStringLiteral);
-      assertEquals(expectedStrings[i], ((DartStringLiteral) e).getValue());
-    }
-  }
-
-  @Override
-  public void testStringsErrors() {
-    parseUnitErrors("StringsErrorsNegativeTest.dart",
-        "Unexpected token 'ILLEGAL'", 7, 13,
-        "Unexpected token 'ILLEGAL'", 9, 9,
-        "Unexpected token 'ILLEGAL'", 11, 9);
-  }
-
-  @Override
-  protected DartUnit parseUnit(String srcName, String sourceCode, Object... errors) {
-    if (errors.length > 0) {
-      throw new RuntimeException("Expected errors not implemented");
-    }
-    return validateUnit(super.parseUnit(srcName, sourceCode));
-  }
-
-  private DartUnit validateUnit(DartUnit unit) {
-    DartASTValidator validator = new DartASTValidator();
-    unit.accept(validator);
-    validator.assertValid();
-    return unit;
-  }
-
-  @Override
-  public void testTiming() {
-    // Ignored.
-  }
-}
diff --git a/compiler/javatests/com/google/dart/compiler/parser/VoidTest.java b/compiler/javatests/com/google/dart/compiler/parser/VoidTest.java
deleted file mode 100644
index 67f2351..0000000
--- a/compiler/javatests/com/google/dart/compiler/parser/VoidTest.java
+++ /dev/null
@@ -1,82 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.parser;
-
-import com.google.dart.compiler.CompilerTestCase;
-
-/**
- * Tests for void-as-a-keyword.  This could be extended to be a general keyword test.  
- */
-public class VoidTest extends CompilerTestCase {
-  private void assertHasErrorsEquals(boolean expected, String code) {
-    DartParserRunner runner = DartParserRunner.parse(getName(), code);
-    assertEquals(expected, runner.hasErrors());
-  }
-  
-  private void assertHasErrorsIsFalse(String code) {
-    assertHasErrorsEquals(false, code);
-  }
-  
-  private void assertHasErrorsIsTrue(String code) {
-    assertHasErrorsEquals(true, code);
-  }
-  
-  public void testExtendVoid() {
-    assertHasErrorsIsTrue("class A extends void { }");
-  }
-
-  public void testImplementsVoid() {
-    assertHasErrorsIsTrue("class A implements void { }");
-  }
-
-  public void testVoidClass() {
-    assertHasErrorsIsTrue("class void { }");
-    assertHasErrorsIsTrue("class void<T> { }");
-  }
-
-  public void testVoidFactory() {
-    assertHasErrorsIsTrue("interface A factory void { }");
-  }
-  
-  public void testVoidFieldType() {
-    assertHasErrorsIsTrue("class A { void x; }");
-  }  
-  
-  public void testVoidFunctionAlias() {
-    assertHasErrorsIsFalse("typedef void a();");
-  }
-  
-  public void testVoidFunctionParamName() {
-    assertHasErrorsIsTrue("class A { int x( int void ) {} }");
-  }
-  
-  public void testVoidFunctionParamType() {
-    assertHasErrorsIsFalse("class A { int x( void y() ) {} }");
-  }
-  
-  public void testVoidFunctionLiteral() {
-    assertHasErrorsIsTrue("class A { int x() { function void(){} } }");
-  }
-  
-  public void testVoidLocalVar() {
-    assertHasErrorsIsTrue("class A { void x() { void y; } }");
-  }
-  
-  public void testVoidLocalVarName() {
-    assertHasErrorsIsTrue("class A { void x() { int void; } }");
-  }
-
-  public void testVoidMethodName() {
-    assertHasErrorsIsTrue("class A { int void() {} }");
-  }
-
-  public void testVoidParamType() {
-    assertHasErrorsIsTrue("class A { int x( void y ) {} }");
-  }
-  
-  public void testVoidTypeParameter() {
-    assertHasErrorsIsTrue("class a<void> { }");
-  }
-}
diff --git a/compiler/javatests/com/google/dart/compiler/resolver/ClassImplementsClassNegativeTest.dart b/compiler/javatests/com/google/dart/compiler/resolver/ClassImplementsClassNegativeTest.dart
deleted file mode 100644
index 146dcd6..0000000
--- a/compiler/javatests/com/google/dart/compiler/resolver/ClassImplementsClassNegativeTest.dart
+++ /dev/null
@@ -1,12 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-// Expect error - Base is not an interface.
-
-class Base {
-}
-
-class Subclass implements Base {}
-
-
diff --git a/compiler/javatests/com/google/dart/compiler/resolver/CompileTimeConstantTest.java b/compiler/javatests/com/google/dart/compiler/resolver/CompileTimeConstantTest.java
deleted file mode 100644
index a86b588d..0000000
--- a/compiler/javatests/com/google/dart/compiler/resolver/CompileTimeConstantTest.java
+++ /dev/null
@@ -1,993 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.resolver;
-
-import com.google.common.base.Joiner;
-
-import static com.google.dart.compiler.common.ErrorExpectation.errEx;
-
-
-
-/**
- * Tests the code in {@link CompileTimeConstantVisitor}
- */
-public class CompileTimeConstantTest extends ResolverTestCase {
-
-  public void test_conditionalExpression() {
-    resolveAndTestCtConstExpectErrors(
-        Joiner.on("\n").join(
-            "// filler filler filler filler filler filler filler filler filler filler",
-            "class Object {}",
-            "const v = true ? 1 : 2;",
-            ""),
-        errEx(ResolverErrorCode.EXPECTED_CONSTANT_EXPRESSION, 3, 11, 12));
-  }
-
-  public void test_nonConstArg() {
-    resolveAndTestCtConstExpectErrors(
-        Joiner.on("\n").join(
-            "class Object {}",
-            "class A { const A(s); }",
-            "main() {",
-            "  var a = const A(new A(null));",
-            "}"),
-            errEx(ResolverErrorCode.EXPECTED_CONSTANT_EXPRESSION, 4, 19, 11));
-  }
-
-  /**
-   * This is allowed in "Spec 0.11".
-   * <p>
-   * http://code.google.com/p/dart/issues/detail?id=3847
-   */
-  public void test_instanceVariable_nonConstInitializer() {
-    resolveAndTestCtConstExpectErrors(Joiner.on("\n").join(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "class Object {}",
-        "class A {",
-        " var f = new Object();",
-        "}"));
-  }
-  
-  /**
-   * Final variable does not have to have constant initializer.
-   */
-  public void test_finalIsNoConst() {
-    resolveAndTestCtConstExpectErrors(Joiner.on("\n").join(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "class Object {}",
-        "class int {}",
-        "",
-        "foo() => 10;",
-        "final g1 = foo();",
-        "var   g2 = foo();",
-        "",
-        "class A {",
-        "  static final f1 = bar();",
-        "  static var   f2 = bar();",
-        "  bar() => 20;",
-        "}",
-        "main() {",
-        "  final v1 = foo();",
-        "}",
-        ""));
-  }
-
-  /**
-   * We can not reference "this" directly or indirectly as reference to other fields.
-   * <p>
-   * http://code.google.com/p/dart/issues/detail?id=3847
-   */
-  public void test_instanceVariable_nonConstInitializer_cannotReferenceThis() {
-    resolveAndTestCtConstExpectErrors(
-        Joiner.on("\n").join(
-            "// filler filler filler filler filler filler filler filler filler filler",
-            "class Object {}",
-            "class Val {",
-            "  Val(var o) {}",
-            "}",
-            "class A {",
-            " var f1 = new Val(1);",
-            " var f2 = this;",
-            " var f3 = new Val(f1);",
-            "}",
-            "class B extends A {",
-            " var f2 = new Val(f3);",
-            "}",
-            ""),
-        errEx(ResolverErrorCode.THIS_OUTSIDE_OF_METHOD, 8, 11, 4),
-        errEx(ResolverErrorCode.CANNOT_USE_INSTANCE_FIELD_IN_INSTANCE_FIELD_INITIALIZER, 9, 19, 2),
-        errEx(ResolverErrorCode.CANNOT_USE_INSTANCE_FIELD_IN_INSTANCE_FIELD_INITIALIZER, 12, 19, 2));
-  }
-
-  /**
-   * We can reference top-level fields, because they are static.
-   * <p>
-   * http://code.google.com/p/dart/issues/detail?id=4400
-   */
-  public void test_instanceVariable_nonConstInitializer_topLevelField() {
-    resolveAndTestCtConstExpectErrors(Joiner.on("\n").join(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "class Object {}",
-        "final TOP = 1;",
-        "class A {",
-        " var f = TOP;",
-        "}",
-        ""));
-  }
-
-  /**
-   * <p>
-   * http://code.google.com/p/dart/issues/detail?id=1655
-   */
-  public void test_constConstructor_nonConstInitializerValue() {
-    resolveAndTestCtConstExpectErrors(
-        Joiner.on("\n").join(
-            "// filler filler filler filler filler filler filler filler filler filler",
-            "class Object {}",
-            "foo() {}",
-            "class A {",
-            " final v;",
-            " const A() : v = foo();",
-            "}",
-            ""),
-        errEx(ResolverErrorCode.EXPECTED_CONSTANT_EXPRESSION, 6, 18, 5));
-  }
-
-  /**
-   * <p>
-   * http://code.google.com/p/dart/issues/detail?id=4294
-   */
-  public void test_constConstructor_redirectInvocation() throws Exception {
-    resolveAndTestCtConstExpectErrors(
-        Joiner.on("\n").join(
-            "// filler filler filler filler filler filler filler filler filler filler",
-            "class Object {}",
-            "class A {",
-            "  final v;",
-            "  const A(this.v);",
-            "  const A.hasValue() : this(generateValue());",
-            "  static generateValue() => 42;",
-            "}"),
-        errEx(ResolverErrorCode.EXPECTED_CONSTANT_EXPRESSION, 6, 29, 15));
-  }
-
-  /**
-   * <p>
-   * http://code.google.com/p/dart/issues/detail?id=4294
-   */
-  public void test_constConstructor_superInvocation() throws Exception {
-    resolveAndTestCtConstExpectErrors(
-        Joiner.on("\n").join(
-            "// filler filler filler filler filler filler filler filler filler filler",
-            "class Object {}",
-            "class A {",
-            "  final v;",
-            "  const A(this.v);",
-            "}",
-            "class B extends A {",
-            "  const B() : super(generateValue());",
-            "  static generateValue() => 42;",
-            "}",
-            ""),
-        errEx(ResolverErrorCode.EXPECTED_CONSTANT_EXPRESSION, 8, 21, 15));
-  }
-
-  /**
-   * At compile time we "trust" user that parameter will have correct type.
-   */
-  public void test_constConstructor_constInitializerValue_plusDynamic() {
-    resolveAndTestCtConstExpectErrors(
-        Joiner.on("\n").join(
-            "// filler filler filler filler filler filler filler filler filler filler",
-            "class Object {}",
-            "class A {",
-            " final v;",
-            " const A(var p) : v = 100 + p;",
-            "}",
-            ""));
-  }
-  
-  public void test_constConstructor_constInitializerValue_boolNulls() {
-    resolveAndTestCtConstExpectErrors(
-        Joiner.on("\n").join(
-            "// filler filler filler filler filler filler filler filler filler filler",
-            "class Object {}",
-            "class A {",
-            " final a, b, c, d;",
-            " const A(var p) : ",
-            "   a = false || null,",
-            "   b = null || false,",
-            "   c = null || null,",
-            "   d = !null;",
-            "}",
-            ""));
-  }
-  
-  public void test_constConstructor_constInitializerValue_numNulls() {
-    resolveAndTestCtConstExpectErrors(
-        Joiner.on("\n").join(
-            "// filler filler filler filler filler filler filler filler filler filler",
-            "class Object {}",
-            "class A {",
-            " final a, b, c, d, e;",
-            " const A(var p) : ",
-            "   a = 1 ^ null,",
-            "   b = 1 << null,",
-            "   c = 1 & null,",
-            "   d = ~null,",
-            "   e = -null;",
-            "}",
-            ""));
-  }
-
-  public void test_nonConstantExpressions() {
-    resolveAndTestCtConstExpectErrors(
-        Joiner.on("\n").join(
-            "var x = 0;",
-            "const c1 = const {'$x' : 1};",
-            "const c2 = const {'key': []};",
-            "const c3 = const [new Object()];",
-            "class Object {}",
-            "class String {}",
-            ""),
-            errEx(ResolverErrorCode.EXPECTED_CONSTANT_EXPRESSION, 2, 21, 1),
-            errEx(ResolverErrorCode.EXPECTED_CONSTANT_EXPRESSION, 3, 26,2),
-            errEx(ResolverErrorCode.EXPECTED_CONSTANT_EXPRESSION, 4, 19, 12));
-  }
-  
-  public void test_parameterDefaultValue_inLocalFunction() {
-    resolveAndTestCtConstExpectErrors(
-        Joiner.on("\n").join(
-            "// filler filler filler filler filler filler filler filler filler filler",
-            "main() {",
-            " int x = 1;",
-            " void func([var y = x]) {}",
-            "}",
-            "class Object {}",
-            "class int {}",
-            ""),
-            errEx(ResolverErrorCode.EXPECTED_CONSTANT_EXPRESSION, 4, 21, 1));
-  }
-
-  public void test_cascade() {
-    resolveAndTestCtConstExpectErrors(
-        Joiner.on("\n").join(
-            "// filler filler filler filler filler filler filler filler filler filler",
-            "main() {",
-            " var v;",
-            " const c = v..foo;",
-            "}",
-            "class Object {}",
-            "class int {}",
-            ""),
-        errEx(ResolverErrorCode.EXPECTED_CONSTANT_EXPRESSION, 4, 12, 1),
-        errEx(ResolverErrorCode.EXPECTED_CONSTANT_EXPRESSION, 4, 13, 5));
-  }
-
-  public void test_stringInterpolation_referenceConstVar_String() {
-    resolveAndTestCtConstExpectErrors(Joiner.on("\n").join(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "class Object {}",
-        "const a = 'aaa';",
-        "const v = '$a';",
-        ""));
-  }
-
-  public void test_stringInterpolation_referenceConstVar_num() {
-    resolveAndTestCtConstExpectErrors(Joiner.on("\n").join(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "class Object {}",
-        "const a = 1.0;",
-        "const v = '$a';",
-        ""));
-  }
-
-  public void test_stringInterpolation_referenceConstVar_bool() {
-    resolveAndTestCtConstExpectErrors(Joiner.on("\n").join(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "class Object {}",
-        "const a = false;",
-        "const v = '$a';",
-        ""));
-  }
-
-  public void test_stringInterpolation_referenceConstVar_Object() {
-    resolveAndTestCtConstExpectErrors(
-        Joiner.on("\n").join(
-            "// filler filler filler filler filler filler filler filler filler filler",
-            "class Object {}",
-            "class C {",
-            "  const C();",
-            "}",
-            "const a = const C();",
-            "const v = '$a';",
-            ""),
-        errEx(ResolverErrorCode.EXPECTED_CONSTANT_EXPRESSION_STRING_NUMBER_BOOL, 7, 13, 1));
-  }
-
-  public void test_stringInterpolation_inMethod() {
-    resolveAndTestCtConstExpectErrors(Joiner.on("\n").join(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "class Object {}",
-        "class Conster {",
-        "  const Conster(this.value);",
-        "  final value;",
-        "}",
-        "const a = 'aaa';",
-        "f() {",
-        "  const Conster('$a');",
-        "}",
-        ""));
-  }
-
-  public void testConstantBinaryExpression1() {
-    resolveAndTestCtConst(Joiner.on("\n").join(
-        "class Object {}",
-        "class A {",
-        " static const INT_LIT = 5;",
-        " static const BOP1_0 = INT_LIT + 1;",
-        " static const BOP1_1 = 1 + INT_LIT;",
-        " static const BOP1_2 = INT_LIT - 1;",
-        " static const BOP1_3 = 1 - INT_LIT;",
-        " static const BOP1_4 = INT_LIT * 1;",
-        " static const BOP1_5 = 1 * INT_LIT;",
-        " static const BOP1_6 = INT_LIT / 1;",
-        " static const BOP1_7 = 1 / INT_LIT;",
-        "}"));
-  }
-
-  public void testConstantBinaryExpression10() {
-    resolveAndTestCtConst(Joiner.on("\n").join(
-        "class Object {}",
-        "class A {",
-        "  static const INT_LIT = 5;",
-        "  static const INT_LIT_REF = INT_LIT;",
-        "  static const DOUBLE_LIT = 1.5;",
-        "  static const BOOL_LIT = true;",
-        "  // Multiple binary expresions",
-        "  static const BOP1 = 1 * INT_LIT / 3 + INT_LIT + 9;",
-        "  // Parenthized expression",
-        "  static const BOP2 = ( 1 > 2 );",
-        "  static const BOP3 = (1 * 2) + 3;",
-        "  static const BOP4 = 3 + (1 * 2);",
-        "}"));
-  }
-
-  public void testConstantBinaryExpression11() {
-    resolveAndTestCtConst(Joiner.on("\n").join(
-        "class Object {}",
-        "class A {",
-        "  static const INT_LIT = 5;",
-        "  static const DOUBLE_LIT = 1.5;",
-        "  const A();",
-        "  static const OBJECT_LIT = const A();",
-        "  // Multiple binary expresions",
-        "  static const BOP1_0 = 0 + 1 + OBJECT_LIT;",
-        "  static const BOP1_1 = 0 + OBJECT_LIT + 1;",
-        "  static const BOP1_2 = OBJECT_LIT + 3 + 9;",
-        "}"),
-        ResolverErrorCode.EXPECTED_CONSTANT_EXPRESSION_NUMBER,
-        ResolverErrorCode.EXPECTED_CONSTANT_EXPRESSION_NUMBER,
-        ResolverErrorCode.EXPECTED_CONSTANT_EXPRESSION_NUMBER,
-        ResolverErrorCode.EXPECTED_CONSTANT_EXPRESSION_NUMBER,
-        ResolverErrorCode.EXPECTED_CONSTANT_EXPRESSION_NUMBER);
-  }
-  
-  public void test_circularReference() {
-    resolveAndTestCtConstExpectErrors(
-        Joiner.on("\n").join(
-            "class Object {}",
-            "class A {",
-            "  static const F1 = F2;",
-            "  static const F2 = F1;",
-            "}"),
-            errEx(ResolverErrorCode.CIRCULAR_REFERENCE, 3, 21, 2),
-            errEx(ResolverErrorCode.CIRCULAR_REFERENCE, 4, 21, 2));
-  }
-  
-  public void test_topLevelFunctionReference() {
-    resolveAndTestCtConstExpectErrors(Joiner.on("\n").join(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "class Object {}",
-        "m() {}",
-        "class A {",
-        "  static const V1 = m;",
-        "}",
-        "final V2 = m;",
-        ""));
-  }
-  
-  public void test_staticMethodReference() {
-    resolveAndTestCtConstExpectErrors(Joiner.on("\n").join(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "class Object {}",
-        "class A {",
-        "  static m() {}",
-        "  static const V1 = m;",
-        "}",
-        "final V2 = A.m;",
-        ""));
-  }
-  
-  public void test_instanceMethodReference() {
-    resolveAndTestCtConstExpectErrors(
-        Joiner.on("\n").join(
-            "// filler filler filler filler filler filler filler filler filler filler",
-            "class Object {}",
-            "class A {",
-            "  m() {}",
-            "  static const V1 = m;",
-            "}",
-            "const V2 = A.m;",
-            ""),
-        errEx(ResolverErrorCode.ILLEGAL_METHOD_ACCESS_FROM_STATIC, 5, 21, 1),
-        errEx(ResolverErrorCode.NOT_A_STATIC_METHOD, 7, 14, 1),
-        errEx(ResolverErrorCode.EXPECTED_CONSTANT_EXPRESSION, 5, 21, 1),
-        errEx(ResolverErrorCode.EXPECTED_CONSTANT_EXPRESSION, 7, 12, 3));
-  }
-
-  public void testConstantBinaryExpression12() {
-    // Multiple binary expressions
-    resolveAndTestCtConst(Joiner.on("\n").join(
-        "class Object {}",
-        "class A {",
-        "  static const INT_LIT = 5;",
-        "  static const DOUBLE_LIT = 1.5;",
-        "  const A();",
-        "  static const OBJECT_LIT = new A();",
-        "  static const PP0 = 0 - (1 + OBJECT_LIT);",
-        "  static const PP1 = 0 + (OBJECT_LIT + 1);",
-        "  static const PP2 = (OBJECT_LIT + 3) + 9;",
-        "  static const PP3 = (OBJECT_LIT) + 3 + 9;",
-        "  static const PP4 = (OBJECT_LIT + 3 + 9);",
-        "  static const PP5 = OBJECT_LIT + (3 + 9);",
-        "}"),
-        ResolverErrorCode.EXPECTED_CONSTANT_EXPRESSION,
-        ResolverErrorCode.EXPECTED_CONSTANT_EXPRESSION,
-        ResolverErrorCode.EXPECTED_CONSTANT_EXPRESSION_NUMBER,
-        ResolverErrorCode.EXPECTED_CONSTANT_EXPRESSION_NUMBER,
-        ResolverErrorCode.EXPECTED_CONSTANT_EXPRESSION,
-        ResolverErrorCode.EXPECTED_CONSTANT_EXPRESSION_NUMBER,
-        ResolverErrorCode.EXPECTED_CONSTANT_EXPRESSION_NUMBER,
-        ResolverErrorCode.EXPECTED_CONSTANT_EXPRESSION,
-        ResolverErrorCode.EXPECTED_CONSTANT_EXPRESSION_NUMBER,
-        ResolverErrorCode.EXPECTED_CONSTANT_EXPRESSION_NUMBER,
-        ResolverErrorCode.EXPECTED_CONSTANT_EXPRESSION,
-        ResolverErrorCode.EXPECTED_CONSTANT_EXPRESSION_NUMBER,
-        ResolverErrorCode.EXPECTED_CONSTANT_EXPRESSION_NUMBER,
-        ResolverErrorCode.EXPECTED_CONSTANT_EXPRESSION,
-        ResolverErrorCode.EXPECTED_CONSTANT_EXPRESSION_NUMBER,
-        ResolverErrorCode.EXPECTED_CONSTANT_EXPRESSION_NUMBER,
-        ResolverErrorCode.EXPECTED_CONSTANT_EXPRESSION,
-        ResolverErrorCode.EXPECTED_CONSTANT_EXPRESSION_NUMBER);
-  }
-
-  public void testConstantBinaryExpression2() {
-    resolveAndTestCtConst(Joiner.on("\n").join(
-        "class Object {}",
-        "class A {",
-        " static const DOUBLE_LIT = 1.5;",
-        " static const BOP2_0 = DOUBLE_LIT + 1.5;",
-        " static const BOP2_1 = 1.5 + DOUBLE_LIT;",
-        " static const BOP2_2 = DOUBLE_LIT - 1.5;",
-        " static const BOP2_3 = 1.5 - DOUBLE_LIT;",
-        " static const BOP2_4 = DOUBLE_LIT * 1.5;",
-        " static const BOP2_5 = 1.5 * DOUBLE_LIT;",
-        " static const BOP2_6 = DOUBLE_LIT / 1.5;",
-        " static const BOP2_7 = 1.5 / DOUBLE_LIT;",
-        "}"));
-  }
-
-  public void testConstantBinaryExpression3() {
-    resolveAndTestCtConst(Joiner.on("\n").join(
-        "class Object {}",
-        "class A {",
-        " static const INT_LIT = 5;",
-        " static const BOP3_0 = 2 < INT_LIT;",
-        " static const BOP3_1 = INT_LIT < 2;",
-        " static const BOP3_2 = 2 > INT_LIT;",
-        " static const BOP3_3 = INT_LIT > 2;",
-        "}"));
-
-    resolveAndTestCtConst(Joiner.on("\n").join(
-        "class Object {}",
-        "class A {",
-        " static const INT_LIT = 5;",
-        " static const DOUBLE_LIT = 1.5;",
-        " static const BOP3_4 = 2 < DOUBLE_LIT;",
-        " static const BOP3_5 = DOUBLE_LIT < 2;",
-        " static const BOP3_6 = 2 > DOUBLE_LIT;",
-        " static const BOP3_7 = DOUBLE_LIT > 2;",
-        " static const BOP3_8 = 2 <= INT_LIT;",
-        " static const BOP3_9 = INT_LIT <= 2;",
-        " static const BOP3_10 = 2 >= INT_LIT;",
-        " static const BOP3_11 = INT_LIT >= 2;",
-        " static const BOP3_12 = 2.0 <= DOUBLE_LIT;",
-        " static const BOP3_13 = DOUBLE_LIT <= 2.0;",
-        " static const BOP3_14 = 2.0 >= DOUBLE_LIT;",
-        " static const BOP3_15 = DOUBLE_LIT >= 2;",
-        "}"));
-  }
-
-  public void testConstantBinaryExpression4() {
-    resolveAndTestCtConst(Joiner.on("\n").join(
-        "class Object {}",
-        "class A {",
-        " static const INT_LIT = 5;",
-        " static const INT_LIT_REF = INT_LIT;",
-        " static const DOUBLE_LIT = 1.5;",
-        " static const BOOL_LIT = true;",
-        " static const STRING_LIT = 'Hello';",
-        " static const BOP4_0 = 5 % INT_LIT;",
-        " static const BOP4_1 = INT_LIT % 5;",
-        " static const BOP4_2 = 5.0 % DOUBLE_LIT;",
-        " static const BOP4_3 = DOUBLE_LIT % 5.0;",
-        " static const BOP5_0 = 0x80 & 0x04;",
-        " static const BOP5_1 = 0x80 | 0x04;",
-        " static const BOP5_2 = 0x80 << 0x04;",
-        " static const BOP5_3 = 0x80 >> 0x04;",
-        " static const BOP5_4 = 0x80 ~/ 0x04;",
-        " static const BOP5_5 = DOUBLE_LIT ~/ DOUBLE_LIT;",
-        " static const BOP5_6 = 0x80 ^ 0x04;",
-        " static const BOP6 = BOOL_LIT && true;",
-        " static const BOP7 = false || BOOL_LIT;",
-        " static const BOP8 = STRING_LIT == 'World!';",
-        " static const BOP9 = 'Hello' != STRING_LIT;",
-        "}"));
-  }
-
-  public void testConstantBinaryExpression5() {
-    resolveAndTestCtConst(Joiner.on("\n").join(
-        "class Object {}",
-        "class int {}",
-        "class A {",
-        " static int foo() { return 1; }",
-        "}",
-        "class B {",
-        " static const BOP1 = A.foo() * 1;",
-        " static const BOP2 = 1 * A.foo();",
-        "}"),
-        ResolverErrorCode.EXPECTED_CONSTANT_EXPRESSION,
-        ResolverErrorCode.EXPECTED_CONSTANT_EXPRESSION_NUMBER,
-        ResolverErrorCode.EXPECTED_CONSTANT_EXPRESSION,
-        ResolverErrorCode.EXPECTED_CONSTANT_EXPRESSION_NUMBER);
-  }
-
-  public void testConstantBinaryExpression6() {
-    resolveAndTestCtConst(Joiner.on("\n").join(
-        "class Object {}",
-        "class int {}",
-        "class String {}",
-        "class A {",
-        " static int foo() { return 1; }",
-        " static String bar() { return '1'; }",
-        "}",
-        "class B {",
-        " static const BOP1 = 2 < A.foo();",
-        " static const BOP2 = A.foo() < 2;",
-        " static const BOP3 = A.foo();",
-        " static const BOP4 = A.bar();",
-        "}"),
-        ResolverErrorCode.EXPECTED_CONSTANT_EXPRESSION,
-        ResolverErrorCode.EXPECTED_CONSTANT_EXPRESSION_NUMBER,
-        ResolverErrorCode.EXPECTED_CONSTANT_EXPRESSION,
-        ResolverErrorCode.EXPECTED_CONSTANT_EXPRESSION_NUMBER,
-        ResolverErrorCode.EXPECTED_CONSTANT_EXPRESSION,
-        ResolverErrorCode.EXPECTED_CONSTANT_EXPRESSION);
-  }
-
-  public void testConstantBinaryExpression7() {
-    resolveAndTestCtConst(Joiner.on("\n").join(
-        "class Object {}",
-        "class int {}",
-        "class double {}",
-        "class num {}",
-        "class A {",
-        " static const BOP1 = 0x80 & 2.0;",
-        " static const BOP2 = 2.0 & 0x80;",
-        "}"),
-        ResolverErrorCode.EXPECTED_CONSTANT_EXPRESSION_INT,
-        ResolverErrorCode.EXPECTED_CONSTANT_EXPRESSION_INT);
-  }
-
-  public void testConstantBinaryExpression8() {
-    resolveAndTestCtConst(Joiner.on("\n").join(
-        "class Object {}",
-        "class bool {}",
-        "class int {}",
-        "class double {}",
-        "class num {}",
-        "class A {",
-        " static bool foo() { return true; }",
-        "}",
-        " class B {",
-        " static const BOP3 = 45 && true;",
-        " static const BOP4 = true || 45;",
-        " static const BOP5 = true && A.foo();",
-        " static const BOP6 = A.foo() && false;",
-        "}"),
-        ResolverErrorCode.EXPECTED_CONSTANT_EXPRESSION_BOOLEAN,
-        ResolverErrorCode.EXPECTED_CONSTANT_EXPRESSION_BOOLEAN,
-        ResolverErrorCode.EXPECTED_CONSTANT_EXPRESSION,
-        ResolverErrorCode.EXPECTED_CONSTANT_EXPRESSION_BOOLEAN,
-        ResolverErrorCode.EXPECTED_CONSTANT_EXPRESSION,
-        ResolverErrorCode.EXPECTED_CONSTANT_EXPRESSION_BOOLEAN);
-  }
-
-  public void testConstantBinaryExpression9() {
-    resolveAndTestCtConst(
-        Joiner.on("\n").join(
-            "class Object {}",
-            "class bool {}",
-            "class int {}",
-            "class double {}",
-            "class num {}",
-            "class A {",
-            " static Object foo() { return true; }",
-            "}",
-            "class B {",
-            " const B();",
-            " static const OBJECT_LIT = const B();",
-            " static const INT_LIT = 1;",
-            " static const STRING_LIT = 'true';",
-            " static const BOP1 = STRING_LIT && true;",
-            " static const BOP2 = false || STRING_LIT;",
-            " static const BOP3 = 59 == OBJECT_LIT;",
-            " static const BOP4 = OBJECT_LIT != 59;",
-            "}"),
-        ResolverErrorCode.EXPECTED_CONSTANT_EXPRESSION_BOOLEAN,
-        ResolverErrorCode.EXPECTED_CONSTANT_EXPRESSION_BOOLEAN,
-        ResolverErrorCode.EXPECTED_CONSTANT_EXPRESSION_STRING_NUMBER_BOOL,
-        ResolverErrorCode.EXPECTED_CONSTANT_EXPRESSION_STRING_NUMBER_BOOL);
-  }
-
-  public void testConstantConstructorAssign1() {
-    resolveAndTestCtConst(Joiner.on("\n").join(
-        "class Object {}",
-        "class A {",
-        "  const A();",
-        "}",
-        "class B {",
-        "  const a = const A();", // Constant constructor
-        "}"));
-  }
-
-  public void testConstantConstructorAssign2() {
-    // Negative tests
-    resolveAndTestCtConst(Joiner.on("\n").join(
-        "class Object {}",
-        "class A {",
-        "  const A();",
-        "  const a = new A();", // Error: not a constant constructor
-        "}"),
-        ResolverErrorCode.EXPECTED_CONSTANT_EXPRESSION);
-  }
-
-  public void testConstantLiteralAssign1() {
-    resolveAndTestCtConst(Joiner.on("\n").join(
-        "class Object {}",
-        "class A {",
-        "  const b = true;",
-        "  const s = 'apple';", // string literal
-        "  const i = 1;", // integer literal
-        "  const d = 3.3;", // double literal
-        "  const h = 0xf;", // hex literal
-        "  const n = null;", // null
-        "}"));
-  }
-
-  public void testConstantLiteralAssign2() {
-    resolveAndTestCtConst(Joiner.on("\n").join(
-        "class Object {}",
-        "class A {",
-        "  foo() { return 'Eve';}",
-        "  const person = 'earthling';",
-        "  const s = 'Hello ${foo()}!';",
-        "}"),
-        ResolverErrorCode.EXPECTED_CONSTANT_EXPRESSION,
-        ResolverErrorCode.EXPECTED_CONSTANT_EXPRESSION_STRING_NUMBER_BOOL);
-  }
-
-  public void testConstantTypedLiteralAssign1() {
-    resolveAndTestCtConst(Joiner.on("\n").join(
-        "class Object {}",
-        "class String {}",
-        "class List<T> {}",
-        "class Map<K,V> {}",
-        "class A {",
-        "  const aList = const[1, 2, 3];", // array literal
-        "  const map = const { '1': 'one', '2': 'banana' };", // map literal
-        "  const val = aList[2];",
-        "}"));
-  }
-
-  public void testConstantTypedLiteralAssign2() {
-    resolveAndTestCtConst(Joiner.on("\n").join(
-        "class Object {}",
-        "class List<T> {}",
-        "class A {",
-        "  // array literal not const",
-        "  const aList= [1, 2, 3];",
-        "}"),
-        ResolverErrorCode.EXPECTED_CONSTANT_EXPRESSION);
-  }
-
-  public void testConstantTypedLiteralAssign3() {
-    resolveAndTestCtConst(Joiner.on("\n").join(
-        "class Object {}",
-        "class List<T> {}",
-        "class A {",
-        "  static foo() { return 1; }",
-        "  // const array literal contains non-const member",
-        "  const aList = const [foo(), 2, 3];",
-        "}"),
-        ResolverErrorCode.EXPECTED_CONSTANT_EXPRESSION);
-  }
-
-  public void testConstantTypedLiteralAssign4() {
-    resolveAndTestCtConst(Joiner.on("\n").join(
-        "class Object {}",
-        "class String {}",
-        "class Map<K,V> {}",
-        "class A {",
-        "  // map literal is not const",
-        "  const aMap = { '1': 'one', '2': 'banana' };",
-        "}"),
-        ResolverErrorCode.EXPECTED_CONSTANT_EXPRESSION);
-  }
-  public void testConstantTypedLiteralAssign5() {
-    resolveAndTestCtConst(Joiner.on("\n").join(
-        "class Object {}",
-        "class String {}",
-        "class Map<K,V> {}",
-        "class A {",
-        "  static String foo() { return 'one'; }",
-        "  const String s = 'apple';",
-        "  // map literal contains non-const member",
-        "  const map = const { '1': foo(), '2': 'banana' };",
-        "  const stringInterp = 'It was that woman who gave me the ${s}';",
-        "}"),
-        ResolverErrorCode.EXPECTED_CONSTANT_EXPRESSION);
-  }
-
-  public void testConstantUnaryExpression1() {
-    resolveAndTestCtConst(Joiner.on("\n").join(
-        "class Object {}",
-        "class A {",
-        "  static const BOOL_LIT = true;",
-        "  static const UOP1_0 = !BOOL_LIT;",
-        "  static const UOP1_1 = BOOL_LIT || !true;",
-        "  static const UOP1_2 = !BOOL_LIT || true;",
-        "  static const UOP1_3 = !(BOOL_LIT && true);",
-        "}"));
-  }
-
-  public void testConstantUnaryExpression2() {
-    resolveAndTestCtConst(Joiner.on("\n").join(
-        "class Object {}",
-        "class A {",
-        "  static const BOOL_LIT = true;",
-        "  static const INT_LIT = 123;",
-        "  static const DOUBLE_LIT = 12.3;",
-        "  static const UOP2_0 = ~0xf0;",
-        "  static const UOP2_1 = ~INT_LIT;",
-        "  static const UOP2_2 = ~INT_LIT & 123;",
-        "  static const UOP2_3 = ~(INT_LIT | 0xff);",
-        "}"));
-  }
-
-  public void testConstantUnaryExpression3() {
-    resolveAndTestCtConst(Joiner.on("\n").join(
-        "class Object {}",
-        "class A {",
-        "  static const INT_LIT = 123;",
-        "  static const DOUBLE_LIT = 12.3;",
-        "  static const UOP3_0 = -0xf0;",
-        "  static const UOP3_1 = -INT_LIT;",
-        "  static const UOP3_2 = -INT_LIT + 123;",
-        "  static const UOP3_3 = -(INT_LIT * 0xff);",
-        "  static const UOP3_4 = -0xf0;",
-        "  static const UOP3_5 = -DOUBLE_LIT;",
-        "  static const UOP3_6 = -DOUBLE_LIT + 123;",
-        "  static const UOP3_7 = -(DOUBLE_LIT * 0xff);",
-        "}"));
-  }
-
-  public void testConstantUnaryExpression4() {
-    resolveAndTestCtConst(Joiner.on("\n").join(
-        "class Object {}",
-        "class int {}",
-        "class A {",
-        "  // Unary expression",
-        "  static const BOOL_LIT = true;",
-        "  static int foo() { return 3; }",
-        "  static const UOP1 = !5;",
-        "  static const UOP2 = !foo();",
-        "  static const UOP3 = !(5);",
-        "  static const UOP4 = !(foo());",
-        "}"),
-        ResolverErrorCode.EXPECTED_CONSTANT_EXPRESSION_BOOLEAN,
-        ResolverErrorCode.EXPECTED_CONSTANT_EXPRESSION,
-        ResolverErrorCode.EXPECTED_CONSTANT_EXPRESSION_BOOLEAN,
-        ResolverErrorCode.EXPECTED_CONSTANT_EXPRESSION_BOOLEAN,
-        ResolverErrorCode.EXPECTED_CONSTANT_EXPRESSION,
-        ResolverErrorCode.EXPECTED_CONSTANT_EXPRESSION_BOOLEAN);
-  }
-
-  public void testConstantVariableAssign1() {
-    resolveAndTestCtConst(Joiner.on("\n").join(
-        "class Object {}",
-        "class A {",
-        "  static const F = 1;",
-        "}",
-        "class B {",
-        "  const i = 1;",
-        "  const j = i;", // variable that is a compile-time constant
-        "  const k = A.F;", // variable that is a compile-time constant
-        "}"));
-  }
-
-  public void testConstantVariableAssign2() {
-    resolveAndTestCtConst(Joiner.on("\n").join(
-        "class Object {}",
-        "class A {",
-        " static foo() {return 1;}",
-        " const i = foo();",  // Error: not a constant integer
-        "}"),
-        ResolverErrorCode.EXPECTED_CONSTANT_EXPRESSION);
-  }
-
-  public void testConstantVariableAssign3() {
-      // Part of the regular resolver pass
-      resolveAndTest(Joiner.on("\n").join(
-          "class Object {}",
-          "class A {",
-          "  const foo;",
-          "}"),
-          ResolverErrorCode.CONST_REQUIRES_VALUE);
-  }
-
-  public void testForwardLookupExpressions() {
-    resolveAndTestCtConst(Joiner.on("\n").join(
-        "class Object {}",
-        "class A {",
-        "  const value1 = value2 * 2;",
-        "  const value2 = value3 * 4;",
-        "  const value3 = 8;",
-        "}"));
-  }
-
-  public void testInvalidDefaultParameterWithField() {
-    resolveAndTestCtConstExpectErrors(
-        Joiner.on("\n").join(
-            "class Object {}",
-            "class Function {}",
-            "Function get topLevelGetter => () {};",
-            "topLevel([var x = topLevelGetter]) { x(); }",
-            "main() { topLevel(); }"),
-        errEx(ResolverErrorCode.EXPECTED_CONSTANT_EXPRESSION, 4, 19, 14),
-        errEx(ResolverErrorCode.EXPECTED_CONSTANT_EXPRESSION, 3, 1, 37));
-  }
-  
-  /** 
-   * Integers used in parenthesis result in integer values.
-   * (A bug caused them to be demoted to 'num')
-   */
-  public void testParenthizedMathExpressions1() {
-    resolveAndTestCtConstExpectErrors(
-        Joiner.on("\n").join(    
-            "class Object {}",
-            "class int {}",
-            "class A {",
-            "  const int value1 = (1 << 5) - 1;",
-            "  const int value2 = value1 & 0xFFFF;",
-            "  const int value3 = (1 << 5) + 1;",
-            "  const int value4 = value3 & 0xFFFF;",
-            "  const int value5 = (1 << 5) * 1;",
-            "  const int value6 = value5 & 0xFFFF;",            
-            "  const int value7 = (1 << 5) / 1;",
-            "  const int value8 = value7 & 0xFFFF;",                        
-            "}"));    
-  }
-  
-  /** 
-   * Doubles used in parenthesis result in double values.
-   * (A bug caused them to be demoted to 'num')
-   */  
-  public void testParenthizedMathExpressions2() {
-    resolveAndTestCtConstExpectErrors(
-        Joiner.on("\n").join(    
-            "class Object {}",
-            "class double {}",
-            "class A {",
-            "  const double value1 = (1.0 * 5.0) - 1.0;",
-            "  const double value2 = value1 + 99.0;",
-            "  const double value3 = (1.0 * 5.0) + 1.0;",
-            "  const double value4 = value3 * 99.0;",
-            "  const double value5 = (1.0 * 5.0) * 1.0;",
-            "  const double value6 = value5 * 99.0;",            
-            "  const double value7 = (1.0 * 5.0) / 1.0;",
-            "  const double value8 = value7 * 99.0;",                        
-            "}"));    
-  }  
-  
-  /**
-   * Mixing doubles and ints in arithmetic should result in a double value.
-   * Not explicitly called out for in the spec yet, but this is the runtime behavior.
-   */
-  public void testParenthizedMathExpressions3() {
-    resolveAndTestCtConstExpectErrors(
-        Joiner.on("\n").join(    
-            "class Object {}",
-            "class double {}",
-            "class A {",
-            "  const double value1 = (1 * 5) - 1.0;",
-            "  const double value2 = value1 + 99.0;",
-            "  const double value3 = (1 * 5) + 1.0;",
-            "  const double value4 = value3 * 99.0;",
-            "  const double value5 = (1 * 5) * 1.0;",
-            "  const double value6 = value5 * 99.0;",            
-            "  const double value7 = (1 * 5) / 1.0;",
-            "  const double value8 = value7 * 99.0;",                        
-            "}"));    
-  }
-  
-  /**
-   * Test mixing strings with ints and doubles in a compile time constant expression.
-   * Should result in errors.
-   */
-  public void testParenthizedMathExpressions4() {
-    resolveAndTestCtConstExpectErrors(
-        Joiner.on("\n").join(    
-            "class Object {}",
-            "class int {}",
-            "class A {",
-            "  const int value1 = ('Invalid') - 1;",
-            "  const int value2 = value1 & 0xFFFF;",
-            "}"),
-            errEx(ResolverErrorCode.EXPECTED_CONSTANT_EXPRESSION_NUMBER, 4, 22, 11),
-            // Unfortunately, the CTConst analyzer reports the same error twice 
-            // because value1 is analyzed twice, once for original assignment, and a
-            // second time when used in the RHS of the value2 definition.
-            errEx(ResolverErrorCode.EXPECTED_CONSTANT_EXPRESSION_NUMBER, 4, 22, 11),
-            errEx(ResolverErrorCode.EXPECTED_CONSTANT_EXPRESSION_INT, 5, 22, 6));
-    
-    resolveAndTestCtConstExpectErrors(
-        Joiner.on("\n").join(            
-            "class Object {}",
-            "class int {}",                             
-            "class A {",
-            "  const int value3 = ('Invalid') + 1;",
-            "  const int value4 = value3 & 0xFFFF;",
-            "}"),
-            errEx(ResolverErrorCode.EXPECTED_CONSTANT_EXPRESSION_STRING, 4, 36, 1),
-            errEx(ResolverErrorCode.EXPECTED_CONSTANT_EXPRESSION_STRING, 4, 36, 1),
-            errEx(ResolverErrorCode.EXPECTED_CONSTANT_EXPRESSION_INT, 5, 22, 6));
-    
-    resolveAndTestCtConstExpectErrors(
-        Joiner.on("\n").join(            
-            "class Object {}",
-            "class int {}",
-            "class A {",                             
-            "  const int value5 = ('Invalid') * 1;",
-            "  const int value6 = value5 & 0xFFFF;",            
-            "}"),
-            errEx(ResolverErrorCode.EXPECTED_CONSTANT_EXPRESSION_NUMBER, 4, 22, 11),
-            errEx(ResolverErrorCode.EXPECTED_CONSTANT_EXPRESSION_NUMBER, 4, 22, 11),
-            errEx(ResolverErrorCode.EXPECTED_CONSTANT_EXPRESSION_INT, 5, 22, 6));            
-                             
-    resolveAndTestCtConstExpectErrors(
-        Joiner.on("\n").join(                
-            "class Object {}",
-            "class int {}",
-            "class A {",
-            "  const int value7 = ('Invalid') / 1;",
-            "  const int value8 = value7 & 0xFFFF;",                        
-            "}"),
-            errEx(ResolverErrorCode.EXPECTED_CONSTANT_EXPRESSION_NUMBER, 4, 22, 11),
-            errEx(ResolverErrorCode.EXPECTED_CONSTANT_EXPRESSION_NUMBER, 4, 22, 11),
-            errEx(ResolverErrorCode.EXPECTED_CONSTANT_EXPRESSION_INT, 5, 22, 6));            
-  }
-}
diff --git a/compiler/javatests/com/google/dart/compiler/resolver/ConstSuperNegativeTest1.dart b/compiler/javatests/com/google/dart/compiler/resolver/ConstSuperNegativeTest1.dart
deleted file mode 100644
index f8cc9dc..0000000
--- a/compiler/javatests/com/google/dart/compiler/resolver/ConstSuperNegativeTest1.dart
+++ /dev/null
@@ -1,14 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-// Expect error - Sub omits call to Base final ctor in the init list.
-
-class Base {
-  const Base();
-}
-
-class Sub extends Base {
- const Sub(a) : this.a_ = a;
- final a_;
-}
diff --git a/compiler/javatests/com/google/dart/compiler/resolver/ConstSuperNegativeTest2.dart b/compiler/javatests/com/google/dart/compiler/resolver/ConstSuperNegativeTest2.dart
deleted file mode 100644
index e273f12..0000000
--- a/compiler/javatests/com/google/dart/compiler/resolver/ConstSuperNegativeTest2.dart
+++ /dev/null
@@ -1,13 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-// expect error - Sub calls a non-const super.
-class Base {
-  Base() { }
-}
-
-class Sub extends Base {
- const Sub(a) : super(1), this.a_ = a;
- final a_;
-}
diff --git a/compiler/javatests/com/google/dart/compiler/resolver/ConstSuperTest.dart b/compiler/javatests/com/google/dart/compiler/resolver/ConstSuperTest.dart
deleted file mode 100644
index 2424b15..0000000
--- a/compiler/javatests/com/google/dart/compiler/resolver/ConstSuperTest.dart
+++ /dev/null
@@ -1,17 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-// expect no failures - Sub.A omits call to const super, but one will be added
-
-class Base {
-  const Base([a]);
-  Base.A(a,b) { }
-}
-
-class Sub extends Base {
- const Sub(a)   : super(a), this.a_ = a;
- const Sub.A(a) : this.a_ = a;
- const Sub.B(a) : super(a), this.a_ = a;
- final a_;
-}
diff --git a/compiler/javatests/com/google/dart/compiler/resolver/ConstVariableInitializationNegativeTest1.dart b/compiler/javatests/com/google/dart/compiler/resolver/ConstVariableInitializationNegativeTest1.dart
deleted file mode 100644
index 8f8ff13..0000000
--- a/compiler/javatests/com/google/dart/compiler/resolver/ConstVariableInitializationNegativeTest1.dart
+++ /dev/null
@@ -1,12 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-// case 1 - const variable must be initialized.
-
-class A {
-  static foo() {
-    final Object x;
-  }
-}
-
diff --git a/compiler/javatests/com/google/dart/compiler/resolver/ConstVariableInitializationNegativeTest2.dart b/compiler/javatests/com/google/dart/compiler/resolver/ConstVariableInitializationNegativeTest2.dart
deleted file mode 100644
index d8731f0..0000000
--- a/compiler/javatests/com/google/dart/compiler/resolver/ConstVariableInitializationNegativeTest2.dart
+++ /dev/null
@@ -1,12 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-// case 2 - const variable must be initialized (variable list).
-
-class A {
-  static foo() {
-    final Object x = 1, y, z = 3;
-  }
-}
-
diff --git a/compiler/javatests/com/google/dart/compiler/resolver/CyclicRedirectedConstructorNegativeTest.dart b/compiler/javatests/com/google/dart/compiler/resolver/CyclicRedirectedConstructorNegativeTest.dart
deleted file mode 100644
index b2a2ee3..0000000
--- a/compiler/javatests/com/google/dart/compiler/resolver/CyclicRedirectedConstructorNegativeTest.dart
+++ /dev/null
@@ -1,9 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-class A {
-  A(x) : this.foo(x);
-  A.foo(x) : this.bar(x, x * 2);
-  A.bar(x,y) : this(x + y);
-}
diff --git a/compiler/javatests/com/google/dart/compiler/resolver/ElementMapTest.java b/compiler/javatests/com/google/dart/compiler/resolver/ElementMapTest.java
deleted file mode 100644
index 55c9cee..0000000
--- a/compiler/javatests/com/google/dart/compiler/resolver/ElementMapTest.java
+++ /dev/null
@@ -1,199 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.resolver;
-
-import com.google.dart.compiler.ast.DartObsoleteMetadata;
-import com.google.dart.compiler.ast.DartNode;
-import com.google.dart.compiler.ast.Modifiers;
-import com.google.dart.compiler.common.SourceInfo;
-import com.google.dart.compiler.type.Type;
-
-import junit.framework.TestCase;
-
-public class ElementMapTest extends TestCase {
-
-  private class MockElement implements NodeElement {
-
-    private final ElementKind kind;
-    private final String name;
-
-    public MockElement(String name, ElementKind kind) {
-      this.name = name;
-      this.kind = kind;
-    }
-
-    @Override
-    public EnclosingElement getEnclosingElement() {
-      throw new RuntimeException();
-    }
-
-    @Override
-    public ElementKind getKind() {
-      return kind;
-    }
-
-    @Override
-    public DartObsoleteMetadata getMetadata() {
-      throw new RuntimeException();
-    }
-
-    @Override
-    public Modifiers getModifiers() {
-      throw new RuntimeException();
-    }
-
-    @Override
-    public String getName() {
-      return name;
-    }
-
-    @Override
-    public DartNode getNode() {
-      throw new RuntimeException();
-    }
-
-    @Override
-    public String getOriginalName() {
-      throw new RuntimeException();
-    }
-
-    @Override
-    public Type getType() {
-      throw new RuntimeException();
-    }
-
-    @Override
-    public boolean isDynamic() {
-      throw new RuntimeException();
-    }
-
-    @Override
-    public SourceInfo getSourceInfo() {
-      throw new RuntimeException();
-    }
-    
-    @Override
-    public SourceInfo getNameLocation() {
-      throw new RuntimeException();
-    }
-  }
-
-  public void testAdd1() {
-    ElementMap map = new ElementMap();
-    MockElement element = new MockElement("foo", ElementKind.METHOD);
-    map.add("foo", element);
-    assertEquals(1, map.size());
-    assertEquals(1, map.values().size());
-    assertEquals(element, map.values().get(0));
-    assertEquals(element, map.get("foo"));
-    assertNull(map.get("bar"));
-    assertNull(map.get("foo", ElementKind.FIELD));
-    assertEquals(element, map.get("foo", ElementKind.METHOD));
-  }
-
-  public void testAdd1DifferentName() {
-    ElementMap map = new ElementMap();
-    MockElement element = new MockElement("bar", ElementKind.METHOD);
-    map.add("foo", element);
-    assertEquals(1, map.size());
-    assertEquals(1, map.values().size());
-    assertEquals(element, map.values().get(0));
-    assertEquals(element, map.get("foo"));
-    assertNull(map.get("bar"));
-    assertNull(map.get("foo", ElementKind.FIELD));
-    assertEquals(element, map.get("foo", ElementKind.METHOD));
-  }
-
-  public void testAdd2() {
-    ElementMap map = new ElementMap();
-    MockElement element = new MockElement("foo", ElementKind.METHOD);
-    MockElement element2 = new MockElement("bar", ElementKind.METHOD);
-    map.add("foo", element);
-    map.add("bar", element2);
-    assertEquals(2, map.size());
-    assertEquals(2, map.values().size());
-    assertEquals(element, map.values().get(0));
-    assertEquals(element2, map.values().get(1));
-    assertEquals(element, map.get("foo"));
-    assertEquals(element2, map.get("bar"));
-    assertNull(map.get("foo", ElementKind.FIELD));
-    assertEquals(element, map.get("foo", ElementKind.METHOD));
-  }
-
-  public void testAdd2SameName() {
-    ElementMap map = new ElementMap();
-    MockElement element = new MockElement("foo", ElementKind.METHOD);
-    MockElement element2 = new MockElement("foo", ElementKind.FIELD);
-    map.add("foo", element);
-    map.add("foo", element2);
-    assertEquals(2, map.size());
-    assertEquals(2, map.values().size());
-    assertEquals(element, map.values().get(0));
-    assertEquals(element2, map.values().get(1));
-    assertEquals(element, map.get("foo"));
-    assertNull(map.get("bar"));
-    assertEquals(element2, map.get("foo", ElementKind.FIELD));
-    assertEquals(element, map.get("foo", ElementKind.METHOD));
-  }
-  
-  public void testDuplicate() throws Exception {
-    ElementMap map = new ElementMap();
-    MockElement element = new MockElement("foo", ElementKind.METHOD);
-    assertEquals(0, map.size());
-    map.add("foo", element);
-    assertEquals(1, map.size());
-    map.add("foo", element);
-    assertEquals(1, map.size());
-  }
-  
-  public void testDuplicate2() throws Exception {
-    ElementMap map = new ElementMap();
-    MockElement element = new MockElement("foo", ElementKind.METHOD);
-    MockElement element2 = new MockElement("foo", ElementKind.FIELD);
-    assertEquals(0, map.size());
-    map.add("foo", element);
-    assertEquals(1, map.size());
-    map.add("foo", element2);
-    assertEquals(2, map.size());
-    map.add("foo", element);
-    assertEquals(2, map.size());
-    map.add("foo", element2);
-    assertEquals(2, map.size());
-  }
-
-  public void testEmpty() throws Exception {
-    ElementMap map = new ElementMap();
-    assertEmpty(map);
-  }
-
-  public void testGrow() throws Exception {
-    ElementMap map = new ElementMap();
-    MockElement element = new MockElement("foo", ElementKind.METHOD);
-    MockElement element2 = new MockElement("foo", ElementKind.FIELD);
-    map.add("foo", element);
-    map.add("foo", element2);
-
-    for (int i = 0; i < 100; i++) {
-      map.add("mem" + i, new MockElement("mem" + i, ElementKind.METHOD));
-    }
-
-    assertEquals(element, map.values().get(0));
-    assertEquals(element2, map.values().get(1));
-    assertEquals(element, map.get("foo"));
-    assertNull(map.get("bar"));
-    assertEquals(element2, map.get("foo", ElementKind.FIELD));
-    assertEquals(element, map.get("foo", ElementKind.METHOD));
-  }
-
-  private void assertEmpty(ElementMap map) {
-    assertTrue(map.isEmpty());
-    assertEquals(0, map.size());
-    assertEquals(0, map.values().size());
-    assertNull(map.get("foo"));
-    assertNull(map.get("bar"));
-    assertNull(map.get("foo", ElementKind.FIELD));
-    assertNull(map.get("foo", ElementKind.METHOD));
-  }
-}
diff --git a/compiler/javatests/com/google/dart/compiler/resolver/Initializer1NegativeTest.dart b/compiler/javatests/com/google/dart/compiler/resolver/Initializer1NegativeTest.dart
deleted file mode 100644
index ed326a0..0000000
--- a/compiler/javatests/com/google/dart/compiler/resolver/Initializer1NegativeTest.dart
+++ /dev/null
@@ -1,9 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-// Check that an unresolved field in an initializer is an error.
-
-class A {
-  A() : this.a = 1 {}
-}
diff --git a/compiler/javatests/com/google/dart/compiler/resolver/Initializer2NegativeTest.dart b/compiler/javatests/com/google/dart/compiler/resolver/Initializer2NegativeTest.dart
deleted file mode 100644
index e0bea1c..0000000
--- a/compiler/javatests/com/google/dart/compiler/resolver/Initializer2NegativeTest.dart
+++ /dev/null
@@ -1,10 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-// Check that a static field in an initializer is an error.
-
-class A {
-  static var a;
-  A() : this.a = 1 {}
-}
diff --git a/compiler/javatests/com/google/dart/compiler/resolver/Initializer3NegativeTest.dart b/compiler/javatests/com/google/dart/compiler/resolver/Initializer3NegativeTest.dart
deleted file mode 100644
index 01598fe..0000000
--- a/compiler/javatests/com/google/dart/compiler/resolver/Initializer3NegativeTest.dart
+++ /dev/null
@@ -1,14 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-// Check that a super field in an initializer is an error.
-
-class B {
-  var a;
-  B() : this.a = 1 {}
-}
-
-class A extends B {
-  A() : super(), this.a = 1 {}
-}
diff --git a/compiler/javatests/com/google/dart/compiler/resolver/Initializer4NegativeTest.dart b/compiler/javatests/com/google/dart/compiler/resolver/Initializer4NegativeTest.dart
deleted file mode 100644
index 00f88d1..0000000
--- a/compiler/javatests/com/google/dart/compiler/resolver/Initializer4NegativeTest.dart
+++ /dev/null
@@ -1,11 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-// Check that using an instance field in an initializer expression is an error.
-
-class A {
-  var a;
-  var b;
-  A() : this.a = b {}
-}
diff --git a/compiler/javatests/com/google/dart/compiler/resolver/Initializer5NegativeTest.dart b/compiler/javatests/com/google/dart/compiler/resolver/Initializer5NegativeTest.dart
deleted file mode 100644
index 27cd0e3..0000000
--- a/compiler/javatests/com/google/dart/compiler/resolver/Initializer5NegativeTest.dart
+++ /dev/null
@@ -1,10 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-// Check that using an undefined variable in an initializer expression is an error.
-
-class A {
-  final aa;
-  A(var a) : this.aa = c {}
-}
diff --git a/compiler/javatests/com/google/dart/compiler/resolver/Initializer6NegativeTest.dart b/compiler/javatests/com/google/dart/compiler/resolver/Initializer6NegativeTest.dart
deleted file mode 100644
index b0c1c76..0000000
--- a/compiler/javatests/com/google/dart/compiler/resolver/Initializer6NegativeTest.dart
+++ /dev/null
@@ -1,10 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-// Check that in a class without a supertype referencing super in the initializer expression is an
-// error.
-
-class A {
-  A() : super(1) {}
-}
diff --git a/compiler/javatests/com/google/dart/compiler/resolver/MockLibraryUnit.java b/compiler/javatests/com/google/dart/compiler/resolver/MockLibraryUnit.java
deleted file mode 100644
index 37bec07..0000000
--- a/compiler/javatests/com/google/dart/compiler/resolver/MockLibraryUnit.java
+++ /dev/null
@@ -1,33 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-package com.google.dart.compiler.resolver;
-
-import com.google.dart.compiler.LibrarySource;
-import com.google.dart.compiler.MockLibrarySource;
-import com.google.dart.compiler.ast.DartUnit;
-import com.google.dart.compiler.ast.LibraryUnit;
-
-/**
- * Testing support for {@link LibraryUnit}.
- */
-public final class MockLibraryUnit {
-  /**
-   * @return the mock {@link LibraryUnit}.
-   */
-  public static LibraryUnit create() {
-    LibrarySource librarySource = new MockLibrarySource();
-    return new LibraryUnit(librarySource);
-  }
-
-  /**
-   * Creates the mock {@link LibraryUnit} and sets it for given {@link DartUnit}.
-   * 
-   * @return the mock {@link LibraryUnit}.
-   */
-  public static LibraryUnit create(DartUnit unit) {
-    LibraryUnit libraryUnit = create();
-    unit.setLibrary(libraryUnit);
-    return libraryUnit;
-  }
-}
diff --git a/compiler/javatests/com/google/dart/compiler/resolver/NegativeResolverTest.java b/compiler/javatests/com/google/dart/compiler/resolver/NegativeResolverTest.java
deleted file mode 100644
index d924a04..0000000
--- a/compiler/javatests/com/google/dart/compiler/resolver/NegativeResolverTest.java
+++ /dev/null
@@ -1,1199 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-package com.google.dart.compiler.resolver;
-
-import com.google.dart.compiler.CompilerTestCase;
-import com.google.dart.compiler.DartCompilationError;
-import com.google.dart.compiler.ast.DartFunctionTypeAlias;
-import com.google.dart.compiler.ast.DartThisExpression;
-import com.google.dart.compiler.ast.DartTypeParameter;
-import com.google.dart.compiler.ast.DartUnit;
-import com.google.dart.compiler.common.ErrorExpectation;
-import com.google.dart.compiler.testing.TestCompilerContext;
-import com.google.dart.compiler.type.Type;
-
-import static com.google.dart.compiler.common.ErrorExpectation.assertErrors;
-import static com.google.dart.compiler.common.ErrorExpectation.errEx;
-
-import java.util.ArrayList;
-import java.util.List;
-
-public class NegativeResolverTest extends CompilerTestCase {
-  List<DartCompilationError> errors = new ArrayList<DartCompilationError>();
-
-  /**
-   * Parses given Dart source, runs {@link Resolver} and checks that expected errors were generated.
-   */
-  public void checkSourceErrors(String source, ErrorExpectation... expectedErrors) {
-    DartUnit unit = parseUnit("Test.dart", source);
-    resolve(unit);
-    assertErrors(errors, expectedErrors);
-  }
-
-  public void checkSourceErrorsAsSystemLibrary(String source, ErrorExpectation... expectedErrors) {
-    DartUnit unit = parseUnitAsSystemLibrary("Test.dart", source);
-    resolve(unit);
-    assertErrors(errors, expectedErrors);
-  }
-
-
-  /**
-   * Parses given Dart file, runs {@link Resolver} and checks that expected errors were generated.
-   */
-  public void checkFileErrors(String source, ErrorExpectation... expectedErrors) {
-    DartUnit unit = parseUnit(source);
-    resolve(unit);
-    assertErrors(errors, expectedErrors);
-  }
-
-  public void checkNumErrors(String fileName, int expectedErrorCount) {
-    DartUnit unit = parseUnit(fileName);
-    resolve(unit);
-    if (errors.size() != expectedErrorCount) {
-      fail(String.format(
-          "Expected %s errors, but got %s: %s",
-          expectedErrorCount,
-          errors.size(),
-          errors));
-    }
-  }
-
-  private void resolve(DartUnit unit) {
-    unit.getTopLevelNodes().add(ResolverTestCase.makeClass("bool", null));
-    unit.getTopLevelNodes().add(ResolverTestCase.makeClass("num", null));
-    unit.getTopLevelNodes().add(ResolverTestCase.makeClass("double", null));
-    unit.getTopLevelNodes().add(ResolverTestCase.makeClass("int", null));
-    unit.getTopLevelNodes().add(ResolverTestCase.makeClass("Object", null));
-    unit.getTopLevelNodes().add(ResolverTestCase.makeClass("Null", null));
-    unit.getTopLevelNodes().add(ResolverTestCase.makeClass("String", null));
-    unit.getTopLevelNodes().add(ResolverTestCase.makeClass("Function", null));
-    unit.getTopLevelNodes().add(ResolverTestCase.makeInterface("List", "T"));
-    unit.getTopLevelNodes().add(ResolverTestCase.makeInterface("Map", "K", "V"));
-    ResolverTestCase.resolve(unit, getContext());
-  }
-
-  public void testInitializer1() {
-    checkNumErrors("Initializer1NegativeTest.dart", 1);
-  }
-
-  public void testInitializer2() {
-    checkNumErrors("Initializer2NegativeTest.dart", 1);
-  }
-
-  public void testInitializer3() {
-    checkNumErrors("Initializer3NegativeTest.dart", 1);
-  }
-
-  public void testInitializer4() {
-    checkNumErrors("Initializer4NegativeTest.dart", 1);
-  }
-
-  public void testInitializer5() {
-    checkNumErrors("Initializer5NegativeTest.dart", 1);
-  }
-
-  public void testInitializer6() {
-    checkNumErrors("Initializer6NegativeTest.dart", 1);
-  }
-
-  public void testArrayLiteralNegativeTest() {
-    checkSourceErrors(
-        makeCode(
-            "// filler filler filler filler filler filler filler filler filler filler",
-            "class A {",
-            "  main() {",
-            "    List<int, int> ints = [1];",
-            "  }",
-            "}"),
-        errEx(TypeErrorCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS, 4, 5, 14));
-  }
-
-  public void testMapLiteralNegativeTest() {
-    checkSourceErrors(
-        makeCode(
-            "// filler filler filler filler filler filler filler filler filler filler",
-            "class A {",
-            "  main() {",
-            "    Map<String, int, int> map = {'foo':1};",
-            "  }",
-            "}"),
-        errEx(TypeErrorCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS, 4, 5, 21));
-  }
-
-  /**
-   * We should not fail in case of using {@link DartThisExpression} outside of method.
-   * <p>
-   * http://code.google.com/p/dart/issues/detail?id=662
-   */
-  public void test_thisExpression_inTopLevelVariable() {
-    checkSourceErrors("var foo = this;", errEx(ResolverErrorCode.THIS_ON_TOP_LEVEL, 1, 11, 4));
-  }
-
-  public void test_thisExpression_inTopLevelMethod() {
-    checkSourceErrors(
-        makeCode(
-            "// filler filler filler filler filler filler filler filler filler filler",
-            "foo() {",
-            "  return this;",
-            "}"),
-        errEx(ResolverErrorCode.THIS_ON_TOP_LEVEL, 3, 10, 4));
-  }
-
-  public void test_thisExpression_outsideOfMethod() {
-    checkSourceErrors(
-        makeCode(
-            "// filler filler filler filler filler filler filler filler filler filler",
-            "class A {",
-            "  var foo = this;",
-            "}"),
-        errEx(ResolverErrorCode.THIS_OUTSIDE_OF_METHOD, 3, 13, 4));
-  }
-
-  public void test_thisExpression_inStaticMethod() {
-    checkSourceErrors(
-        makeCode(
-            "// filler filler filler filler filler filler filler filler filler filler",
-            "class A {",
-            "  static foo() {",
-            "    return this;",
-            "  }",
-            "}"),
-        errEx(ResolverErrorCode.THIS_IN_STATIC_METHOD, 4, 12, 4));
-  }
-
-  public void test_thisExpression_inFactoryMethod() {
-    checkSourceErrors(
-        makeCode(
-            "// filler filler filler filler filler filler filler filler filler filler",
-            "class A {",
-            "  factory A() {",
-            "    return this;",
-            "  }",
-            "}"),
-        errEx(ResolverErrorCode.THIS_IN_FACTORY_CONSTRUCTOR, 4, 12, 4));
-  }
-
-  /**
-   * We should not fail in case of using {@link DartThisExpression} outside of method.
-   * <p>
-   * http://code.google.com/p/dart/issues/detail?id=662
-   */
-  public void test_superExpression_inTopLevelVariable() {
-    checkSourceErrors(
-        "var foo = super.foo();",
-        errEx(ResolverErrorCode.SUPER_ON_TOP_LEVEL, 1, 11, 5));
-  }
-
-  public void test_superExpression_inTopLevelMethod() {
-    checkSourceErrors(
-        makeCode(
-            "// filler filler filler filler filler filler filler filler filler filler",
-            "foo() {",
-            "  return super.foo();",
-            "}"),
-        errEx(ResolverErrorCode.SUPER_ON_TOP_LEVEL, 3, 10, 5));
-  }
-
-  public void test_superExpression_outsideOfMethod() {
-    checkSourceErrors(
-        makeCode(
-            "// filler filler filler filler filler filler filler filler filler filler",
-            "class A {",
-            "  var foo = super.foo();",
-            "}"),
-        errEx(ResolverErrorCode.SUPER_OUTSIDE_OF_METHOD, 3, 13, 5));
-  }
-
-  public void test_superExpression_inStaticMethod() {
-    checkSourceErrors(
-        makeCode(
-            "// filler filler filler filler filler filler filler filler filler filler",
-            "class A {",
-            "  static foo() {",
-            "    return super.foo();",
-            "  }",
-            "}"),
-        errEx(ResolverErrorCode.SUPER_IN_STATIC_METHOD, 4, 12, 5));
-  }
-
-  public void test_superExpression_inFactoryMethod() {
-    checkSourceErrors(
-        makeCode(
-            "// filler filler filler filler filler filler filler filler filler filler",
-            "class A {",
-            "  factory A() {",
-            "    return super.foo();",
-            "  }",
-            "}"),
-        errEx(ResolverErrorCode.SUPER_IN_FACTORY_CONSTRUCTOR, 4, 12, 5));
-  }
-
-  public void testNameConflict_field_field() {
-    checkSourceErrors(
-        makeCode(
-            "// filler filler filler filler filler filler filler filler filler filler",
-            "class A {",
-            "  var foo;",
-            "  var foo;",
-            "}"),
-        errEx(ResolverErrorCode.DUPLICATE_MEMBER, 3, 7, 3),
-        errEx(ResolverErrorCode.DUPLICATE_MEMBER, 4, 7, 3));
-  }
-
-  public void testCall1() {
-    checkNumErrors("StaticInstanceCallNegativeTest.dart", 1);
-  }
-
-  /**
-   * Class can implement class, this causes implementation of an implicit interface.
-   */
-  public void test_classImplementsClass() {
-    checkSourceErrors(makeCode(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "class A {}",
-        "class B implements A {",
-        "}"));
-  }
-
-  public void testConstSuperNegativeTest1() {
-    checkNumErrors("ConstSuperNegativeTest1.dart", 0);
-  }
-
-  public void testConstSuperNegativeTest2() {
-    checkNumErrors("ConstSuperNegativeTest2.dart", 1);
-  }
-
-  public void testConstSuperTest() {
-    checkNumErrors("ConstSuperTest.dart", 0);
-  }
-
-  public void testParameterInitializerNegativeTest1() {
-    checkNumErrors("ParameterInitializerNegativeTest1.dart", 1);
-  }
-
-  public void testParameterInitializerNegativeTest2() {
-    checkNumErrors("ParameterInitializerNegativeTest2.dart", 1);
-  }
-
-  public void testParameterInitializerNegativeTest3() {
-    checkNumErrors("ParameterInitializerNegativeTest3.dart", 1);
-  }
-
-  public void testStaticToInstanceInvocationNegativeTest1() {
-    checkNumErrors("StaticToInstanceInvocationNegativeTest1.dart", 1);
-  }
-
-  public void testConstVariableInitializationNegativeTest1() {
-    checkNumErrors("ConstVariableInitializationNegativeTest1.dart", 1);
-  }
-
-  public void testConstVariableInitializationNegativeTest2() {
-    checkNumErrors("ConstVariableInitializationNegativeTest2.dart", 1);
-  }
-
-  public void test_nameShadow_topLevel_method_class() {
-    checkSourceErrors(
-        makeCode(
-            "// filler filler filler filler filler filler filler filler filler filler",
-            "foo() {}",
-            "class foo {}"),
-        errEx(ResolverErrorCode.DUPLICATE_TOP_LEVEL_DECLARATION, 2, 1, 3),
-        errEx(ResolverErrorCode.DUPLICATE_TOP_LEVEL_DECLARATION, 3, 7, 3));
-    assertEquals(
-        "duplicate top-level declaration class 'foo' at Test.dart line:3 col:7",
-        errors.get(0).getMessage());
-    assertEquals(
-        "duplicate top-level declaration top-level function 'foo' at Test.dart line:2 col:1",
-        errors.get(1).getMessage());
-  }
-
-  public void test_nameShadow_topLevel_getterSetter_class() {
-    checkSourceErrors(
-        makeCode(
-            "// filler filler filler filler filler filler filler filler filler filler",
-            "get foo {}",
-            "set bar(x) {}",
-            "class foo {}",
-            "class bar{}"),
-        errEx(ResolverErrorCode.DUPLICATE_TOP_LEVEL_DECLARATION, 2, 5, 3),
-        errEx(ResolverErrorCode.DUPLICATE_TOP_LEVEL_DECLARATION, 4, 7, 3));
-  }
-
-  public void test_nameShadow_topLevel_class_getterSetter() {
-    checkSourceErrors(
-        makeCode(
-            "// filler filler filler filler filler filler filler filler filler filler",
-            "class foo {}",
-            "class bar {}",
-            "get foo {}",
-            "set bar(x) {}"),
-        errEx(ResolverErrorCode.DUPLICATE_TOP_LEVEL_DECLARATION, 2, 7, 3),
-        errEx(ResolverErrorCode.DUPLICATE_TOP_LEVEL_DECLARATION, 4, 5, 3));
-    assertEquals(
-        "duplicate top-level declaration top-level variable 'foo' at Test.dart line:4 col:5",
-        errors.get(0).getMessage());
-    assertEquals(
-        "duplicate top-level declaration class 'foo' at Test.dart line:2 col:7",
-        errors.get(1).getMessage());
-  }
-
-  public void test_nameShadow_topLevel_getter_setter() {
-    checkSourceErrors(makeCode(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "get bar {}",
-        "set bar(x) {}"));
-  }
-
-  public void test_nameShadow_topLevel_setter_getter() {
-    checkSourceErrors(makeCode(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "set bar(x) {}",
-        "get bar {}"));
-  }
-
-  public void test_nameShadow_topLevel_setter_variable() {
-    checkSourceErrors(
-        makeCode(
-            "// filler filler filler filler filler filler filler filler filler filler",
-            "set bar(x) {}",
-            "var bar;"),
-        errEx(ResolverErrorCode.DUPLICATE_TOP_LEVEL_DECLARATION, 2, 5, 3),
-        errEx(ResolverErrorCode.DUPLICATE_TOP_LEVEL_DECLARATION, 3, 5, 3));
-  }
-
-  public void test_nameShadow_topLevel_variable_setter() {
-    checkSourceErrors(
-        makeCode(
-            "// filler filler filler filler filler filler filler filler filler filler",
-            "var bar;",
-            "set bar(x) {}"),
-        errEx(ResolverErrorCode.DUPLICATE_TOP_LEVEL_DECLARATION, 2, 5, 3),
-        errEx(ResolverErrorCode.DUPLICATE_TOP_LEVEL_DECLARATION, 3, 5, 3));
-  }
-
-  public void test_nameShadow_topLevel_getters() {
-    checkSourceErrors(
-        makeCode(
-            "// filler filler filler filler filler filler filler filler filler filler",
-            "get bar {}",
-            "get bar {}"),
-        errEx(ResolverErrorCode.DUPLICATE_TOP_LEVEL_DECLARATION, 2, 5, 3),
-        errEx(ResolverErrorCode.DUPLICATE_TOP_LEVEL_DECLARATION, 3, 5, 3));
-    assertEquals(
-        "duplicate top-level declaration top-level variable 'bar' at Test.dart line:3 col:5",
-        errors.get(0).getMessage());
-    assertEquals(
-        "duplicate top-level declaration top-level variable 'bar' at Test.dart line:2 col:5",
-        errors.get(1).getMessage());
-  }
-
-  public void test_nameShadow_topLevel_setters() {
-    checkSourceErrors(
-        makeCode(
-            "// filler filler filler filler filler filler filler filler filler filler",
-            "set bar(x) {}",
-            "set bar(x) {}"),
-        errEx(ResolverErrorCode.DUPLICATE_TOP_LEVEL_DECLARATION, 2, 5, 3),
-        errEx(ResolverErrorCode.DUPLICATE_TOP_LEVEL_DECLARATION, 3, 5, 3));
-    assertEquals(
-        "duplicate top-level declaration top-level variable 'setter bar' at Test.dart line:3 col:5",
-        errors.get(0).getMessage());
-    assertEquals(
-        "duplicate top-level declaration top-level variable 'setter bar' at Test.dart line:2 col:5",
-        errors.get(1).getMessage());
-  }
-
-  public void test_nameShadow_topLevel_variables() {
-    checkSourceErrors(
-        makeCode(
-            "// filler filler filler filler filler filler filler filler filler filler",
-            "var foo;",
-            "var bar;",
-            "var foo;"),
-        errEx(ResolverErrorCode.DUPLICATE_TOP_LEVEL_DECLARATION, 2, 5, 3),
-        errEx(ResolverErrorCode.DUPLICATE_TOP_LEVEL_DECLARATION, 4, 5, 3));
-    assertEquals(
-        "duplicate top-level declaration top-level variable 'foo' at Test.dart line:4 col:5",
-        errors.get(0).getMessage());
-    assertEquals(
-        "duplicate top-level declaration top-level variable 'foo' at Test.dart line:2 col:5",
-        errors.get(1).getMessage());
-  }
-
-  /**
-   * Multiple unnamed constructor definitions.
-   */
-  public void test_nameShadow_unnamedConstructors() {
-    checkSourceErrors(
-        makeCode(
-            "// filler filler filler filler filler filler filler filler filler filler",
-            "class A {",
-            "  A(x) {}",
-            "  A(x,y) {}",
-            "}"),
-        errEx(ResolverErrorCode.DUPLICATE_MEMBER, 3, 3, 1),
-        errEx(ResolverErrorCode.DUPLICATE_MEMBER, 4, 3, 1));
-    {
-      String message = errors.get(0).getMessage();
-      assertTrue(message, message.contains("'A'"));
-    }
-    {
-      String message = errors.get(1).getMessage();
-      assertTrue(message, message.contains("'A'"));
-    }
-  }
-
-  /**
-   * Multiple unnamed constructor definitions. Make sure modifiers works as expected.
-   */
-  public void test_nameShadow_unnamedConstructors_constModifier() {
-    checkSourceErrors(
-        makeCode(
-            "// filler filler filler filler filler filler filler filler filler filler",
-            "class A {",
-            "  A(x) {}",
-            "  const A(x,y) {}",
-            "}"),
-        errEx(ResolverErrorCode.DUPLICATE_MEMBER, 3, 3, 1),
-        errEx(ResolverErrorCode.DUPLICATE_MEMBER, 4, 9, 1),
-        errEx(ResolverErrorCode.CONST_CONSTRUCTOR_CANNOT_HAVE_BODY, 4, 9, 1));
-    {
-      String message = errors.get(0).getMessage();
-      assertTrue(message, message.contains("'A'"));
-    }
-  }
-
-  /**
-   * Named constructor shadows another named constructor.
-   */
-  public void test_nameShadow_namedConstructors() {
-    checkSourceErrors(
-        makeCode(
-            "// filler filler filler filler filler filler filler filler filler filler",
-            "class A {",
-            "  A.foo() {}",
-            "  A.foo() {}",
-            "}"),
-        errEx(ResolverErrorCode.DUPLICATE_MEMBER, 3, 3, 5),
-        errEx(ResolverErrorCode.DUPLICATE_MEMBER, 4, 3, 5));
-    {
-      String message = errors.get(0).getMessage();
-      assertTrue(message, message.contains("'A.foo'"));
-    }
-    {
-      String message = errors.get(1).getMessage();
-      assertTrue(message, message.contains("'A.foo'"));
-    }
-  }
-
-  /**
-   * Method shadows another method.
-   */
-  public void test_nameShadow_methods() {
-    checkSourceErrors(
-        makeCode(
-            "// filler filler filler filler filler filler filler filler filler filler",
-            "class A {",
-            "  foo() {}",
-            "  foo() {}",
-            "}"),
-        errEx(ResolverErrorCode.DUPLICATE_MEMBER, 3, 3, 3),
-        errEx(ResolverErrorCode.DUPLICATE_MEMBER, 4, 3, 3));
-  }
-
-  /**
-   * Field shadows method.
-   */
-  public void test_nameShadow_method_field() {
-    checkSourceErrors(
-        makeCode(
-            "// filler filler filler filler filler filler filler filler filler filler",
-            "class A {",
-            "  foo() {}",
-            "  var foo;",
-            "}"),
-        errEx(ResolverErrorCode.DUPLICATE_MEMBER, 4, 7, 3),
-        errEx(ResolverErrorCode.DUPLICATE_MEMBER, 3, 3, 3));
-  }
-
-  /**
-   * Static method shadows instance method.
-   */
-  public void test_nameShadow_method_staticMethod() {
-    checkSourceErrors(
-        makeCode(
-            "// filler filler filler filler filler filler filler filler filler filler",
-            "class A {",
-            "  foo(x) {}",
-            "  static foo(a,b) {}",
-            "}"),
-        errEx(ResolverErrorCode.DUPLICATE_MEMBER, 3, 3, 3),
-        errEx(ResolverErrorCode.DUPLICATE_MEMBER, 4, 10, 3));
-  }
-
-  /**
-   * Field shadows another field.
-   */
-  public void test_nameShadow_fields() {
-    checkSourceErrors(
-        makeCode(
-            "// filler filler filler filler filler filler filler filler filler filler",
-            "class A {",
-            "  var _a;",
-            "  var _a = 2;",
-            "}"),
-        errEx(ResolverErrorCode.DUPLICATE_MEMBER, 3, 7, 2),
-        errEx(ResolverErrorCode.DUPLICATE_MEMBER, 4, 7, 2));
-  }
-
-  public void test_nameShadow_variables_sameBlock() {
-    checkSourceErrors(
-        makeCode(
-            "// filler filler filler filler filler filler filler filler filler filler",
-            "class A {",
-            "  foo() {",
-            "    var a;",
-            "    var a = 2;",
-            "  }",
-            "}"),
-        errEx(ResolverErrorCode.DUPLICATE_LOCAL_VARIABLE_ERROR, 5, 9, 1));
-  }
-
-  /**
-   * Here we have two local variables: one in "main" and one in the scope on "block". However
-   * variables are declared in lexical scopes, i.e. in "block", so using it before declaration is
-   * error.
-   * <p>
-   * http://code.google.com/p/dart/issues/detail?id=2382
-   */
-  public void test_useVariable_beforeDeclaration_inLexicalScope() throws Exception {
-    checkSourceErrors(
-        makeCode(
-            "// filler filler filler filler filler filler filler filler filler filler",
-            "main() {",
-            "  var x;",
-            "  {",
-            "    x = 1;",
-            "    var x;",
-            "  }",
-            "}",
-            ""),
-        errEx(ResolverErrorCode.USING_LOCAL_VARIABLE_BEFORE_DECLARATION, 5, 5, 1));
-  }
-
-  public void test_nameShadow_methodParameters() {
-    checkSourceErrors(
-        makeCode(
-            "// filler filler filler filler filler filler filler filler filler filler",
-            "class A {",
-            "  foo(a, bb, a) {",
-            "  }",
-            "}"),
-        errEx(ResolverErrorCode.DUPLICATE_PARAMETER, 3, 14, 1));
-  }
-
-  /**
-   * In static method instance fields are out of scope, so it is OK to have parameter with same
-   * name.
-   */
-  public void test_nameShadow_instanceField_staticMethodParameter() {
-    checkSourceErrors(makeCode(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "class A {",
-        "  var a;",
-        "  static foo(a) {",
-        "  }",
-        "}"));
-  }
-
-  public void test_nameShadow_field_methodParameterThis() {
-    checkSourceErrors(makeCode(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "class A {",
-        "  final a;",
-        "  const A(this.a);",
-        "}"));
-  }
-
-  public void test_nameShadow_field_interfaceMethodParameter() {
-    checkSourceErrors(makeCode(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "abstract class A {",
-        "  var a;",
-        "  foo(a);",
-        "}"));
-  }
-
-  public void test_nameShadow_field_nativeMethodParameter() {
-    checkSourceErrorsAsSystemLibrary(makeCode(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "class A {",
-        "  var a;",
-        "  foo(a) native;",
-        "}"));
-  }
-
-  public void test_nameShadow_classTypeVariables() {
-    checkSourceErrors(
-        makeCode(
-            "// filler filler filler filler filler filler filler filler filler filler",
-            "class C<A, BB, A> {",
-            "}"),
-        errEx(ResolverErrorCode.DUPLICATE_TYPE_VARIABLE, 2, 16, 1));
-  }
-
-  /**
-   * Field shadows setter/getter.
-   */
-  public void test_nameShadow_setter_field() {
-    checkSourceErrors(
-        makeCode(
-            "// filler filler filler filler filler filler filler filler filler filler",
-            "class A {",
-            "  set foo(x) {}",
-            "  get foo {}",
-            "  var foo;",
-            "}"),
-        errEx(ResolverErrorCode.DUPLICATE_MEMBER, 4, 7, 3),
-        errEx(ResolverErrorCode.DUPLICATE_MEMBER, 5, 7, 3));
-  }
-
-  /**
-   * Setter shadows field.
-   */
-  public void test_nameShadow_field_setter() {
-    checkSourceErrors(
-        makeCode(
-            "// filler filler filler filler filler filler filler filler filler filler",
-            "class A {",
-            "  var foo;",
-            "  set foo(x) {}",
-            "}"),
-        errEx(ResolverErrorCode.DUPLICATE_MEMBER, 3, 7, 3),
-        errEx(ResolverErrorCode.DUPLICATE_MEMBER, 4, 7, 3));
-  }
-
-  /**
-   * Method does not shadow setter, because "=" is implicitly appended to the setter name.
-   */
-  public void test_nameShadow_setter_method() {
-    checkSourceErrors(
-        makeCode(
-            "// filler filler filler filler filler filler filler filler filler filler",
-            "class A {",
-            "  set foo(x) {}",
-            "  foo() {}",
-            "}"));
-  }
-
-  /**
-   * We should ignore if setter parameter has same name and name of the setter method.
-   */
-  public void test_nameShadow_setter_sameParameterName() {
-    checkSourceErrors(
-        makeCode(
-            "// filler filler filler filler filler filler filler filler filler filler",
-            "class A {",
-            "  set foo(foo) {}",
-            "}"));
-  }
-
-  /**
-   * Getter shadows field.
-   */
-  public void test_nameShadow_field_getter() {
-    checkSourceErrors(
-        makeCode(
-            "// filler filler filler filler filler filler filler filler filler filler",
-            "class A {",
-            "  var foo;",
-            "  get foo {}",
-            "}"),
-        errEx(ResolverErrorCode.DUPLICATE_MEMBER, 3, 7, 3),
-        errEx(ResolverErrorCode.DUPLICATE_MEMBER, 4, 7, 3));
-  }
-
-  /**
-   * Getter shadows another getter.
-   */
-  public void test_nameShadow_getters() {
-    checkSourceErrors(
-        makeCode(
-            "// filler filler filler filler filler filler filler filler filler filler",
-            "class A {",
-            "  get foo {}",
-            "  set foo(x) {}",
-            "  get foo {}",
-            "}"),
-        errEx(ResolverErrorCode.DUPLICATE_MEMBER, 3, 7, 3),
-        errEx(ResolverErrorCode.DUPLICATE_MEMBER, 5, 7, 3));
-  }
-
-  /**
-   * Setter shadows another setter.
-   */
-  public void test_nameShadow_setters() {
-    checkSourceErrors(
-        makeCode(
-            "// filler filler filler filler filler filler filler filler filler filler",
-            "class A {",
-            "  set foo(x) {}",
-            "  get foo {}",
-            "  set foo(x) {}",
-            "}"),
-        errEx(ResolverErrorCode.DUPLICATE_MEMBER, 3, 7, 3),
-        errEx(ResolverErrorCode.DUPLICATE_MEMBER, 5, 7, 3));
-  }
-
-  /**
-   * Field shadows getter.
-   */
-  public void test_nameShadow_getter_field() {
-    checkSourceErrors(
-        makeCode(
-            "// filler filler filler filler filler filler filler filler filler filler",
-            "class A {",
-            "  get foo {}",
-            "  var foo;",
-            "}"),
-        errEx(ResolverErrorCode.DUPLICATE_MEMBER, 3, 7, 3),
-        errEx(ResolverErrorCode.DUPLICATE_MEMBER, 4, 7, 3));
-  }
-
-  /**
-   * Setter does not shadow method, because "=" is implicitly appended to the setter name.
-   */
-  public void test_nameShadow_method_setter() {
-    checkSourceErrors(
-        makeCode(
-            "// filler filler filler filler filler filler filler filler filler filler",
-            "class A {",
-            "  foo() {}",
-            "  set foo(x) {}",
-            "}"));
-  }
-
-  public void test_nameShadow_functionExpressionParameters() {
-    checkSourceErrors(
-        makeCode(
-            "// filler filler filler filler filler filler filler filler filler filler",
-            "class A {",
-            "  foo() {",
-            "    fn(a, b, a) {};",
-            "  }",
-            "}"),
-        errEx(ResolverErrorCode.DUPLICATE_PARAMETER, 4, 14, 1));
-  }
-
-  public void test_nameShadow_variable_functionExpressionNamed() {
-    checkSourceErrors(
-        makeCode(
-            "// filler filler filler filler filler filler filler filler filler filler",
-            "class A {",
-            "  foo() {",
-            "    var a;",
-            "    a() => 0;",
-            "  }",
-            "}"),
-        errEx(ResolverErrorCode.DUPLICATE_FUNCTION_EXPRESSION, 5, 5, 1));
-    {
-      String message = errors.get(0).getMessage();
-      assertEquals("Duplicate function expression 'a'", message);
-    }
-  }
-
-  public void testUnresolvedSuperFieldNegativeTest() {
-    checkNumErrors("UnresolvedSuperFieldNegativeTest.dart", 1);
-  }
-
-  public void testStaticSuperFieldNegativeTest() {
-    checkNumErrors("StaticSuperFieldNegativeTest.dart", 1);
-  }
-
-  public void testStaticSuperGetterNegativeTest() {
-    checkNumErrors("StaticSuperGetterNegativeTest.dart", 1);
-  }
-
-  public void testStaticSuperMethodNegativeTest() {
-    checkNumErrors("StaticSuperMethodNegativeTest.dart", 1);
-  }
-
-  public void testCyclicRedirectedConstructorNegativeTest() {
-    checkNumErrors("CyclicRedirectedConstructorNegativeTest.dart", 3);
-  }
-
-  public void testConstRedirectedConstructorNegativeTest() {
-    checkSourceErrors(
-        makeCode(
-            "// filler filler filler filler filler filler filler filler filler filler",
-            "class A {",
-            "  const A(x) : this.foo(x);",
-            "  A.foo(this.x) { }",
-            "  final x;",
-            "}"),
-        errEx(ResolverErrorCode.CONST_CONSTRUCTOR_MUST_CALL_CONST_SUPER, 3, 9, 1));
-  }
-
-  public void testConstConstructorNonFinalFieldsNegativeTest() {
-    checkSourceErrors(
-        makeCode(
-            "class A extends B {",
-            "  const A();",
-            "  var x;",
-            "  final y = 10;",
-            "  set z(value) {}",
-            "}",
-            "class B implements C {",
-            "  final bar;",
-            "  var baz;",
-            "}",
-            "abstract class C {",
-            "  var x;",
-            "}"),
-        errEx(ResolverErrorCode.CONST_CLASS_WITH_NONFINAL_FIELDS, 3, 7, 1),
-        errEx(ResolverErrorCode.CONST_CLASS_WITH_INHERITED_NONFINAL_FIELDS, 9, 7, 3),
-        errEx(ResolverErrorCode.FINAL_FIELD_MUST_BE_INITIALIZED, 8, 9, 3));
-  }
-
-  private TestCompilerContext getContext() {
-    return new TestCompilerContext() {
-      @Override
-      public void onError(DartCompilationError event) {
-        errors.add(event);
-      }
-    };
-  }
-
-  public void test_blackListed_dynamic() throws Exception {
-    checkSourceErrors(
-        makeCode(
-            "// filler filler filler filler filler filler filler filler filler filler",
-            "class A extends dynamic {",
-            "}",
-            "class B implements dynamic {",
-            "}"),
-        errEx(ResolverErrorCode.BLACK_LISTED_EXTENDS, 2, 17, 7),
-        errEx(ResolverErrorCode.BLACK_LISTED_IMPLEMENTS, 4, 20, 7));
-    assertEquals("'dynamic' can not be used as superclass", errors.get(0).getMessage());
-    assertEquals("'dynamic' can not be used as superinterface", errors.get(1).getMessage());
-  }
-
-  public void test_blackListed_Function() throws Exception {
-    checkSourceErrors(
-        makeCode(
-            "// filler filler filler filler filler filler filler filler filler filler",
-            "class A extends Function {",
-            "}",
-            "class B implements Function {",
-            "}"),
-        errEx(ResolverErrorCode.BLACK_LISTED_EXTENDS, 2, 17, 8),
-        errEx(ResolverErrorCode.BLACK_LISTED_IMPLEMENTS, 4, 20, 8));
-  }
-
-  public void test_blackListed_bool() throws Exception {
-    checkSourceErrors(
-        makeCode(
-            "// filler filler filler filler filler filler filler filler filler filler",
-            "class A extends bool {",
-            "}",
-            "class B implements bool {",
-            "}"),
-        errEx(ResolverErrorCode.BLACK_LISTED_EXTENDS, 2, 17, 4),
-        errEx(ResolverErrorCode.BLACK_LISTED_IMPLEMENTS, 4, 20, 4));
-    assertEquals("'bool' can not be used as superclass", errors.get(0).getMessage());
-    assertEquals("'bool' can not be used as superinterface", errors.get(1).getMessage());
-  }
-
-  public void test_blackListed_int() throws Exception {
-    checkSourceErrors(
-        makeCode(
-            "// filler filler filler filler filler filler filler filler filler filler",
-            "class A extends int {",
-            "}",
-            "class B implements int {",
-            "}"),
-        errEx(ResolverErrorCode.BLACK_LISTED_EXTENDS, 2, 17, 3),
-        errEx(ResolverErrorCode.BLACK_LISTED_IMPLEMENTS, 4, 20, 3));
-  }
-
-  public void test_blackListed_double() throws Exception {
-    checkSourceErrors(
-        makeCode(
-            "// filler filler filler filler filler filler filler filler filler filler",
-            "class A extends double {",
-            "}",
-            "class B implements double {",
-            "}"),
-        errEx(ResolverErrorCode.BLACK_LISTED_EXTENDS, 2, 17, 6),
-        errEx(ResolverErrorCode.BLACK_LISTED_IMPLEMENTS, 4, 20, 6));
-  }
-
-  public void test_blackListed_num() throws Exception {
-    checkSourceErrors(
-        makeCode(
-            "// filler filler filler filler filler filler filler filler filler filler",
-            "class A extends num {",
-            "}",
-            "class B implements num {",
-            "}"),
-        errEx(ResolverErrorCode.BLACK_LISTED_EXTENDS, 2, 17, 3),
-        errEx(ResolverErrorCode.BLACK_LISTED_IMPLEMENTS, 4, 20, 3));
-  }
-
-  public void test_blackListed_String() throws Exception {
-    checkSourceErrors(
-        makeCode(
-            "// filler filler filler filler filler filler filler filler filler filler",
-            "class A extends String {",
-            "}",
-            "class B implements String {",
-            "}"),
-        errEx(ResolverErrorCode.BLACK_LISTED_EXTENDS, 2, 17, 6),
-        errEx(ResolverErrorCode.BLACK_LISTED_IMPLEMENTS, 4, 20, 6));
-  }
-
-  public void test_noSuchType_classImplements() throws Exception {
-    checkSourceErrors(
-        makeCode(
-            "// filler filler filler filler filler filler filler filler filler filler",
-            "class MyClass implements Unknown {",
-            "}"),
-        errEx(ResolverErrorCode.NO_SUCH_TYPE, 2, 26, 7));
-  }
-
-  public void test_noSuchType_classImplementsTypeVariable() throws Exception {
-    checkSourceErrors(
-        makeCode(
-            "// filler filler filler filler filler filler filler filler filler filler",
-            "class MyClass<E> implements E {",
-            "}"),
-        errEx(ResolverErrorCode.NOT_A_CLASS_OR_INTERFACE, 2, 29, 1));
-  }
-
-  public void test_explicitDynamicTypeArgument() throws Exception {
-    checkSourceErrors(makeCode(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "class MyClass implements Map<Object, dynamic> {",
-        "}"));
-  }
-
-  public void testAssignToFunc() {
-    checkSourceErrors(
-        makeCode(
-            "// filler filler filler filler filler filler filler filler filler filler",
-            "double func(a) {}",
-            "main() {",
-            "  func = null;",
-            "}"),
-        errEx(ResolverErrorCode.CANNOT_ASSIGN_TO_METHOD, 4, 3, 4));
-  }
-
-  public void testConstructorDuplicateInitializationTest() {
-    checkSourceErrors(
-        makeCode(
-            "class A {",
-            "  A.one(this.x) : this.x = 42;",
-            "  A.two(y) : this.x = y, x = y;",
-            "  var x;",
-            "}"),
-        errEx(ResolverErrorCode.DUPLICATE_INITIALIZATION, 2, 19, 11),
-        errEx(ResolverErrorCode.DUPLICATE_INITIALIZATION, 3, 26, 5));
-  }
-
-  public void testInitializerReferenceToThis() throws Exception {
-    checkSourceErrors(
-        makeCode(
-            "class A {",
-            "  var x, y;",
-            "  A.one(z) : x = z, y = this.x;",
-            "  A.two(this.x) : y = (() { return this; });",
-            "  A.three(this.x) : y = this.x;",
-            "}"),
-        errEx(ResolverErrorCode.THIS_IN_INITIALIZER_AS_EXPRESSION, 3, 25, 4),
-        errEx(ResolverErrorCode.THIS_IN_INITIALIZER_AS_EXPRESSION, 4, 36, 4),
-        errEx(ResolverErrorCode.THIS_IN_INITIALIZER_AS_EXPRESSION, 5, 25, 4));
-  }
-
-  public void test_resolvedTypeVariableBounds_inFunctionTypeAlias() throws Exception {
-    DartUnit unit =
-        parseUnit(
-            getName(),
-            makeCode(
-                "// filler filler filler filler filler filler filler filler filler filler",
-                "class A {}",
-                "typedef T Foo<T extends A>();",
-                ""));
-    resolve(unit);
-    DartFunctionTypeAlias func = (DartFunctionTypeAlias) unit.getTopLevelNodes().get(1);
-    DartTypeParameter typeParameter = func.getTypeParameters().get(0);
-    Type boundType = typeParameter.getBound().getType();
-    assertEquals("A", boundType.getElement().getName());
-  }
-
-  /**
-   * <p>
-   * http://code.google.com/p/dart/issues/detail?id=3986
-   */
-  public void test_memberWithNameOfClass() throws Exception {
-    checkSourceErrors(
-        makeCode(
-            "// filler filler filler filler filler filler filler filler filler filler",
-            "class A {",
-            "  A() {}",
-            "}",
-            "class B {",
-            "  var B;",
-            "}",
-            "class C {",
-            "  void C() {}",
-            "}",
-            ""),
-        errEx(ResolverErrorCode.MEMBER_WITH_NAME_OF_CLASS, 6, 7, 1),
-        errEx(ResolverErrorCode.CONSTRUCTOR_CANNOT_HAVE_RETURN_TYPE, 9, 3, 4));
-  }
-
-  public void test_methodCannotBeResolved() throws Exception {
-    checkSourceErrors(
-        makeCode(
-            "class A {",
-            "}",
-            "method() {",
-            "  A.method();", // error
-            "}"),
-            errEx(ResolverErrorCode.CANNOT_RESOLVE_METHOD_IN_CLASS, 4, 5, 6));
-  }
-
-  /**
-   * <p>
-   * http://code.google.com/p/dart/issues/detail?id=4090
-   */
-  public void test_forEachVariableIsNotVisibleInIterableExpression() throws Exception {
-    checkSourceErrors(
-        makeCode(
-            "// filler filler filler filler filler filler filler filler filler filler",
-            "List foo(var a) {}",
-            "main() {",
-            "  for (var y in foo(y)) {",
-            "  }",
-            "}"),
-            errEx(TypeErrorCode.CANNOT_BE_RESOLVED, 4, 21, 1));
-  }
-
-  /**
-   * <p>
-   * http://code.google.com/p/dart/issues/detail?id=4374
-   */
-  public void test_unaryOperatorForFinal_variable() throws Exception {
-    checkSourceErrors(
-        makeCode(
-            "// filler filler filler filler filler filler filler filler filler filler",
-            "main() {",
-            "  final v = 0;",
-            "  v++;",
-            "  v--;",
-            "  ++v;",
-            "  --v;",
-            "}"),
-            errEx(ResolverErrorCode.CANNOT_ASSIGN_TO_FINAL, 4, 3, 1),
-            errEx(ResolverErrorCode.CANNOT_ASSIGN_TO_FINAL, 5, 3, 1),
-            errEx(ResolverErrorCode.CANNOT_ASSIGN_TO_FINAL, 6, 5, 1),
-            errEx(ResolverErrorCode.CANNOT_ASSIGN_TO_FINAL, 7, 5, 1));
-  }
-
-  /**
-   * <p>
-   * http://code.google.com/p/dart/issues/detail?id=4374
-   */
-  public void test_unaryOperatorForFinal_parameter() throws Exception {
-    checkSourceErrors(
-        makeCode(
-            "// filler filler filler filler filler filler filler filler filler filler",
-            "foo(final v) {",
-            "  v++;",
-            "  v--;",
-            "  ++v;",
-            "  --v;",
-            "}"),
-            errEx(ResolverErrorCode.CANNOT_ASSIGN_TO_FINAL, 3, 3, 1),
-            errEx(ResolverErrorCode.CANNOT_ASSIGN_TO_FINAL, 4, 3, 1),
-            errEx(ResolverErrorCode.CANNOT_ASSIGN_TO_FINAL, 5, 5, 1),
-            errEx(ResolverErrorCode.CANNOT_ASSIGN_TO_FINAL, 6, 5, 1));
-  }
-
-  /**
-   * <p>
-   * http://code.google.com/p/dart/issues/detail?id=4374
-   */
-  public void test_unaryOperatorForFinal_field() throws Exception {
-    checkSourceErrors(
-        makeCode(
-            "// filler filler filler filler filler filler filler filler filler filler",
-            "class A {",
-            "  final v = 0;",
-            "  foo() {",
-            "    v++;",
-            "    v--;",
-            "    ++v;",
-            "    --v;",
-            "  }",
-            "}"),
-            errEx(ResolverErrorCode.CANNOT_ASSIGN_TO_FINAL, 5, 5, 1),
-            errEx(ResolverErrorCode.CANNOT_ASSIGN_TO_FINAL, 6, 5, 1),
-            errEx(ResolverErrorCode.CANNOT_ASSIGN_TO_FINAL, 7, 7, 1),
-            errEx(ResolverErrorCode.CANNOT_ASSIGN_TO_FINAL, 8, 7, 1));
-  }
-
-  /**
-   * <p>
-   * http://code.google.com/p/dart/issues/detail?id=5987
-   */
-  public void test_accessConstInstanceField_fromConstStaticField() throws Exception {
-    checkSourceErrors(
-        makeCode(
-            "// filler filler filler filler filler filler filler filler filler filler",
-            "class A {",
-            "  const x = 499;",
-            "  static const bar = x;",
-            "}",
-            ""),
-        errEx(ResolverErrorCode.ILLEGAL_FIELD_ACCESS_FROM_STATIC, 4, 22, 1));
-  }
-
-  /**
-   * <p>
-   * http://code.google.com/p/dart/issues/detail?id=6489
-   */
-  public void test_accessConstInstanceField_fromConstStaticMethod() throws Exception {
-    checkSourceErrors(
-        makeCode(
-            "// filler filler filler filler filler filler filler filler filler filler",
-            "class A {",
-            "  const CONST = 26;",
-            "  static int foo() {",
-            "    return CONST;",
-            "  }",
-            "}",
-            ""),
-        errEx(ResolverErrorCode.ILLEGAL_FIELD_ACCESS_FROM_STATIC, 5, 12, 5));
-  }
-
-  /**
-   * <p>
-   * http://code.google.com/p/dart/issues/detail?id=7633
-   */
-  public void test_accessInstanceField_fromConstFactory() throws Exception {
-    checkSourceErrors(
-        makeCode(
-            "// filler filler filler filler filler filler filler filler filler filler",
-            "class A {",
-            "  var foo;",
-            "  factory A() {",
-            "    var v = foo;",
-            "    return null;",
-            "  }",
-            "}",
-            ""),
-        errEx(ResolverErrorCode.ILLEGAL_FIELD_ACCESS_FROM_FACTORY, 5, 13, 3));
-  }
-}
diff --git a/compiler/javatests/com/google/dart/compiler/resolver/ParameterInitializerNegativeTest1.dart b/compiler/javatests/com/google/dart/compiler/resolver/ParameterInitializerNegativeTest1.dart
deleted file mode 100644
index 8c10717..0000000
--- a/compiler/javatests/com/google/dart/compiler/resolver/ParameterInitializerNegativeTest1.dart
+++ /dev/null
@@ -1,10 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-// expect error - parameter initializer does not resolve to a field.
-
-class A {
-   A(this.a) { }
-   Object b;
-}
diff --git a/compiler/javatests/com/google/dart/compiler/resolver/ParameterInitializerNegativeTest2.dart b/compiler/javatests/com/google/dart/compiler/resolver/ParameterInitializerNegativeTest2.dart
deleted file mode 100644
index 4233115..0000000
--- a/compiler/javatests/com/google/dart/compiler/resolver/ParameterInitializerNegativeTest2.dart
+++ /dev/null
@@ -1,12 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-// expect error - parameter initializer is not valid in ordinary methods.
-
-class A {
-   A(this.x) { }
-   A.myctor(this.x) { }
-   foo(Object y, this.x) { } // expect to fail.
-   Object x;
-}
diff --git a/compiler/javatests/com/google/dart/compiler/resolver/ParameterInitializerNegativeTest3.dart b/compiler/javatests/com/google/dart/compiler/resolver/ParameterInitializerNegativeTest3.dart
deleted file mode 100644
index 4677564..0000000
--- a/compiler/javatests/com/google/dart/compiler/resolver/ParameterInitializerNegativeTest3.dart
+++ /dev/null
@@ -1,10 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-// expect error - parameter initializer cannot initialize static fields.
-
-class A {
-   A(this.x) { } // expect error - cannot use param initializer to initialize a static field.
-   static Object x;
-}
diff --git a/compiler/javatests/com/google/dart/compiler/resolver/ResolverAuditVisitor.java b/compiler/javatests/com/google/dart/compiler/resolver/ResolverAuditVisitor.java
deleted file mode 100644
index 106da37..0000000
--- a/compiler/javatests/com/google/dart/compiler/resolver/ResolverAuditVisitor.java
+++ /dev/null
@@ -1,87 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-
-package com.google.dart.compiler.resolver;
-
-import com.google.common.base.Joiner;
-import com.google.common.collect.Lists;
-import com.google.dart.compiler.ast.DartClass;
-import com.google.dart.compiler.ast.DartIdentifier;
-import com.google.dart.compiler.ast.DartNode;
-import com.google.dart.compiler.ast.ASTVisitor;
-import com.google.dart.compiler.ast.DartParameterizedTypeNode;
-import com.google.dart.compiler.ast.DartTypeNode;
-import com.google.dart.compiler.ast.DartTypeParameter;
-import com.google.dart.compiler.common.SourceInfo;
-
-import java.util.List;
-
-/**
- * Look for  DartIdentifier nodes in the tree whose elements are null.  They should all either
- * be resolved, or marked as an unresolved element.
- */
-public class ResolverAuditVisitor extends ASTVisitor<Void> {
-  public static void exec(DartNode root) {
-    ResolverAuditVisitor visitor = new ResolverAuditVisitor();
-    root.accept(visitor);
-    List<String> results = visitor.getFailures();
-    if (results.size() > 0) {
-      StringBuilder out = new StringBuilder("Missing elements found in AST\n");
-      Joiner.on("\n").appendTo(out, results);
-      ResolverTestCase.fail(out.toString());
-    }
-  }
-
-  private List<String> failures = Lists.newArrayList();
-
-  public List<String> getFailures() {
-    return failures;
-  }
-
-  @Override
-  public Void visitClass(DartClass node) {
-    node.getName().accept(this);
-    node.visitChildren(this);
-    return null;
-  }
-
-  @Override
-  public Void visitIdentifier(DartIdentifier node) {
-    if (node.getElement() == null) {
-      SourceInfo sourceInfo = node.getSourceInfo();
-      failures.add("Identifier: "
-          + node.getName()
-          + " has null element @ ("
-          + sourceInfo.getLine()
-          + ":"
-          + sourceInfo.getColumn()
-          + ")");
-    }
-    return null;
-  }
-
-  @Override
-  public Void visitParameterizedTypeNode(DartParameterizedTypeNode node) {
-    node.getExpression().accept(this);
-    visit(node.getTypeParameters());
-    return null;
-  }
-
-  @Override
-  public Void visitTypeNode(DartTypeNode node) {
-    node.getIdentifier().accept(this);
-    visit(node.getTypeArguments());
-    return null;
-  }
-
-  @Override
-  public Void visitTypeParameter(DartTypeParameter node) {
-    node.getName().accept(this);
-    if (node.getBound() != null) {
-      node.getBound().accept(this);
-    }
-    return null;
-  }
-}
\ No newline at end of file
diff --git a/compiler/javatests/com/google/dart/compiler/resolver/ResolverCompilerTest.java b/compiler/javatests/com/google/dart/compiler/resolver/ResolverCompilerTest.java
deleted file mode 100644
index b60d8b4..0000000
--- a/compiler/javatests/com/google/dart/compiler/resolver/ResolverCompilerTest.java
+++ /dev/null
@@ -1,400 +0,0 @@
-// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-package com.google.dart.compiler.resolver;
-
-import com.google.common.collect.Lists;
-import com.google.common.io.CharStreams;
-import com.google.dart.compiler.CompilerTestCase;
-import com.google.dart.compiler.Source;
-import com.google.dart.compiler.ast.ASTVisitor;
-import com.google.dart.compiler.ast.DartClass;
-import com.google.dart.compiler.ast.DartDeclaration;
-import com.google.dart.compiler.ast.DartExprStmt;
-import com.google.dart.compiler.ast.DartExpression;
-import com.google.dart.compiler.ast.DartField;
-import com.google.dart.compiler.ast.DartFieldDefinition;
-import com.google.dart.compiler.ast.DartFunctionExpression;
-import com.google.dart.compiler.ast.DartFunctionTypeAlias;
-import com.google.dart.compiler.ast.DartIdentifier;
-import com.google.dart.compiler.ast.DartLabel;
-import com.google.dart.compiler.ast.DartMethodDefinition;
-import com.google.dart.compiler.ast.DartNewExpression;
-import com.google.dart.compiler.ast.DartNode;
-import com.google.dart.compiler.ast.DartParameter;
-import com.google.dart.compiler.ast.DartStatement;
-import com.google.dart.compiler.ast.DartTypeNode;
-import com.google.dart.compiler.ast.DartTypeParameter;
-import com.google.dart.compiler.ast.DartUnit;
-import com.google.dart.compiler.ast.DartVariableStatement;
-import com.google.dart.compiler.common.SourceInfo;
-import com.google.dart.compiler.type.FunctionAliasType;
-import com.google.dart.compiler.type.Type;
-import com.google.dart.compiler.type.TypeVariable;
-
-import static com.google.dart.compiler.common.ErrorExpectation.assertErrors;
-import static com.google.dart.compiler.common.ErrorExpectation.errEx;
-
-import java.io.Reader;
-import java.util.LinkedList;
-import java.util.List;
-
-/**
- * Variant of {@link ResolverTest}, which is based on {@link CompilerTestCase}. It is probably
- * slower, not actually unit test, but easier to use if you need access to DartNode's.
- */
-public class ResolverCompilerTest extends CompilerTestCase {
-
-  public void test_parameters_withFunctionAlias() throws Exception {
-    AnalyzeLibraryResult libraryResult = analyzeLibrary(
-        "typedef List<T> TypeAlias<T, U extends List<T>>(List<T> arg, U u);");
-    assertErrors(libraryResult.getCompilationErrors());
-    DartUnit unit = libraryResult.getLibraryUnitResult().getUnits().iterator().next();
-    DartFunctionTypeAlias typeAlias = findTypedef(unit, "TypeAlias");
-    assertNotNull(typeAlias);
-    FunctionAliasElement element = typeAlias.getElement();
-    FunctionAliasType ftype = element.getType();
-    Type returnType = ftype.getElement().getFunctionType().getReturnType();
-    assertEquals("List<TypeAlias.T>", returnType.toString());
-    List<? extends Type> arguments = ftype.getArguments();
-    assertEquals(2, arguments.size());
-    TypeVariable arg0 = (TypeVariable) arguments.get(0);
-    assertEquals("T", arg0.getTypeVariableElement().getName());
-    Type bound0 = arg0.getTypeVariableElement().getBound();
-    assertEquals("Object", bound0.toString());
-    TypeVariable arg1 = (TypeVariable) arguments.get(1);
-    assertEquals("U", arg1.getTypeVariableElement().getName());
-    Type bound1 = arg1.getTypeVariableElement().getBound();
-    assertEquals("List<TypeAlias.T>", bound1.toString());
-  }
-
-  /**
-   * This test succeeds if no exceptions are thrown.
-   */
-  public void test_recursiveTypes() throws Exception {
-    analyzeLibrary(
-        "class A extends A implements A {}",
-        "class B extends C {}",
-        "class C extends B {}");
-  }
-
-  /**
-   * This test checks the class declarations to make sure that elements are set for all identifiers.
-   * This is useful to the editor and other consumers of the AST.
-   */
-  public void test_resolution_on_class_decls() throws Exception {
-    AnalyzeLibraryResult libraryResult = analyzeLibrary(
-            "class A {}",
-            "abstract class B<T> {}",
-            "class C<T> extends A implements B<T> {}",
-            "class D extends C<int> {}",
-            "class E implements C<int> {}",
-            "class F<T extends A> {}",
-            "class G extends F<C<int>> {}");
-    assertErrors(libraryResult.getCompilationErrors());
-    DartUnit unit = libraryResult.getLibraryUnitResult().getUnits().iterator().next();
-    List<DartNode> nodes = unit.getTopLevelNodes();
-    DartClass A = (DartClass) nodes.get(0);
-    assertEquals("A", A.getClassName());
-    DartClass B = (DartClass) nodes.get(1);
-    assertEquals("B", B.getClassName());
-    DartClass C = (DartClass) nodes.get(2);
-    assertEquals("C", C.getClassName());
-    DartClass D = (DartClass) nodes.get(3);
-    assertEquals("D", D.getClassName());
-    DartClass E = (DartClass) nodes.get(4);
-    assertEquals("E", E.getClassName());
-    DartClass F = (DartClass) nodes.get(5);
-    assertEquals("F", F.getClassName());
-    DartClass G = (DartClass) nodes.get(6);
-    assertEquals("G", G.getClassName());
-
-    // class A
-    assertNotNull(A.getName().getElement());
-    assertSame(A.getElement(), A.getName().getElement());
-
-    // interface B<T> default C
-    assertNotNull(B.getName().getElement());
-    assertSame(B.getName().getElement(), B.getElement());
-    assertEquals(1, B.getTypeParameters().size());
-    DartTypeParameter T;
-    T = B.getTypeParameters().get(0);
-    assertNotNull(T);
-    assertNotNull(T.getName().getElement());
-    assertTrue(T.getName().getElement() instanceof TypeVariableElement);
-    assertEquals("T", T.getName().getName());
-
-    // class C<T> extends A implements B<T> {}
-    assertNotNull(C.getName().getElement());
-    assertSame(C.getElement(), C.getName().getElement());
-    assertEquals(1, C.getTypeParameters().size());
-    T = C.getTypeParameters().get(0);
-    assertNotNull(T);
-    assertNotNull(T.getName().getElement());
-    assertTrue(T.getName().getElement() instanceof TypeVariableElement);
-    assertEquals("T", T.getName().getName());
-    assertSame(A.getElement(), C.getSuperclass().getIdentifier().getElement());
-    assertEquals(1, C.getInterfaces().size());
-    DartTypeNode iface = C.getInterfaces().get(0);
-    assertNotNull(iface);
-    assertSame(B.getElement(), iface.getIdentifier().getElement());
-    assertSame(
-        T.getName().getElement(),
-        iface.getTypeArguments().get(0).getIdentifier().getElement());
-
-    // class D extends C<int> {}
-    assertNotNull(D.getName().getElement());
-    assertSame(D.getElement(), D.getName().getElement());
-    assertEquals(0, D.getTypeParameters().size());
-    assertSame(C.getElement(), D.getSuperclass().getIdentifier().getElement());
-    DartTypeNode typeArg;
-    typeArg = D.getSuperclass().getTypeArguments().get(0);
-    assertNotNull(typeArg.getIdentifier());
-    assertEquals("int", typeArg.getIdentifier().getElement().getOriginalName());
-
-    // class E implements C<int> {}
-    assertNotNull(E.getName().getElement());
-    assertSame(E.getElement(), E.getName().getElement());
-    assertEquals(0, E.getTypeParameters().size());
-    assertSame(C.getElement(), E.getInterfaces().get(0).getIdentifier().getElement());
-    typeArg = E.getInterfaces().get(0).getTypeArguments().get(0);
-    assertNotNull(typeArg.getIdentifier());
-    assertEquals("int", typeArg.getIdentifier().getElement().getOriginalName());
-
-    // class F<T extends A> {}",
-    assertNotNull(F.getName().getElement());
-    assertSame(F.getElement(), F.getName().getElement());
-    assertEquals(1, F.getTypeParameters().size());
-    T = F.getTypeParameters().get(0);
-    assertNotNull(T);
-    assertNotNull(T.getName().getElement());
-    assertTrue(T.getName().getElement() instanceof TypeVariableElement);
-    assertEquals("T", T.getName().getName());
-    assertSame(A.getElement(), T.getBound().getIdentifier().getElement());
-
-    // class G extends F<C<int>> {}
-    assertNotNull(G.getName().getElement());
-    assertSame(G.getElement(), G.getName().getElement());
-    assertEquals(0, G.getTypeParameters().size());
-    assertNotNull(G.getSuperclass());
-    assertSame(F.getElement(), G.getSuperclass().getIdentifier().getElement());
-    typeArg = G.getSuperclass().getTypeArguments().get(0);
-    assertSame(C.getElement(), typeArg.getIdentifier().getElement());
-    assertEquals(
-        "int",
-        typeArg.getTypeArguments().get(0).getIdentifier().getElement().getOriginalName());
-  }
-
-  /**
-   * We should be able to resolve implicit default constructor.
-   */
-  public void test_resolveConstructor_implicit() throws Exception {
-    AnalyzeLibraryResult libraryResult = analyzeLibrary(
-        "class F {",
-        "}",
-        "class Test {",
-        "  foo() {",
-        "    new F();",
-        "  }",
-        "}");
-    assertErrors(libraryResult.getCompilationErrors());
-    DartUnit unit = libraryResult.getLibraryUnitResult().getUnits().iterator().next();
-    DartNewExpression newExpression = findNodeBySource(unit, "new F()");
-    ConstructorElement constructorElement = newExpression.getElement();
-    assertNotNull(constructorElement);
-    assertEquals("", getElementSource(constructorElement));
-  }
-
-  public void test_resolveConstructor_noSuchConstructor() throws Exception {
-    AnalyzeLibraryResult libraryResult = analyzeLibrary(
-        "class A {",
-        "}",
-        "class Test {",
-        "  foo() {",
-        "    new A.foo();",
-        "  }",
-        "}");
-    assertErrors(
-        libraryResult.getErrors(),
-        errEx(TypeErrorCode.NEW_EXPRESSION_NOT_CONSTRUCTOR, 5, 11, 3));
-    DartUnit unit = libraryResult.getLibraryUnitResult().getUnits().iterator().next();
-    DartNewExpression newExpression = findNodeBySource(unit, "new A.foo()");
-    ConstructorElement constructorElement = newExpression.getElement();
-    assertNull(constructorElement);
-  }
-
-  public void test_resolveConstructor_super_implicitDefault() throws Exception {
-    AnalyzeLibraryResult libraryResult = analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "class A {",
-        "}",
-        "class B extends A {",
-        "  B() : super() {}",
-        "}",
-        "");
-    assertErrors(libraryResult.getErrors());
-  }
-
-  public void test_superMethodInvocation_inConstructorInitializer() throws Exception {
-    AnalyzeLibraryResult libraryResult = analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "class A {",
-        "  foo() {}",
-        "}",
-        "class B extends A {",
-        "  var x;",
-        "  B() : x = super.foo() {}",
-        "}",
-        "");
-    assertErrors(
-        libraryResult.getErrors(),
-        errEx(ResolverErrorCode.SUPER_METHOD_INVOCATION_IN_CONSTRUCTOR_INITIALIZER, 7, 13, 11));
-  }
-
-  private static String getElementSource(Element element) throws Exception {
-    SourceInfo sourceInfo = element.getSourceInfo();
-    // TODO(scheglov) When we will remove Source.getNode(), this null check may be removed
-    Source source = sourceInfo.getSource();
-    if (source == null) {
-      return "";
-    }
-    Reader reader = sourceInfo.getSource().getSourceReader();
-    try {
-      String code = CharStreams.toString(reader);
-      int offset = sourceInfo.getOffset();
-      return code.substring(offset, offset + sourceInfo.getLength());
-    } finally {
-      reader.close();
-    }
-  }
-
-  /**
-   * Each name in {@link DartNode}, such as all names in {@link DartDeclaration}s should have same
-   * {@link Element} as the {@link Element} of enclosing {@link DartNode}.
-   */
-  public void test_setElement_forName_inDeclarations() throws Exception {
-    AnalyzeLibraryResult libraryResult = analyzeLibrary(
-            "// filler filler filler filler filler filler filler filler filler filler",
-            "class A<B extends A> {",
-            "  var a1;",
-            "  get a2 {}",
-            "  A() {}",
-            "}",
-            "var c;",
-            "d(e) {",
-            "  var f;",
-            "  g() {};",
-            "  () {} ();",
-            "  h: d(0);",
-            "}",
-            "typedef i();",
-            "");
-    assertErrors(libraryResult.getErrors());
-    DartUnit unit = libraryResult.getLibraryUnitResult().getUnits().iterator().next();
-    // in class A
-    {
-      DartClass classA = (DartClass) unit.getTopLevelNodes().get(0);
-      assertDeclarationNameElement(classA, "A");
-      {
-        DartTypeParameter typeParameter = classA.getTypeParameters().get(0);
-        assertDeclarationNameElement(typeParameter, "B");
-      }
-      {
-        DartFieldDefinition fieldDef = (DartFieldDefinition) classA.getMembers().get(0);
-        assertDeclarationNameElement(fieldDef.getFields().get(0), "a1");
-      }
-      {
-        DartFieldDefinition fieldDef = (DartFieldDefinition) classA.getMembers().get(1);
-        // since this is a getter, its actually a method element different from the original.
-        DartField f = fieldDef.getFields().get(0);
-        assertNotNull(f);
-        Element e = f.getElement();
-        assertNotNull(e);
-        assertTrue(f.getName().getName().equals("a2"));
-        assertTrue(e.getName().equals("a2"));
-      }
-      {
-        DartMethodDefinition constructor = (DartMethodDefinition) classA.getMembers().get(2);
-        assertDeclarationNameElement(constructor, "");
-      }
-    }
-    // top level "c"
-    {
-      DartFieldDefinition fieldDef = (DartFieldDefinition) unit.getTopLevelNodes().get(1);
-      assertDeclarationNameElement(fieldDef.getFields().get(0), "c");
-    }
-    // top level "d"
-    {
-      DartMethodDefinition method = (DartMethodDefinition) unit.getTopLevelNodes().get(2);
-      assertDeclarationNameElement(method, "d");
-      {
-        DartParameter parameter = method.getFunction().getParameters().get(0);
-        assertDeclarationNameElement(parameter, "e");
-      }
-      {
-        List<DartStatement> statements = method.getFunction().getBody().getStatements();
-        {
-          DartVariableStatement variableStatement = (DartVariableStatement) statements.get(0);
-          assertDeclarationNameElement(variableStatement.getVariables().get(0), "f");
-        }
-        {
-          DartExprStmt statement = (DartExprStmt) statements.get(1);
-          DartFunctionExpression functionExpression = (DartFunctionExpression) statement.getExpression();
-          assertNameHasSameElement(functionExpression, functionExpression.getName(), "g");
-        }
-        {
-          DartLabel label = (DartLabel) statements.get(4);
-          assertNameHasSameElement(label, label.getLabel(), "h");
-        }
-      }
-    }
-    // top level "i"
-    {
-      DartFunctionTypeAlias functionType = (DartFunctionTypeAlias) unit.getTopLevelNodes().get(3);
-      assertDeclarationNameElement(functionType, "i");
-    }
-    // assert that all DartIdentifiers are visited
-    final LinkedList<String> visitedIdentifiers = Lists.newLinkedList();
-    unit.accept(new ASTVisitor<Void>() {
-      @Override
-      public Void visitIdentifier(DartIdentifier node) {
-        visitedIdentifiers.addLast(node.getName());
-        return null;
-      }
-    });
-    assertEquals("A", visitedIdentifiers.removeFirst());
-    assertEquals("B", visitedIdentifiers.removeFirst());
-    assertEquals("A", visitedIdentifiers.removeFirst());
-    assertEquals("a1", visitedIdentifiers.removeFirst());
-    assertEquals("a2", visitedIdentifiers.removeFirst());
-    assertEquals("a2", visitedIdentifiers.removeFirst());
-    assertEquals("A", visitedIdentifiers.removeFirst());
-    assertEquals("c", visitedIdentifiers.removeFirst());
-    assertEquals("d", visitedIdentifiers.removeFirst());
-    assertEquals("e", visitedIdentifiers.removeFirst());
-    assertEquals("f", visitedIdentifiers.removeFirst());
-    assertEquals("g", visitedIdentifiers.removeFirst());
-    assertEquals("h", visitedIdentifiers.removeFirst());
-    assertEquals("d", visitedIdentifiers.removeFirst());
-    assertEquals("i", visitedIdentifiers.removeFirst());
-  }
-
-  /**
-   * Asserts that given nodes have same not <code>null</code> {@link Element}.
-   */
-  private static void assertDeclarationNameElement(
-      DartDeclaration<? extends DartExpression> declaration,
-      String name) {
-    assertNameHasSameElement(declaration, declaration.getName(), name);
-  }
-
-  /**
-   * Asserts that given nodes have same not <code>null</code> {@link Element}.
-   */
-  private static void assertNameHasSameElement(DartNode node, DartExpression nameNode, String name) {
-    Element expectedElement = node.getElement();
-    assertNotNull(expectedElement);
-    assertEquals(name, expectedElement.getName());
-    assertSame(expectedElement, nameNode.getElement());
-  }
-}
diff --git a/compiler/javatests/com/google/dart/compiler/resolver/ResolverTest.java b/compiler/javatests/com/google/dart/compiler/resolver/ResolverTest.java
deleted file mode 100644
index 29826f4..0000000
--- a/compiler/javatests/com/google/dart/compiler/resolver/ResolverTest.java
+++ /dev/null
@@ -1,1439 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.resolver;
-
-import com.google.common.base.Joiner;
-import com.google.dart.compiler.DartCompilationError;
-import com.google.dart.compiler.ErrorCode;
-import com.google.dart.compiler.ast.DartClass;
-import com.google.dart.compiler.common.ErrorExpectation;
-import com.google.dart.compiler.type.DynamicType;
-import com.google.dart.compiler.type.InterfaceType;
-import com.google.dart.compiler.type.Type;
-import com.google.dart.compiler.type.Types;
-
-import static com.google.dart.compiler.common.ErrorExpectation.errEx;
-
-import junit.framework.Assert;
-
-import java.util.List;
-
-/**
- * Basic tests of the resolver.
- */
-public class ResolverTest extends ResolverTestCase {
-  private final DartClass object = makeClass("Object", null);
-  private final DartClass array = makeClass("Array", makeType("Object"), "E");
-  private final DartClass growableArray = makeClass("GrowableArray", makeType("Array", "S"), "S");
-  private final Types types = Types.getInstance(null);
-
-  private ClassElement findElementOrFail(Scope libScope, String elementName) {
-    Element element = libScope.findElement(libScope.getLibrary(), elementName);
-    assertEquals(ElementKind.CLASS, ElementKind.of(element));
-    return (ClassElement) element;
-  }
-
-  public void testToString() {
-    Assert.assertEquals("class Object {\n}", object.toString().trim());
-    Assert.assertEquals("class Array<E> extends Object {\n}", array.toString().trim());
-  }
-
-  public void testResolve() {
-    Scope libScope = resolve(makeUnit(object, array, growableArray), getContext());
-    LibraryElement library = libScope.getLibrary();
-    ClassElement objectElement = (ClassElement) libScope.findElement(library, "Object");
-    Assert.assertNotNull(objectElement);
-    ClassElement arrayElement = (ClassElement) libScope.findElement(library, "Array");
-    Assert.assertNotNull(arrayElement);
-    ClassElement growableArrayElement = (ClassElement) libScope.findElement(library,
-                                                                            "GrowableArray");
-    Assert.assertNotNull(growableArrayElement);
-
-    Type objectType = objectElement.getType();
-    Type arrayType = arrayElement.getType();
-    Type growableArrayType = growableArrayElement.getType();
-    Assert.assertNotNull(objectType);
-    Assert.assertNotNull(arrayType);
-    Assert.assertNotNull(growableArrayType);
-
-    Assert.assertTrue(types.isSubtype(arrayType, objectType));
-    Assert.assertFalse(types.isSubtype(objectType, arrayType));
-
-    Assert.assertTrue(types.isSubtype(growableArrayType, objectType));
-
-    // GrowableArray<S> is not a subtype of Array<E> because S and E aren't
-    // related.
-    Assert.assertFalse(types.isSubtype(growableArrayType, arrayType));
-    Assert.assertFalse(types.isSubtype(objectType, growableArrayType));
-    Assert.assertFalse(types.isSubtype(arrayType, growableArrayType));
-  }
-
-  /**
-   * class A {}
-   * class B extends A {}
-   * class C extends A {}
-   * class E extends C {}
-   * class D extends C {}
-   */
-  @SuppressWarnings("unused")
-  public void testGetSubtypes() {
-    DartClass a = makeClass("A", makeType("Object"));
-    DartClass b = makeClass("B", makeType("A"));
-    DartClass c = makeClass("C", makeType("A"));
-    DartClass e = makeClass("E", makeType("C"));
-    DartClass d = makeClass("D", makeType("C"));
-
-    Scope libScope = resolve(makeUnit(object, a, b, c, d, e), getContext());
-
-    ClassElement elementA = findElementOrFail(libScope, "A");
-    ClassElement elementB = findElementOrFail(libScope, "B");
-    ClassElement elementC = findElementOrFail(libScope, "C");
-    ClassElement elementD = findElementOrFail(libScope, "D");
-    ClassElement elementE = findElementOrFail(libScope, "E");
-  }
-
-  /**
-   * interface IA extends ID default B {}
-   * interface IB extends IA {}
-   * interface IC extends IA, IB {}
-   * interface ID extends IB {}
-   * class A extends IA {}
-   * class B {}
-   */
-  @SuppressWarnings("unused")
-  public void testGetSubtypesWithInterfaceCycles() {
-    DartClass ia = makeInterface("IA", makeTypes("ID"), makeDefault("B"));
-    DartClass ib = makeInterface("IB", makeTypes("IA"), null);
-    DartClass ic = makeInterface("IC", makeTypes("IA", "IB"), null);
-    DartClass id = makeInterface("ID", makeTypes("IB"), null);
-
-    DartClass a = makeClass("A", null, makeTypes("IA"));
-    DartClass b = makeClass("B", null);
-
-    Scope libScope = resolve(makeUnit(object, ia, ib, ic, id, a, b), getContext());
-    ErrorCode[] expected = {
-        ResolverErrorCode.CYCLIC_CLASS,
-        ResolverErrorCode.CYCLIC_CLASS,
-        ResolverErrorCode.CYCLIC_CLASS,
-        ResolverErrorCode.CYCLIC_CLASS,
-        ResolverErrorCode.CYCLIC_CLASS,
-    };
-    checkExpectedErrors(expected);
-
-    ClassElement elementIA = findElementOrFail(libScope, "IA");
-    ClassElement elementIB = findElementOrFail(libScope, "IB");
-    ClassElement elementIC = findElementOrFail(libScope, "IC");
-    ClassElement elementID = findElementOrFail(libScope, "ID");
-    ClassElement elementA = findElementOrFail(libScope, "A");
-    ClassElement elementB = findElementOrFail(libScope, "B");
-
-    assert(elementIA.getDefaultClass().getElement().getName().equals("B"));
-  }
-
-  /**
-   * interface IA extends IB {}
-   * interface IB extends IA {}
-   */
-  @SuppressWarnings("unused")
-  public void testGetSubtypesWithSimpleInterfaceCycle() {
-    DartClass ia = makeInterface("IA", makeTypes("IB"), null);
-    DartClass ib = makeInterface("IB", makeTypes("IA"), null);
-
-
-    Scope libScope = resolve(makeUnit(object, ia, ib), getContext());
-    ErrorCode[] expected = {
-        ResolverErrorCode.CYCLIC_CLASS,
-        ResolverErrorCode.CYCLIC_CLASS,
-    };
-    checkExpectedErrors(expected);
-
-    ClassElement elementIA = findElementOrFail(libScope, "IA");
-    ClassElement elementIB = findElementOrFail(libScope, "IB");
-  }
-
-  /**
-   * class A<T> {}
-   * class B extends A<C> {}
-   * class C {}
-   */
-  @SuppressWarnings("unused")
-  public void testGetSubtypesWithParemeterizedSupertypes() {
-    DartClass a = makeClass("A", null, "T");
-    DartClass b = makeClass("B", makeType("A", "C"));
-    DartClass c = makeClass("C", null);
-
-    Scope libScope = resolve(makeUnit(object, a, b, c), getContext());
-
-    ClassElement elementA = findElementOrFail(libScope, "A");
-    ClassElement elementB = findElementOrFail(libScope, "B");
-    ClassElement elementC = findElementOrFail(libScope, "C");
-
-  }
-
-  public void testDuplicatedInterfaces() {
-    // The analyzer used to catch inheriting from two different variations of the same interface
-    // but the spec mentions no such error
-    resolveAndTest(Joiner.on("\n").join(
-        "class Object {}",
-        "class int {}",
-        "class bool {}",
-        "abstract class I<X> {",
-        "}",
-        "class A extends C implements I<int> {}",
-        "class B extends C implements I<bool> {}",
-        "class C implements I<int> {}"));
-  }
-
-  public void testImplicitDefaultConstructor() {
-    // Check that the implicit constructor is resolved correctly
-    resolveAndTest(Joiner.on("\n").join(
-        "class Object {}",
-        "class B {}",
-        "class C { main() { new B(); } }"));
-
-    /*
-     * We should check for signature mismatch but that is a TypeAnalyzer issue.
-     */
-  }
-
-  public void testImplicitDefaultConstructor_WithConstCtor() {
-    // Check that we generate an error if the implicit constructor would violate const.
-    resolveAndTest(Joiner.on("\n").join(
-        "class Object {}",
-        "class B { const B() {} }",
-        "class C extends B {}",
-        "class D { main() { new C(); } }"),
-          ResolverErrorCode.CONST_CONSTRUCTOR_CANNOT_HAVE_BODY);
-  }
-
-  public void testImplicitSuperCall_ImplicitCtor() {
-    // Check that we can properly resolve the super ctor that exists.
-    resolveAndTest(Joiner.on("\n").join(
-        "class Object {}",
-        "class B { B() {} }",
-        "class C extends B {}",
-        "class D { main() { new C(); } }"));
-  }
-
-  public void testImplicitSuperCall_OnExistingCtor() {
-    // Check that we can properly resolve the super ctor that exists.
-    resolveAndTest(Joiner.on("\n").join(
-        "class Object {}",
-        "class B { B() {} }",
-        "class C extends B { C(){} }",
-        "class D { main() { new C(); } }"));
-  }
-
-  public void testImplicitSuperCall_NonExistentSuper() {
-    // Check that we generate an error if the implicit constructor would call a non-existent super.
-    resolveAndTest(Joiner.on("\n").join(
-        "class Object {}",
-        "class B { B(Object o) {} }",
-        "class C extends B {}",
-        "class D { main() { new C(); } }"),
-        ResolverErrorCode.CANNOT_RESOLVE_IMPLICIT_CALL_TO_SUPER_CONSTRUCTOR);
-  }
-
-  public void testImplicitSuperCall_NonExistentSuper2() {
-    // Check that we generate an error if the implicit constructor would call a non-existent super.
-    resolveAndTest(Joiner.on("\n").join(
-        "class Object {}",
-        "class B { B.foo() {} }",
-        "class C extends B {}",
-        "class D { main() { new C(); } }"),
-        ResolverErrorCode.CANNOT_RESOLVE_IMPLICIT_CALL_TO_SUPER_CONSTRUCTOR);
-  }
-
-  public void testCyclicSupertype() {
-
-    resolveAndTest(Joiner.on("\n").join(
-        "class Object {}",
-        "class int {}",
-        "class bool {}",
-        "class Cyclic extends Cyclic {",
-        "}",
-        "class A extends B {",
-        "}",
-        "class B extends A {",
-        "}",
-        "class C implements C {",
-        "}"),
-        ResolverErrorCode.CYCLIC_CLASS,
-        ResolverErrorCode.CYCLIC_CLASS,
-        ResolverErrorCode.CYCLIC_CLASS,
-        ResolverErrorCode.CYCLIC_CLASS
-    );
-  }
-
-  public void test_constFactory() throws Exception {
-    resolveAndTest(Joiner.on("\n").join(
-        "class Object {}",
-        "class A {",
-        "  const factory A() { }",
-        "}"),
-        errEx(ResolverErrorCode.FACTORY_CANNOT_BE_CONST, 3, 17, 1));
-  }
-
-  public void testBadGenerativeConstructor1() {
-    resolveAndTest(Joiner.on("\n").join(
-        "class Object { }",
-        "class B { }",
-        "class A {",
-        "  var val; ",
-        "  B.foo() : this.val = 1;",
-        "}"),
-        ResolverErrorCode.CANNOT_DECLARE_NON_FACTORY_CONSTRUCTOR);
-  }
-
-  public void testBadGenerativeConstructor2() {
-    resolveAndTest(Joiner.on("\n").join(
-        "class Object { }",
-        "class A {",
-        "  var val; ",
-        "  A.foo.bar() : this.val = 1;",
-        "}"),
-        ResolverErrorCode.TOO_MANY_QUALIFIERS_FOR_METHOD);
-  }
-
-  public void testGenerativeConstructor() {
-    resolveAndTest(Joiner.on("\n").join(
-        "class Object {}",
-        "class A {",
-        "  var val; ",
-        "  A.foo(arg) : this.val = arg;",
-        "}"));
-  }
-
-  /**
-   * Test that a class may implement the implied interface of another class and that interfaces may
-   * extend the implied interface of a class.
-   */
-  @SuppressWarnings("unused")
-  public void testImpliedInterfaces() throws Exception {
-    DartClass a = makeClass("A", null);
-    DartClass b = makeClass("B", null, makeTypes("A"));
-    DartClass ia = makeInterface("IA", makeTypes("B"), null);
-    Scope libScope = resolve(makeUnit(object, a, b, ia), getContext());
-    ErrorCode[] expected = {};
-    checkExpectedErrors(expected);
-
-    ClassElement elementA = findElementOrFail(libScope, "A");
-    ClassElement elementB = findElementOrFail(libScope, "B");
-    ClassElement elementIA = findElementOrFail(libScope, "IA");
-    List<InterfaceType> superTypes = elementB.getAllSupertypes();
-    assertEquals(2, superTypes.size()); // Object and A
-    superTypes = elementIA.getAllSupertypes();
-    assertEquals(3, superTypes.size()); // Object, A, and B
-  }
-
-  public void testUnresolvedSuper() {
-    resolveAndTest(Joiner.on("\n").join(
-        "class Object {}",
-        "class Foo {",
-        "  foo() { super.foo(); }",
-        "}"));
-  }
-
-  /**
-   * Tests for the 'new' keyword
-   */
-  public void testNewExpression1() {
-    // A very ordinary new expression is OK
-    resolveAndTest(Joiner.on("\n").join(
-        "class Object {}",
-        "class Foo {",
-        "  Foo create() {",
-        "    return new Foo();",
-        "  }",
-        "}"));
-  }
-
-  public void testNewExpression2() {
-    // A  new expression with generic type argument is OK
-    resolveAndTest(Joiner.on("\n").join(
-        "class Object {}",
-        "class Foo<T> {",
-        "  Foo<T> create() {",
-        "    return new Foo<T>();",
-        "  }",
-        "}"));
-  }
-
-  public void testNewExpression3() {
-    // Trying new on a variable name shouldn't work.
-    resolveAndTest(Joiner.on("\n").join(
-        "class Object {}",
-        "class Foo {",
-        "  var Bar;",
-        "  create() { return new Bar();}",
-        "}"),
-        TypeErrorCode.NOT_A_TYPE);
-  }
-
-  public void testNewExpression4() {
-    // New expression tied to an unbound type variable is not allowed.
-    resolveAndTest(Joiner.on("\n").join(
-        "class Object {}",
-        "class Foo<T> {",
-        "  T create() {",
-        "    return new T();",
-        "  }",
-        "}"),
-        ResolverErrorCode.NEW_EXPRESSION_CANT_USE_TYPE_VAR);
-  }
-  
-  public void testConstExpression4() {
-    // New expression tied to an unbound type variable is not allowed.
-    resolveAndTest(Joiner.on("\n").join(
-        "class Object {}",
-        "class Foo<T> {",
-        "  T create() {",
-        "    return const T();",
-        "  }",
-        "}"),
-        ResolverErrorCode.CONST_EXPRESSION_CANT_USE_TYPE_VAR);
-  }
-
-  public void testNewExpression5() {
-    // More cowbell. (Foo<T> isn't a type yet)
-    resolveAndTest(Joiner.on("\n").join(
-      "class Object {}",
-      "class Foo<T> { }",
-      "class B {",
-      "  foo() { return new Foo<T>(); }",
-      "}"),
-      TypeErrorCode.NO_SUCH_TYPE);
-  }
-
-  public void test_noSuchType_field() throws Exception {
-    resolveAndTest(Joiner.on("\n").join(
-        "class Object {}",
-        "class MyClass {",
-        "  Unknown field;",
-        "}"),
-        TypeErrorCode.NO_SUCH_TYPE);
-  }
-
-  public void test_variableStatement_noSuchType() throws Exception {
-    resolveAndTest(Joiner.on("\n").join(
-        "class Object {}",
-        "class MyClass {",
-        "  foo() {",
-        "    Unknown bar;",
-        "  }",
-        "}"),
-        TypeErrorCode.NO_SUCH_TYPE);
-  }
-
-  public void test_variableStatement_noSuchType_typeArgument() throws Exception {
-    resolveAndTest(Joiner.on("\n").join(
-        "class Object {}",
-        "class Foo<T> {}",
-        "class MyClass {",
-        "  bar() {",
-        "    Foo<Unknown> foo;",
-        "  }",
-        "}"),
-        TypeErrorCode.NO_SUCH_TYPE);
-  }
-
-  public void test_variableStatement_wrongTypeArgumentsNumber() throws Exception {
-    resolveAndTest(Joiner.on("\n").join(
-        "class Object {}",
-        "class Foo<T> {}",
-        "class MyClass {",
-        "  bar() {",
-        "    Foo<Object, Object> foo;",
-        "  }",
-        "}"),
-        TypeErrorCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS);
-  }
-
-  public void test_variableStatement_typeArgumentsForNonGeneric() throws Exception {
-    resolveAndTest(Joiner.on("\n").join(
-        "class Object {}",
-        "class Foo {}",
-        "class MyClass {",
-        "  bar() {",
-        "    Foo<Object> foo;",
-        "  }",
-        "}"),
-        TypeErrorCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS);
-  }
-
-  public void test_variableStatement_typeArgumentsForDynamic() throws Exception {
-    resolveAndTest(
-        Joiner.on("\n").join(
-            "class Object {}",
-            "class MyClass {",
-            "  bar() {",
-            "    dynamic<Object> v1;",
-            "  }",
-            "}"),
-        TypeErrorCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS);
-  }
-
-  public void test_noSuchType_classExtends() throws Exception {
-    resolveAndTest(Joiner.on("\n").join(
-        "class Object {}",
-        "class MyClass extends Unknown {",
-        "}"),
-        ResolverErrorCode.NO_SUCH_TYPE);
-  }
-
-  public void test_noSuchType_classExtendsTypeVariable() throws Exception {
-    resolveAndTest(Joiner.on("\n").join(
-        "class Object {}",
-        "class MyClass<E> extends E {",
-        "}"),
-        ResolverErrorCode.NOT_A_CLASS);
-  }
-
-  public void test_noSuchType_superClass_typeArgument() throws Exception {
-    String source =
-        Joiner.on("\n").join(
-            "class Object {}",
-            "class Base<T> {}",
-            "class MyClass extends Base<Unknown> {",
-            "}");
-    List<DartCompilationError> errors = resolveAndTest(source, ResolverErrorCode.NO_SUCH_TYPE);
-    assertEquals(1, errors.size());
-    {
-      DartCompilationError error = errors.get(0);
-      assertEquals(3, error.getLineNumber());
-      assertEquals(28, error.getColumnNumber());
-      assertEquals("Unknown".length(), error.getLength());
-      assertEquals(source.indexOf("Unknown"), error.getStartPosition());
-    }
-  }
-
-  public void test_noSuchType_superInterface_typeArgument() throws Exception {
-    String source =
-        Joiner.on("\n").join(
-            "class Object {}",
-            "abstract class Base<T> {}",
-            "class MyClass implements Base<Unknown> {",
-            "}");
-    List<DartCompilationError> errors = resolveAndTest(source, ResolverErrorCode.NO_SUCH_TYPE);
-    assertEquals(1, errors.size());
-    {
-      DartCompilationError error = errors.get(0);
-      assertEquals(3, error.getLineNumber());
-      assertEquals(31, error.getColumnNumber());
-      assertEquals("Unknown".length(), error.getLength());
-      assertEquals(source.indexOf("Unknown"), error.getStartPosition());
-    }
-  }
-
-  public void test_noSuchType_methodParameterType() throws Exception {
-    resolveAndTest(Joiner.on("\n").join(
-        "class Object {}",
-        "class MyClass {",
-        "  Object foo(Unknown p) {",
-        "    return null;",
-        "  }",
-        "}"),
-        TypeErrorCode.NO_SUCH_TYPE);
-  }
-
-  public void test_noSuchType_methodParameterType_noQualifier() throws Exception {
-    resolveAndTest(Joiner.on("\n").join(
-        "class Object {}",
-        "class MyClass {",
-        "  Object foo(lib.Unknown p) {",
-        "    return null;",
-        "  }",
-        "}"),
-        TypeErrorCode.NO_SUCH_TYPE);
-  }
-
-  public void test_noSuchType_returnType() throws Exception {
-    resolveAndTest(Joiner.on("\n").join(
-        "class Object {}",
-        "class MyClass {",
-        "  Unknown foo() {",
-        "    return null;",
-        "  }",
-        "}"),
-        TypeErrorCode.NO_SUCH_TYPE);
-  }
-
-  public void test_noSuchType_inExpression() throws Exception {
-    resolveAndTest(Joiner.on("\n").join(
-        "class Object {}",
-        "class MyClass {",
-        "  foo() {",
-        "    var bar;",
-        "    if (bar is Bar) {",
-        "    }",
-        "  }",
-        "}"),
-        TypeErrorCode.NO_SUCH_TYPE);
-  }
-
-  public void test_noSuchType_inCatch() throws Exception {
-    resolveAndTest(Joiner.on("\n").join(
-        "class Object {}",
-        "class MyClass {",
-        "  foo() {",
-        "    try {",
-        "    } on Unknown catch (e) {",
-        "    }",
-        "  }",
-        "}"),
-        TypeErrorCode.NO_SUCH_TYPE);
-  }
-
-  public void test_const_array() throws Exception {
-    resolveAndTest(Joiner.on("\n").join(
-        "class Object {}",
-        "class int {}",
-        "class MyClass<E> {",
-        "  var a1 = <int>[];",
-        "  var a2 = <E>[];",
-        "  var a3 = const <int>[];",
-        "  var a4 = const <E>[];",
-        "}"),
-        ErrorExpectation.errEx(ResolverErrorCode.CONST_ARRAY_WITH_TYPE_VARIABLE, 7, 19, 1));
-  }
-
-  public void test_const_map() throws Exception {
-    resolveAndTest(Joiner.on("\n").join(
-        "class Object {}",
-        "class String {}",
-        "class int {}",
-        "class MyClass<E> {",
-        "  var a1 = <int>{};",
-        "  var a2 = <E>{};",
-        "  var a3 = const <int>{};",
-        "  var a4 = const <E>{};",
-        "}"),
-        ErrorExpectation.errEx(ResolverErrorCode.CONST_MAP_WITH_TYPE_VARIABLE, 8, 19, 1));
-  }
-
-  public void test_multipleLabels() {
-    resolveAndTest(Joiner.on("\n").join(
-        "class Object {}",
-        "class MyClass<E> {",
-        "  foo() {",
-        "    a: b: while (true) { break a; } // ok",
-        "    a: b: while (true) { break b; } // ok",
-        "    a: b: while (true) { break c; } // error, no such label",
-        "  }",
-        "}"),
-        ErrorExpectation.errEx(ResolverErrorCode.CANNOT_RESOLVE_LABEL, 6, 32, 1));
-  }
-
-  public void test_multipleLabelsSwitch() {
-    resolveAndTest(Joiner.on("\n").join(
-        "class Object {}",
-        "foo() {",
-        "  switch(1) {",
-        "  a: case (0): break;",
-        "  a: case (1): break;",
-        "  }",
-        "}"),
-        ErrorExpectation.errEx(ResolverErrorCode.DUPLICATE_LABEL_IN_SWITCH_STATEMENT, 5, 3, 2));
-  }
-
-  public void test_breakInSwitch() {
-    resolveAndTest(Joiner.on("\n").join(
-        "class Object {}",
-        "foo() {",
-        "  switch(1) {",
-        "    a: case 0:",
-        "       break a;",
-        "  }",
-        "}"),
-        ErrorExpectation.errEx(ResolverErrorCode.BREAK_LABEL_RESOLVES_TO_CASE_OR_DEFAULT, 5, 14, 1));
-  }
-
-  public void test_continueInSwitch1() {
-    resolveAndTest(Joiner.on("\n").join(
-        "class Object {}",
-        "foo() {",
-        "  switch(1) {",
-        "    a: case 0:",
-        "       continue a;",
-        "  }",
-        "}"));
-  }
-
-  public void test_continueInSwitch2() {
-    resolveAndTest(Joiner.on("\n").join(
-        "class Object {}",
-        "foo() {",
-        "  switch(1) {",
-        "    case 0:",
-        "       continue a;",
-        "    a: case 1:",
-        "      break;",
-        "  }",
-        "}"));
-  }
-
-  public void test_continueInSwitch3() {
-    resolveAndTest(Joiner.on("\n").join(
-        "class Object {}",
-        "foo() {",
-        "  a: switch(1) {",
-        "    case 0:",
-        "       continue a;",
-        "  }",
-        "}"),
-        ErrorExpectation.errEx(ResolverErrorCode.CONTINUE_LABEL_RESOLVES_TO_SWITCH, 5, 17, 1));
-  }
-
-  public void test_new_noSuchType() throws Exception {
-    resolveAndTest(Joiner.on("\n").join(
-        "class Object {}",
-        "class MyClass {",
-        "  foo() {",
-        "    new Unknown();",
-        "  }",
-        "}"),
-        TypeErrorCode.NO_SUCH_TYPE);
-  }
-
-  public void test_new_noSuchType_typeArgument() throws Exception {
-    resolveAndTest(Joiner.on("\n").join(
-        "class Object {}",
-        "class Foo<T> {}",
-        "class MyClass {",
-        "  foo() {",
-        "    new Foo<T>();",
-        "  }",
-        "}"),
-        TypeErrorCode.NO_SUCH_TYPE);
-  }
-
-  public void test_new_wrongTypeArgumentsNumber() throws Exception {
-    resolveAndTest(Joiner.on("\n").join(
-        "class Object {}",
-        "class Foo<T> {}",
-        "class MyClass {",
-        "  foo() {",
-        "    new Foo<Object, Object>();",
-        "  }",
-        "}"),
-        ResolverErrorCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS);
-  }
-
-  public void test_noSuchType_mapLiteral_typeArgument() throws Exception {
-    resolveAndTest(Joiner.on("\n").join(
-        "class Object {}",
-        "class String {}",
-        "class MyClass {",
-        "  foo() {",
-        "    var map = <T>{};",
-        "  }",
-        "}"),
-        ResolverErrorCode.NO_SUCH_TYPE);
-  }
-
-  public void test_noSuchType_mapLiteral_num_type_args() throws Exception {
-    resolveAndTest(Joiner.on("\n").join(
-        "class Object {}",
-        "class int {}",
-        "class String {}",
-        "class MyClass {",
-        "  foo() {",
-        "    var map0 = {};",
-        "    var map1 = <int>{'foo': 1};",
-        "    var map2 = <String, int>{'foo' : 1};",
-        "    var map3 = <String, int, int>{'foo' : 1};",
-        "  }",
-        "}"),
-//        ResolverErrorCode.DEPRECATED_MAP_LITERAL_SYNTAX,
-        ResolverErrorCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS);
-  }
-
-  public void test_noSuchType_arrayLiteral_typeArgument() throws Exception {
-    resolveAndTest(Joiner.on("\n").join(
-        "class Object {}",
-        "class MyClass {",
-        "  foo() {",
-        "    var map = <T>[null];",
-        "  }",
-        "}"),
-        ResolverErrorCode.NO_SUCH_TYPE);
-  }
-
-  /**
-   * When {@link SupertypeResolver} can not find "UnknownA", it uses {@link DynamicType}, which
-   * returns {@link DynamicElement}. By itself, this is OK. However when we later try to resolve
-   * second unknown type "UnknownB", we expect in {@link Elements#findElement()} specific
-   * {@link ClassElement} implementation and {@link DynamicElement} is not valid.
-   */
-  public void test_classExtendsUnknown_fieldUnknownType() throws Exception {
-    resolveAndTest(Joiner.on("\n").join(
-        "class Object {}",
-        "class MyClass extends UnknownA {",
-        "  UnknownB field;",
-        "}"),
-        ResolverErrorCode.NO_SUCH_TYPE,
-        TypeErrorCode.NO_SUCH_TYPE);
-  }
-
-  public void test_cascadeWithTypeVariable() {
-    resolveAndTest(Joiner.on("\n").join(
-        "class Object {}",
-        "class C<T> {",
-        "  test() {",
-        "    this..T;",
-        "  }",
-        "}"),
-        ResolverErrorCode.TYPE_VARIABLE_NOT_ALLOWED_IN_IDENTIFIER);
-  }
-
-  public void test_cascade_complex() {
-    resolveAndTest(Joiner.on("\n").join(
-        "class Object {}",
-        "class Spline {",
-        "  Spline a() {",
-        "    return this;",
-        "  }",
-        "  Line b() {",
-        "    return null;",
-        "  }",
-        "  Spline f() {",
-        "    Line x = new Line();",
-        "    x.h()..a()..b().g();",
-        "  }",
-        "}",
-        "class Line {",
-        "  Line g() {",
-        "    return this;",
-        "  }",
-        "  Spline h() {",
-        "    return null;",
-        "  }",
-        "}"
-    ));
-  }
-
-  /**
-   * When {@link SupertypeResolver} can not find "UnknownA", it uses {@link DynamicType}, which
-   * returns {@link DynamicElement}. By itself, this is OK. However when we later try to resolve
-   * super() constructor invocation, this should not cause exception.
-   */
-  public void test_classExtendsUnknown_callSuperConstructor() throws Exception {
-    resolveAndTest(Joiner.on("\n").join(
-        "class Object {}",
-        "class MyClass extends UnknownA {",
-        "  MyClass() : super() {",
-        "  }",
-        "}"),
-        ResolverErrorCode.NO_SUCH_TYPE);
-  }
-
-  public void test_typedefUsedAsExpression() {
-    resolveAndTest(Joiner.on("\n").join(
-        "class Object {}",
-        "typedef f();",
-        "main() {",
-        "  try {",
-        "    0.25 - f;",
-        "  } catch(e) {}",
-        "}"));
-  }
-
-  public void test_classUsedAsExpression() {
-    resolveAndTest(Joiner.on("\n").join(
-        "class Object {}",
-        "main() {",
-        "    0.25 - Object;",
-        "}"));
-  }
-
-  public void test_typeVariableUsedAsExpression() {
-    resolveAndTest(Joiner.on("\n").join(
-        "class Object {}",
-        "class A<B> {",
-        "  var field = B;",
-        "  f() {",
-        "    process(x);",
-        "  }",
-        "}",
-        "process(x) {}",
-        ""));
-  }
-
-  public void test_shadowType_withVariable() throws Exception {
-    resolveAndTest(Joiner.on("\n").join(
-        "class Object {}",
-        "class Foo<T> {}",
-        "class Param {}",
-        "class MyClass {",
-        "  foo() {",
-        "    var Param;",
-        "    new Foo<Param>();",
-        "  }",
-        "}"),
-        TypeErrorCode.NOT_A_TYPE);
-  }
-
-  public void test_operatorIs_withFunctionAlias() throws Exception {
-    resolveAndTest(Joiner.on("\n").join(
-        "class Object {}",
-        "class int {}",
-        "typedef dynamic F1<T>(dynamic x, T y);",
-        "class MyClass {",
-        "  main() {",
-        "    F1<int> f1 = (Object o, int i) => null;",
-        "    if (f1 is F1<int>) {",
-        "    }",
-        "  }",
-        "}"));
-  }
-
-  public void testTypeVariableInStatic() {
-    resolveAndTest(Joiner.on("\n").join(
-        "class Object {}",
-        "class A<T> {",
-        "  static foo() { new T(); }", // can't ref type variable in method
-        "  static bar() { T variable = 1; }",
-        "}"),
-        errEx(ResolverErrorCode.TYPE_VARIABLE_IN_STATIC_CONTEXT, 3, 22 , 1),
-        errEx(ResolverErrorCode.TYPE_VARIABLE_IN_STATIC_CONTEXT, 4, 18, 1));
-  }
-
-  public void testConstClass() {
-    resolveAndTest(Joiner.on("\n").join(
-        "class Object {}",
-        "class int {}",
-        "class GoodBase {",
-        "  const GoodBase() : foo = 1;",
-        "  final foo;",
-        "}",
-        "class BadBase {",
-        "  BadBase() {}",
-        "  var foo;",
-        "}",                                       // line 10
-        "class Bad {",
-        "  const Bad() : bar = 1;",
-        "  var bar;", // error: non-final field in const class
-        "}",
-        "class BadSub1 extends BadBase {",
-        "  const BadSub1() : super(),  bar = 1;", // error2: inherits non-final field, super !const
-        "  final bar;",
-        "}",
-        "class BadSub2 extends GoodBase {",
-        "  const BadSub2() : super(),  bar = 1;", // line 20
-        "  var bar;",                             // error: non-final field in constant class
-        "}",
-        "class GoodSub1 extends GoodBase {",
-        "  const GoodSub1() : super(),  bar = 1;",
-        "  final bar;",
-        "}",
-        "class GoodSub2 extends GoodBase {",
-        "  const GoodSub2() : super();",
-        "  static int bar;",                      // OK, non-final but it is static
-        "}"),
-        errEx(ResolverErrorCode.CONST_CLASS_WITH_NONFINAL_FIELDS, 13, 7, 3),
-        errEx(ResolverErrorCode.CONST_CONSTRUCTOR_MUST_CALL_CONST_SUPER, 16, 9, 7),
-        errEx(ResolverErrorCode.CONST_CLASS_WITH_INHERITED_NONFINAL_FIELDS, 9, 7, 3),
-        errEx(ResolverErrorCode.CONST_CLASS_WITH_NONFINAL_FIELDS, 21, 7, 3));
-  }
-
-  public void testFinalInit1() {
-    resolveAndTest(Joiner.on("\n").join(
-        "class Object {}",
-        "class int {}",
-        "final f1 = 1;",
-        "final f2;",  // error
-        "class A {",
-        "  final f3 = 1;",
-        "  final f4;",  // should be initialized in constructor
-        "  static final f5 = 1;",
-        "  static final f6;",    // error
-        "  method() {",
-        "    final f7 = 1;",
-        "    final f8;",  // error
-        "  }",
-        "}"),
-        errEx(ResolverErrorCode.TOPLEVEL_FINAL_REQUIRES_VALUE, 4, 7 , 2),
-        errEx(ResolverErrorCode.STATIC_FINAL_REQUIRES_VALUE, 9, 16, 2),
-        errEx(ResolverErrorCode.CONSTANTS_MUST_BE_INITIALIZED, 12, 11, 2),
-        errEx(ResolverErrorCode.FINAL_FIELD_MUST_BE_INITIALIZED, 7, 9, 2));
-  }
-
-  public void testFinalInit2() {
-    resolveAndTest(Joiner.on("\n").join(
-        "class Object {}",
-        "class C {",
-        "  final a;",
-        "  C() {}",   // explicit constructor does not initialize
-        "}"),
-        errEx(ResolverErrorCode.FINAL_FIELD_MUST_BE_INITIALIZED, 3, 9, 1));
-  }
-
-  public void testFinalInit3() {
-    resolveAndTest(Joiner.on("\n").join(
-        "class Object {}",
-        "class C {",
-        "  final a;",  // implicit constructor does not initialize
-        "}"),
-        errEx(ResolverErrorCode.FINAL_FIELD_MUST_BE_INITIALIZED, 3, 9, 1));
-  }
-
-  public void testFinalInit4() {
-    resolveAndTest(Joiner.on("\n").join(
-        "class Object {}",
-        "class C {",
-        "  final a;",
-        "  C(this.a);", // no error if initialized in initializer list
-        "}"));
-  }
-
-  public void testFinalInit5() {
-    resolveAndTest(Joiner.on("\n").join(
-        "class Object {}",
-        "class C {",
-        "  final a;",
-        "  C() : this.named(1);",  // no error on redirect
-        "  C.named(this.a) {}",
-        "}"));
-  }
-
-  public void testFinalInit7() {
-    resolveAndTest(Joiner.on("\n").join(
-        "class Object {}",
-        "class C {",
-        "  final a = 1;",
-        "}"));
-  }
-
-  public void testFinalInit8() {
-    resolveAndTest(Joiner.on("\n").join(
-        "class Object {}",
-        "class C {",
-        "  final a;",
-        "  C() : this.a = 1;",
-        "}"));
-  }
-
-  public void test_const_requiresValue() {
-    resolveAndTest(Joiner.on("\n").join(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "class Object {}",
-        "class int {}",
-        "const f;",
-        ""),
-        errEx(ResolverErrorCode.CONST_REQUIRES_VALUE, 4, 7, 1));
-  }
-
-  public void test_const_requiresConstValue() {
-    resolveAndTestCtConstExpectErrors(Joiner.on("\n").join(
-        "class Object {}",
-        "f() {",
-        "  const id = 1.toString();",
-        "}"),
-        errEx(ResolverErrorCode.EXPECTED_CONSTANT_EXPRESSION, 3, 14, 12));
-  }
-
-  public void test_const_undefinedClass() {
-    resolveAndTest(Joiner.on("\n").join(
-        "class Object {}",
-        "main() {",
-        " const A();",
-        "}"),
-        errEx(ResolverErrorCode.NO_SUCH_TYPE_CONST, 3, 8, 1));
-  }
-
-  public void testNoGetterOrSetter() {
-    resolveAndTest(Joiner.on("\n").join(
-        "class Object {}",
-        "get getter1 {}",
-        "set setter1(arg) {}",
-        "class A {",
-        "  static get getter2 {}",
-        "  static set setter2(arg) {}",
-        "  get getter3 {}",
-        "  set setter3(arg) {}",
-        "}",
-        "method() {",
-        "  var result;",
-        "  result = getter1;",
-        "  getter1 = 1;",
-        "  result = setter1;",
-        "  setter1 = 1;",
-        "  result = A.getter2;",
-        "  A.getter2 = 1;",
-        "  result = A.setter2;",
-        "  A.setter2 = 1;",
-        "  var instance = new A();",
-        "  result = instance.getter3;",
-        "  instance.getter3 = 1;",
-        "  result = instance.setter3;",
-        "  instance.setter3 = 1;",
-        "}"),
-        errEx(ResolverErrorCode.FIELD_DOES_NOT_HAVE_A_SETTER, 13, 3, 7),
-        errEx(ResolverErrorCode.FIELD_DOES_NOT_HAVE_A_GETTER, 14, 12, 7),
-        errEx(ResolverErrorCode.FIELD_DOES_NOT_HAVE_A_SETTER, 17, 5, 7),
-        errEx(ResolverErrorCode.FIELD_DOES_NOT_HAVE_A_GETTER, 18, 14, 7));
-  }
-
-  public void testErrorInUnqualifiedInvocation1() {
-    resolveAndTest(Joiner.on("\n").join(
-        "class Object {}",
-        "class int {}",
-        "class Foo {",
-        "  Foo() {}",
-        "}",
-        "method() {",
-        " Foo();",
-        "}"),
-        errEx(ResolverErrorCode.DID_YOU_MEAN_NEW, 7, 2, 5));
-  }
-
-  public void testErrorInUnqualifiedInvocation2() {
-    resolveAndTest(Joiner.on("\n").join(
-        "class Object {}",
-        "class int {}",
-        "class Foo {}",
-        "method() {",
-        " Foo();",
-        "}"),
-        errEx(ResolverErrorCode.DID_YOU_MEAN_NEW, 5, 2, 5));
-  }
-
-  public void testErrorInUnqualifiedInvocation3() {
-    resolveAndTest(Joiner.on("\n").join(
-        "class Object {}",
-        "class int {}",
-        "class Foo<T> {",
-        "  method() {",
-        "   T();",
-        "  }",
-        "}"),
-        errEx(ResolverErrorCode.DID_YOU_MEAN_NEW, 5, 4, 3));
-  }
-
-
-  public void testErrorInUnqualifiedInvocation4() {
-    resolveAndTest(Joiner.on("\n").join(
-        "class Object {}",
-        "class int {}",
-        "typedef int foo();",
-        "method() {",
-        " foo();",
-        "}"),
-        errEx(ResolverErrorCode.CANNOT_CALL_FUNCTION_TYPE_ALIAS, 5, 2, 5));
-  }
-
-  public void testErrorInUnqualifiedInvocation5() {
-    resolveAndTest(Joiner.on("\n").join(
-        "class Object {}",
-        "class int {}",
-        "method() {",
-        "  outer: for(int i = 0; i < 1; i++) {",
-        "    outer();",
-        "  }",
-        "}"),
-        errEx(ResolverErrorCode.CANNOT_RESOLVE_METHOD, 5, 5, 5));
-  }
-
-  public void testUndercoreInNamedParameterMethodDefinition() {
-    // TODO(scheglov)
-    // Language change 4288 adds new syntax for optional named parameters.
-    // However before "remove old optional parameter syntax" we have to support old syntax too.
-    // And this conflicts with "_" handling in optional named parameters.
-    // 
-    // http://code.google.com/p/dart/issues/detail?id=4539
-    // requested to disable this
-    resolveAndTest(Joiner.on("\n").join(
-        "class Object {}",
-        "method({_foo}) {}",
-        "class Foo {",
-        "  var _bar;",
-        "  //Foo({this._bar}){}",
-        "  method({_foo}){}",
-        "}"),
-        errEx(ResolverErrorCode.NAMED_PARAMETERS_CANNOT_START_WITH_UNDER, 2, 9, 4),
-//        errEx(ResolverErrorCode.NAMED_PARAMETERS_CANNOT_START_WITH_UNDER, 5, 8, 9),
-        errEx(ResolverErrorCode.NAMED_PARAMETERS_CANNOT_START_WITH_UNDER, 6, 11, 4));
-  }
-  
-  public void testUndercoreInOptionalParameterMethodDefinition() {
-    resolveAndTest(Joiner.on("\n").join(
-        "class Object {}",
-        "method([_foo]) {}",
-        "typedef myFuncType([_foo]);",
-        "class Foo {",
-        "  var _bar;",
-        "  method([_foo]){}",
-        "}"),
-        errEx(ResolverErrorCode.OPTIONAL_PARAMETERS_CANNOT_START_WITH_UNDER, 2, 9, 4),
-        errEx(ResolverErrorCode.OPTIONAL_PARAMETERS_CANNOT_START_WITH_UNDER, 6, 11, 4),
-        errEx(ResolverErrorCode.OPTIONAL_PARAMETERS_CANNOT_START_WITH_UNDER, 3, 21, 4));
-  }
-
-  public void testUndercoreInNamedParameterFunctionDefinition() {
-    resolveAndTest(Joiner.on("\n").join(
-        "class Object {}",
-        "func({_foo}) {}"),
-        errEx(ResolverErrorCode.NAMED_PARAMETERS_CANNOT_START_WITH_UNDER, 2, 7, 4));
-  }
-
-  public void testUndercoreInNamedParameterFunctionAlias() {
-    resolveAndTest(Joiner.on("\n").join(
-        "class Object {}",
-        "typedef Object func({_foo});"),
-        errEx(ResolverErrorCode.NAMED_PARAMETERS_CANNOT_START_WITH_UNDER, 2, 22, 4));
-  }
-
-  /**
-   * "this" is not accessible to initializers, so invocation of instance method is error.
-   * <p>
-   * http://code.google.com/p/dart/issues/detail?id=2477
-   */
-  public void test_callInstanceMethod_fromInitializer() throws Exception {
-    resolveAndTest(
-        Joiner.on("\n").join(
-            "// filler filler filler filler filler filler filler filler filler filler",
-            "class Object {}",
-            "class A {",
-            "  var x;",
-            "  A() : x = foo() {}",
-            "  foo() {}",
-            "}",
-            ""),
-        errEx(ResolverErrorCode.INSTANCE_METHOD_FROM_INITIALIZER, 5, 13, 5));
-  }
-
-  /**
-   * "this" is not accessible to initializers, so reference of instance method is error.
-   * <p>
-   * http://code.google.com/p/dart/issues/detail?id=2477
-   */
-  public void test_referenceInstanceMethod_fromInitializer() throws Exception {
-    resolveAndTest(
-        Joiner.on("\n").join(
-            "// filler filler filler filler filler filler filler filler filler filler",
-            "class Object {}",
-            "class A {",
-            "  var x;",
-            "  A() : x = foo {}",
-            "  foo() {}",
-            "}",
-            ""),
-            errEx(ResolverErrorCode.INSTANCE_METHOD_FROM_INITIALIZER, 5, 13, 3));
-  }
-
-  public void test_redirectConstructor() {
-    resolveAndTest(Joiner.on("\n").join(
-        "class Object {}",
-        "class int {}",
-        "int topLevel() {}",
-        "class A {",
-        "  method() {}",
-        "}",
-        "class C {",
-        "  C(arg){}",
-        "  C.named1() : this(topLevel());", // ok
-        "  C.named2() : this(method());", // error, not a static method
-        "  C.named3() : this(new A().method());", // ok
-        "  method() {}",
-        "}"),
-        errEx(ResolverErrorCode.INSTANCE_METHOD_FROM_REDIRECT, 10, 21, 8));
-  }
-
-  public void test_unresolvedRedirectConstructor() throws Exception {
-    resolveAndTest(Joiner.on("\n").join(
-        "class Object {}",
-        "class A {",
-        "  A() : this.named();",
-        "}"),
-        errEx(ResolverErrorCode.CANNOT_RESOLVE_CONSTRUCTOR, 3, 9, 12));
-  }
-
-  public void test_unresolvedSuperConstructor() throws Exception {
-    resolveAndTest(Joiner.on("\n").join(
-        "class Object {}",
-        "class A {",
-        "  A() : super.named() {}",
-        "}"),
-        errEx(ResolverErrorCode.CANNOT_RESOLVE_SUPER_CONSTRUCTOR, 3, 9, 13));
-  }
-
-  public void test_unresolvedFieldInInitializer() throws Exception {
-    resolveAndTest(Joiner.on("\n").join(
-        "class Object {}",
-        "class A {",
-        "  const A() : this.field = 1;",
-        "}"),
-        errEx(ResolverErrorCode.CANNOT_RESOLVE_FIELD, 3, 20, 5));
-  }
-
-  public void test_illegalConstructorModifiers() throws Exception {
-    resolveAndTest(Joiner.on("\n").join(
-        "class Object {}",
-        "class A {",
-        "  static A() {}",
-        "  static A.named() {}",
-        "}"),
-        errEx(ResolverErrorCode.CONSTRUCTOR_CANNOT_BE_STATIC, 3, 10, 1),
-        errEx(ResolverErrorCode.CONSTRUCTOR_CANNOT_BE_STATIC, 4, 10, 7));
-  }
-
-  public void test_illegalConstructorReturnType() throws Exception {
-    resolveAndTest(Joiner.on("\n").join(
-        "class Object {}",
-        "class int {}",
-        "class A {",
-        "  void A();",
-        "  void A.named();",
-        "}",
-        "class B {",
-        "  int B();",
-        "  int B.named();",
-        "}"),
-        errEx(ResolverErrorCode.CONSTRUCTOR_CANNOT_HAVE_RETURN_TYPE, 4, 3, 4),
-        errEx(ResolverErrorCode.CONSTRUCTOR_CANNOT_HAVE_RETURN_TYPE, 5, 3, 4),
-        errEx(ResolverErrorCode.CONSTRUCTOR_CANNOT_HAVE_RETURN_TYPE, 8, 3, 3),
-        errEx(ResolverErrorCode.CONSTRUCTOR_CANNOT_HAVE_RETURN_TYPE, 9, 3, 3));
-  }
-
-  public void test_fieldAccessInInitializer() throws Exception {
-    resolveAndTest(Joiner.on("\n").join(
-        "class Object {}",
-        "class A {",
-        "  var f1;",
-        "  var f2;",
-        "  A() : this.f2 = f1;",
-        "}"),
-        errEx(ResolverErrorCode.CANNOT_ACCESS_FIELD_IN_INIT, 5, 19, 2));
-  }
-
-  public void test_cannotBeResolved() throws Exception {
-    resolveAndTest(Joiner.on("\n").join(
-        "class Object {}",
-        "class A {",
-        "  static var field = B;",
-        " }",
-        "method() {",
-        "  A.noField = 1;",
-        "}"),
-        errEx(TypeErrorCode.CANNOT_BE_RESOLVED, 3, 22, 1),
-        errEx(TypeErrorCode.CANNOT_BE_RESOLVED, 6, 5, 7));
-  }
-
-  public void test_invokeTypeAlias() throws Exception {
-    resolveAndTest(Joiner.on("\n").join(
-        "class Object {}",
-        "typedef Object func();",
-        "method() {",
-        "  func();",
-        "}"),
-        errEx(ResolverErrorCode.CANNOT_CALL_FUNCTION_TYPE_ALIAS, 4, 3, 6));
-  }
-
-  public void test_initializerErrors() {
-    resolveAndTest(Joiner.on("\n").join(
-        "class Object {}",
-        "class A { }",
-        "class B<T> {",
-        "  method() { }",
-        "  B(arg) : A = 1, ",
-        "           method = 2,",
-        "           arg = 3,",
-        "           T = 4 {}",
-        "}"),
-        errEx(ResolverErrorCode.EXPECTED_FIELD_NOT_CLASS, 5, 12, 1),
-        errEx(ResolverErrorCode.EXPECTED_FIELD_NOT_METHOD, 6, 12, 6),
-        errEx(ResolverErrorCode.EXPECTED_FIELD_NOT_PARAMETER, 7, 12, 3),
-        errEx(ResolverErrorCode.EXPECTED_FIELD_NOT_TYPE_VAR, 8, 12, 1));
-  }
-
-  public void test_illegalAccessFromStatic() throws Exception {
-    resolveAndTest(Joiner.on("\n").join(
-        "class Object {}",
-        "class C {",
-        "  var f;",
-        "  m() {}",
-        "  static method () {",
-        "    f = 1;",
-        "    m();",
-        "    var func = m;",
-        "  }",
-        "}"),
-        errEx(ResolverErrorCode.ILLEGAL_FIELD_ACCESS_FROM_STATIC, 6, 5, 1),
-        errEx(ResolverErrorCode.INSTANCE_METHOD_FROM_STATIC, 7, 5, 3),
-        errEx(ResolverErrorCode.ILLEGAL_METHOD_ACCESS_FROM_STATIC, 8, 16, 1));
-  }
-
-  public void test_invalidGenerativeConstructorReturn() throws Exception {
-    resolveAndTest(Joiner.on("\n").join(
-        "class Object {}",
-        "class C {",
-        "  C() { return 5 + 7; }",
-        "}"),
-        errEx(ResolverErrorCode.INVALID_RETURN_IN_CONSTRUCTOR, 3, 9, 13));
-  }
-
-  public void test_isAClass() {
-    resolveAndTest(Joiner.on("\n").join(
-        "class Object {}",
-        "method () {",
-        "  var a = Object;",
-        "}"));
-  }
-
-  public void test_isAnInstanceMethod() {
-    resolveAndTest(Joiner.on("\n").join(
-        "class Object {}",
-        "class C {",
-        "  method() {}",
-        "}",
-        "method () {",
-        "  var a = C.method();",
-        "}"),
-        errEx(ResolverErrorCode.IS_AN_INSTANCE_METHOD, 6, 13, 6));
-  }
-
-  public void test_staticAccess() throws Exception {
-    resolveAndTest(Joiner.on("\n").join(
-        "class Object {}",
-        "class C {",
-        "  var field;",
-        "  method() {}",
-        "}",
-        "method() {",
-        "  C.method = 1;",
-        "  C.field();",
-        "  var a = C.field;",
-        "}"),
-        errEx(ResolverErrorCode.NOT_A_STATIC_METHOD, 7, 5, 6),
-        errEx(ResolverErrorCode.CANNOT_ASSIGN_TO_METHOD, 7, 3, 8),
-        errEx(ResolverErrorCode.IS_AN_INSTANCE_FIELD, 8, 5, 5),
-        errEx(ResolverErrorCode.NOT_A_STATIC_FIELD, 9, 13, 5));
-  }
-
-  public void test_redirectedConstructor() throws Exception {
-  resolveAndTest(Joiner.on("\n").join(
-        "class Object {}",
-        "class A {",
-        "  A() : this.named1();",
-        "  A.named1() : this.named2();",
-        "  A.named2() : this.named1();",
-        "}"),
-        errEx(ResolverErrorCode.REDIRECTED_CONSTRUCTOR_CYCLE, 3, 3, 20),
-        errEx(ResolverErrorCode.REDIRECTED_CONSTRUCTOR_CYCLE, 4, 3, 27),
-        errEx(ResolverErrorCode.REDIRECTED_CONSTRUCTOR_CYCLE, 5, 3, 27));
-  }
-
-  public void test_tooFewArgumentsInImplicitSuper() throws Exception {
-    resolveAndTest(Joiner.on("\n").join(
-        "class Object {}",
-        "class A {",
-        "  A(arg) {}",
-        "}",
-        "class B extends A {",
-        "  B() { }",
-        "}"),
-        errEx(ResolverErrorCode.TOO_FEW_ARGUMENTS_IN_IMPLICIT_SUPER, 6, 3, 7));
-  }
-}
diff --git a/compiler/javatests/com/google/dart/compiler/resolver/ResolverTestCase.java b/compiler/javatests/com/google/dart/compiler/resolver/ResolverTestCase.java
deleted file mode 100644
index 7de5552..0000000
--- a/compiler/javatests/com/google/dart/compiler/resolver/ResolverTestCase.java
+++ /dev/null
@@ -1,548 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.resolver;
-
-import com.google.common.base.Joiner;
-import com.google.common.base.Splitter;
-import com.google.common.collect.Lists;
-import com.google.common.collect.Sets;
-import com.google.dart.compiler.DartCompilationError;
-import com.google.dart.compiler.DartCompilerListener;
-import com.google.dart.compiler.ErrorCode;
-import com.google.dart.compiler.ast.ASTVisitor;
-import com.google.dart.compiler.ast.DartClass;
-import com.google.dart.compiler.ast.DartIdentifier;
-import com.google.dart.compiler.ast.DartNode;
-import com.google.dart.compiler.ast.DartParameterizedTypeNode;
-import com.google.dart.compiler.ast.DartTypeNode;
-import com.google.dart.compiler.ast.DartTypeParameter;
-import com.google.dart.compiler.ast.DartUnit;
-import com.google.dart.compiler.ast.LibraryUnit;
-import com.google.dart.compiler.ast.Modifiers;
-import com.google.dart.compiler.common.ErrorExpectation;
-import com.google.dart.compiler.parser.DartParser;
-import com.google.dart.compiler.testing.TestCompilerContext;
-import com.google.dart.compiler.type.DynamicType;
-import com.google.dart.compiler.type.InterfaceType;
-import com.google.dart.compiler.type.Type;
-import com.google.dart.compiler.type.Types;
-import com.google.dart.compiler.util.DartSourceString;
-
-import junit.framework.TestCase;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.List;
-
-/**
- * Utility methods for resolver tests.
- */
-abstract class ResolverTestCase extends TestCase {
-
-  private List<DartCompilationError> parseErrors = Lists.newArrayList();
-
-  @Override
-  public void setUp() {
-    resetParseErrors();
-  }
-
-  @Override
-  public void tearDown() {
-    resetParseErrors();
-  }
-
-  private static CoreTypeProvider setupTypeProvider(DartUnit unit, TestCompilerContext context, Scope scope) {
-    new TopLevelElementBuilder().exec(unit.getLibrary(), unit, context);
-    new TopLevelElementBuilder().fillInUnitScope(unit, context, scope, null);
-    ClassElement object = (ClassElement) scope.findElement(null, "Object");
-    assertNotNull("Cannot resolve Object", object);
-    return new MockCoreTypeProvider(object);
-  }
-
-  static Scope resolve(DartUnit unit, TestCompilerContext context) {
-    LibraryUnit libraryUnit = MockLibraryUnit.create(unit);
-
-    // Prepare for running phases.
-    Scope scope = libraryUnit.getElement().getScope();
-    CoreTypeProvider typeProvider = setupTypeProvider(unit, context, scope);
-    // Run phases as in compiler.
-    new SupertypeResolver().exec(unit, context, scope, typeProvider);
-    new MemberBuilder().exec(unit, context, scope, typeProvider);
-    new Resolver(context, scope, typeProvider).exec(unit);
-    // TODO(zundel): One day, we want all AST nodes that are identifiers to point to
-    // elements if they are resolved.  Uncommenting this line helps track missing elements
-    // down.
-    // ResolverAuditVisitor.exec(unit);
-    return scope;
-  }
-
-  static Scope resolveCompileTimeConst(DartUnit unit, TestCompilerContext context) {
-    LibraryUnit libraryUnit = MockLibraryUnit.create(unit);
-    // Prepare for running phases.
-    Scope scope = libraryUnit.getElement().getScope();
-    CoreTypeProvider typeProvider = setupTypeProvider(unit, context, scope);
-    // Run phases as in compiler.
-    new SupertypeResolver().exec(unit, context, scope, typeProvider);
-    new MemberBuilder().exec(unit, context, scope, typeProvider);
-    new Resolver.Phase().exec(unit, context, typeProvider);
-    new CompileTimeConstantAnalyzer(typeProvider, context).exec(unit);
-    return scope;
-  }
-
-
-  static DartClass makeClass(String name, DartTypeNode supertype, String... typeParameters) {
-    return makeClass(name, supertype, Collections.<DartTypeNode>emptyList(), typeParameters);
-  }
-
-  static DartClass makeInterface(String name, String... typeParameters) {
-    return makeInterface(name, Collections.<DartTypeNode>emptyList(), null, typeParameters);
-  }
-
-  static DartClass makeClass(String name, DartTypeNode supertype, List<DartTypeNode> interfaces,
-      String... typeParameters) {
-    List<DartTypeNode> mixins = new ArrayList<DartTypeNode>();
-    List<DartTypeParameter> parameterNodes = new ArrayList<DartTypeParameter>();
-    for (String parameter : typeParameters) {
-      parameterNodes.add(makeTypeVariable(parameter));
-    }
-    List<DartNode> members = Arrays.<DartNode> asList();
-    return new DartClass(-1, 0, new DartIdentifier(name), null, supertype, -1, interfaces, mixins,
-        -1, -1, -1, members, parameterNodes, null, false, Modifiers.NONE);
-  }
-
-  static DartClass makeInterface(String name, List<DartTypeNode> interfaces,
-      DartParameterizedTypeNode defaultClass, String... typeParameters) {
-    List<DartTypeNode> mixins = new ArrayList<DartTypeNode>();
-    List<DartTypeParameter> parameterNodes = new ArrayList<DartTypeParameter>();
-    for (String parameter : typeParameters) {
-      parameterNodes.add(makeTypeVariable(parameter));
-    }
-    List<DartNode> members = Arrays.<DartNode> asList();
-    return new DartClass(-1, 0, new DartIdentifier(name), null, null, -1, interfaces, mixins, -1,
-        -1, -1, members, parameterNodes, defaultClass, true, Modifiers.NONE);
-  }
-
-  static DartParameterizedTypeNode makeDefault(String name) {
-    return new DartParameterizedTypeNode(new DartIdentifier(name), null);
-  }
-
-  private static DartTypeParameter makeTypeVariable(String name) {
-    return new DartTypeParameter(new DartIdentifier(name), null);
-  }
-
-  /**
-   * Look for  DartIdentifier nodes in the tree whose elements are null.  They should all either
-   * be resolved, or marked as an unresolved element.
-   */
-  static class ResolverAuditVisitor extends ASTVisitor<Void> {
-    private List<String> failures = Lists.newArrayList();
-
-    @Override
-    public Void visitIdentifier(DartIdentifier node) {
-
-      if (node.getElement() == null) {
-        failures.add("Identifier: "
-            + node.getName()
-            + " has null element @ ("
-            + node.getSourceInfo().getLine()
-            + ":"
-            + node.getSourceInfo().getColumn()
-            + ")");
-      }
-      return null;
-    }
-
-    public List<String> getFailures() {
-      return failures;
-    }
-
-    public static void exec(DartNode root) {
-      ResolverAuditVisitor visitor = new ResolverAuditVisitor();
-      root.accept(visitor);
-      List<String> results = visitor.getFailures();
-      if (results.size() > 0) {
-        StringBuilder out = new StringBuilder("Missing elements found in AST\n");
-        Joiner.on("\n").appendTo(out, results);
-        fail(out.toString());
-      }
-    }
-  }
-
-  static class MockCoreTypeProvider implements CoreTypeProvider {
-
-    private final InterfaceType boolType;
-    private final InterfaceType intType;
-    private final InterfaceType doubleType;
-    private final InterfaceType numType;
-    private final InterfaceType stringType;
-    private final InterfaceType functionType;
-    private final InterfaceType dynamicType;
-    private final InterfaceType defaultMapLiteralType;
-    private final InterfaceType defaultListType;
-    private final InterfaceType typeType;
-    private final Type voidType;
-    private final ClassElement objectElement;
-
-    {
-      ClassElement dynamicElement = Elements.classNamed("dynamic");
-      dynamicType = Types.interfaceType(dynamicElement, Collections.<Type>emptyList());
-      dynamicElement.setType(dynamicType);
-
-      ClassElement boolElement = Elements.classNamed("bool");
-      boolType = Types.interfaceType(boolElement, Collections.<Type>emptyList());
-      boolElement.setType(boolType);
-
-      ClassElement intElement = Elements.classNamed("int");
-      intType = Types.interfaceType(intElement, Collections.<Type>emptyList());
-      intElement.setType(intType);
-
-      ClassElement doubleElement = Elements.classNamed("double");
-      doubleType = Types.interfaceType(doubleElement, Collections.<Type>emptyList());
-      doubleElement.setType(doubleType);
-
-      ClassElement numElement = Elements.classNamed("num");
-      numType = Types.interfaceType(numElement, Collections.<Type>emptyList());
-      numElement.setType(numType);
-
-      ClassElement stringElement = Elements.classNamed("String");
-      stringType = Types.interfaceType(stringElement, Collections.<Type>emptyList());
-      stringElement.setType(stringType);
-
-      ClassElement functionElement = Elements.classNamed("Function");
-      functionType = Types.interfaceType(functionElement, Collections.<Type>emptyList());
-      functionElement.setType(functionType);
-
-      ClassElement mapElement = Elements.classNamed("Map");
-      defaultMapLiteralType =
-          Types.interfaceType(mapElement, Lists.<Type>newArrayList(stringType, dynamicType));
-      mapElement.setType(defaultMapLiteralType);
-
-      ClassElement listElement = Elements.classNamed("List");
-      defaultListType = Types.interfaceType(listElement, Lists.<Type>newArrayList(dynamicType));
-      listElement.setType(defaultListType);
-
-      ClassElement typeElement = Elements.classNamed("Type");
-      typeType = Types.interfaceType(typeElement, Collections.<Type>emptyList());
-      listElement.setType(defaultListType);
-
-      voidType = Types.newVoidType();
-    }
-
-    MockCoreTypeProvider(ClassElement objectElement) {
-      this.objectElement = objectElement;
-    }
-
-    @Override
-    public InterfaceType getIntType() {
-      return intType;
-    }
-
-    @Override
-    public InterfaceType getDoubleType() {
-      return doubleType;
-    }
-
-    @Override
-    public InterfaceType getNumType() {
-      return numType;
-    }
-
-    @Override
-    public InterfaceType getBoolType() {
-      return boolType;
-    }
-
-    @Override
-    public InterfaceType getStringType() {
-      return stringType;
-    }
-
-    @Override
-    public InterfaceType getFunctionType() {
-      return functionType;
-    }
-
-    @Override
-    public InterfaceType getArrayType(Type elementType) {
-      return defaultListType;
-    }
-
-    @Override
-    public Type getNullType() {
-      throw new AssertionError();
-    }
-
-    @Override
-    public Type getVoidType() {
-      return voidType;
-    }
-
-    @Override
-    public DynamicType getDynamicType() {
-      return Types.newDynamicType();
-    }
-
-    @Override
-    public InterfaceType getMapType(Type key, Type value) {
-      return defaultMapLiteralType;
-    }
-
-    @Override
-    public InterfaceType getObjectType() {
-      return objectElement.getType();
-    }
-
-    @Override
-    public InterfaceType getIteratorType(Type elementType) {
-      throw new AssertionError();
-    }
-
-    @Override
-    public InterfaceType getTypeType() {
-      return typeType;
-    }
-  }
-
-  protected static DartTypeNode makeType(String name, String... arguments) {
-    List<DartTypeNode> argumentNodes = makeTypes(arguments);
-    return new DartTypeNode(new DartIdentifier(name), argumentNodes);
-  }
-
-  static List<DartTypeNode> makeTypes(String... typeNames) {
-    List<DartTypeNode> types = new ArrayList<DartTypeNode>();
-    for (String typeName : typeNames) {
-      types.add(makeType(typeName));
-    }
-    return types;
-  }
-
-
-  protected static DartUnit makeUnit(DartNode... topLevelElements) {
-    DartUnit unit = new DartUnit(null, false);
-    for (DartNode topLevelElement : topLevelElements) {
-      unit.getTopLevelNodes().add(topLevelElement);
-    }
-    return unit;
-  }
-
-  protected DartUnit parseUnit(String firstLine, String secondLine, String... rest) {
-    return parseUnit(Joiner.on('\n').join(firstLine, secondLine, (Object[]) rest).toString());
-  }
-
-  protected DartUnit parseUnit(String string) {
-    DartSourceString source = new DartSourceString("<source string>", string);
-    DartParser parser = new DartParser(
-        source,
-        string,
-        false,
-        Sets.<String>newHashSet(),
-        getListener(),
-        null);
-    return parser.parseUnit();
-  }
-
-  private DartCompilerListener getListener() {
-    return new DartCompilerListener.Empty() {
-      @Override
-      public void onError(DartCompilationError event) {
-        parseErrors.add(event);
-      }
-    };
-  }
-
-  protected void checkExpectedErrors(ErrorCode[] errorCodes) {
-    checkExpectedErrors(parseErrors, errorCodes, null);
-  }
-
-  /**
-   * Given a list of errors encountered during parse/resolve, compare them to
-   * a list of expected error codes.
-   *
-   * @param encountered errors actually encountered
-   * @param errorCodes expected errors.
-   */
-  protected void checkExpectedErrors(List<DartCompilationError> encountered,
-                                        ErrorCode[] errorCodes,
-                                        String source) {
-    if (errorCodes.length != encountered.size()) {
-      printSource(source);
-      printEncountered(encountered);
-      assertEquals(errorCodes.length, encountered.size());
-    }
-    int index = 0;
-    for (ErrorCode errorCode : errorCodes) {
-      ErrorCode found = encountered.get(index).getErrorCode();
-      if (!found.equals(errorCode)) {
-        printSource(source);
-        printEncountered(encountered);
-        assertEquals("Unexpected Error Code: ", errorCode, found);
-      }
-      index++;
-    }
-  }
-
-  /**
-   * Returns a context with a listener that remembers all DartCompilationErrors and records
-   * them.
-   * @return
-   */
-  protected TestCompilerContext getContext() {
-    return new TestCompilerContext() {
-      @Override
-      public void onError(DartCompilationError event) {
-        recordParseError(event);
-      }
-    };
-  }
-
-  /**
-   * Resets the global list of encountered errors.  Call this before evaluating a new test.
-   */
-  protected void resetParseErrors() {
-    parseErrors = Lists.newArrayList();
-  }
-
-  /**
-   * Save an error event in the global list of encountered errors.  For use by
-   * custom {@link DartCompilerListener} implementations.
-   */
-  protected void recordParseError(DartCompilationError event) {
-    parseErrors.add(event);
-  }
-
-  protected void printSource(String source) {
-    if (source != null) {
-      int count = 1;
-      for (String line : Splitter.on("\n").split(source)) {
-        System.out.println(String.format(" %02d: %s", count++, line));
-      }
-    }
-  }
-  /**
-   * For debugging.
-   */
-  protected void printEncountered(List<DartCompilationError> encountered) {
-    for (DartCompilationError error : encountered) {
-      ErrorCode errorCode = error.getErrorCode();
-      String msg =
-          String.format(
-              "%s > %s (%d:%d)",
-              errorCode.toString(),
-              error.getMessage(),
-              error.getLineNumber(),
-              error.getColumnNumber());
-      System.out.println(msg);
-    }
-  }
-
-  /**
-   * Convenience method to parse and resolve a code snippet, then test for error codes.
-   *
-   * @return resolve errors.
-   */
-  protected List<DartCompilationError> resolveAndTest(String source, ErrorCode errorCode, ErrorCode... errorCodeRest) {
-    ErrorCode errorCodes[] = new ErrorCode[errorCodeRest.length + 1];
-    errorCodes[0] = errorCode;
-    if (errorCodeRest.length > 0) {
-      System.arraycopy(errorCodeRest, 0, errorCodes, 1, errorCodeRest.length);
-    }
-    // parse DartUnit
-    DartUnit unit = parseUnit(source);
-    if (parseErrors.size() != 0) {
-      printSource(source);
-      printEncountered(parseErrors);
-      assertEquals("Expected no errors in parse step:", 0, parseErrors.size());
-    }
-    // prepare for recording resolving errors
-    resetParseErrors();
-    final List<DartCompilationError> resolveErrors = Lists.newArrayList();
-    TestCompilerContext ctx =  new TestCompilerContext() {
-      @Override
-      public void onError(DartCompilationError event) {
-        resolveErrors.add(event);
-      }
-    };
-    // resolve and check errors
-    resolve(unit, ctx);
-    checkExpectedErrors(resolveErrors, errorCodes, source);
-    return resolveErrors;
-  }
-
-  protected List<DartCompilationError> resolveAndTest(String source,
-                                                      ErrorExpectation... expectedErrors) {
-    // parse DartUnit
-    DartUnit unit = parseUnit(source);
-    if (parseErrors.size() != 0) {
-      printSource(source);
-      printEncountered(parseErrors);
-      assertEquals("Expected no errors in parse step:", 0, parseErrors.size());
-    }
-    // prepare for recording resolving errors
-    resetParseErrors();
-    final List<DartCompilationError> resolveErrors = Lists.newArrayList();
-    TestCompilerContext ctx =  new TestCompilerContext() {
-      @Override
-      public void onError(DartCompilationError event) {
-        resolveErrors.add(event);
-      }
-    };
-    // resolve and check errors
-    resolve(unit, ctx);
-    ErrorExpectation.assertErrors(resolveErrors, expectedErrors);
-    return resolveErrors;
-  }
-
-  /**
-   * Convenience method to parse and resolve a code snippet, then test for error codes.
-   *
-   * @return resolve errors.
-   */
-  protected List<DartCompilationError> resolveAndTestCtConst(String source, ErrorCode... errorCodes) {
-    // parse DartUnit
-    DartUnit unit = parseUnit(source);
-    if (parseErrors.size() != 0) {
-      printSource(source);
-      printEncountered(parseErrors);
-      assertEquals("Expected no errors in parse step:", 0, parseErrors.size());
-    }
-    // prepare for recording resolving errors
-    resetParseErrors();
-    final List<DartCompilationError> resolveErrors = Lists.newArrayList();
-    TestCompilerContext ctx =  new TestCompilerContext() {
-      @Override
-      public void onError(DartCompilationError event) {
-        resolveErrors.add(event);
-      }
-    };
-    // resolve and check errors
-    resolveCompileTimeConst(unit, ctx);
-    checkExpectedErrors(resolveErrors, errorCodes, source);
-    return resolveErrors;
-  }
-
-  protected List<DartCompilationError> resolveAndTestCtConstExpectErrors(String source, ErrorExpectation... expectedErrors) {
-    // parse DartUnit
-    DartUnit unit = parseUnit(source);
-    if (parseErrors.size() != 0) {
-      printSource(source);
-      printEncountered(parseErrors);
-      assertEquals("Expected no errors in parse step:", 0, parseErrors.size());
-    }
-    // prepare for recording resolving errors
-    resetParseErrors();
-    final List<DartCompilationError> resolveErrors = Lists.newArrayList();
-    TestCompilerContext ctx =  new TestCompilerContext() {
-      @Override
-      public void onError(DartCompilationError event) {
-        resolveErrors.add(event);
-      }
-    };
-    // resolve and check errors
-    resolveCompileTimeConst(unit, ctx);
-    ErrorExpectation.assertErrors(resolveErrors, expectedErrors);
-    return resolveErrors;
-  }
-}
diff --git a/compiler/javatests/com/google/dart/compiler/resolver/ResolverTests.java b/compiler/javatests/com/google/dart/compiler/resolver/ResolverTests.java
deleted file mode 100644
index cc4e1cb..0000000
--- a/compiler/javatests/com/google/dart/compiler/resolver/ResolverTests.java
+++ /dev/null
@@ -1,30 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.resolver;
-
-import junit.extensions.TestSetup;
-import junit.framework.Test;
-import junit.framework.TestSuite;
-
-/**
- * Tests of the resolver.
- */
-public class ResolverTests extends TestSetup {
-
-  public ResolverTests(Test test) {
-    super(test);
-  }
-
-  public static Test suite() {
-    TestSuite suite = new TestSuite("Dart Resolver test suite.");
-
-    suite.addTestSuite(ElementMapTest.class);
-    suite.addTestSuite(ResolverTest.class);
-    suite.addTestSuite(ResolverCompilerTest.class);
-    suite.addTestSuite(NegativeResolverTest.class);
-    suite.addTestSuite(CompileTimeConstantTest.class);
-    return suite;
-  }
-}
diff --git a/compiler/javatests/com/google/dart/compiler/resolver/StaticInstanceCallNegativeTest.dart b/compiler/javatests/com/google/dart/compiler/resolver/StaticInstanceCallNegativeTest.dart
deleted file mode 100644
index de5d0a4..0000000
--- a/compiler/javatests/com/google/dart/compiler/resolver/StaticInstanceCallNegativeTest.dart
+++ /dev/null
@@ -1,12 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-// Check that an instance method cannot be called as a static method.
-
-class A {
-  foo() {}
-  static bar() {
-    A.foo();
-  }
-}
diff --git a/compiler/javatests/com/google/dart/compiler/resolver/StaticSuperFieldNegativeTest.dart b/compiler/javatests/com/google/dart/compiler/resolver/StaticSuperFieldNegativeTest.dart
deleted file mode 100644
index 2e445d1..0000000
--- a/compiler/javatests/com/google/dart/compiler/resolver/StaticSuperFieldNegativeTest.dart
+++ /dev/null
@@ -1,15 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-// Check that one cannot access a static field through super.
-
-class A {
-  static var x;
-}
-
-class B {
-  foo() {
-    return super.x;
-  }
-}
diff --git a/compiler/javatests/com/google/dart/compiler/resolver/StaticSuperGetterNegativeTest.dart b/compiler/javatests/com/google/dart/compiler/resolver/StaticSuperGetterNegativeTest.dart
deleted file mode 100644
index 5d593e2..0000000
--- a/compiler/javatests/com/google/dart/compiler/resolver/StaticSuperGetterNegativeTest.dart
+++ /dev/null
@@ -1,15 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-// Check that oen cannot access a static getter through super.
-
-class A {
-  static get x {}
-}
-
-class B {
-  foo() {
-    return super.x;
-  }
-}
diff --git a/compiler/javatests/com/google/dart/compiler/resolver/StaticSuperMethodNegativeTest.dart b/compiler/javatests/com/google/dart/compiler/resolver/StaticSuperMethodNegativeTest.dart
deleted file mode 100644
index e8b51ce..0000000
--- a/compiler/javatests/com/google/dart/compiler/resolver/StaticSuperMethodNegativeTest.dart
+++ /dev/null
@@ -1,15 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-// Check that one cannot access a static method through super.
-
-class A {
-  static x() {}
-}
-
-class B {
-  foo() {
-    return super.x;
-  }
-}
diff --git a/compiler/javatests/com/google/dart/compiler/resolver/StaticToInstanceInvocationNegativeTest1.dart b/compiler/javatests/com/google/dart/compiler/resolver/StaticToInstanceInvocationNegativeTest1.dart
deleted file mode 100644
index 5a81d0a..0000000
--- a/compiler/javatests/com/google/dart/compiler/resolver/StaticToInstanceInvocationNegativeTest1.dart
+++ /dev/null
@@ -1,10 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-// case 1 - unqualified - expect failure.
-
-class A {
-  static foo() { bar(); }
-  bar() { }
-}
diff --git a/compiler/javatests/com/google/dart/compiler/resolver/UnresolvedSuperFieldNegativeTest.dart b/compiler/javatests/com/google/dart/compiler/resolver/UnresolvedSuperFieldNegativeTest.dart
deleted file mode 100644
index 2b3ef2d..0000000
--- a/compiler/javatests/com/google/dart/compiler/resolver/UnresolvedSuperFieldNegativeTest.dart
+++ /dev/null
@@ -1,14 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-// Check that an unresolved super field is an error.
-
-class A {
-}
-
-class B {
-  foo() {
-    return super.x;
-  }
-}
diff --git a/compiler/javatests/com/google/dart/compiler/type/FunctionTypeTest.java b/compiler/javatests/com/google/dart/compiler/type/FunctionTypeTest.java
deleted file mode 100644
index 99a7236..0000000
--- a/compiler/javatests/com/google/dart/compiler/type/FunctionTypeTest.java
+++ /dev/null
@@ -1,113 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.type;
-
-import java.util.Arrays;
-import java.util.List;
-
-public class FunctionTypeTest extends TypeTestCase {
-  private final Types types = Types.getInstance(null);
-
-  private final FunctionType objectsToObject = ftype(function, itype(object), null, itype(object));
-  private final FunctionType objectAndObjectsToObject =
-      ftype(function, itype(object), null, itype(object), itype(object));
-  private final FunctionType stringsToObject = ftype(function, itype(object), null, itype(string));
-  private final FunctionType namedStringToObject =
-      ftype(function, itype(object), named(itype(string), "arg"), null);
-  private final FunctionType namedObjectToObject =
-      ftype(function, itype(object), named(itype(object), "arg"), null);
-  private final FunctionType objectAndNamedStringToObject =
-      ftype(function, itype(object), named(itype(string), "arg"), null, itype(object));
-  private final FunctionType manyNames =
-      ftype(function, itype(object),
-            named(itype(string), "arg1", itype(intElement), "arg2", itype(object), "arg3"),
-            null, itype(object));
-
-  @Override
-  Types getTypes() {
-    return types;
-  }
-
-  public void testToString() {
-    assertEquals("() -> Object", returnObject.toString());
-    assertEquals("() -> String", returnString.toString());
-    assertEquals("(Object) -> String", objectToString.toString());
-    assertEquals("(String) -> Object", stringToObject.toString());
-    assertEquals("(String, int) -> bool", stringAndIntToBool.toString());
-    assertEquals("(Object...) -> Object", objectsToObject.toString());
-    assertEquals("(Object, Object...) -> Object", objectAndObjectsToObject.toString());
-    assertEquals("([String arg]) -> Object", namedStringToObject.toString());
-    assertEquals("(Object, [String arg]) -> Object", objectAndNamedStringToObject.toString());
-    assertEquals("(Object, [String arg1, int arg2, Object arg3]) -> Object", manyNames.toString());
-  }
-
-  public void testAsInstanceOf() {
-    checkAsInstanceOf(returnObject);
-    checkAsInstanceOf(returnString);
-    checkAsInstanceOf(objectToString);
-    checkAsInstanceOf(stringToObject);
-    checkAsInstanceOf(stringAndIntToBool);
-    checkAsInstanceOf(stringAndIntToMap);
-    checkAsInstanceOf(objectAndNamedStringToObject);
-  }
-
-  private void checkAsInstanceOf(FunctionType type) {
-    assertEquals(itype(function), types.asInstanceOf(type, function));
-    assertEquals(itype(object), types.asInstanceOf(type, object));
-    assertNull(types.asInstanceOf(type, string));
-  }
-
-  public void testSubst() {
-    Type s = typeVar("S", itype(object));
-    Type o = typeVar("O", itype(object));
-    List<Type> vars = Arrays.<Type>asList(s, o);
-    List<Type> args = Arrays.<Type>asList(itype(string), itype(object));
-    Type returnO = ftype(function, o, null, null);
-    Type returnS = ftype(function, s, null, null);
-    Type oToO = ftype(function, o, null, null, o);
-    Type oToS = ftype(function, s, null, null, o);
-    Type stringAndIntToMapS = ftype(function, itype(map, s, itype(intElement)),
-                                    null, null, itype(string), itype(intElement));
-    Type sAndIntToBool = ftype(function, itype(bool), null, null, s, itype(intElement));
-    assertEquals(returnObject, returnO.subst(args, vars));
-    assertEquals(returnString, returnS.subst(args, vars));
-    assertEquals(objectToObject, oToO.subst(args, vars));
-    assertEquals(objectToString, oToS.subst(args, vars));
-    assertEquals(stringAndIntToBool, sAndIntToBool.subst(args, vars));
-    assertEquals(stringAndIntToMap, stringAndIntToMapS.subst(args, vars));
-
-    FunctionType oAndNamedToO = FunctionTypeImplementation.of(function, Arrays.<Type>asList(o),
-                                                              null,
-                                                              named(itype(string), "arg"), null, o);
-    assertEquals(objectAndNamedStringToObject, oAndNamedToO.subst(args, vars));
-
-    Type osToO = FunctionTypeImplementation.of(function, Arrays.<Type>asList(), null, null, o, o);
-    assertEquals(objectsToObject, osToO.subst(args, vars));
-  }
-
-  public void testEquals() {
-    assertEquals(returnObject, ftype(function, itype(object), null, null));
-    assertEquals(returnObject, ftype(function, object.getType(), null, null));
-    assertFalse(returnObject.equals(returnString));
-    assertFalse(returnObject.equals(returnString));
-    assertEquals(objectToObject, ftype(function, itype(object), null, null, itype(object)));
-    assertFalse(objectToObject.equals(objectToString));
-    assertFalse(objectToObject.equals(objectsToObject));
-    assertEquals(objectsToObject, objectsToObject);
-    assertEquals(objectAndNamedStringToObject, objectAndNamedStringToObject);
-    assertFalse(objectsToObject.equals(objectAndNamedStringToObject));
-    assertFalse(objectAndNamedStringToObject.equals(objectsToObject));
-  }
-
-  public void testIsSubtype() {
-    checkSubtype(returnObject, returnObject);
-    checkSubtype(returnString, returnObject);
-    checkSubtype(objectToObject, stringToObject);
-    checkSubtype(objectsToObject, objectsToObject);
-    checkSubtype(objectsToObject, stringsToObject);
-    checkSubtype(namedObjectToObject, namedObjectToObject);
-    checkSubtype(namedObjectToObject, namedStringToObject);
-  }
-}
diff --git a/compiler/javatests/com/google/dart/compiler/type/TypeAnalyzerBench.java b/compiler/javatests/com/google/dart/compiler/type/TypeAnalyzerBench.java
deleted file mode 100644
index c7aed3d..0000000
--- a/compiler/javatests/com/google/dart/compiler/type/TypeAnalyzerBench.java
+++ /dev/null
@@ -1,169 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.type;
-
-import com.google.dart.compiler.CommandLineOptions.CompilerOptions;
-import com.google.dart.compiler.CompilerConfiguration;
-import com.google.dart.compiler.DartArtifactProvider;
-import com.google.dart.compiler.DartCompilationPhase;
-import com.google.dart.compiler.DartCompiler;
-import com.google.dart.compiler.DartCompilerContext;
-import com.google.dart.compiler.DartCompilerListener;
-import com.google.dart.compiler.DefaultCompilerConfiguration;
-import com.google.dart.compiler.DefaultDartArtifactProvider;
-import com.google.dart.compiler.DefaultLibrarySource;
-import com.google.dart.compiler.LibrarySource;
-import com.google.dart.compiler.Source;
-import com.google.dart.compiler.UrlLibrarySource;
-import com.google.dart.compiler.ast.DartUnit;
-import com.google.dart.compiler.resolver.CoreTypeProvider;
-
-import org.kohsuke.args4j.CmdLineException;
-import org.kohsuke.args4j.CmdLineParser;
-
-import java.io.CharArrayReader;
-import java.io.CharArrayWriter;
-import java.io.File;
-import java.io.IOException;
-import java.io.Reader;
-import java.io.Writer;
-import java.net.URI;
-import java.util.ArrayDeque;
-import java.util.ArrayList;
-import java.util.Deque;
-import java.util.List;
-import java.util.concurrent.ConcurrentHashMap;
-
-/**
- * Benchmark for the type analyzer. The benchmark will loop forever to ease profiling.
- */
-public class TypeAnalyzerBench {
-  private static final double SCORE_SCALE = 1000d;
-  private static final long ROUND_DURATION_MS = 5000L;
-
-  public static void main(String... arguments) throws CmdLineException, IOException {
-    CompilerOptions compilerOptions = new CompilerOptions();
-    CmdLineParser cmdLineParser = new CmdLineParser(compilerOptions);
-    cmdLineParser.parseArgument(arguments);
-    final CollectingPhase phase = new CollectingPhase();
-    CompilerConfiguration config = new DefaultCompilerConfiguration(compilerOptions) {
-      @Override
-      public List<DartCompilationPhase> getPhases() {
-        ArrayList<DartCompilationPhase> phases = new ArrayList<DartCompilationPhase>();
-        phases.addAll(super.getPhases());
-        phases.add(phase);
-        return phases;
-      }
-    };
-    DartArtifactProvider provider = getArtifactProvider(config.getOutputDirectory());
-    DartCompilerListener listener = getListener();
-    List<String> sourceFiles = compilerOptions.getSourceFiles();
-    if (sourceFiles.size() != 1) {
-      throw new IllegalArgumentException("incorrect number of source files " + sourceFiles);
-    }
-    File sourceFile = new File(sourceFiles.get(0));
-    LibrarySource lib;
-    if (sourceFile.getName().endsWith(".dart")) {
-      lib = new DefaultLibrarySource(sourceFile, null);
-    } else {
-      lib = new UrlLibrarySource(sourceFile);
-    }
-    DartCompiler.compileLib(lib, config, provider, listener);
-    Deque<Double> scores = new ArrayDeque<Double>(10);
-    for (int i = 0; i < 10; i++) {
-      scores.addLast(0d);
-    }
-    long start = System.currentTimeMillis();
-    int i = 0;
-    while (true) {
-      i++;
-      TypeAnalyzer typeAnalyzer = new TypeAnalyzer();
-      for (DartUnit unit : phase.units) {
-        typeAnalyzer.exec(unit, phase.context, phase.typeProvider);
-      }
-      long elapsed = System.currentTimeMillis() - start;
-      if (elapsed > ROUND_DURATION_MS) {
-        double score = i * SCORE_SCALE / elapsed;
-        scores.removeFirst();
-        scores.addLast(score);
-        printScores(scores);
-        start = System.currentTimeMillis();
-        i = 0;
-      }
-    }
-  }
-
-  private static void printScores(Deque<Double> scores) {
-    double xn = 1d;
-    for (double x : scores) {
-      xn *= x;
-    }
-    double geomean = Math.pow(xn, 1d / scores.size());
-    xn = 0d;
-    for (double x : scores) {
-      double deviation = x - geomean;
-      xn += deviation * deviation;
-    }
-    double stddev = Math.sqrt(xn / (scores.size() - 1));
-    System.out.println(String.format("geomean %.03f std. dev. %.03f", geomean, stddev));
-  }
-
-  private static DartArtifactProvider getArtifactProvider(File outputDirectory) {
-    final DartArtifactProvider provider = new DefaultDartArtifactProvider(outputDirectory);
-    return new DartArtifactProvider() {
-      ConcurrentHashMap<URI, CharArrayWriter> artifacts =
-          new ConcurrentHashMap<URI, CharArrayWriter>();
-
-      @Override
-      public boolean isOutOfDate(Source source, Source base, String extension) {
-        return true;
-      }
-
-      @Override
-      public Writer getArtifactWriter(Source source, String part, String extension) {
-        URI uri = getArtifactUri(source, part, extension);
-        CharArrayWriter writer = new CharArrayWriter();
-        CharArrayWriter existing = artifacts.putIfAbsent(uri, writer);
-        return (existing == null) ? writer : existing;
-      }
-
-
-      @Override
-      public URI getArtifactUri(Source source, String part, String extension) {
-        return provider.getArtifactUri(source, part, extension);
-      }
-
-      @Override
-      public Reader getArtifactReader(Source source, String part, String extension)
-          throws IOException {
-        URI uri = getArtifactUri(source, part, extension);
-        CharArrayWriter writer = artifacts.get(uri);
-        if (writer != null) {
-          return new CharArrayReader(writer.toCharArray());
-        }
-        return provider.getArtifactReader(source, part, extension);
-      }
-    };
-  }
-
-  private static DartCompilerListener getListener() {
-    return DartCompilerListener.EMPTY;
-  }
-
-  static class CollectingPhase implements DartCompilationPhase {
-    List<DartUnit> units = new ArrayList<DartUnit>();
-    DartCompilerContext context;
-    CoreTypeProvider typeProvider;
-
-    @Override
-    public synchronized DartUnit exec(DartUnit unit, DartCompilerContext context,
-                                      CoreTypeProvider typeProvider) {
-      units.add(unit);
-      this.context = context;
-      this.typeProvider = typeProvider;
-      return unit;
-    }
-  }
-}
diff --git a/compiler/javatests/com/google/dart/compiler/type/TypeAnalyzerCompilerTest.java b/compiler/javatests/com/google/dart/compiler/type/TypeAnalyzerCompilerTest.java
deleted file mode 100644
index f016f2a..0000000
--- a/compiler/javatests/com/google/dart/compiler/type/TypeAnalyzerCompilerTest.java
+++ /dev/null
@@ -1,6545 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-package com.google.dart.compiler.type;
-
-import com.google.common.collect.Iterables;
-import com.google.common.collect.Sets;
-import com.google.dart.compiler.CommandLineOptions.CompilerOptions;
-import com.google.dart.compiler.CompilerTestCase;
-import com.google.dart.compiler.DartCompilationError;
-import com.google.dart.compiler.DartCompilerErrorCode;
-import com.google.dart.compiler.DefaultCompilerConfiguration;
-import com.google.dart.compiler.ast.ASTVisitor;
-import com.google.dart.compiler.ast.DartArrayAccess;
-import com.google.dart.compiler.ast.DartBinaryExpression;
-import com.google.dart.compiler.ast.DartClass;
-import com.google.dart.compiler.ast.DartCommentNewName;
-import com.google.dart.compiler.ast.DartCommentRefName;
-import com.google.dart.compiler.ast.DartDeclaration;
-import com.google.dart.compiler.ast.DartExprStmt;
-import com.google.dart.compiler.ast.DartExpression;
-import com.google.dart.compiler.ast.DartField;
-import com.google.dart.compiler.ast.DartFieldDefinition;
-import com.google.dart.compiler.ast.DartForInStatement;
-import com.google.dart.compiler.ast.DartFunctionExpression;
-import com.google.dart.compiler.ast.DartIdentifier;
-import com.google.dart.compiler.ast.DartInvocation;
-import com.google.dart.compiler.ast.DartMapLiteralEntry;
-import com.google.dart.compiler.ast.DartMethodDefinition;
-import com.google.dart.compiler.ast.DartMethodInvocation;
-import com.google.dart.compiler.ast.DartNewExpression;
-import com.google.dart.compiler.ast.DartNode;
-import com.google.dart.compiler.ast.DartPropertyAccess;
-import com.google.dart.compiler.ast.DartSuperConstructorInvocation;
-import com.google.dart.compiler.ast.DartTypeNode;
-import com.google.dart.compiler.ast.DartUnaryExpression;
-import com.google.dart.compiler.ast.DartUnit;
-import com.google.dart.compiler.ast.DartUnqualifiedInvocation;
-import com.google.dart.compiler.parser.ParserErrorCode;
-import com.google.dart.compiler.resolver.ClassElement;
-import com.google.dart.compiler.resolver.ConstructorElement;
-import com.google.dart.compiler.resolver.ConstructorNodeElement;
-import com.google.dart.compiler.resolver.Element;
-import com.google.dart.compiler.resolver.ElementKind;
-import com.google.dart.compiler.resolver.EnclosingElement;
-import com.google.dart.compiler.resolver.FieldElement;
-import com.google.dart.compiler.resolver.LibraryElement;
-import com.google.dart.compiler.resolver.MethodElement;
-import com.google.dart.compiler.resolver.ResolverErrorCode;
-import com.google.dart.compiler.resolver.TypeErrorCode;
-import com.google.dart.compiler.resolver.VariableElement;
-
-import static com.google.dart.compiler.common.ErrorExpectation.assertErrors;
-import static com.google.dart.compiler.common.ErrorExpectation.errEx;
-import static com.google.dart.compiler.type.TypeQuality.EXACT;
-import static com.google.dart.compiler.type.TypeQuality.INFERRED;
-import static com.google.dart.compiler.type.TypeQuality.INFERRED_EXACT;
-
-import java.net.URI;
-import java.util.List;
-import java.util.Set;
-import java.util.concurrent.atomic.AtomicInteger;
-
-/**
- * Variant of {@link TypeAnalyzerTest}, which is based on {@link CompilerTestCase}. It is probably
- * slower, not actually unit test, but easier to use if you need access to DartNode's.
- */
-public class TypeAnalyzerCompilerTest extends CompilerTestCase {
-
-  /**
-   * Top-level "main" function should not have parameters.
-   * <p>
-   * http://code.google.com/p/dart/issues/detail?id=3271
-   */
-  public void test_topLevelMainFunction() throws Exception {
-    AnalyzeLibraryResult libraryResult = analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "main(var p) {}",
-        "class A {",
-        "  main(var p) {}",
-        "}",
-        "");
-    assertErrors(
-        libraryResult.getErrors(),
-        errEx(ResolverErrorCode.MAIN_FUNCTION_PARAMETERS, 2, 1, 4));
-  }
-
-  /**
-   * A setter definition that is prefixed with the static modifier defines a static setter.
-   * Otherwise, it defines an instance setter. The name of a setter is obtained by appending the
-   * string `=' to the identifier given in its signature.
-   * <p>
-   * Hence, a setter name can never conflict with, override or be overridden by a getter or method.
-   * <p>
-   * http://code.google.com/p/dart/issues/detail?id=5153
-   */
-  public void test_setterNameImplicitEquals() throws Exception {
-    AnalyzeLibraryResult libraryResult = analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "class A {",
-        "  set foo(x) {}",
-        "  foo(x) {}",
-        "}",
-        "main() {",
-        "  A a = new A();",
-        "  a.foo = 0;",
-        "  a.foo(0);",
-        "}",
-        "");
-    assertErrors(libraryResult.getErrors());
-  }
-
-  /**
-   * <p>
-   * http://code.google.com/p/dart/issues/detail?id=4785
-   */
-  public void test_labelForBlockInSwitchCase() throws Exception {
-    AnalyzeLibraryResult libraryResult = analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "main() {",
-        "  switch (0) {",
-        "    case 0: qwerty: {",
-        "      break qwerty;",
-        "    }",
-        "    break;",
-        "  }",
-        "}",
-        "");
-    assertErrors(libraryResult.getErrors());
-  }
-
-  /**
-   * We should support resolving to the method "call".
-   * <p>
-   * http://code.google.com/p/dart/issues/detail?id=1355
-   */
-  public void test_resolveCallMethod() throws Exception {
-    AnalyzeLibraryResult libraryResult = analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "class A {",
-        "  call() => 42;",
-        "}",
-        "main() {",
-        "  A a = new A();",
-        "  a();",
-        "}",
-        "");
-    assertErrors(libraryResult.getErrors());
-    // find a()
-    DartIdentifier aVar = findNode(DartIdentifier.class, "a()");
-    assertNotNull(aVar);
-    DartUnqualifiedInvocation invocation = (DartUnqualifiedInvocation) aVar.getParent();
-    // analyze a() element
-    MethodElement element = (MethodElement) invocation.getElement();
-    assertNotNull(element);
-    assertEquals("call", element.getName());
-    assertEquals(
-        libraryResult.source.indexOf("call() => 42"),
-        element.getNameLocation().getOffset());
-  }
-
-  /**
-   * If a type I includes a method named call(), and the type of call() is the function type F, then
-   * I is considered to be a subtype of F.
-   * <p>
-   * http://code.google.com/p/dart/issues/detail?id=7271
-   */
-  public void test_classWithCallMethod_isFunction() throws Exception {
-    AnalyzeLibraryResult libraryResult = analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "class X {",
-        "  call() => 42;",
-        "}",
-        "",
-        "class Y {",
-        "  call(int x) => 87;",
-        "}",
-        "",
-        "typedef F(int x);",
-        "typedef G(String y);",
-        "",
-        "main() {",
-        "  X x = new X();",
-        "  Y y = new Y();",
-        "  Function f = x;", // OK
-        "  Function g = y;", // OK
-        "  F f0 = x;", // WARN
-        "  F f1 = y;", // OK
-        "  G g0 = x;", // WARN
-        "  G g1 = y;", // WARN
-        "}",
-        "");
-    assertErrors(
-        libraryResult.getErrors(),
-        errEx(TypeErrorCode.TYPE_NOT_ASSIGNMENT_COMPATIBLE, 18, 10, 1),
-        errEx(TypeErrorCode.TYPE_NOT_ASSIGNMENT_COMPATIBLE, 20, 10, 1),
-        errEx(TypeErrorCode.TYPE_NOT_ASSIGNMENT_COMPATIBLE, 21, 10, 1));
-  }
-
-  /**
-   * It is a compile-time error if a typedef refers to itself via a chain of references that does
-   * not include a class or interface type.
-   * <p>
-   * http://code.google.com/p/dart/issues/detail?id=3534
-   */
-  public void test_functionTypeAlias_selfRerences_direct() throws Exception {
-    AnalyzeLibraryResult libraryResult = analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "typedef A A();",
-        "typedef B(B b);",
-        "typedef C([C c]);",
-        "typedef D({D d});",
-        "typedef E<T extends E>();",
-        "");
-    assertErrors(
-        libraryResult.getErrors(),
-        errEx(TypeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF, 2, 1, 14),
-        errEx(TypeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF, 3, 1, 15),
-        errEx(TypeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF, 4, 1, 17),
-        errEx(TypeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF, 5, 1, 17),
-        errEx(TypeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF, 6, 1, 25));
-  }
-
-  /**
-   * It is a compile-time error if a typedef refers to itself via a chain of references that does
-   * not include a class or interface type.
-   * <p>
-   * http://code.google.com/p/dart/issues/detail?id=3534
-   */
-  public void test_functionTypeAlias_selfRerences_indirect() throws Exception {
-    AnalyzeLibraryResult libraryResult = analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "typedef B1 A1();",
-        "typedef A1 B1();",
-        "typedef B2 A2();",
-        "typedef B2(A2 a);",
-        "typedef B3 A3();",
-        "typedef B3([A3 a]);",
-        "typedef B4 A4();",
-        "typedef B4({A4 a});",
-        "typedef A5<T extends B5>();",
-        "typedef B5(A5 a);",
-        "");
-    assertErrors(
-        libraryResult.getErrors(),
-        errEx(TypeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF, 2, 1, 16),
-        errEx(TypeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF, 3, 1, 16),
-        errEx(TypeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF, 4, 1, 16),
-        errEx(TypeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF, 5, 1, 17),
-        errEx(TypeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF, 6, 1, 16),
-        errEx(TypeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF, 7, 1, 19),
-        errEx(TypeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF, 8, 1, 16),
-        errEx(TypeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF, 9, 1, 19),
-        errEx(TypeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF, 10, 1, 27),
-        errEx(TypeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF, 11, 1, 17));
-  }
-
-  /**
-   * Type parameters should not conflict with formal parameters.
-   * <p>
-   * http://code.google.com/p/dart/issues/detail?id=5302
-   */
-  public void test_functionTypeAlias_typePaarameter_scope() throws Exception {
-    AnalyzeLibraryResult libraryResult = analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "typedef f<f>(f);",
-        "");
-    assertErrors(libraryResult.getErrors());
-  }
-
-  /**
-   * It is a compile-time error if initializer list contains an initializer for a variable that
-   * is not an instance variable declared in the immediately surrounding class.
-   * <p>
-   * http://code.google.com/p/dart/issues/detail?id=3181
-   */
-  public void test_initializerForNotField() throws Exception {
-    AnalyzeLibraryResult libraryResult = analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "var x;",
-        "class A {",
-        "  A() : x = 5 {}",
-        "}",
-        "");
-    assertErrors(
-        libraryResult.getErrors(),
-        errEx(ResolverErrorCode.INIT_FIELD_ONLY_IMMEDIATELY_SURROUNDING_CLASS, 4, 9, 1));
-  }
-
-  /**
-   * Tests that we correctly provide {@link Element#getEnclosingElement()} for method of class.
-   */
-  public void test_resolveClassMethod() throws Exception {
-    AnalyzeLibraryResult libraryResult =
-        analyzeLibrary(
-                "class Object {}",
-                "class Test {",
-                "  foo() {",
-                "    f();",
-                "  }",
-                "  f() {",
-                "  }",
-                "}");
-    DartUnit unit = libraryResult.getLibraryUnitResult().getUnits().iterator().next();
-    // find f() invocation
-    DartInvocation invocation = findInvocationSimple(unit, "f()");
-    assertNotNull(invocation);
-    // referenced Element should be resolved to MethodElement
-    Element methodElement = invocation.getElement();
-    assertNotNull(methodElement);
-    assertSame(ElementKind.METHOD, methodElement.getKind());
-    assertEquals("f", ((MethodElement) methodElement).getOriginalName());
-    // enclosing Element of MethodElement is ClassElement
-    Element classElement = methodElement.getEnclosingElement();
-    assertNotNull(classElement);
-    assertSame(ElementKind.CLASS, classElement.getKind());
-    assertEquals("Test", ((ClassElement) classElement).getOriginalName());
-  }
-
-  /**
-   * Test that local {@link DartFunctionExpression} has {@link Element} with enclosing
-   * {@link Element}.
-   * <p>
-   * http://code.google.com/p/dart/issues/detail?id=145
-   */
-  public void test_resolveLocalFunction() throws Exception {
-    AnalyzeLibraryResult libraryResult =
-        analyzeLibrary(
-            "class Object {}",
-            "class Test {",
-            "  foo() {",
-            "    f() {",
-            "    }",
-            "    f();",
-            "  }",
-            "}");
-    DartUnit unit = libraryResult.getLibraryUnitResult().getUnits().iterator().next();
-    // find f() invocation
-    DartInvocation invocation = findInvocationSimple(unit, "f()");
-    assertNotNull(invocation);
-    // referenced Element should be resolved to MethodElement
-    Element functionElement = invocation.getElement();
-    assertNotNull(functionElement);
-    assertSame(ElementKind.FUNCTION_OBJECT, functionElement.getKind());
-    assertEquals("f", ((MethodElement) functionElement).getOriginalName());
-    // enclosing Element of this FUNCTION_OBJECT is enclosing method
-    MethodElement methodElement = (MethodElement) functionElement.getEnclosingElement();
-    assertNotNull(methodElement);
-    assertSame(ElementKind.METHOD, methodElement.getKind());
-    assertEquals("foo", methodElement.getName());
-    // use EnclosingElement methods implementations in MethodElement
-    assertEquals(false, methodElement.isInterface());
-    assertEquals(true, Iterables.isEmpty(methodElement.getMembers()));
-    assertEquals(null, methodElement.lookupLocalElement("f"));
-  }
-
-  /**
-   * It is a static warning if the type of "switch expression" may not be assigned to the type of
-   * "case expression".
-   * <p>
-   * http://code.google.com/p/dart/issues/detail?id=3269
-   */
-  public void test_switchExpression_case_switchTypeMismatch() throws Exception {
-    AnalyzeLibraryResult libraryResult = analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "main() {",
-        "  int v = 1;",
-        "  switch (v) {",
-        "    case 0: break;",
-        "  }",
-        "  switch (v) {",
-        "    case 'a': break;",
-        "  }",
-        "}",
-        "");
-    assertErrors(
-        libraryResult.getErrors(),
-        errEx(TypeErrorCode.TYPE_NOT_ASSIGNMENT_COMPATIBLE, 8, 10, 3));
-  }
-
-  /**
-   * It is a compile-time error if the values of the case expressions are not compile-time
-   * constants.
-   * <p>
-   * http://code.google.com/p/dart/issues/detail?id=4553
-   */
-  public void test_switchExpression_case_anyConst() throws Exception {
-    AnalyzeLibraryResult libraryResult = analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "class A {",
-        "  const A();",
-        "}",
-        "const A CONST_1 = const A();",
-        "const A CONST_2 = const A();",
-        "foo(var v) {",
-        "  switch (v) {",
-        "    case 0: break;",
-        "  }",
-        "  switch (v) {",
-        "    case '0': break;",
-        "  }",
-        "  switch (v) {",
-        "    case 0.0: break;",
-        "  }",
-        "  switch (v) {",
-        "    case CONST_1: break;",
-        "    case CONST_2: break;",
-        "  }",
-        "}",
-        "");
-    assertErrors(libraryResult.getErrors());
-  }
-
-  /**
-   * It is a compile-time error if the values of the case expressions are not compile-time
-   * constants.
-   * <p>
-   * http://code.google.com/p/dart/issues/detail?id=4553
-   */
-  public void test_switchExpression_case_notConst() throws Exception {
-    AnalyzeLibraryResult libraryResult = analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "class A {}",
-        "foo(var v) {",
-        "  A notConst = new A();",
-        "  switch (v) {",
-        "    case notConst: break;",
-        "  }",
-        "}",
-        "");
-    assertErrors(
-        libraryResult.getErrors(),
-        errEx(ResolverErrorCode.EXPECTED_CONSTANT_EXPRESSION, 6, 10, 8));
-  }
-
-  /**
-   * It is a compile-time error if the class C implements the operator ==.
-   * <p>
-   * http://code.google.com/p/dart/issues/detail?id=4553
-   */
-  public void test_switchExpression_case_hasOperatorEquals() throws Exception {
-    AnalyzeLibraryResult libraryResult = analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "class C {",
-        "  const C();",
-        "  operator ==(other) => false;",
-        "}",
-        "const C CONST = const C();",
-        "foo(var v) {",
-        "  switch (v) {",
-        "    case CONST: break;",
-        "  }",
-        "}",
-        "");
-    assertErrors(
-        libraryResult.getErrors(),
-        errEx(TypeErrorCode.CASE_EXPRESSION_TYPE_SHOULD_NOT_HAVE_EQUALS, 9, 10, 5));
-  }
-
-  /**
-   * It is a compile-time error if the values of the case expressions do not all have the same type.
-   * <p>
-   * http://code.google.com/p/dart/issues/detail?id=3528
-   */
-  public void test_switchExpression_case_differentTypes() throws Exception {
-    AnalyzeLibraryResult libraryResult = analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "foo(var v) {",
-        "  switch (v) {",
-        "    case 0: break;",
-        "    case 'a': break;",
-        "  }",
-        "}",
-        "");
-    assertErrors(
-        libraryResult.getErrors(),
-        errEx(TypeErrorCode.CASE_EXPRESSIONS_SHOULD_BE_SAME_TYPE, 5, 10, 3));
-  }
-
-  public void test_switchExpression_case_constLocalVariable() throws Exception {
-    AnalyzeLibraryResult libraryResult = analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "foo(var v) {",
-        "  const int VALUE = 0;",
-        "  switch (v) {",
-        "    case VALUE: break;",
-        "  }",
-        "}",
-        "");
-    assertErrors(libraryResult.getErrors());
-  }
-
-  /**
-   * <p>
-   * http://code.google.com/p/dart/issues/detail?id=2862
-   */
-  public void test_switchCase_fallThrough() throws Exception {
-    AnalyzeLibraryResult libraryResult = analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "foo(int x) {",
-        "  while (true) {",
-        "    switch (x) {",
-        "      case 0:",
-        "        break;",
-        "      case 1:",
-        "        continue;",
-        "      case 2:",
-        "        return;",
-        "      case 3:",
-        "        throw new Exception();",
-        "      case 4:",
-        "        bar();",
-        "      default:",
-        "        bar();",
-        "    }",
-        "  }",
-        "}",
-        "bar() {}",
-        "");
-    assertErrors(
-        libraryResult.getErrors(),
-        errEx(ResolverErrorCode.SWITCH_CASE_FALL_THROUGH, 14, 9, 6));
-  }
-
-  /**
-   * Language specification requires that factory should be declared in class. However declaring
-   * factory on top level should not cause exceptions in compiler.
-   * <p>
-   * http://code.google.com/p/dart/issues/detail?id=345
-   */
-  public void test_badTopLevelFactory() throws Exception {
-    AnalyzeLibraryResult libraryResult = analyzeLibrary("factory foo() {}");
-    DartUnit unit = libraryResult.getLibraryUnitResult().getUnits().iterator().next();
-    DartMethodDefinition factory = (DartMethodDefinition) unit.getTopLevelNodes().get(0);
-    assertNotNull(factory);
-    // this factory has name, which is allowed for normal method
-    assertEquals(true, factory.getName() instanceof DartIdentifier);
-    assertEquals("foo", ((DartIdentifier) factory.getName()).getName());
-    // compilation error expected
-    assertBadTopLevelFactoryError(libraryResult);
-  }
-
-  /**
-   * Asserts that given {@link AnalyzeLibraryResult} contains {@link DartCompilationError} for
-   * invalid factory on top level.
-   */
-  private void assertBadTopLevelFactoryError(AnalyzeLibraryResult libraryResult) {
-    List<DartCompilationError> compilationErrors = libraryResult.getCompilationErrors();
-    assertEquals(1, compilationErrors.size());
-    DartCompilationError compilationError = compilationErrors.get(0);
-    assertEquals(ParserErrorCode.FACTORY_CANNOT_BE_TOP_LEVEL, compilationError.getErrorCode());
-    assertEquals(1, compilationError.getLineNumber());
-    assertEquals(1, compilationError.getColumnNumber());
-    assertEquals("factory".length(), compilationError.getLength());
-  }
-
-  /**
-   * @return the {@link DartInvocation} with given source. This is inaccurate approach, but good
-   *         enough for specific tests.
-   */
-  private static DartInvocation findInvocationSimple(DartNode rootNode,
-      final String invocationString) {
-    final DartInvocation invocationRef[] = new DartInvocation[1];
-    rootNode.accept(new ASTVisitor<Void>() {
-      @Override
-      public Void visitInvocation(DartInvocation node) {
-        if (node.toSource().equals(invocationString)) {
-          invocationRef[0] = node;
-        }
-        return super.visitInvocation(node);
-      }
-    });
-    return invocationRef[0];
-  }
-
-  /**
-   * In contrast, if A is intended to be concrete, the checker should warn about all unimplemented
-   * methods, but allow clients to instantiate it freely.
-   */
-  public void test_warnAbstract_onConcreteClassDeclaration_hasUnimplemented_method_fromInterface()
-      throws Exception {
-    AnalyzeLibraryResult libraryResult =
-        analyzeLibrary(
-            "abstract class Foo {",
-            "  int fooA;",
-            "  void fooB();",
-            "}",
-            "abstract class Bar {",
-            "  void barA();",
-            "}",
-            "class A implements Foo, Bar {",
-            "}",
-            "main() {",
-            "  new A();",
-            "}");
-    assertErrors(
-        libraryResult.getErrors(),
-        errEx(TypeErrorCode.CONCRETE_CLASS_WITH_UNIMPLEMENTED_MEMBERS, 8, 7, 1));
-    {
-      DartCompilationError typeError = libraryResult.getErrors().get(0);
-      String message = typeError.getMessage();
-      assertTrue(message.contains("# From Foo:"));
-      assertTrue(message.contains("int fooA"));
-      assertTrue(message.contains("void fooB()"));
-      assertTrue(message.contains("# From Bar:"));
-      assertTrue(message.contains("void barA()"));
-    }
-  }
-
-  /**
-   * In contrast, if A is intended to be concrete, the checker should warn about all unimplemented
-   * methods, but allow clients to instantiate it freely.
-   */
-  public void test_warnAbstract_onConcreteClassDeclaration_hasUnimplemented_method_inherited()
-      throws Exception {
-    AnalyzeLibraryResult libraryResult =
-        analyzeLibrary(
-                "abstract class A {",
-                "  void foo();",
-                "}",
-                "class B extends A {",
-                "}",
-                "main() {",
-                "  new B();",
-                "}");
-    assertErrors(
-        libraryResult.getErrors(),
-        errEx(TypeErrorCode.CONCRETE_CLASS_WITH_UNIMPLEMENTED_MEMBERS, 4, 7, 1));
-    {
-      DartCompilationError typeError = libraryResult.getErrors().get(0);
-      String message = typeError.getMessage();
-      assertTrue(message.contains("# From A:"));
-      assertTrue(message.contains("void foo()"));
-    }
-  }
-
-  /**
-   * In contrast, if A is intended to be concrete, the checker should warn about all unimplemented
-   * methods, but allow clients to instantiate it freely.
-   */
-  public void test_warnAbstract_onConcreteClassDeclaration_hasUnimplemented_method_self()
-      throws Exception {
-    AnalyzeLibraryResult libraryResult =
-        analyzeLibrary(
-            "class A {",
-            "  void foo();",
-            "}",
-            "main() {",
-            "  new A();",
-            "}");
-    assertErrors(
-        libraryResult.getErrors(),
-        errEx(TypeErrorCode.CONCRETE_CLASS_WITH_UNIMPLEMENTED_MEMBERS, 1, 7, 1));
-    {
-      DartCompilationError typeError = libraryResult.getErrors().get(0);
-      String message = typeError.getMessage();
-      assertTrue(message.contains("# From A:"));
-      assertTrue(message.contains("void foo()"));
-    }
-  }
-
-  /**
-   * When class implements "noSuchMethod", we presume that it will handle unimplemented methods.
-   * <p>
-   * http://code.google.com/p/dart/issues/detail?id=6964
-   */
-  public void test_warnAbstract_onConcreteClassDeclaration_hasUnimplementedMethod_noSuchMethod()
-      throws Exception {
-    // report by default
-    {
-      AnalyzeLibraryResult libraryResult =
-          analyzeLibrary(
-              "class A {",
-              "  void foo();",
-              "  noSuchMethod(Invocation m) {}",
-              "}",
-              "main() {",
-              "  new A();",
-              "}");
-      assertErrors(
-          libraryResult.getErrors(),
-          errEx(TypeErrorCode.CONCRETE_CLASS_WITH_UNIMPLEMENTED_MEMBERS, 1, 7, 1));
-    }
-    // disable warnings if has "noSuchMethod"
-    {
-      compilerConfiguration = new DefaultCompilerConfiguration(new CompilerOptions() {
-        @Override
-        public boolean reportNoMemberWhenHasInterceptor() {
-          return false;
-        }
-      });
-      AnalyzeLibraryResult libraryResult =
-          analyzeLibrary(
-              "class A {",
-              "  void foo();",
-              "  noSuchMethod(Invocation m) {}",
-              "}",
-              "main() {",
-              "  new A();",
-              "}");
-      assertErrors(libraryResult.getErrors());
-    }
-  }
-
-  public void test_warnAbstract_onConcreteClassDeclaration_hasUnimplemented_getter()
-      throws Exception {
-    AnalyzeLibraryResult libraryResult =
-        analyzeLibrary(
-                "class A {",
-                "  get x;",
-                "}",
-                "main() {",
-                "  new A();",
-                "}");
-    assertErrors(
-        libraryResult.getErrors(),
-        errEx(TypeErrorCode.CONCRETE_CLASS_WITH_UNIMPLEMENTED_MEMBERS, 1, 7, 1));
-  }
-
-  public void test_warnAbstract_onConcreteClassDeclaration_hasUnimplemented_mixin() throws Exception {
-    AnalyzeLibraryResult result = analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "abstract class A {",
-        "  foo();",
-        "}",
-        "class B extends Object with A {",
-        "}",
-        "");
-    assertErrors(
-        result.getErrors(),
-        errEx(TypeErrorCode.CONCRETE_CLASS_WITH_UNIMPLEMENTED_MEMBERS, 5, 7, 1));
-  }
-
-  /**
-   * Class "B" has implementation for "bVal" and "bVal=", so we don't need any warning.
-   * <p>
-   * http://code.google.com/p/dart/issues/detail?id=7605
-   */
-  public void test_warnAbstract_onConcreteClassDeclaration_inheritedGetter_abstractGetter() throws Exception {
-    AnalyzeLibraryResult result = analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "abstract class A {",
-        "  get bVal {}",
-        "  set bVal(var val);",
-        "}",
-        "class B extends A {",
-        "  set bVal(var val) {}",
-        "}",
-        "");
-    assertErrors(result.getErrors());
-  }
-
-  /**
-   * There was bug that implementing setter still caused warning.
-   * <p>
-   * http://code.google.com/p/dart/issues/detail?id=5327
-   */
-  public void test_warnAbstract_whenInstantiate_implementSetter() throws Exception {
-    AnalyzeLibraryResult libraryResult = analyzeLibrary(
-        "abstract class I {",
-        "  set foo(x);",
-        "}",
-        "class A implements I {",
-        "  set foo(x) {}",
-        "}",
-        "main() {",
-        "  new A();",
-        "}");
-    assertErrors(libraryResult.getErrors());
-  }
-
-  /**
-   * When both getter and setter were abstract and only getter implemented, we should report error.
-   * <p>
-   * http://code.google.com/p/dart/issues/detail?id=5327
-   */
-  public void test_warnAbstract_whenInstantiate_implementsOnlyGetter() throws Exception {
-    AnalyzeLibraryResult libraryResult = analyzeLibrary(
-        "abstract class I {",
-        "  get foo;",
-        "  set foo(x);",
-        "}",
-        "class A implements I {",
-        "  get foo => 0;",
-        "}",
-        "main() {",
-        "  new A();",
-        "}");
-    assertErrors(
-        libraryResult.getErrors(),
-        errEx(TypeErrorCode.CONCRETE_CLASS_WITH_UNIMPLEMENTED_MEMBERS, 5, 7, 1));
-  }
-
-  /**
-   * <p>
-   * http://code.google.com/p/dart/issues/detail?id=5327
-   */
-  public void test_warnAbstract_whenInstantiate_implementsSetter_inSuperClass() throws Exception {
-    AnalyzeLibraryResult libraryResult = analyzeLibrary(
-        "abstract class I {",
-        "  get foo;",
-        "  set foo(x);",
-        "}",
-        "abstract class A implements I {",
-        "  get foo;",
-        "  set foo(x) {}",
-        "}",
-        "class B extends A {",
-        "  get foo => 0;",
-        "}",
-        "main() {",
-        "  new B();",
-        "}");
-    assertErrors(libraryResult.getErrors());
-  }
-
-  public void test_warnAbstract_onAbstractClass_whenInstantiate_normalConstructor()
-      throws Exception {
-    AnalyzeLibraryResult libraryResult =
-        analyzeLibrary(
-            "abstract class A {",
-            "  void bar();",
-            "}",
-            "main() {",
-            "  new A();",
-            "}");
-    assertErrors(
-        libraryResult.getErrors(),
-        errEx(TypeErrorCode.INSTANTIATION_OF_ABSTRACT_CLASS, 5, 7, 1));
-  }
-
-  /**
-   * Factory constructor can instantiate any class and return it non-abstract class instance, Even
-   * thought this is an abstract class, there should be no warnings for the invocation of the
-   * factory constructor.
-   */
-  public void test_warnAbstract_onAbstractClass_whenInstantiate_factoryConstructor()
-      throws Exception {
-    AnalyzeLibraryResult libraryResult = analyzeLibrary(
-        "abstract class A {", // explicitly abstract
-        "  factory A() {",
-        "    return null;",
-        "  }",
-        "}",
-        "class C {",
-        "  foo() {",
-        "    return new A();", // no error - factory constructor
-        "  }",
-        "}");
-    assertErrors(libraryResult.getErrors());
-  }
-
-  /**
-   * Factory constructor can instantiate any class and return it non-abstract class instance, Even
-   * thought this is an abstract class, there should be no warnings for the invocation of the
-   * factory constructor.
-   */
-  public void test_wanrAbstract_onAbstractClass_whenInstantiate_factoryConstructor2()
-      throws Exception {
-    AnalyzeLibraryResult libraryResult =
-        analyzeLibrary(
-            "abstract class A {", // class is abstract
-            "  factory A() {",
-            "    return null;",
-            "  }",
-            "  method();",
-            "}",
-            "class C {",
-            "  foo() {",
-            "    return new A();",  // no error, factory constructor
-            "  }",
-            "}");
-    assertErrors(libraryResult.getErrors());
-  }
-
-  /**
-   * Spec 7.3 It is a static warning if a setter declares a return type other than void.
-   */
-  public void testWarnOnNonVoidSetter() throws Exception {
-    AnalyzeLibraryResult libraryResult =
-        analyzeLibrary(
-                "class A {",
-                "  void set foo(bool a) {}",
-                "  set bar(bool a) {}",
-                "  dynamic set baz(bool a) {}",
-                "  bool set bob(bool a) {}",
-                "}");
-    assertErrors(
-        libraryResult.getErrors(),
-        errEx(TypeErrorCode.SETTER_RETURN_TYPE, 4, 3, 7),
-        errEx(TypeErrorCode.SETTER_RETURN_TYPE, 5, 3, 4));
-  }
-
-  public void test_callUnknownFunction() throws Exception {
-    AnalyzeLibraryResult libraryResult = analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "main() {",
-        "  foo();",
-        "}",
-        "");
-    assertErrors(libraryResult.getErrors(), errEx(ResolverErrorCode.CANNOT_RESOLVE_METHOD, 3, 3, 3));
-  }
-
-  /**
-   * We should be able to call <code>Function</code> even if it is in the field.
-   * <p>
-   * http://code.google.com/p/dart/issues/detail?id=933
-   */
-  public void test_callFunctionFromField() throws Exception {
-    AnalyzeLibraryResult libraryResult =
-        analyzeLibrary(
-            "class WorkElement {",
-            "  Function run;",
-            "}",
-            "foo(WorkElement e) {",
-            "  e.run();",
-            "}");
-    assertErrors(libraryResult.getErrors());
-  }
-
-  /**
-   * When we attempt to use function as type, we should report only one error.
-   * <p>
-   * http://code.google.com/p/dart/issues/detail?id=3309
-   */
-  public void test_useFunctionAsType() throws Exception {
-    AnalyzeLibraryResult libraryResult = analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "func() {}",
-        "main() {",
-        "  new func();",
-        "}",
-        "");
-    assertErrors(libraryResult.getErrors(), errEx(TypeErrorCode.NOT_A_TYPE, 4, 7, 4));
-  }
-
-  /**
-   * There was problem that {@link DartForInStatement} visits "iterable" two times. At first time we
-   * set {@link MethodElement}, because we resolve it to getter. However because of this at second
-   * time we can not resolve. Solution - don't try to resolve second time, we already done at first
-   * time. Note: double getter is important.
-   */
-  public void test_doubleGetterAccess_inForEach() throws Exception {
-    AnalyzeLibraryResult libraryResult = analyzeLibrary(
-            "class Test {",
-            "  Iterable get iter {}",
-            "}",
-            "Test get test {}",
-            "f() {",
-            "  for (var v in test.iter) {}",
-            "}",
-            "");
-    assertErrors(libraryResult.getErrors());
-  }
-
-  /**
-   * Test for errors and warnings related to positional and named arguments for required and
-   * optional parameters.
-   */
-  public void test_invocationArguments() throws Exception {
-    AnalyzeLibraryResult libraryResult =
-        analyzeLibrary(
-                "/* 01 */ foo() {",
-                "/* 02 */   f_0_0();",
-                "/* 03 */   f_0_0(-1);",
-                "/* 04 */",
-                "/* 05 */   f_1_0();",
-                "/* 06 */   f_1_0(-1);",
-                "/* 07 */   f_1_0(-1, -2, -3);",
-                "/* 08 */",
-                "/* 09 */   f_2_0();",
-                "/* 10 */",
-                "/* 11 */   f_0_1();",
-                "/* 12 */   f_0_1(1);",
-                "/* 13 */   f_0_1(0, 0);",
-                "/* 14 */   f_0_1(n1: 1);",
-                "/* 15 */   f_0_1(x: 1);",
-                "/* 16 */   f_0_1(n1: 1, n1: 2);",
-                "}",
-                "",
-                "f_0_0() {}",
-                "f_1_0(r1) {}",
-                "f_2_0(r1, r2) {}",
-                "f_0_1({n1}) {}",
-                "f_0_2({n1, n2}) {}",
-                "");
-    assertErrors(
-        libraryResult.getErrors(),
-        errEx(TypeErrorCode.EXTRA_ARGUMENT, 3, 18, 2),
-        errEx(TypeErrorCode.MISSING_ARGUMENT, 5, 12, 5),
-        errEx(TypeErrorCode.EXTRA_ARGUMENT, 7, 22, 2),
-        errEx(TypeErrorCode.EXTRA_ARGUMENT, 7, 26, 2),
-        errEx(TypeErrorCode.MISSING_ARGUMENT, 9, 12, 5),
-        errEx(TypeErrorCode.EXTRA_ARGUMENT, 12, 18, 1),
-        errEx(TypeErrorCode.EXTRA_ARGUMENT, 13, 18, 1),
-        errEx(TypeErrorCode.EXTRA_ARGUMENT, 13, 21, 1),
-        errEx(TypeErrorCode.NO_SUCH_NAMED_PARAMETER, 15, 18, 4),
-        errEx(ResolverErrorCode.DUPLICATE_NAMED_ARGUMENT, 16, 25, 5));
-  }
-
-  /**
-   * Test that optional positional and named parameters are handled separately.
-   */
-  public void test_invocationArguments2() throws Exception {
-    AnalyzeLibraryResult libraryResult = analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "func([int np1, int np2, int np3]) {}",
-        "main() {",
-        "  func(np1: 1, np2: 2, np3: 2);",
-        "}",
-        "");
-    assertErrors(
-        libraryResult.getErrors(),
-        errEx(TypeErrorCode.NO_SUCH_NAMED_PARAMETER, 4, 8, 6),
-        errEx(TypeErrorCode.NO_SUCH_NAMED_PARAMETER, 4, 16, 6),
-        errEx(TypeErrorCode.NO_SUCH_NAMED_PARAMETER, 4, 24, 6));
-  }
-
-  /**
-   * We should return correct {@link Type} for {@link DartNewExpression}.
-   */
-  public void test_DartNewExpression_getType() throws Exception {
-    AnalyzeLibraryResult libraryResult =
-        analyzeLibrary(
-            "// filler filler filler filler filler filler filler filler filler filler",
-            "class A {",
-            "  A() {}",
-            "  A.foo() {}",
-            "}",
-            "var a1 = new A();",
-            "var a2 = new A.foo();",
-            "");
-    assertErrors(libraryResult.getErrors());
-    // new A()
-    {
-      DartNewExpression newExpression = (DartNewExpression) getTopLevelFieldInitializer(testUnit, 1);
-      Type newType = newExpression.getType();
-      assertEquals("A", newType.getElement().getName());
-    }
-    // new A.foo()
-    {
-      DartNewExpression newExpression = (DartNewExpression) getTopLevelFieldInitializer(testUnit, 2);
-      Type newType = newExpression.getType();
-      assertEquals("A", newType.getElement().getName());
-    }
-  }
-
-  /**
-   * Expects that given {@link DartUnit} has {@link DartFieldDefinition} as <code>index</code> top
-   * level node and return initializer of first {@link DartField}.
-   */
-  private static DartExpression getTopLevelFieldInitializer(DartUnit unit, int index) {
-    DartFieldDefinition fieldDefinition = (DartFieldDefinition) unit.getTopLevelNodes().get(index);
-    DartField field = fieldDefinition.getFields().get(0);
-    return field.getValue();
-  }
-
-  /**
-   * If property has only setter, no getter, then attempt to use getter should cause static type
-   * warning.
-   * <p>
-   * http://code.google.com/p/dart/issues/detail?id=1251
-   */
-  public void test_setterOnlyProperty_noGetter() throws Exception {
-    AnalyzeLibraryResult libraryResult =
-        analyzeLibrary(
-            "class SetOnly {",
-            "  set foo(arg) {}",
-            "}",
-            "class SetOnlyWrapper {",
-            "  SetOnly setOnly;",
-            "}",
-            "",
-            "main() {",
-            "  SetOnly setOnly = new SetOnly();",
-            "  setOnly.foo = 1;", // 10: OK, use setter
-            "  setOnly.foo += 2;", // 11: ERR, no getter
-            "  print(setOnly.foo);", // 12: ERR, no getter
-            "  var bar;",
-            "  bar = setOnly.foo;", // 14: ERR, assignment, but we are not LHS
-            "  bar = new SetOnlyWrapper().setOnly.foo;", // 15: ERR, even in chained expression
-            "  new SetOnlyWrapper().setOnly.foo = 3;", // 16: OK
-            "}");
-    assertErrors(
-        libraryResult.getErrors(),
-        errEx(TypeErrorCode.FIELD_HAS_NO_GETTER, 11, 11, 3),
-        errEx(TypeErrorCode.FIELD_HAS_NO_GETTER, 12, 17, 3),
-        errEx(TypeErrorCode.FIELD_HAS_NO_GETTER, 14, 17, 3),
-        errEx(TypeErrorCode.FIELD_HAS_NO_GETTER, 15, 38, 3));
-  }
-
-  public void test_setterOnlyProperty_normalField() throws Exception {
-    AnalyzeLibraryResult libraryResult =
-        analyzeLibrary(
-            "class A {",
-            "  var foo;",
-            "}",
-            "",
-            "main() {",
-            "  A a = new A();",
-            "  a.foo = 1;",
-            "  a.foo += 2;",
-            "  print(a.foo);",
-            "}");
-    assertErrors(libraryResult.getErrors());
-  }
-
-  public void test_setterOnlyProperty_getterInSuper() throws Exception {
-    AnalyzeLibraryResult libraryResult =
-        analyzeLibrary(
-                "class A {",
-                "  get foo {}",
-                "}",
-                "class B extends A {",
-                "  set foo(arg) {}",
-                "}",
-                "",
-                "main() {",
-                "  B b = new B();",
-                "  b.foo = 1;",
-                "  b.foo += 2;",
-                "  print(b.foo);",
-                "}");
-    assertErrors(libraryResult.getErrors());
-  }
-
-  public void test_setterOnlyProperty_getterInInterface() throws Exception {
-    AnalyzeLibraryResult libraryResult =
-        analyzeLibrary(
-                "abstract class A {",
-                "  get foo {}",
-                "}",
-                "abstract class B implements A {",
-                "  set foo(arg) {}",
-                "}",
-                "",
-                "main() {",
-                "  B b = new B();",
-                "  b.foo = 1;",
-                "  b.foo += 2;",
-                "  print(b.foo);",
-                "}");
-    assertErrors(
-        libraryResult.getErrors(),
-        errEx(TypeErrorCode.INSTANTIATION_OF_ABSTRACT_CLASS, 9, 13, 1));
-  }
-
-  public void test_getterOnlyProperty_noSetter() throws Exception {
-    AnalyzeLibraryResult libraryResult =
-        analyzeLibrary(
-                "class GetOnly {",
-                "  get foo {}",
-                "}",
-                "class GetOnlyWrapper {",
-                "  GetOnly getOnly;",
-                "}",
-                "",
-                "main() {",
-                "  GetOnly getOnly = new GetOnly();",
-                "  print(getOnly.foo);", // 10: OK, use getter
-                "  getOnly.foo = 1;", // 11: ERR, no setter
-                "  getOnly.foo += 2;", // 12: ERR, no setter
-                "  var bar;",
-                "  bar = getOnly.foo;", // 14: OK, use getter
-                "  new GetOnlyWrapper().getOnly.foo = 3;", // 15: ERR, no setter
-                "  bar = new GetOnlyWrapper().getOnly.foo;", // 16: OK, use getter
-                "}");
-    assertErrors(
-        libraryResult.getErrors(),
-        errEx(TypeErrorCode.FIELD_HAS_NO_SETTER, 11, 11, 3),
-        errEx(TypeErrorCode.FIELD_HAS_NO_SETTER, 12, 11, 3),
-        errEx(TypeErrorCode.FIELD_HAS_NO_SETTER, 15, 32, 3));
-  }
-
-  public void test_getterOnlyProperty_setterInSuper() throws Exception {
-    AnalyzeLibraryResult libraryResult =
-        analyzeLibrary(
-                "class A {",
-                "  set foo(arg) {}",
-                "}",
-                "class B extends A {",
-                "  get foo {}",
-                "}",
-                "",
-                "main() {",
-                "  B b = new B();",
-                "  b.foo = 1;",
-                "  b.foo += 2;",
-                "  print(b.foo);",
-                "}");
-    assertErrors(libraryResult.getErrors());
-  }
-
-  public void test_getterOnlyProperty_setterInInterface() throws Exception {
-    AnalyzeLibraryResult libraryResult =
-        analyzeLibrary(
-                "abstract class A {",
-                "  set foo(arg) {}",
-                "}",
-                "abstract class B implements A {",
-                "  get foo {}",
-                "}",
-                "",
-                "main() {",
-                "  B b = new B();",
-                "  b.foo = 1;",
-                "  b.foo += 2;",
-                "  print(b.foo);",
-                "}");
-    assertErrors(
-        libraryResult.getErrors(),
-        errEx(TypeErrorCode.INSTANTIATION_OF_ABSTRACT_CLASS, 9, 13, 1));
-  }
-
-  public void test_assert_notUserFunction() throws Exception {
-    AnalyzeLibraryResult libraryResult = analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "main() {",
-        "  assert(true);",
-        "  assert(false);",
-        "  assert('message');", // not 'bool'
-        "  assert('null');", // not 'bool'
-        "  assert(0);", // not 'bool'
-        "  assert(f1);", // OK, dynamic
-        "  assert(f2);", // OK, '() -> bool'
-        "  assert(f3);", // OK, 'Object' compatible with 'bool'
-        "  assert(f4);", // not '() -> bool', return type
-        "  assert(f5);", // not '() -> bool', parameter
-        "  assert(true, false);", // not single argument
-        "  assert;", // incomplete
-        "}",
-        "f1() {}",
-        "bool f2() {}",
-        "Object f3() {}",
-        "String f4() {}",
-        "bool f5(x) {}",
-        "");
-    assertErrors(
-        libraryResult.getErrors(),
-        errEx(ParserErrorCode.EXPECTED_TOKEN, 13, 10, 4),
-        errEx(ParserErrorCode.EXPECTED_TOKEN, 14, 9, 1),
-        errEx(TypeErrorCode.ASSERT_BOOL, 5, 10, 9),
-        errEx(TypeErrorCode.ASSERT_BOOL, 6, 10, 6),
-        errEx(TypeErrorCode.ASSERT_BOOL, 7, 10, 1),
-        errEx(TypeErrorCode.ASSERT_BOOL, 11, 10, 2),
-        errEx(TypeErrorCode.ASSERT_BOOL, 12, 10, 2));
-  }
-
-  /**
-   * <p>
-   * http://code.google.com/p/dart/issues/detail?id=3264
-   */
-  public void test_initializingFormalType_useFieldType() throws Exception {
-    AnalyzeLibraryResult libraryResult = analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "class A {",
-        "  final double f;",
-        "  A(this.f);",
-        "}",
-        "class B {",
-        "  B(this.f);",
-        "  final double f;",
-        "}",
-        "",
-        "main() {",
-        "  new A('0');",
-        "  new B('0');",
-        "}",
-        "");
-    assertErrors(
-        libraryResult.getErrors(),
-        errEx(TypeErrorCode.TYPE_NOT_ASSIGNMENT_COMPATIBLE, 12, 9, 3),
-        errEx(TypeErrorCode.TYPE_NOT_ASSIGNMENT_COMPATIBLE, 13, 9, 3));
-  }
-
-  /**
-   * If "this.field" parameter has declared type, it should be assignable to the field.
-   * <p>
-   * http://code.google.com/p/dart/issues/detail?id=3264
-   */
-  public void test_initializingFormalType_compatilityWithFieldType() throws Exception {
-    AnalyzeLibraryResult libraryResult = analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "class A {",
-        "  final double f;",
-        "  A.useDynamic(dynamic this.f);",
-        "  A.useNum(num this.f);",
-        "  A.useString(String this.f);",
-        "}",
-        "");
-    assertErrors(
-        libraryResult.getErrors(),
-        errEx(TypeErrorCode.TYPE_NOT_ASSIGNMENT_COMPATIBLE, 6, 15, 13));
-  }
-
-  public void test_finalField_inClass() throws Exception {
-    AnalyzeLibraryResult libraryResult = analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "class A {",
-        "  final f = 0;",
-        "}",
-        "main() {",
-        "  A a = new A();",
-        "  a.f = 0;", // 6: ERR, is final
-        "  a.f += 1;", // 7: ERR, is final
-        "  print(a.f);", // 8: OK, can read
-        "}");
-    assertErrors(
-        libraryResult.getErrors(),
-        errEx(TypeErrorCode.FIELD_IS_FINAL, 7, 5, 1),
-        errEx(TypeErrorCode.FIELD_IS_FINAL, 8, 5, 1));
-  }
-
-  public void test_notFinalField() throws Exception {
-    AnalyzeLibraryResult libraryResult = analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "class A {",
-        "  var f;",
-        "}",
-        "main() {",
-        "  A a = new A();",
-        "  a.f = 0;", // 6: OK, field "f" is not final
-        "  a.f += 1;", // 7: OK, field "f" is not final
-        "  print(a.f);", // 8: OK, can read
-        "}");
-    assertErrors(libraryResult.getErrors());
-  }
-
-  public void test_constField() throws Exception {
-    AnalyzeLibraryResult libraryResult = analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "const f = 1;",
-        "class A {",
-        "  const f = 1;",
-        "  method() {",
-        "    f = 2;",
-        "    this.f = 2;",
-        "  }",
-        "}",
-        "main() {",
-        "  f = 2;",
-        "  A a = new A();",
-        "  a.f = 2;",
-        "}",
-        "");
-    assertErrors(
-        libraryResult.getErrors(),
-        errEx(ResolverErrorCode.CANNOT_ASSIGN_TO_FINAL, 6, 5, 1),
-        errEx(ResolverErrorCode.CANNOT_ASSIGN_TO_FINAL, 7, 5, 6),
-        errEx(ResolverErrorCode.CANNOT_ASSIGN_TO_FINAL, 11, 3, 1),
-        errEx(TypeErrorCode.FIELD_IS_FINAL, 13, 5, 1));
-  }
-
-  public void test_assignConst_topLevelVariable() throws Exception {
-    AnalyzeLibraryResult libraryResult = analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "const f = 1;",
-        "main() {",
-        "  f = 2;",
-        "}",
-        "");
-    assertErrors(
-        libraryResult.getErrors(),
-        errEx(ResolverErrorCode.CANNOT_ASSIGN_TO_FINAL, 4, 3, 1));
-  }
-
-  public void test_assignFinal_topLevelVariable() throws Exception {
-    AnalyzeLibraryResult libraryResult = analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "final f = 1;",
-        "main() {",
-        "  f = 2;",
-        "}",
-        "");
-    assertErrors(
-        libraryResult.getErrors(),
-        errEx(ResolverErrorCode.CANNOT_ASSIGN_TO_FINAL, 4, 3, 1));
-  }
-
-  public void test_assignFinal_instanceVariable_inConstructor() throws Exception {
-    AnalyzeLibraryResult libraryResult = analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "class A {",
-        "  final f = 1;",
-        "  A() {",
-        "    f = 2;",
-        "    f += 3;",
-        "    print(f);",
-        "  }",
-        "",
-        "}",
-        "");
-    assertErrors(
-        libraryResult.getErrors(),
-        errEx(ResolverErrorCode.CANNOT_ASSIGN_TO_FINAL_ERROR, 5, 5, 1),
-        errEx(ResolverErrorCode.CANNOT_ASSIGN_TO_FINAL_ERROR, 6, 5, 1));
-  }
-
-  public void test_identicalFunction() throws Exception {
-    AnalyzeLibraryResult libraryResult = analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "const A = 1;",
-        "const B = 2;",
-        "const C = identical(A, B);",
-        "const D = !identical(A, B);",
-        "");
-    assertErrors(libraryResult.getErrors());
-  }
-
-  public void test_constantEvaluationException_divZero() throws Exception {
-    AnalyzeLibraryResult libraryResult = analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "const C1 = 1 ~/ 0;",
-        "const C2 = 1 % 0;",
-        "");
-    assertErrors(
-        libraryResult.getErrors(),
-        errEx(ResolverErrorCode.CONSTANTS_EVALUATION_EXCEPTION, 2, 12, 6),
-        errEx(ResolverErrorCode.CONSTANTS_EVALUATION_EXCEPTION, 3, 12, 5));
-  }
-
-  /**
-   * It is a compile-time error to use type variables in "const" instance creation.
-   * <p>
-   * http://code.google.com/p/dart/issues/detail?id=2379
-   */
-  public void test_constInstantiation_withTypeVariable() throws Exception {
-    AnalyzeLibraryResult libraryResult = analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "class A<T> {",
-        "  const A();",
-        "  const A.name();",
-        "}",
-        "class B<U> {",
-        "  test() {",
-        "    const A<U>();",
-        "    const A<U>.name();",
-        "  }",
-        "}",
-        "");
-    assertErrors(
-        libraryResult.getErrors(),
-        errEx(ResolverErrorCode.CONST_WITH_TYPE_VARIABLE, 8, 13, 1),
-        errEx(ResolverErrorCode.CONST_WITH_TYPE_VARIABLE, 9, 13, 1));
-  }
-
-  /**
-   * <p>
-   * http://code.google.com/p/dart/issues/detail?id=3182
-   */
-  public void test_extendNotType() throws Exception {
-    AnalyzeLibraryResult libraryResult = analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "int A;",
-        "class B extends A {",
-        "}",
-        "",
-        "");
-    assertErrors(
-        libraryResult.getErrors(),
-        errEx(ResolverErrorCode.NOT_A_TYPE, 3, 17, 1));
-  }
-
-  public void test_constInstanceCreation_noSuchType() throws Exception {
-    AnalyzeLibraryResult libraryResult = analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "main() {",
-        "  const NoSuchType();",
-        "}",
-        "");
-    assertErrors(
-        libraryResult.getErrors(),
-        errEx(ResolverErrorCode.NO_SUCH_TYPE_CONST, 3, 9, 10));
-  }
-
-  public void test_constInstanceCreation_noSuchConstructor() throws Exception {
-    AnalyzeLibraryResult libraryResult = analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "class A {}",
-        "main() {",
-        "  const A.noSuchName();",
-        "}",
-        "");
-    assertErrors(
-        libraryResult.getErrors(),
-        errEx(ResolverErrorCode.NEW_EXPRESSION_NOT_CONST_CONSTRUCTOR, 4, 11, 10));
-  }
-
-  public void test_constInstanceCreation_notType() throws Exception {
-    AnalyzeLibraryResult libraryResult = analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "var notType;",
-        "main() {",
-        "  const notType();",
-        "}",
-        "");
-    assertErrors(
-        libraryResult.getErrors(),
-        errEx(ResolverErrorCode.NOT_A_TYPE, 4, 9, 7));
-  }
-
-  /**
-   * Test for variants of {@link DartMethodDefinition} return types.
-   */
-  public void test_methodReturnTypes() throws Exception {
-    AnalyzeLibraryResult libraryResult =
-        analyzeLibrary(
-                "// filler filler filler filler filler filler filler filler filler filler",
-                "int fA() {}",
-                "dynamic fB() {}",
-                "void fC() {}",
-                "fD() {}",
-                "");
-    assertErrors(libraryResult.getErrors());
-    {
-      DartMethodDefinition fA = (DartMethodDefinition) testUnit.getTopLevelNodes().get(0);
-      assertEquals("int", fA.getElement().getReturnType().getElement().getName());
-    }
-    {
-      DartMethodDefinition fB = (DartMethodDefinition) testUnit.getTopLevelNodes().get(1);
-      assertEquals("dynamic", fB.getElement().getReturnType().getElement().getName());
-    }
-    {
-      DartMethodDefinition fC = (DartMethodDefinition) testUnit.getTopLevelNodes().get(2);
-      assertEquals("void", fC.getElement().getReturnType().getElement().getName());
-    }
-    {
-      DartMethodDefinition fD = (DartMethodDefinition) testUnit.getTopLevelNodes().get(3);
-      assertEquals("dynamic", fD.getElement().getReturnType().getElement().getName());
-    }
-  }
-
-  public void test_bindToLibraryFunctionFirst() throws Exception {
-    analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "foo() {}",
-        "class A {",
-        " foo() {}",
-        "}",
-        "class B extends A {",
-        "  bar() {",
-        "    foo();",
-        "  }",
-        "}",
-        "");
-    // Find foo() invocation.
-    DartUnqualifiedInvocation invocation;
-    {
-      DartClass classB = (DartClass) testUnit.getTopLevelNodes().get(2);
-      DartMethodDefinition methodBar = (DartMethodDefinition) classB.getMembers().get(0);
-      DartExprStmt stmt = (DartExprStmt) methodBar.getFunction().getBody().getStatements().get(0);
-      invocation = (DartUnqualifiedInvocation) stmt.getExpression();
-    }
-    // Check that unqualified foo() invocation is resolved to the top-level (library) function.
-    Element element = invocation.getTarget().getElement();
-    assertNotNull(element);
-    assertTrue(element.getEnclosingElement() instanceof LibraryElement);
-  }
-
-  /**
-   * If there was <code>import</code> with invalid {@link URI}, it should be reported as error, not
-   * as an exception.
-   */
-  public void test_invalidImportUri() throws Exception {
-    AnalyzeLibraryResult libraryResult = analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "library test;",
-        "import 'badURI';",
-        "");
-    assertErrors(libraryResult.getErrors(), errEx(DartCompilerErrorCode.MISSING_SOURCE, 3, 1, 16));
-  }
-
-  /**
-   * If there was <code>part</code> with invalid {@link URI}, it should be reported as error, not
-   * as an exception.
-   */
-  public void test_invalidSourceUri() throws Exception {
-    AnalyzeLibraryResult libraryResult = analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "library test;",
-        "part 'badURI';",
-        "");
-    assertErrors(libraryResult.getErrors(), errEx(DartCompilerErrorCode.MISSING_SOURCE, 3, 1, 14));
-  }
-
-  public void test_mapLiteralKeysUnique() throws Exception {
-    AnalyzeLibraryResult libraryResult = analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "var m = {'a' : 0, 'b': 1, 'a': 2};",
-        "");
-    assertErrors(libraryResult.getErrors(), errEx(TypeErrorCode.MAP_LITERAL_KEY_UNIQUE, 2, 27, 3));
-  }
-
-  /**
-   * No required parameter "x".
-   */
-  public void test_implementsAndOverrides_noRequiredParameter() throws Exception {
-    AnalyzeLibraryResult result =
-        analyzeLibrary(
-            "abstract class I {",
-            "  foo(x);",
-            "}",
-            "class C implements I {",
-            "  foo() {}",
-            "}");
-    assertErrors(
-        result.getErrors(),
-        errEx(ResolverErrorCode.CANNOT_OVERRIDE_METHOD_NUM_REQUIRED_PARAMS, 5, 3, 3));
-  }
-
-  /**
-   * It is OK to add more named parameters, if list prefix is same as in "super".
-   */
-  public void test_implementsAndOverrides_additionalNamedParameter() throws Exception {
-    AnalyzeLibraryResult result =
-        analyzeLibrary(
-            "abstract class I {",
-            "  foo({x});",
-            "}",
-            "class C implements I {",
-            "  foo({x,y}) {}",
-            "}");
-    assertErrors(result.getErrors());
-  }
-
-  public void test_implementsAndOverrides_lessNamedParameter() throws Exception {
-    AnalyzeLibraryResult result = analyzeLibrary(
-        "abstract class A {",
-        "  foo({x, y});",
-        "}",
-        "abstract class B extends A {",
-        "  foo({x});",
-        "}");
-    assertErrors(
-        result.getErrors(),
-        errEx(ResolverErrorCode.CANNOT_OVERRIDE_METHOD_NAMED_PARAMS, 5, 3, 3));
-  }
-
-  /**
-   * We override "foo" with method that has named parameter. So, this method is not abstract and
-   * class is not abstract too, so no warning.
-   */
-  public void test_implementsAndOverrides_additionalNamedParameter_notAbstract() throws Exception {
-    AnalyzeLibraryResult result =
-        analyzeLibrary(
-            "abstract class A {",
-            "  foo();",
-            "}",
-            "class B extends A {",
-            "  foo({x}) {}",
-            "}",
-            "bar() {",
-            "  new B();",
-            "}",
-            "");
-    assertErrors(result.getErrors());
-  }
-
-  public void test_implementsAndOverrides_lessOptionalPositionalParameter() throws Exception {
-    AnalyzeLibraryResult result = analyzeLibrary(
-        "abstract class A {",
-        "  foo([x, y]);",
-        "}",
-        "abstract class B extends A {",
-        "  foo([x]);",
-        "}");
-    assertErrors(
-        result.getErrors(),
-        errEx(ResolverErrorCode.CANNOT_OVERRIDE_METHOD_OPTIONAL_PARAMS, 5, 3, 3));
-  }
-
-  public void test_implementsAndOverrides_moreOptionalPositionalParameter() throws Exception {
-    AnalyzeLibraryResult result = analyzeLibrary(
-        "abstract class A {",
-        "  foo([x]);",
-        "}",
-        "abstract class B extends A {",
-        "  foo([a, b]);",
-        "}");
-    assertErrors(result.getErrors());
-  }
-
-  /**
-   * No required parameter "x". Named parameter "x" is not enough.
-   */
-  public void test_implementsAndOverrides_extraRequiredParameter() throws Exception {
-    AnalyzeLibraryResult result =
-        analyzeLibrary(
-            "abstract class I {",
-            "  foo();",
-            "}",
-            "class C implements I {",
-            "  foo(x) {}",
-            "}");
-    assertErrors(
-        result.getErrors(),
-        errEx(ResolverErrorCode.CANNOT_OVERRIDE_METHOD_NUM_REQUIRED_PARAMS, 5, 3, 3));
-  }
-
-  /**
-   * <p>
-   * http://code.google.com/p/dart/issues/detail?id=3183
-   */
-  public void test_implementsAndOverrides_differentDefaultValue_optional() throws Exception {
-    AnalyzeLibraryResult result =
-        analyzeLibrary(
-            "// filler filler filler filler filler filler filler filler filler filler",
-            "class A {",
-            "  f1([x]) {}",
-            "  f2([x = 1]) {}",
-            "  f3([x = 1]) {}",
-            "  f4([x = 1]) {}",
-            "}",
-            "class B extends A {",
-            "  f1([x = 2]) {}",
-            "  f2([x]) {}",
-            "  f3([x = 2]) {}",
-            "  f4([x = '2']) {}",
-            "}",
-            "");
-    assertErrors(
-        result.getErrors(),
-        errEx(TypeErrorCode.CANNOT_OVERRIDE_METHOD_DEFAULT_VALUE, 10, 7, 1),
-        errEx(TypeErrorCode.CANNOT_OVERRIDE_METHOD_DEFAULT_VALUE, 11, 7, 5),
-        errEx(TypeErrorCode.CANNOT_OVERRIDE_METHOD_DEFAULT_VALUE, 12, 7, 7));
-  }
-
-  /**
-   * <p>
-   * http://code.google.com/p/dart/issues/detail?id=3183
-   */
-  public void test_implementsAndOverrides_differentDefaultValue_named() throws Exception {
-    AnalyzeLibraryResult result =
-        analyzeLibrary(
-            "// filler filler filler filler filler filler filler filler filler filler",
-            "class A {",
-            "  f1({x}) {}",
-            "  f2({x: 1}) {}",
-            "  f3({x: 1}) {}",
-            "  f4({x: 1}) {}",
-            "}",
-            "class B extends A {",
-            "  f1({x: 2}) {}",
-            "  f2({x]) {}",
-            "  f3({x: 2}) {}",
-            "  f4({x: '2'}) {}",
-            "}",
-            "");
-    assertErrors(
-        result.getErrors(),
-        errEx(TypeErrorCode.CANNOT_OVERRIDE_METHOD_DEFAULT_VALUE, 10, 7, 1),
-        errEx(TypeErrorCode.CANNOT_OVERRIDE_METHOD_DEFAULT_VALUE, 11, 7, 4),
-        errEx(TypeErrorCode.CANNOT_OVERRIDE_METHOD_DEFAULT_VALUE, 12, 7, 6));
-  }
-
-  /**
-   * It is a compile-time error if an instance method m1 overrides an instance member m2 and m1 does
-   * not declare all the named parameters declared by m2 in the same order.
-   * <p>
-   * Here: no "y" parameter.
-   */
-  public void test_implementsAndOverrides_noNamedParameter() throws Exception {
-    AnalyzeLibraryResult result =
-        analyzeLibrary(
-            "abstract class I {",
-            "  foo({x,y});",
-            "}",
-            "class C implements I {",
-            "  foo({x}) {}",
-            "}");
-    assertErrors(
-        result.getErrors(),
-        errEx(ResolverErrorCode.CANNOT_OVERRIDE_METHOD_NAMED_PARAMS, 5, 3, 3));
-  }
-
-  public void test_metadataCommentOverride_OK_method() throws Exception {
-    AnalyzeLibraryResult result = analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "class A {",
-        "  foo() {}",
-        "}",
-        "class B extends A {",
-        "  // @override",
-        "  foo() {}",
-        "}",
-        "");
-    assertErrors(result.getErrors());
-  }
-
-  public void test_metadataCommentOverride_Bad_method() throws Exception {
-    AnalyzeLibraryResult result = analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "const override = 0;",
-        "class A {",
-        "}",
-        "class B extends A {",
-        "  @override",
-        "  foo() {}",
-        "}",
-        "");
-    assertErrors(
-        result.getErrors(),
-        errEx(ResolverErrorCode.INVALID_OVERRIDE_METADATA, 7, 3, 3));
-  }
-
-  public void testImplementsAndOverrides5() throws Exception {
-    AnalyzeLibraryResult result =
-        analyzeLibrary(
-            "abstract class I {",
-            "  foo({y,x});",
-            "}",
-            "class C implements I {",
-            "  foo({x,y}) {}",
-            "}");
-    assertErrors(result.getErrors());
-  }
-
-  /**
-   * <p>
-   * http://code.google.com/p/dart/issues/detail?id=1936
-   */
-  public void test_propertyAccess_whenExtendsUnknown() throws Exception {
-    AnalyzeLibraryResult result =
-        analyzeLibrary(
-            "// filler filler filler filler filler filler filler filler filler filler",
-            "class C extends Unknown {",
-            "  foo() {",
-            "    this.elements;",
-            "  }",
-            "}");
-    assertErrors(result.getErrors(), errEx(ResolverErrorCode.NO_SUCH_TYPE, 2, 17, 7));
-  }
-
-  /**
-   * <p>
-   * http://code.google.com/p/dart/issues/detail?id=3860
-   */
-  public void test_setterGetterDifferentStatic() throws Exception {
-    AnalyzeLibraryResult result =
-        analyzeLibrary(
-            "// filler filler filler filler filler filler filler filler filler filler",
-            "class A {",
-            "  static get field => 0;",
-            "         set field(var v) {}",
-            "}",
-            "class B {",
-            "         get field => 0;",
-            "  static set field(var v) {}",
-            "}",
-            "");
-    assertErrors(result.getErrors(),
-        errEx(TypeErrorCode.FIELD_GETTER_SETTER_SAME_STATIC, 4, 14, 5),
-        errEx(TypeErrorCode.FIELD_GETTER_SETTER_SAME_STATIC, 8, 14, 5));
-  }
-
-  /**
-   * <p>
-   * http://code.google.com/p/dart/issues/detail?id=380
-   */
-  public void test_setterGetterDifferentType() throws Exception {
-    AnalyzeLibraryResult result =
-        analyzeLibrary(
-            "// filler filler filler filler filler filler filler filler filler filler",
-            "class A {} ",
-            "class B extends A {}",
-            "class C {",
-            "  A getterField; ",
-            "  B setterField; ",
-            "  A get field { return getterField; }",
-            "  void set field(B arg) { setterField = arg; }",
-            "}",
-            "main() {",
-            "  C instance = new C();",
-            "  instance.field = new B();",
-            "  A resultA = instance.field;",
-            "  instance.field = new A();",
-            "  B resultB = instance.field;",
-            "}");
-    assertErrors(result.getErrors());
-  }
-
-  /**
-   * <p>
-   * http://code.google.com/p/dart/issues/detail?id=7597
-   */
-  public void test_setterIsNotOverriddenByMethod() throws Exception {
-    AnalyzeLibraryResult result =
-        analyzeLibrary(
-            "// filler filler filler filler filler filler filler filler filler filler",
-            "class A {",
-            "  set foo(var v) {}",
-            "}",
-            "class C extends A {",
-            "  foo(value) {}",
-            "}",
-            "main() {",
-            "  C c = new C();",
-            "  c.foo(1);",
-            "  c.foo = 1;",
-            "}");
-    assertErrors(result.getErrors());
-  }
-
-
-  public void test_setterGetterAssignable1() throws Exception {
-    AnalyzeLibraryResult result =
-        analyzeLibrary(
-            "// filler filler filler filler filler filler filler filler filler filler",
-            "class A {} ",
-            "A topGetterField; ",
-            "var topSetterField; ",
-            "A get topField { return topGetterField; }",
-            "void set topField(arg) { topSetterField = arg; }",
-            "class C {",
-            "  A getterField; ",
-            "  var setterField; ",
-            "  A get field { return getterField; }",
-            "  void set field(arg) { setterField = arg; }",
-            "}");
-    assertErrors(result.getErrors());
-  }
-
-  public void test_setterGetterAssignable2() throws Exception {
-    AnalyzeLibraryResult result =
-        analyzeLibrary(
-            "// filler filler filler filler filler filler filler filler filler filler",
-            "class A {} ",
-            "var topGetterField; ",
-            "A topSetterField; ",
-            "get topField { return topGetterField; }",
-            "void set topField(A arg) { topSetterField = arg; }",
-            "class C {",
-            "  var getterField; ",
-            "  A setterField; ",
-            "  get field { return getterField; }",
-            "  void set field(A arg) { setterField = arg; }",
-            "}");
-    assertErrors(result.getErrors());
-  }
-
-  public void test_setterGetterNotAssignable() throws Exception {
-    AnalyzeLibraryResult result =
-        analyzeLibrary(
-            "// filler filler filler filler filler filler filler filler filler filler",
-            "class A {} ",
-            "class B {}",
-            "A topGetterField; ",
-            "B topSetterField; ",
-            "A get topField { return topGetterField; }",
-            "void set topField(B arg) { topSetterField = arg; }",
-            "class C {",
-            "  A getterField; ",
-            "  B setterField; ",
-            "  A get field { return getterField; }",
-            "  void set field(B arg) { setterField = arg; }",
-            "}");
-    assertErrors(result.getErrors(),
-        errEx(TypeErrorCode.SETTER_TYPE_MUST_BE_ASSIGNABLE, 7, 19, 5),
-        errEx(TypeErrorCode.SETTER_TYPE_MUST_BE_ASSIGNABLE, 12, 18, 5));
-  }
-
-  public void test_setterInvokedAsMethod() throws Exception {
-    AnalyzeLibraryResult result =
-        analyzeLibrary(
-            "// filler filler filler filler filler filler filler filler filler filler",
-            "class C {",
-            "  void set foo(String arg) {}",
-            "} ",
-            "method() {",
-            " C c = new C();",
-            " c.foo(1);",
-            "}");
-    /* This could probably use a better error message.  The user likely intends
-     * to set the property foo, but it is invoking foo as a getter and
-     * invoking the result.
-     */
-    assertErrors(result.getErrors(),
-        errEx(TypeErrorCode.USE_ASSIGNMENT_ON_SETTER, 7, 4, 3));
-  }
-
-  /**
-   * <p>
-   * http://code.google.com/p/dart/issues/detail?id=3221
-   */
-  public void test_conditionalExpressionType() throws Exception {
-    AnalyzeLibraryResult result =
-        analyzeLibrary(
-            "// filler filler filler filler filler filler filler filler filler filler",
-            "main() {",
-            "  bool x = (true ? 1 : 2.0);",
-            "}", "");
-    List<DartCompilationError> errors = result.getErrors();
-    assertErrors(errors, errEx(TypeErrorCode.TYPE_NOT_ASSIGNMENT_COMPATIBLE, 3, 12, 16));
-    {
-      String message = errors.get(0).getMessage();
-      assertTrue(message.contains("'num'"));
-      assertTrue(message.contains("'bool'"));
-    }
-  }
-
-  /**
-   * <p>
-   * http://code.google.com/p/dart/issues/detail?id=4394
-   */
-  public void test_conditionalExpressionType_genericInterface() throws Exception {
-    AnalyzeLibraryResult result = analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "class A<T> { const A(); }",
-        "class B<T> extends A<T> { const B(); }",
-        "class C<T> implements B<T> { const C(); }",
-        "class D<T> implements B<T> { const D(); }",
-        "main() {",
-        "  B<int> test = true ? new C<int>() : const D<int>();",
-        "}",
-        "");
-    assertErrors(result.getErrors());
-  }
-
-  /**
-   * <p>
-   * https://codereview.chromium.org/12787002/
-   */
-  public void test_typeVariableBounds_12787002() throws Exception {
-    AnalyzeLibraryResult result =
-        analyzeLibrary(
-            "// filler filler filler filler filler filler filler filler filler filler",
-            "class A<T> {",
-            "  m() {",
-            "    B a = this;",
-            "  }",
-            "}",
-            "class B extends A<String> {}");
-    assertErrors(result.getErrors());
-  }
-
-  public void test_typeVariableBoundsMismatch() throws Exception {
-    AnalyzeLibraryResult result =
-        analyzeLibrary(
-            "// filler filler filler filler filler filler filler filler filler filler",
-            "abstract class I<T extends num> { }",
-            "class A<T extends num> implements I<T> { }",
-            "class B<T> implements I<T> { }"); // static type error B.T not assignable to num
-    assertErrors(result.getErrors(), errEx(TypeErrorCode.TYPE_NOT_ASSIGNMENT_COMPATIBLE, 4, 25, 1));
-  }
-
-  public void test_typeVariableBoundsMismatch2() throws Exception {
-    AnalyzeLibraryResult result =
-        analyzeLibrary(
-            "// filler filler filler filler filler filler filler filler filler filler",
-            "class C<T extends num> { }",
-            "class A<T extends num> extends C<T> { }",
-            "class B<T> extends C<T> { }"); // static type error B.T not assignable to num
-    assertErrors(result.getErrors(), errEx(TypeErrorCode.TYPE_NOT_ASSIGNMENT_COMPATIBLE, 4, 22, 1));
-  }
-
-  public void test_typeVariableBoundsCheckNew() throws Exception {
-    AnalyzeLibraryResult libraryResult = analyzeLibrary(
-        "class Object {}",
-        "class A { }",
-        "class B { }",
-        "class C<T extends A> { }",
-        "method() {",
-        "  new C<B>();", // B not assignable to A
-        "}");
-    assertErrors(
-        libraryResult.getErrors(),
-        errEx(TypeErrorCode.TYPE_NOT_ASSIGNMENT_COMPATIBLE, 6, 9, 1));
-  }
-
-  /**
-   * When we check getter/setter compatibility, we should compare propagated type variables.
-   * <p>
-   * http://code.google.com/p/dart/issues/detail?id=3067
-   */
-  public void test_typeVariables_getterSetter() throws Exception {
-    AnalyzeLibraryResult result =
-        analyzeLibrary(
-            "// filler filler filler filler filler filler filler filler filler filler",
-            "class Base1<T1> {",
-            "  T1 get val {}",
-            "}",
-            "class Base2<T2> extends Base1<T2> {",
-            "}",
-            "class Sub<T3> extends Base2<T3> {",
-            "  void set val(T3 value) {}",
-            "}",
-            "");
-    assertErrors(result.getErrors());
-  }
-
-  public void test_inferredTypes_noMemberWarnings() throws Exception {
-    // disabled by default
-    {
-      AnalyzeLibraryResult result = analyzeLibrary(
-          "// filler filler filler filler filler filler filler filler filler filler",
-          "class A {}",
-          "foo(A a) {",
-          "  var v = a;",
-          "  v.f = 0;",
-          "  v.m();",
-          "}",
-          "");
-      assertErrors(result.getErrors());
-    }
-    // use CompilerConfiguration to enable
-    {
-      compilerConfiguration = new DefaultCompilerConfiguration(new CompilerOptions() {
-        @Override
-        public boolean typeChecksForInferredTypes() {
-          return true;
-        }
-      });
-      AnalyzeLibraryResult result = analyzeLibrary(
-          "// filler filler filler filler filler filler filler filler filler filler",
-          "class A {}",
-          "foo(A a) {",
-          "  var v = a;",
-          "  v.f = 0;",
-          "  v.m();",
-          "}",
-          "");
-      assertErrors(
-          result.getErrors(),
-          errEx(TypeErrorCode.NOT_A_MEMBER_OF_INFERRED, 5, 5, 1),
-          errEx(TypeErrorCode.INTERFACE_HAS_NO_METHOD_NAMED_INFERRED, 6, 5, 1));
-    }
-  }
-
-  /**
-   * There was bug that for-in loop did not mark type of variable as inferred, so we produced
-   * warnings even when this is disabled.
-   * <p>
-   * http://code.google.com/p/dart/issues/detail?id=4460
-   */
-  public void test_inferredTypes_noMemberWarnings_forInLoop() throws Exception {
-    compilerConfiguration = new DefaultCompilerConfiguration(new CompilerOptions() {
-      @Override
-      public boolean typeChecksForInferredTypes() {
-        return false;
-      }
-    });
-    AnalyzeLibraryResult result = analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "class A {}",
-        "foo() {",
-        "  List<A> values;",
-        "  for (var v in values) {",
-        "    v.bar();",
-        "  }",
-        "}",
-        "");
-    assertErrors(result.getErrors());
-  }
-
-  public void test_inferredTypes_whenInvocationArgument_checkAssignable() throws Exception {
-    // disabled by default
-    {
-      AnalyzeLibraryResult result = analyzeLibrary(
-          "// filler filler filler filler filler filler filler filler filler filler",
-          "class A {}",
-          "class B {}",
-          "foo(A a) {}",
-          "main() {",
-          "  var v = new B();",
-          "  foo(v);",
-          "}",
-          "");
-      assertErrors(result.getErrors());
-    }
-    // use CompilerConfiguration to enable
-    {
-      compilerConfiguration = new DefaultCompilerConfiguration(new CompilerOptions() {
-        @Override
-        public boolean typeChecksForInferredTypes() {
-          return true;
-        }
-      });
-      AnalyzeLibraryResult result = analyzeLibrary(
-          "// filler filler filler filler filler filler filler filler filler filler",
-          "class A {}",
-          "class B {}",
-          "foo(A a) {}",
-          "main() {",
-          "  var v = new B();",
-          "  foo(v);",
-          "}",
-          "");
-      assertErrors(
-          result.getErrors(),
-          errEx(TypeErrorCode.TYPE_NOT_ASSIGNMENT_COMPATIBLE_INFERRED, 7, 7, 1));
-    }
-  }
-
-  /**
-   * When we resolved method from inferred type, it is possible that arguments of invocation
-   * don't is not assignable to the parameters. So, we report warning. But if we would not infer
-   * types, there would be no warnings.
-   * <p>
-   * http://code.google.com/p/dart/issues/detail?id=4849
-   */
-  public void test_inferredTypes_invocationOfMethodFromInferredType_arguments() throws Exception {
-    AnalyzeLibraryResult result = analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "class A {",
-        "  foo(int p) {}",
-        "}",
-        "main() {",
-        "  var a = new A();",
-        "  a.foo('');",
-        "}",
-        "");
-    assertErrors(result.getErrors());
-  }
-
-  public void test_typesPropagation_assignAtDeclaration() throws Exception {
-    analyzeLibrary(
-        "f() {",
-        "  var v0 = true;",
-        "  var v1 = true && false;",
-        "  var v2 = 1;",
-        "  var v3 = 1 + 2;",
-        "  var v4 = 1.0;",
-        "  var v5 = 1.0 + 2.0;",
-        "  var v6 = new Map<String, int>();",
-        "  var v7 = new Map().length;",
-        "}",
-        "");
-    assertInferredElementTypeString(testUnit, "v0", "bool", INFERRED_EXACT);
-    assertInferredElementTypeString(testUnit, "v1", "bool", INFERRED_EXACT);
-    assertInferredElementTypeString(testUnit, "v2", "int", INFERRED_EXACT);
-    assertInferredElementTypeString(testUnit, "v3", "int", INFERRED_EXACT);
-    assertInferredElementTypeString(testUnit, "v4", "double", INFERRED_EXACT);
-    assertInferredElementTypeString(testUnit, "v5", "double", INFERRED_EXACT);
-    assertInferredElementTypeString(testUnit, "v6", "Map<String, int>", INFERRED);
-    assertInferredElementTypeString(testUnit, "v7", "int", INFERRED);
-  }
-
-  public void test_typesPropagation_arrayAccess() throws Exception {
-    analyzeLibrary(
-        "class A {}",
-        "class B extends A {}",
-        "List<A> list() => [new B()];",
-        "main() {",
-        "  var v0 = list();",
-        "  var v1 = list();",
-        "  var v2 = v1[0];",
-        "}",
-        "");
-    {
-      DartExpression expr = findNode(DartUnqualifiedInvocation.class, "list();");
-      assertInferredElementTypeString(expr.getType(), "v0", "List<A>", EXACT);
-    }
-    assertInferredElementTypeString(testUnit, "v1", "List<A>", INFERRED);
-    {
-      DartExpression expr = findNode(DartArrayAccess.class, "v1[0]");
-      assertInferredElementTypeString(expr.getType(), "v2", "A", INFERRED);
-    }
-  }
-
-  /**
-   * We should infer types only if variable declared without type.
-   */
-  public void test_typesPropagation_dontChangeDeclaredType() throws Exception {
-    AnalyzeLibraryResult libraryResult = analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "class A {}",
-        "class B extends A {}",
-        "main() {",
-        "  B v = new B();",
-        "  var v1 = v;",
-        "  v = new A();",
-        "  var v2 = v;",
-        "}",
-        "");
-    assertErrors(libraryResult.getErrors());
-    assertInferredElementTypeString(testUnit, "v1", "B", INFERRED_EXACT);
-    assertInferredElementTypeString(testUnit, "v2", "B", INFERRED_EXACT);
-  }
-
-  public void test_typesPropagation_multiAssign() throws Exception {
-    analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "f() {",
-        "  var v = true;",
-        "  var v1 = v;",
-        "  v = 0;",
-        "  var v2 = v;",
-        "}",
-        "");
-    assertInferredElementTypeString(testUnit, "v1", "bool", INFERRED_EXACT);
-    assertInferredElementTypeString(testUnit, "v2", "int", INFERRED_EXACT);
-  }
-
-  public void test_typesPropagation_multiAssign_noInitialValue() throws Exception {
-    analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "f() {",
-        "  var v;",
-        "  v = 0;",
-        "  var v1 = v;",
-        "}",
-        "");
-    assertInferredElementTypeString(testUnit, "v1", "int", INFERRED_EXACT);
-  }
-
-  public void test_typesPropagation_multiAssign_IfThen() throws Exception {
-    analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "f() {",
-        "  var v = true;",
-        "  var v1 = v;",
-        "  if (true) {",
-        "    v = 0;",
-        "    var v2 = v;",
-        "  }",
-        "  var v3 = v;",
-        "}",
-        "");
-    assertInferredElementTypeString(testUnit, "v1", "bool", INFERRED_EXACT);
-    assertInferredElementTypeString(testUnit, "v2", "int", INFERRED_EXACT);
-    assertInferredElementTypeString(testUnit, "v3", "Object", INFERRED);
-  }
-
-  public void test_typesPropagation_multiAssign_IfThenElse() throws Exception {
-    analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "f() {",
-        "  var a = true;",
-        "  var b = true;",
-        "  var c = true;",
-        "  var d = true;",
-        "  if (true) {",
-        "    a = 0;",
-        "    b = 0;",
-        "  } else {",
-        "    a = 0;",
-        "    c = 0;",
-        "  }",
-        "  var a1 = a;",
-        "  var b1 = b;",
-        "  var c1 = c;",
-        "  var d1 = d;",
-        "}",
-        "");
-    assertInferredElementTypeString(testUnit, "a1", "int", INFERRED_EXACT);
-    assertInferredElementTypeString(testUnit, "b1", "Object", INFERRED);
-    assertInferredElementTypeString(testUnit, "c1", "Object", INFERRED);
-    assertInferredElementTypeString(testUnit, "d1", "bool", INFERRED_EXACT);
-  }
-
-  public void test_typesPropagation_multiAssign_IfThenElse_whenAsTypeCondition() throws Exception {
-    analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "f(var v) {",
-        "  if (v is String) {",
-        "    var v1 = v;",
-        "    v = null;",
-        "  } else {",
-        "    var v2 = v;",
-        "  }",
-        "  var v3 = v;",
-        "}",
-        "");
-    assertInferredElementTypeString(testUnit, "v1", "String", INFERRED);
-    assertInferredElementTypeString(testUnit, "v2", "dynamic", EXACT);
-    assertInferredElementTypeString(testUnit, "v3", "dynamic", EXACT);
-  }
-
-  public void test_typesPropagation_multiAssign_While() throws Exception {
-    analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "f() {",
-        "  var v = true;",
-        "  var v1 = v;",
-        "  while (true) {",
-        "    var v2 = v;",
-        "    v = 0;",
-        "    var v3 = v;",
-        "  }",
-        "  var v4 = v;",
-        "}",
-        "");
-    assertInferredElementTypeString(testUnit, "v1", "bool", INFERRED_EXACT);
-    assertInferredElementTypeString(testUnit, "v2", "bool", INFERRED_EXACT);
-    assertInferredElementTypeString(testUnit, "v3", "int", INFERRED_EXACT);
-    assertInferredElementTypeString(testUnit, "v4", "Object", INFERRED);
-  }
-
-  public void test_typesPropagation_multiAssign_DoWhile() throws Exception {
-    analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "f() {",
-        "  var v = true;",
-        "  var v1 = v;",
-        "  do {",
-        "    var v2 = v;",
-        "    v = 0;",
-        "    var v3 = v;",
-        "  } while (true);",
-        "  var v4 = v;",
-        "}",
-        "");
-    assertInferredElementTypeString(testUnit, "v1", "bool", INFERRED_EXACT);
-    assertInferredElementTypeString(testUnit, "v2", "bool", INFERRED_EXACT);
-    assertInferredElementTypeString(testUnit, "v3", "int", INFERRED_EXACT);
-    assertInferredElementTypeString(testUnit, "v4", "int", INFERRED_EXACT);
-  }
-
-  public void test_typesPropagation_multiAssign_For() throws Exception {
-    analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "f() {",
-        "  var v = true;",
-        "  var v1 = v;",
-        "  for (int i = 0; i < 10; i++) {",
-        "    var v2 = v;",
-        "    v = 0;",
-        "    var v3 = v;",
-        "  }",
-        "  var v4 = v;",
-        "}",
-        "");
-    assertInferredElementTypeString(testUnit, "v1", "bool", INFERRED_EXACT);
-    assertInferredElementTypeString(testUnit, "v2", "bool", INFERRED_EXACT);
-    assertInferredElementTypeString(testUnit, "v3", "int", INFERRED_EXACT);
-    assertInferredElementTypeString(testUnit, "v4", "Object", INFERRED);
-  }
-
-  public void test_typesPropagation_multiAssign_ForIn() throws Exception {
-    analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "f() {",
-        "  var v = true;",
-        "  var v1 = v;",
-        "  List<String> names = [];",
-        "  for (var name in names) {",
-        "    var v2 = v;",
-        "    v = 0;",
-        "    var v3 = v;",
-        "  }",
-        "  var v4 = v;",
-        "}",
-        "");
-    assertInferredElementTypeString(testUnit, "v1", "bool", INFERRED_EXACT);
-    assertInferredElementTypeString(testUnit, "v2", "bool", INFERRED_EXACT);
-    assertInferredElementTypeString(testUnit, "v3", "int", INFERRED_EXACT);
-    assertInferredElementTypeString(testUnit, "v4", "Object", INFERRED);
-  }
-
-  /**
-   * We should understand type with type arguments and choose the most generic version.
-   * <p>
-   * http://code.google.com/p/dart/issues/detail?id=4792
-   */
-  public void test_typesPropagation_multiAssign_withGenerics_type_type() throws Exception {
-    analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "f() {",
-        "  var a = new List<String>();",
-        "  var b = <Object>[];",
-        "  if (true) {",
-        "    a = <Object>[];",
-        "    b = new List<String>();",
-        "  }",
-        "  var a1 = a;",
-        "  var b1 = b;",
-        "}",
-        "");
-    assertInferredElementTypeString(testUnit, "a1", "List<Object>", INFERRED);
-    assertInferredElementTypeString(testUnit, "b1", "List<Object>", INFERRED);
-  }
-
-  /**
-   * Prefer specific type, not "dynamic" type argument.
-   * <p>
-   * http://code.google.com/p/dart/issues/detail?id=4792
-   */
-  public void test_typesPropagation_multiAssign_withGenerics_type_dynamic() throws Exception {
-    analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "f() {",
-        "  var a = new List<String>();",
-        "  var b = [];",
-        "  if (true) {",
-        "    a = [];",
-        "    b = new List<String>();",
-        "  }",
-        "  var a1 = a;",
-        "  var b1 = b;",
-        "}",
-        "");
-    assertInferredElementTypeString(testUnit, "a1", "List<String>", INFERRED);
-    assertInferredElementTypeString(testUnit, "b1", "List<String>", INFERRED);
-  }
-
-  /**
-   * <p>
-   * http://code.google.com/p/dart/issues/detail?id=4791
-   */
-  public void test_typesPropagation_multiAssign_type_null() throws Exception {
-    analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "f() {",
-        "  var v = null;",
-        "  var v1 = v;",
-        "  if (true) {",
-        "    v = '';",
-        "    var v2 = v;",
-        "  }",
-        "  var v3 = v;",
-        "}",
-        "");
-    assertInferredElementTypeString(testUnit, "v1", "dynamic", EXACT);
-    assertInferredElementTypeString(testUnit, "v2", "String", INFERRED_EXACT);
-    assertInferredElementTypeString(testUnit, "v3", "String", INFERRED);
-  }
-
-  /**
-   * There was bug that when we analyze assignment in initializer, we don't have context.
-   */
-  public void test_typesPropagation_multiAssign_assignmentOutsideFunction() throws Exception {
-    analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "class A {",
-        "  A(p) {}",
-        "}",
-        "class B extends A {",
-        "  B(p) : super(p = 0) {}",
-        "}",
-        "");
-    // no exceptions
-  }
-
-  /**
-   * When we can not identify type of assigned value we should keep "dynamic" as type of variable.
-   */
-  public void test_typesPropagation_assign_newUnknownType() throws Exception {
-    analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "f() {",
-        "  var v1 = new Unknown();",
-        "  var v2 = new Unknown.name();",
-        "}",
-        "");
-    assertInferredElementTypeString(testUnit, "v1", "dynamic", EXACT);
-    assertInferredElementTypeString(testUnit, "v2", "dynamic", EXACT);
-  }
-
-  public void test_typesPropagation_ifAsType() throws Exception {
-    analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "f(var v) {",
-        "  if ((v as String).length != 0) {",
-        "    var v1 = v;",
-        "  }",
-        "  var v2 = v;",
-        "}",
-        "");
-    assertInferredElementTypeString(testUnit, "v1", "String", INFERRED);
-    assertInferredElementTypeString(testUnit, "v2", "dynamic", EXACT);
-  }
-
-  /**
-   * Even if there is negation, we still apply "as" cast, so visit "then" statement only if cast was
-   * successful.
-   */
-  public void test_typesPropagation_ifAsType_negation() throws Exception {
-    analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "f(var v) {",
-        "  if (!(v as String).isEmpty()) {",
-        "    var v1 = v;",
-        "  }",
-        "  var v2 = v;",
-        "}",
-        "");
-    assertInferredElementTypeString(testUnit, "v1", "String", INFERRED);
-    assertInferredElementTypeString(testUnit, "v2", "dynamic", EXACT);
-  }
-
-  public void test_typesPropagation_ifIsType() throws Exception {
-    analyzeLibrary(
-        "f(var v) {",
-        "  if (v is List<String>) {",
-        "    var v1 = v;",
-        "  }",
-        "  if (v is Map<int, String>) {",
-        "    var v2 = v;",
-        "  }",
-        "  var v3 = v;",
-        "}",
-        "");
-    assertInferredElementTypeString(testUnit, "v1", "List<String>", INFERRED);
-    assertInferredElementTypeString(testUnit, "v2", "Map<int, String>", INFERRED);
-    assertInferredElementTypeString(testUnit, "v3", "dynamic", EXACT);
-  }
-
-  /**
-   * We should not make variable type less specific, even if there is such (useless) user code.
-   */
-  public void test_typesPropagation_ifIsType_mostSpecific() throws Exception {
-    analyzeLibrary(
-        "f() {",
-        "  int a;",
-        "  num b;",
-        "  if (a is num) {",
-        "    var a1 = a;",
-        "  }",
-        "  if (a is dynamic) {",
-        "    var a2 = a;",
-        "  }",
-        "  if (b is int) {",
-        "    var b1 = b;",
-        "  }",
-        "}",
-        "");
-    assertInferredElementTypeString(testUnit, "a1", "int", INFERRED_EXACT);
-    assertInferredElementTypeString(testUnit, "a2", "int", INFERRED_EXACT);
-    assertInferredElementTypeString(testUnit, "b1", "int", INFERRED);
-  }
-
-  /**
-   * When single variable has conflicting type constraints, we use union of types.
-   */
-  public void test_typesPropagation_ifIsType_conflictingTypes() throws Exception {
-    compilerConfiguration = new DefaultCompilerConfiguration(new CompilerOptions() {
-      @Override
-      public boolean typeChecksForInferredTypes() {
-        return true;
-      }
-    });
-    AnalyzeLibraryResult result = analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "f(int v) {",
-        "  if (v is String) {",
-        "    var v1 = v;",
-        "    // should be OK because 'v' is String",
-        "    v.abs; // from num",
-        "    v.length; // from String",
-        "    processInt(v);",
-        "    processString(v);",
-        "  }",
-        "}",
-        "processInt(int p) {}",
-        "processString(String p) {}",
-        "");
-    // should be no errors, we because "v" is String
-    assertErrors(result.getErrors());
-    assertInferredElementTypeString(testUnit, "v1", "[int, String]", INFERRED);
-  }
-
-  public void test_typesPropagation_ifIsType_negation() throws Exception {
-    analyzeLibrary(
-        "f(var v) {",
-        "  if (v is! String) {",
-        "    var v1 = v;",
-        "  }",
-        "  if (!(v is String)) {",
-        "    var v2 = v;",
-        "  }",
-        "  if (!!(v is String)) {",
-        "    var v3 = v;",
-        "  }",
-        "}",
-        "");
-    assertInferredElementTypeString(testUnit, "v1", "dynamic", EXACT);
-    assertInferredElementTypeString(testUnit, "v2", "dynamic", EXACT);
-    assertInferredElementTypeString(testUnit, "v3", "String", INFERRED);
-  }
-
-  public void test_typesPropagation_ifIsType_and() throws Exception {
-    analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "f(var a, var b) {",
-        "  if (a is String && b is List<String>) {",
-        "    var a1 = a;",
-        "    var b1 = b;",
-        "  }",
-        "}",
-        "");
-    assertInferredElementTypeString(testUnit, "a1", "String", INFERRED);
-    assertInferredElementTypeString(testUnit, "b1", "List<String>", INFERRED);
-  }
-
-  public void test_typesPropagation_ifIsType_or() throws Exception {
-    analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "f(var v) {",
-        "  if (true || v is String) {",
-        "    var v1 = v;",
-        "  }",
-        "  if (v is String || true) {",
-        "    var v2 = v;",
-        "  }",
-        "}",
-        "");
-    assertInferredElementTypeString(testUnit, "v1", "dynamic", EXACT);
-    assertInferredElementTypeString(testUnit, "v2", "dynamic", EXACT);
-  }
-
-  public void test_typesPropagation_whileIsType() throws Exception {
-    analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "f(var v) {",
-        "  var v = null;",
-        "  while (v is String) {",
-        "    var v1 = v;",
-        "  }",
-        "  var v2 = v;",
-        "}",
-        "");
-    assertInferredElementTypeString(testUnit, "v1", "String", INFERRED);
-    assertInferredElementTypeString(testUnit, "v2", "dynamic", EXACT);
-  }
-
-  public void test_typesPropagation_forIsType() throws Exception {
-    analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "f(var v) {",
-        "  var v = null;",
-        "  for (; v is String; () {var v2 = v;} ()) {",
-        "    var v1 = v;",
-        "  }",
-        "  var v3 = v;",
-        "}",
-        "");
-    assertInferredElementTypeString(testUnit, "v1", "String", INFERRED);
-    assertInferredElementTypeString(testUnit, "v2", "String", INFERRED);
-    assertInferredElementTypeString(testUnit, "v3", "dynamic", EXACT);
-  }
-
-  public void test_typesPropagation_forEach() throws Exception {
-    analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "f(var v) {",
-        "  List<String> values = [];",
-        "  for (var v in values) {",
-        "    var v1 = v;",
-        "  }",
-        "}",
-        "");
-    assertInferredElementTypeString(testUnit, "v1", "String", INFERRED);
-  }
-
-  public void test_typesPropagation_ifIsNotType_withElse() throws Exception {
-    analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "f(var v) {",
-        "  if (v is! String) {",
-        "    var v1 = v;",
-        "  } else {",
-        "    var v2 = v;",
-        "  }",
-        "  var v3 = v;",
-        "}",
-        "");
-    // we don't know type, but not String
-    assertInferredElementTypeString(testUnit, "v1", "dynamic", EXACT);
-    // we know that String
-    assertInferredElementTypeString(testUnit, "v2", "String", INFERRED);
-    // again, we don't know after "if"
-    assertInferredElementTypeString(testUnit, "v3", "dynamic", EXACT);
-  }
-
-  public void test_typesPropagation_ifIsNotType_hasThenReturn() throws Exception {
-    analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "f(var v) {",
-        "  var v1 = v;",
-        "  if (v is! String) {",
-        "    return;",
-        "  }",
-        "  var v2 = v;",
-        "}",
-        "");
-    assertInferredElementTypeString(testUnit, "v1", "dynamic", EXACT);
-    assertInferredElementTypeString(testUnit, "v2", "String", INFERRED);
-  }
-
-  public void test_typesPropagation_ifIsNotType_hasThenThrow() throws Exception {
-    analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "f(var v) {",
-        "  if (v is! String) {",
-        "    throw new Exception();",
-        "  }",
-        "  var v1 = v;",
-        "}",
-        "");
-    assertInferredElementTypeString(testUnit, "v1", "String", INFERRED);
-  }
-
-  public void test_typesPropagation_ifIsNotType_emptyThen() throws Exception {
-    analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "f(var v) {",
-        "  if (v is! String) {",
-        "  }",
-        "  var v1 = v;",
-        "}",
-        "");
-    assertInferredElementTypeString(testUnit, "v1", "dynamic", EXACT);
-  }
-
-  public void test_typesPropagation_ifIsNotType_otherThen() throws Exception {
-    analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "f(var v) {",
-        "  if (v is! String) {",
-        "    ;",
-        "  }",
-        "  var v1 = v;",
-        "}",
-        "");
-    assertInferredElementTypeString(testUnit, "v1", "dynamic", EXACT);
-  }
-
-  public void test_typesPropagation_ifIsNotType_hasThenThrow_withCatch() throws Exception {
-    analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "f(var v) {",
-        "  try {",
-        "    if (v is! String) {",
-        "      throw new Exception();",
-        "    }",
-        "  } catch (var e) {",
-        "  }",
-        "  var v1 = v;",
-        "}",
-        "");
-    assertInferredElementTypeString(testUnit, "v1", "dynamic", EXACT);
-  }
-
-  public void test_typesPropagation_ifIsNotType_hasThenContinue() throws Exception {
-    AnalyzeLibraryResult libraryResult = analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "main() {",
-        "  for (var v in <Object>[1, 'two', 3]) {",
-        "    var v1 = v;",
-        "    if (v is! String) {",
-        "      continue;",
-        "    }",
-        "    var v2 = v;",
-        "  }",
-        "}",
-        "");
-    assertErrors(libraryResult.getErrors());
-    assertInferredElementTypeString(testUnit, "v1", "Object", INFERRED);
-    assertInferredElementTypeString(testUnit, "v2", "String", INFERRED);
-  }
-
-  public void test_typesPropagation_ifIsNotType_hasThenBreak() throws Exception {
-    AnalyzeLibraryResult libraryResult = analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "main() {",
-        "  for (var v in <Object>[1, 'two', 3]) {",
-        "    var v1 = v;",
-        "    if (v is! String) {",
-        "      break;",
-        "    }",
-        "    var v2 = v;",
-        "  }",
-        "}",
-        "");
-    assertErrors(libraryResult.getErrors());
-    assertInferredElementTypeString(testUnit, "v1", "Object", INFERRED);
-    assertInferredElementTypeString(testUnit, "v2", "String", INFERRED);
-  }
-
-  public void test_typesPropagation_ifIsNotType_or() throws Exception {
-    analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "f(var p1, var p2) {",
-        "  if (p1 is! int || p2 is! String) {",
-        "    return;",
-        "  }",
-        "  var v1 = p1;",
-        "  var v2 = p2;",
-        "}",
-        "");
-    assertInferredElementTypeString(testUnit, "v1", "int", INFERRED);
-    assertInferredElementTypeString(testUnit, "v2", "String", INFERRED);
-  }
-
-  public void test_typesPropagation_ifIsNotType_and() throws Exception {
-    analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "f(var v) {",
-        "  if (v is! String && true) {",
-        "    return;",
-        "  }",
-        "  var v1 = v;",
-        "}",
-        "");
-    assertInferredElementTypeString(testUnit, "v1", "dynamic", EXACT);
-  }
-
-  public void test_typesPropagation_ifIsNotType_not() throws Exception {
-    analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "f(var v) {",
-        "  if (!(v is! String)) {",
-        "    return;",
-        "  }",
-        "  var v1 = v;",
-        "}",
-        "");
-    assertInferredElementTypeString(testUnit, "v1", "dynamic", EXACT);
-  }
-
-  public void test_typesPropagation_ifIsNotType_not2() throws Exception {
-    analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "f(var v) {",
-        "  if (!!(v is! String)) {",
-        "    return;",
-        "  }",
-        "  var v1 = v;",
-        "}",
-        "");
-    assertInferredElementTypeString(testUnit, "v1", "String", INFERRED);
-  }
-
-  public void test_typesPropagation_ifNotIsType() throws Exception {
-    analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "f(var v) {",
-        "  if (!(v is String)) {",
-        "    return;",
-        "  }",
-        "  var v1 = v;",
-        "}",
-        "");
-    assertInferredElementTypeString(testUnit, "v1", "String", INFERRED);
-  }
-
-  /**
-   * <p>
-   * http://code.google.com/p/dart/issues/detail?id=4410
-   */
-  public void test_typesPropagation_assertIsType() throws Exception {
-    analyzeLibrary(
-        "f(var v) {",
-        "  if (true) {",
-        "    var v1 = v;",
-        "    assert(v is String);",
-        "    var v2 = v;",
-        "    {",
-        "      var v3 = v;",
-        "    }",
-        "    var v4 = v;",
-        "  }",
-        "  var v5 = v;",
-        "}",
-        "");
-    // we don't know type initially
-    assertInferredElementTypeString(testUnit, "v1", "dynamic", EXACT);
-    // after "assert" all next statements know type
-    assertInferredElementTypeString(testUnit, "v2", "String", INFERRED);
-    assertInferredElementTypeString(testUnit, "v3", "String", INFERRED);
-    // type is set to unknown only when we exit control Block, not just any Block
-    assertInferredElementTypeString(testUnit, "v4", "String", INFERRED);
-    // we exited "if" Block, so "assert" may be was not executed, so we don't know type
-    assertInferredElementTypeString(testUnit, "v5", "dynamic", EXACT);
-  }
-
-  /**
-   * <p>
-   * http://code.google.com/p/dart/issues/detail?id=4410
-   */
-  public void test_typesPropagation_assertIsType_twoVariables() throws Exception {
-    analyzeLibrary(
-        "f(a, b) {",
-        "  while (true) {",
-        "    var a1 = a;",
-        "    var b1 = b;",
-        "    assert(a is String);",
-        "    assert(b is String);",
-        "    var a2 = a;",
-        "    var b2 = b;",
-        "  }",
-        "  var a3 = a;",
-        "  var b3 = b;",
-        "}",
-        "");
-    // we don't know type initially
-    assertInferredElementTypeString(testUnit, "a1", "dynamic", EXACT);
-    assertInferredElementTypeString(testUnit, "b1", "dynamic", EXACT);
-    // after "assert" all next statements know type
-    assertInferredElementTypeString(testUnit, "a2", "String", INFERRED);
-    assertInferredElementTypeString(testUnit, "b2", "String", INFERRED);
-    // we exited "if" Block, so "assert" may be was not executed, so we don't know type
-    assertInferredElementTypeString(testUnit, "a3", "dynamic", EXACT);
-    assertInferredElementTypeString(testUnit, "b3", "dynamic", EXACT);
-  }
-
-  /**
-   * When variable has explicit type, we should not fall to 'dynamic', we need to keep this type.
-   * <p>
-   * http://code.google.com/p/dart/issues/detail?id=6399
-   */
-  public void test_typesPropagation_assertIsType_hasExplicitType() throws Exception {
-    analyzeLibrary(
-        "class A {}",
-        "class B extends A {}",
-        "class C extends B {}",
-        "main() {",
-        "  B v;",
-        "  if (v is A) {",
-        "    var v1 = v;",
-        "  }",
-        "  if (v is B) {",
-        "    var v2 = v;",
-        "  }",
-        "  if (v is C) {",
-        "    var v3 = v;",
-        "  }",
-        "  if (v is String) {",
-        "    var v4 = v;",
-        "  }",
-        "}",
-        "");
-    assertInferredElementTypeString(testUnit, "v1", "B", INFERRED_EXACT);
-    assertInferredElementTypeString(testUnit, "v2", "B", INFERRED_EXACT);
-    assertInferredElementTypeString(testUnit, "v3", "C", INFERRED);
-    assertInferredElementTypeString(testUnit, "v4", "[B, String]", INFERRED);
-  }
-
-  public void test_typesPropagation_field_inClass_final() throws Exception {
-    analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "class A {",
-        "  final v1 = 123;",
-        "  final v2 = 1 + 2.0;",
-        "}",
-        "");
-    assertInferredElementTypeString(testUnit, "v1", "int", INFERRED_EXACT);
-    assertInferredElementTypeString(testUnit, "v2", "double", INFERRED_EXACT);
-  }
-
-  public void test_typesPropagation_field_inClass_const() throws Exception {
-    analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "class A {",
-        "  const v1 = 123;",
-        "  final v2 = 1 + 2.0;",
-        "}",
-        "");
-    assertInferredElementTypeString(testUnit, "v1", "int", INFERRED_EXACT);
-    assertInferredElementTypeString(testUnit, "v2", "double", INFERRED_EXACT);
-  }
-
-  /**
-   * If field is not final, we don't know if is will be assigned somewhere else, may be even not in
-   * there same unit, so we cannot be sure about its type.
-   */
-  public void test_typesPropagation_field_inClass_notFinal() throws Exception {
-    analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "class A {",
-        "  var v1 = 123;",
-        "}",
-        "");
-    assertInferredElementTypeString(testUnit, "v1", "dynamic", EXACT);
-  }
-
-  public void test_typesPropagation_field_topLevel_final() throws Exception {
-    analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "final v1 = 123;",
-        "final v2 = 1 + 2.0;",
-        "");
-    assertInferredElementTypeString(testUnit, "v1", "int", INFERRED_EXACT);
-    assertInferredElementTypeString(testUnit, "v2", "double", INFERRED_EXACT);
-  }
-
-  public void test_typesPropagation_field_topLevel_const() throws Exception {
-    analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "const v1 = 123;",
-        "const v2 = 1 + 2.0;",
-        "");
-    assertInferredElementTypeString(testUnit, "v1", "int", INFERRED_EXACT);
-    assertInferredElementTypeString(testUnit, "v2", "double", INFERRED_EXACT);
-  }
-
-  /**
-   * If field is not final, we don't know if is will be assigned somewhere else, may be even not in
-   * there same unit, so we cannot be sure about its type.
-   */
-  public void test_typesPropagation_field_topLevel_notFinal() throws Exception {
-    analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "var v1 = 123;",
-        "");
-    assertInferredElementTypeString(testUnit, "v1", "dynamic", EXACT);
-  }
-
-  public void test_typesPropagation_FunctionAliasType() throws Exception {
-    analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "typedef F();",
-        "foo(F f) {",
-        "  var v = f;",
-        "  v();",
-        "}",
-        "",
-        "");
-    assertInferredElementTypeString(testUnit, "v", "F", INFERRED_EXACT);
-  }
-
-  /**
-   * When we pass "function literal" into invocation on some method, we may know exact
-   * <code>Function</code> type expected by this method, so we know types of "function literal"
-   * parameters. So, if these types are not specified in "function literal", we can use "expected"
-   * types.
-   * <p>
-   * http://code.google.com/p/dart/issues/detail?id=3712
-   */
-  public void test_typesPropagation_parameterOfClosure_invocationNormalParameter() throws Exception {
-    analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "class Event {}",
-        "typedef void EventListener(Event event);",
-        "foo(EventListener listener) {",
-        "}",
-        "main() {",
-        "  foo((e) {",
-        "    var v = e;",
-        "  });",
-        "}",
-        "");
-    assertInferredElementTypeString(testUnit, "v", "Event", INFERRED);
-  }
-
-  /**
-   * <p>
-   * http://code.google.com/p/dart/issues/detail?id=3712
-   */
-  public void test_typesPropagation_parameterOfClosure_invocationNamedPositionalParameter() throws Exception {
-    analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "class Event {}",
-        "typedef void EventListener(Event event);",
-        "foo([EventListener listener]) {",
-        "}",
-        "main() {",
-        "  foo((e) {",
-        "    var v = e;",
-        "  });",
-        "}",
-        "");
-    assertInferredElementTypeString(testUnit, "v", "Event", INFERRED);
-  }
-
-  /**
-   * <p>
-   * http://code.google.com/p/dart/issues/detail?id=3712
-   */
-  public void test_typesPropagation_parameterOfClosure_invocationNamedParameter() throws Exception {
-    analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "class Event {}",
-        "typedef void EventListener(Event event);",
-        "foo({EventListener listener}) {",
-        "}",
-        "main() {",
-        "  foo(listener: (e) {",
-        "    var v = e;",
-        "  });",
-        "}",
-        "");
-    assertInferredElementTypeString(testUnit, "v", "Event", INFERRED);
-  }
-
-  /**
-   * http://code.google.com/p/dart/issues/detail?id=3712
-   */
-  public void test_typesPropagation_parameterOfClosure_invocationOfMethod() throws Exception {
-    analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "class Event {}",
-        "typedef void EventListener(Event event);",
-        "class Button {",
-        "  onClick(EventListener listener) {",
-        "  }",
-        "}",
-        "main() {",
-        "  Button button = new Button();",
-        "  button.onClick((e) {",
-        "    var v = e;",
-        "  });",
-        "}",
-        "");
-    assertInferredElementTypeString(testUnit, "v", "Event", INFERRED);
-  }
-
-  /**
-   * We should infer closure parameter types even in {@link FunctionType} is specified directly,
-   * without using {@link FunctionAliasType}.
-   */
-  public void test_typesPropagation_parameterOfClosure_functionType() throws Exception {
-    analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "class Event {}",
-        "class Button<T> {",
-        "  onClick(listener(T e)) {",
-        "  }",
-        "}",
-        "main() {",
-        "  var button = new Button<Event>();",
-        "  button.onClick((e) {",
-        "    var v = e;",
-        "  });",
-        "}",
-        "");
-    assertInferredElementTypeString(testUnit, "v", "Event", INFERRED);
-  }
-
-  public void test_typesPropagation_parameterOfClosure_assignVariable() throws Exception {
-    analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "class Event {}",
-        "typedef void EventListener(Event event);",
-        "main() {",
-        "  // local variable assign",
-        "  {",
-        "    EventListener listener;",
-        "    listener = (e) {",
-        "      var v1 = e;",
-        "    };",
-        "  }",
-        "  // local variable declare",
-        "  {",
-        "    EventListener listener = (e) {",
-        "      var v2 = e;",
-        "    };",
-        "  }",
-        "}",
-        "");
-    assertInferredElementTypeString(testUnit, "v1", "Event", INFERRED);
-    assertInferredElementTypeString(testUnit, "v2", "Event", INFERRED);
-  }
-
-  public void test_typesPropagation_parameterOfClosure_assignField() throws Exception {
-    analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "class Event {}",
-        "typedef void EventListener(Event event);",
-        "class Button {",
-        "  EventListener listener;",
-        "}",
-        "EventListener topLevelListener;",
-        "main() {",
-        "  // top-level field",
-        "  {",
-        "    topLevelListener = (e) {",
-        "      var v1 = e;",
-        "    };",
-        "  }",
-        "  // member field",
-        "  {",
-        "    Button button = new Button();",
-        "    button.listener = (e) {",
-        "      var v2 = e;",
-        "    };",
-        "  }",
-        "}",
-        "EventListener topLevelListener2 = (e) {",
-        "  var v3 = e;",
-        "};",
-        "");
-    assertInferredElementTypeString(testUnit, "v1", "Event", INFERRED);
-    assertInferredElementTypeString(testUnit, "v2", "Event", INFERRED);
-    assertInferredElementTypeString(testUnit, "v3", "Event", INFERRED);
-  }
-
-  /**
-   * Sometimes inferred type is too generic - such as "Object" or "Collection", so there are no
-   * reason to reports problems.
-   */
-  public void deprecatedCollection_test_typesPropagation_dontWant_ifTooGeneric() throws Exception {
-    compilerConfiguration = new DefaultCompilerConfiguration(new CompilerOptions() {
-      @Override
-      public boolean typeChecksForInferredTypes() {
-        return true;
-      }
-    });
-    AnalyzeLibraryResult libraryResult = analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "typedef void HandlerObject(Object o);",
-        "typedef void HandlerCollection(Collection o);",
-        "fObject(HandlerObject h) {}",
-        "fCollection(HandlerCollection h) {}",
-        "main() {",
-        "  fObject((x) {",
-        "    x.myNoSuchField;",
-        "    x.myNoSuchMethod();",
-        "  });",
-        "  fCollection((x) {",
-        "    x.myNoSuchField;",
-        "    x.myNoSuchMethod();",
-        "  });",
-        "}",
-        "");
-    assertErrors(libraryResult.getErrors());
-  }
-
-  /**
-   * Helpful (but not perfectly satisfying Specification) type of "conditional" is intersection of
-   * then/else types, not just their "least upper bounds". And this corresponds runtime behavior.
-   */
-  public void test_typesPropagation_conditional() throws Exception {
-    AnalyzeLibraryResult libraryResult = analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "abstract class I1 {",
-        "  f1();",
-        "}",
-        "abstract class I2 {",
-        "  f2();",
-        "}",
-        "class A implements I1, I2 {",
-        "  f1() => 11;",
-        "  f2() => 12;",
-        "}",
-        "class B implements I1, I2 {",
-        "  f1() => 21;",
-        "  f2() => 22;",
-        "}",
-        "main() {",
-        "  var v = true ? new A() : new B();",
-        "  v.f1();",
-        "  v.f2();",
-        "}",
-        "");
-    // no errors, because both f1() and f2() invocations were resolved
-    assertErrors(libraryResult.getErrors());
-    // v.f1() was resolved
-    {
-      DartExpression expression = findNodeBySource(testUnit, "v.f1()");
-      assertNotNull(expression);
-      assertNotNull(expression.getElement());
-    }
-    // v.f2() was resolved
-    {
-      DartExpression expression = findNodeBySource(testUnit, "v.f1()");
-      assertNotNull(expression);
-      assertNotNull(expression.getElement());
-    }
-  }
-
-  public void test_getType_binaryExpression() throws Exception {
-    analyzeLibrary(
-        "f(var arg) {",
-        "  var v1 = 1 + 2;",
-        "  var v2 = 1 - 2;",
-        "  var v3 = 1 * 2;",
-        "  var v4 = 1 ~/ 2;",
-        "  var v5 = 1 % 2;",
-        "  var v6 = 1 / 2;",
-        "  var v7 = 1.0 + 2;",
-        "  var v8 = 1 + 2.0;",
-        "  var v9 = 1 - 2.0;",
-        "  var v10 = 1.0 - 2;",
-        "  var v11 = 1 * 2.0;",
-        "  var v12 = 1.0 * 2;",
-        "  var v13 = 1.0 / 2;",
-        "  var v14 = 1 / 2.0;",
-        "  var v15 = 1.0 ~/ 2.0;",
-        "  var v16 = 1.0 ~/ 2;",
-        "  var v17 = arg as int",
-        "}",
-        "");
-    assertInferredElementTypeString(testUnit, "v1", "int", INFERRED_EXACT);
-    assertInferredElementTypeString(testUnit, "v2", "int", INFERRED_EXACT);
-    assertInferredElementTypeString(testUnit, "v3", "int", INFERRED_EXACT);
-    assertInferredElementTypeString(testUnit, "v4", "int", INFERRED_EXACT);
-    assertInferredElementTypeString(testUnit, "v5", "int", INFERRED_EXACT);
-    assertInferredElementTypeString(testUnit, "v6", "double", INFERRED_EXACT);
-    assertInferredElementTypeString(testUnit, "v7", "double", INFERRED_EXACT);
-    assertInferredElementTypeString(testUnit, "v8", "double", INFERRED_EXACT);
-    assertInferredElementTypeString(testUnit, "v9", "double", INFERRED_EXACT);
-    assertInferredElementTypeString(testUnit, "v10", "double", INFERRED_EXACT);
-    assertInferredElementTypeString(testUnit, "v11", "double", INFERRED_EXACT);
-    assertInferredElementTypeString(testUnit, "v12", "double", INFERRED_EXACT);
-    assertInferredElementTypeString(testUnit, "v13", "double", INFERRED_EXACT);
-    assertInferredElementTypeString(testUnit, "v14", "double", INFERRED_EXACT);
-    assertInferredElementTypeString(testUnit, "v15", "double", INFERRED_EXACT);
-    assertInferredElementTypeString(testUnit, "v16", "double", INFERRED_EXACT);
-    assertInferredElementTypeString(testUnit, "v17", "int", INFERRED);
-  }
-
-  /**
-   * It was requested that even if Editor can be helpful and warn about types incompatibility, it
-   * should not do this to completely satisfy specification.
-   * <p>
-   * http://code.google.com/p/dart/issues/detail?id=3223
-   * <p>
-   * This feature was requested by users, so we introduce it again, but disabled to command line.
-   * <p>
-   * http://code.google.com/p/dart/issues/detail?id=4518
-   */
-  public void test_typesPropagation_noExtraWarnings() throws Exception {
-    AnalyzeLibraryResult libraryResult = analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "f(int v) {}",
-        "f1() {",
-        "  var v = true;",
-        "  f(v);",
-        "}",
-        "f2(var v) {",
-        "  if (v is bool) {",
-        "    f(v);",
-        "  }",
-        "}",
-        "f3(var v) {",
-        "  while (v is bool) {",
-        "    f(v);",
-        "  }",
-        "}",
-        "");
-    assertErrors(libraryResult.getErrors());
-  }
-
-  /**
-   * There was problem that using <code>() -> bool</code> getter in negation ('!') caused assignment
-   * warnings. Actual reason was that with negation getter access is visited twice and on the second
-   * time type of getter method, instead of return type, was returned.
-   */
-  public void test_getType_getterInNegation() throws Exception {
-    AnalyzeLibraryResult libraryResult = analyzeLibrary(
-        "class A {",
-        "  int get intProperty => 42;",
-        "  bool get boolProperty => true;",
-        "}",
-        "f() {",
-        "  var a = new A();",
-        "  var v1 = a.intProperty;",
-        "  var v2 = a.boolProperty;",
-        "  if (a.boolProperty) {",
-        "  }",
-        "  if (!a.boolProperty) {",
-        "  }",
-        "}",
-        "");
-    assertErrors(libraryResult.getErrors());
-    assertInferredElementTypeString(testUnit, "v1", "int", INFERRED);
-    assertInferredElementTypeString(testUnit, "v2", "bool", INFERRED);
-  }
-
-  public void test_getType_getterInNegation_generic() throws Exception {
-    AnalyzeLibraryResult libraryResult = analyzeLibrary(
-        "class A<T> {",
-        "  T field;",
-        "  T get prop => null;",
-        "}",
-        "f() {",
-        "  var a = new A<bool>();",
-        "  var v1 = a.field;",
-        "  var v2 = a.prop;",
-        "  if (a.field) {",
-        "  }",
-        "  if (!a.field) {",
-        "  }",
-        "  if (a.prop) {",
-        "  }",
-        "  if (!a.prop) {",
-        "  }",
-        "}",
-        "");
-    assertErrors(libraryResult.getErrors());
-    assertInferredElementTypeString(testUnit, "v1", "bool", INFERRED);
-    assertInferredElementTypeString(testUnit, "v2", "bool", INFERRED);
-  }
-
-  public void test_getType_getterInSwitch_default() throws Exception {
-    AnalyzeLibraryResult libraryResult = analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "int get foo {}",
-        "f() {",
-        "  switch (true) {",
-        "    default:",
-        "      int v = foo;",
-        "      break;",
-        "  }",
-        "}",
-        "");
-    assertErrors(libraryResult.getErrors());
-  }
-
-  /**
-   * <p>
-   * http://code.google.com/p/dart/issues/detail?id=3515
-   */
-  public void test_getType_getterInSwitchExpression_topLevel() throws Exception {
-    AnalyzeLibraryResult libraryResult = analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "int get foo => 42;",
-        "f() {",
-        "  switch (foo) {",
-        "    case 2:",
-        "      break;",
-        "  }",
-        "}",
-        "");
-    assertErrors(libraryResult.getErrors());
-  }
-
-  /**
-   * <p>
-   * http://code.google.com/p/dart/issues/detail?id=3515
-   */
-  public void test_getType_getterInSwitchExpression_inClass() throws Exception {
-    AnalyzeLibraryResult libraryResult = analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "class A<T> {",
-        "  T get foo => null;",
-        "}",
-        "f() {",
-        "  A<int> a = new A<int>();",
-        "  switch (a.foo) {",
-        "    case 2:",
-        "      break;",
-        "  }",
-        "}",
-        "");
-    assertErrors(libraryResult.getErrors());
-  }
-
-  /**
-   * <p>
-   * http://code.google.com/p/dart/issues/detail?id=3272
-   */
-  public void test_assignVoidToDynamic() throws Exception {
-    AnalyzeLibraryResult libraryResult = analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "void foo() {}",
-        "main() {",
-        "  var v = foo();",
-        "}",
-        "");
-    assertErrors(libraryResult.getErrors());
-  }
-
-  /**
-   * <p>
-   * http://code.google.com/p/dart/issues/detail?id=5114
-   */
-  public void test_lowerCaseDynamicType() throws Exception {
-    AnalyzeLibraryResult libraryResult = analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "main() {",
-        "  dynamic v = null;",
-        "}",
-        "");
-    assertErrors(libraryResult.getErrors());
-  }
-
-  /**
-   * <p>
-   * http://code.google.com/p/dart/issues/detail?id=7980
-   */
-  public void test_whenVariableNamedDynamic() throws Exception {
-    AnalyzeLibraryResult libraryResult = analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "main() {",
-        "  var dynamic = 42;",
-        "  new List<dynamic>();",
-        "}",
-        "");
-    assertErrors(
-        libraryResult.getErrors(),
-        errEx(TypeErrorCode.NOT_A_TYPE, 4, 12, 7));
-  }
-
-  /**
-   * It is a static warning if the return type of the user-declared operator == is explicitly
-   * declared and not bool.
-   */
-  public void test_equalsOperator_type() throws Exception {
-    AnalyzeLibraryResult libraryResult = analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "class A {",
-        "  bool operator ==(other) {}",
-        "}",
-        "class B {",
-        "  String operator ==(other) {}",
-        "}",
-        "class C {",
-        "  Object operator ==(other) {}",
-        "}",
-        "");
-    assertErrors(
-        libraryResult.getErrors(),
-        errEx(TypeErrorCode.CANNOT_OVERRIDE_METHOD_NOT_SUBTYPE, 6, 19, 2),
-        errEx(TypeErrorCode.OPERATOR_EQUALS_BOOL_RETURN_TYPE, 6, 3, 6),
-        errEx(TypeErrorCode.OPERATOR_EQUALS_BOOL_RETURN_TYPE, 9, 3, 6));
-  }
-
-  /**
-   * We should be able to resolve "a == b" to the "equals" operator.
-   */
-  public void test_equalsOperator_resolving() throws Exception {
-    AnalyzeLibraryResult libraryResult = analyzeLibrary(
-            "// filler filler filler filler filler filler filler filler filler filler",
-            "class C {",
-            "  operator ==(other) => false;",
-            "}",
-            "main() {",
-            "  new C() == new C();",
-            "}",
-            "");
-    assertErrors(libraryResult.getErrors());
-    // find == expression
-    DartExpression expression = findNodeBySource(testUnit, "new C() == new C()");
-    assertNotNull(expression);
-    // validate == element
-    MethodElement equalsElement = (MethodElement) expression.getElement();
-    assertNotNull(equalsElement);
-  }
-
-  /**
-   * We can not override getter. But setter has name "setter=", so there are no conflict.
-   */
-  public void test_supertypeHasMethod() throws Exception {
-    AnalyzeLibraryResult libraryResult = analyzeLibrary(
-            "// filler filler filler filler filler filler filler filler filler filler",
-            "class A {}",
-            "abstract class I {",
-            "  foo();",
-            "  bar();",
-            "}",
-            "abstract class J implements I {",
-            "  get foo;",
-            "  set bar(x);",
-            "}");
-      assertErrors(libraryResult.getErrors(),
-          errEx(TypeErrorCode.SUPERTYPE_HAS_METHOD, 8, 7, 3));
-  }
-
-  /**
-   * Ensure that "operator call()" is parsed, and "operator" is not considered as return type. This
-   * too weak test, but for now we are interested only in parsing.
-   */
-  public void test_callOperator_parsing() throws Exception {
-    AnalyzeLibraryResult libraryResult = analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "class A {",
-        "  operator call() => 42;",
-        "}",
-        "");
-    assertErrors(libraryResult.getErrors());
-  }
-
-  /**
-   * The spec in the section 10.28 says:
-   * "It is a compile-time error to use a built-in identifier other than dynamic as a type annotation."
-   * <p>
-   * http://code.google.com/p/dart/issues/detail?id=3307
-   */
-  public void test_builtInIdentifier_asTypeAnnotation() throws Exception {
-    AnalyzeLibraryResult libraryResult = analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "main() {",
-        "  abstract   v01;",
-        "  as         v02;",
-        "  dynamic    v03;",
-        "  export     v04;",
-        "  external   v05;",
-        "  factory    v06;",
-        "  get        v07;",
-        "  implements v08;",
-        "  import     v09;",
-        "  library    v10;",
-        "  operator   v11;",
-        "  part       v12;",
-        "  set        v13;",
-        "  static     v14;",
-        "//  typedef    v15;",
-        "}",
-        "");
-    assertErrors(
-        libraryResult.getErrors(),
-        errEx(ResolverErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE, 3, 3, 8),   // abstract
-        errEx(ResolverErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE, 4, 3, 2),   // as
-                                                                         // dynamic
-        errEx(ResolverErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE, 6, 3, 6),   // export
-        errEx(ResolverErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE, 7, 3, 8),   // external
-        errEx(ResolverErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE, 8, 3, 7),   // factory
-        errEx(ResolverErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE, 9, 3, 3),   // get
-        errEx(ResolverErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE, 10, 3, 10), // implements
-        errEx(ResolverErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE, 11, 3, 6),  // import
-        errEx(ResolverErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE, 12, 3, 7),  // library
-        errEx(ResolverErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE, 13, 3, 8),  // operator
-        errEx(ResolverErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE, 14, 3, 4),  // part
-        errEx(ResolverErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE, 15, 3, 3),  // set
-        errEx(ResolverErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE, 16, 3, 6)  // static
-//        ,errEx(ResolverErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE, 17, 3, 7)   // typedef
-    );
-  }
-
-  public void test_supertypeHasField() throws Exception {
-    AnalyzeLibraryResult libraryResult = analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "class A {",
-        "  var foo;",
-        "  var bar;",
-        "}",
-        "class B extends A {",
-        "  foo() {}",
-        "  bar() {}",
-        "}");
-    assertErrors(libraryResult.getErrors(),
-        errEx(TypeErrorCode.SUPERTYPE_HAS_FIELD, 7, 3, 3),
-        errEx(TypeErrorCode.SUPERTYPE_HAS_FIELD, 8, 3, 3));
-  }
-
-  /**
-   * We can not override getter. But setter has name "setter=", so there are no conflict.
-   */
-  public void test_supertypeHasGetterSetter() throws Exception {
-    AnalyzeLibraryResult libraryResult = analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "class A {",
-        "  get foo => 0;",
-        "  set bar(x) {}",
-        "}",
-        "class B extends A {",
-        "  foo() {}",
-        "  bar() {}",
-        "}");
-    assertErrors(libraryResult.getErrors(),
-        errEx(TypeErrorCode.SUPERTYPE_HAS_FIELD, 7, 3, 3));
-  }
-
-  /**
-   * <p>
-   * http://code.google.com/p/dart/issues/detail?id=3280
-   */
-  public void test_typeVariableExtendsFunctionAliasType() throws Exception {
-    AnalyzeLibraryResult libraryResult = analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "typedef void F();",
-        "class C<T extends F> {",
-        "  test() {",
-        "    new C<T>();",
-        "  }",
-        "}",
-        "");
-    assertErrors(libraryResult.getErrors());
-  }
-
-  /**
-   * <p>
-   * http://code.google.com/p/dart/issues/detail?id=3344
-   */
-  public void test_typeVariableExtendsTypeVariable() throws Exception {
-    AnalyzeLibraryResult libraryResult = analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "class A<T, U extends T> {",
-        "  f1(U u) {",
-        "    T t = u;",
-        "  }",
-        "  f2(T t) {",
-        "    U u = t;",
-        "  }",
-        "}",
-        "");
-    assertErrors(libraryResult.getErrors());
-  }
-
-  public void test_staticMemberAccessThroughInstance() throws Exception {
-    AnalyzeLibraryResult libraryResult = analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "class A {",
-        "  static var x;",
-        "  static y() {}",
-        "  static method() {",
-        "    var a = new A();",
-        "    a.x = 1;",
-        "    var foo = a.x;",
-        "    a.y();",
-        "    a.y = 1;",
-        "  }",
-        "}",
-        "");
-    assertErrors(libraryResult.getErrors(),
-        errEx(TypeErrorCode.STATIC_MEMBER_ACCESSED_THROUGH_INSTANCE, 7, 7, 1),
-        errEx(TypeErrorCode.STATIC_MEMBER_ACCESSED_THROUGH_INSTANCE, 8, 17, 1),
-        errEx(TypeErrorCode.IS_STATIC_METHOD_IN, 9, 7, 1),
-        errEx(TypeErrorCode.STATIC_MEMBER_ACCESSED_THROUGH_INSTANCE, 10, 7, 1),
-        errEx(TypeErrorCode.CANNOT_ASSIGN_TO, 10, 5, 3));
-  }
-
-  public void testExpectedPositionalArgument() throws Exception {
-    AnalyzeLibraryResult libraryResult = analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "method1(a, [b]) {}",
-        "method2() {",
-        "  method1(b:1);",
-        "}");
-    assertErrors(libraryResult.getErrors(),
-        errEx(TypeErrorCode.EXPECTED_POSITIONAL_ARGUMENT, 4, 11, 3));
-  }
-
-  public void test_cannotResolveMethod_unqualified() throws Exception {
-    AnalyzeLibraryResult libraryResult = analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "class A {",
-        "  f() {",
-        "    foo();",
-        "  }",
-        "}",
-        "");
-    assertErrors(
-        libraryResult.getErrors(),
-        errEx(TypeErrorCode.INTERFACE_HAS_NO_METHOD_NAMED, 4, 5, 3));
-  }
-
-  public void test_canNotResolveMethod_qualified() throws Exception {
-    AnalyzeLibraryResult libraryResult = analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "class A {",
-        "}",
-        "main() {",
-        "  A a = new A();",
-        "  a.foo();",
-        "}",
-        "");
-    assertErrors(
-        libraryResult.getErrors(),
-        errEx(TypeErrorCode.INTERFACE_HAS_NO_METHOD_NAMED, 6, 5, 3));
-  }
-
-  public void test_operatorLocation() throws Exception {
-    AnalyzeLibraryResult libraryResult = analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "class A {",
-        "}",
-        "main() {",
-        "  A a = new A();",
-        "  a + 0;",
-        "  -a;",
-        "  a--;",
-        "}",
-        "");
-    assertErrors(
-        libraryResult.getErrors(),
-        errEx(TypeErrorCode.INTERFACE_HAS_NO_METHOD_NAMED, 6, 5, 1),
-        errEx(TypeErrorCode.CANNOT_BE_RESOLVED, 7, 3, 1),
-        errEx(TypeErrorCode.CANNOT_BE_RESOLVED, 8, 4, 2));
-  }
-
-  /**
-   * It is a static warning if T does not denote a type available in the current lexical scope.
-   * <p>
-   * http://code.google.com/p/dart/issues/detail?id=2373
-   */
-  public void test_asType_unknown() throws Exception {
-    AnalyzeLibraryResult libraryResult = analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "main() {",
-        "  null as T;",
-        "}",
-        "");
-    assertErrors(
-        libraryResult.getErrors(),
-        errEx(TypeErrorCode.NO_SUCH_TYPE, 3, 11, 1));
-  }
-
-  /**
-   * It is a compile-time error if T is a parameterized type of the form G < T1; : : : ; Tn > and G
-   * is not a generic type with n type parameters.
-   * <p>
-   * http://code.google.com/p/dart/issues/detail?id=2373
-   */
-  public void test_asType_wrongNumberOfTypeArguments() throws Exception {
-    AnalyzeLibraryResult libraryResult = analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "class A {}",
-        "main() {",
-        "  null as A<int, bool>;",
-        "}",
-        "");
-    assertErrors(
-        libraryResult.getErrors(),
-        errEx(ResolverErrorCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS, 4, 11, 12));
-  }
-
-  /**
-   * It is a static warning if T does not denote a type available in the current lexical scope.
-   * <p>
-   * http://code.google.com/p/dart/issues/detail?id=2373
-   */
-  public void test_isType_unknown() throws Exception {
-    AnalyzeLibraryResult libraryResult = analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "main() {",
-        "  null is T;",
-        "}",
-        "");
-    assertErrors(
-        libraryResult.getErrors(),
-        errEx(TypeErrorCode.NO_SUCH_TYPE, 3, 11, 1));
-  }
-
-  public void test_incompatibleTypesInHierarchy1() throws Exception {
-    AnalyzeLibraryResult libraryResult = analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "abstract class Interface<T> {",
-        "  T m();",
-        "}",
-        "abstract class A implements Interface {",
-        "}",
-        "class C extends A implements Interface<int> {",
-        "  int m() => 0;",
-        "}");
-    assertErrors(
-        libraryResult.getErrors());
-  }
-
-  public void test_incompatibleTypesInHierarchy2() throws Exception {
-    AnalyzeLibraryResult libraryResult = analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "abstract class Interface<T> {",
-        "  T m();",
-        "}",
-        "abstract class A implements Interface<String> {",
-        "}",
-        "class C extends A implements Interface<int> {",
-        "  int m() => 0;",
-        "}");
-    assertErrors(
-        libraryResult.getErrors(),
-        errEx(TypeErrorCode.CANNOT_OVERRIDE_METHOD_NOT_SUBTYPE, 8, 7, 1),
-        errEx(TypeErrorCode.INCOMPATIBLE_TYPES_IN_HIERARCHY, 7, 7, 1));
-  }
-
-  public void test_variableUsedAsType() throws Exception {
-    AnalyzeLibraryResult libraryResult = analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "var func;",
-        "func i;");
-    assertErrors(
-        libraryResult.getErrors(),
-        errEx(TypeErrorCode.NOT_A_TYPE, 3, 1, 4));
-  }
-
-  public void test_metadataComment_deprecated_1() throws Exception {
-    AnalyzeLibraryResult libraryResult = analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "const deprecated = 0;",
-        "@deprecated",
-        "ttt() {}",
-        "@deprecated",
-        "get topLevelGet => 42;",
-        "class A {",
-        "  var @deprecated fff;",
-        "  @deprecated",
-        "  mmmm() {}",
-        "  @deprecated",
-        "  operator + (other) {}",
-        "}",
-        "method() {",
-        "  ttt();",
-        "  print(topLevelGet);",
-        "  A a = new A();",
-        "  a.fff = 0;",
-        "  a.mmmm();",
-        "  a + 0;",
-        "}",
-        "");
-    assertErrors(
-        libraryResult.getErrors(),
-        errEx(TypeErrorCode.DEPRECATED_ELEMENT, 16, 9, 11),
-        errEx(TypeErrorCode.DEPRECATED_ELEMENT, 15, 3, 3),
-        errEx(TypeErrorCode.DEPRECATED_ELEMENT, 18, 5, 3),
-        errEx(TypeErrorCode.DEPRECATED_ELEMENT, 19, 5, 4),
-        errEx(TypeErrorCode.DEPRECATED_ELEMENT, 20, 5, 1));
-  }
-
-  public void test_metadataComment_deprecated_2() throws Exception {
-    AnalyzeLibraryResult libraryResult = analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "const deprecated = 0;",
-        "@deprecated",
-        "class A {",
-        "  A.named() {}",
-        "  @deprecated",
-        "  A.depreca() {}",
-        "}",
-        "method() {",
-        "  new A.named();",
-        "  new A.depreca();",
-        "}",
-        "");
-    assertErrors(
-        libraryResult.getErrors(),
-        errEx(TypeErrorCode.DEPRECATED_ELEMENT, 10, 7, 1),
-        errEx(TypeErrorCode.DEPRECATED_ELEMENT, 11, 7, 1),
-        errEx(TypeErrorCode.DEPRECATED_ELEMENT, 11, 9, 7));
-  }
-
-  public void test_metadata_resolving() throws Exception {
-    AnalyzeLibraryResult libraryResult = analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "const test = 0;",
-        "",
-        "@test",
-        "class A {",
-        "  @test",
-        "  m(@test p) {",
-        "    @test var v = 0;",
-        "  }",
-        "}",
-        "",
-        "f(@test p) {}",
-        "",
-        "@test typedef F();",
-        "",
-        "");
-    // @deprecated should be resolved at every place, so no errors
-    assertErrors(libraryResult.getErrors());
-  }
-
-  public void test_assignMethod() throws Exception {
-    AnalyzeLibraryResult libraryResult = analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "class C {",
-        "  method() { }",
-        "}",
-        "main () {",
-        "  new C().method = f;",
-        "}",
-        "f() {}",
-        "");
-    assertErrors(libraryResult.getErrors(), errEx(TypeErrorCode.CANNOT_ASSIGN_TO, 6, 3, 14));
-  }
-
-  public void test_assignSetter() throws Exception {
-    AnalyzeLibraryResult libraryResult = analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "class C {",
-        "  set method(arg) { }",
-        "}",
-        "main () {",
-        "  new C().method = f;",
-        "}",
-        "f() {}",
-        "");
-    assertErrors(libraryResult.getErrors());
-  }
-
-  public void test_assignGetter() throws Exception {
-    AnalyzeLibraryResult libraryResult = analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "class C {",
-        "  get method { }",
-        "}",
-        "main () {",
-        "  new C().method = f;",
-        "}",
-        "f() {}",
-        "");
-    assertErrors(libraryResult.getErrors(), errEx(TypeErrorCode.FIELD_HAS_NO_SETTER, 6, 11, 6));
-  }
-
-  /**
-   * Test for "operator []=".
-   * <p>
-   * http://code.google.com/p/dart/issues/detail?id=4881
-   */
-  public void test_assignArrayElement() throws Exception {
-    AnalyzeLibraryResult libraryResult = analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "class C {" +
-        "  get method { }",
-        "  operator []=(k, v) {}",
-        "}",
-        "main () {",
-        "  new C()[0] = 1;",
-        "}");
-    assertErrors(
-        libraryResult.getErrors());
-  }
-
-  /**
-   * Test for resolving variants of array access and unary/binary expressions.
-   * <p>
-   * http://code.google.com/p/dart/issues/detail?id=5042
-   */
-  public void test_opAssignArrayElement() throws Exception {
-    AnalyzeLibraryResult libraryResult = analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "class A {",
-        "  B operator [](k) => new B();",
-        "    operator []=(k, v) { }",
-        "}",
-        "class B {",
-        "  B operator +(x) => new B();",
-        "}",
-        "main () {",
-        "  var a = new A();",
-        "  process( a[2] );",
-        "  a[0]++;",
-        "  ++a[0];",
-        "  a[0] += 1;",
-        "  a[0] = 1;",
-        "}",
-        "process(x) {}",
-        "");
-    assertErrors(libraryResult.getErrors());
-    // print( a[2] )
-    {
-      DartArrayAccess access = findNode(DartArrayAccess.class, "a[2]");
-      // a[2] is invocation of method "[]"
-      assertHasMethodElement(access, "A", "[]");
-    }
-    // a[0]++
-    {
-      DartUnaryExpression unary = findNode(DartUnaryExpression.class, "a[0]++");
-      // a[0]++ is invocation of method "+"
-      assertHasMethodElement(unary, "B", "+");
-      // a[0] is invocation of method []
-      assertHasMethodElement(unary.getArg(), "A", "[]");
-    }
-    // ++a[0]
-    {
-      DartUnaryExpression unary = findNode(DartUnaryExpression.class, "++a[0]");
-      // ++a[0] is invocation of method "+"
-      assertHasMethodElement(unary, "B", "+");
-      // a[0] is invocation of method []
-      assertHasMethodElement(unary.getArg(), "A", "[]");
-    }
-    // a[0] += 1
-    {
-      DartBinaryExpression binary = findNode(DartBinaryExpression.class, "a[0] += 1");
-      // a[0] += 1 is invocation of method "+"
-      assertHasMethodElement(binary, "B", "+");
-      // a[0] is invocation of method []
-      assertHasMethodElement(binary.getArg1(), "A", "[]");
-    }
-    // a[0] = 1
-    {
-      DartBinaryExpression binary = findNode(DartBinaryExpression.class, "a[0] = 1");
-      // a[0] = 1 is invocation of method "[]="
-      assertHasMethodElement(binary, "A", "[]=");
-      // a[0] is invocation of method []=
-      assertHasMethodElement(binary.getArg1(), "A", "[]=");
-    }
-  }
-
-  /**
-   * Test for resolving variants of property access and unary/binary expressions.
-   * <p>
-   * http://code.google.com/p/dart/issues/detail?id=5049
-   */
-  public void test_opAssignPropertyAccess_instance() throws Exception {
-    AnalyzeLibraryResult libraryResult = analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "class A {",
-        "  B get b => new B();",
-        "    set b(B x) {}",
-        "}",
-        "class B {",
-        "  B operator +(x) => new B();",
-        "}",
-        "main () {",
-        "  A a = new A();",
-        "  process( a.b );",
-        "  a.b++;",
-        "  ++a.b;",
-        "  a.b += 1;",
-        "  a.b = null;",
-        "}",
-        "process(x) {}",
-        "");
-    assertErrors(libraryResult.getErrors());
-    // print( a.b )
-    {
-      DartPropertyAccess access = findNode(DartPropertyAccess.class, "a.b");
-      // a.b is field "A.b"
-      assertHasFieldElement(access, "A", "b");
-    }
-    // a.b++
-    {
-      DartUnaryExpression unary = findNode(DartUnaryExpression.class, "a.b++");
-      // a.b++ is invocation of method "+"
-      assertHasMethodElement(unary, "B", "+");
-      // a.b is field "A.b"
-      assertHasFieldElement(unary.getArg(), "A", "b");
-    }
-    // ++a.b
-    {
-      DartUnaryExpression unary = findNode(DartUnaryExpression.class, "++a.b");
-      // ++a.b is invocation of method "+"
-      assertHasMethodElement(unary, "B", "+");
-      // a.b is field "A.b"
-      assertHasFieldElement(unary.getArg(), "A", "b");
-    }
-    // a.b += 1
-    {
-      DartBinaryExpression binary = findNode(DartBinaryExpression.class, "a.b += 1");
-      // a.b += 1 is invocation of method "+"
-      assertHasMethodElement(binary, "B", "+");
-      // a.b is field "A.b"
-      assertHasFieldElement(binary.getArg1(), "A", "b");
-    }
-    // a.b = null
-    {
-      DartBinaryExpression binary = findNode(DartBinaryExpression.class, "a.b = null");
-      // a.b = null has no Element
-      assertSame(null, binary.getElement());
-      // a.b is field "A.b"
-      assertHasFieldElement(binary.getArg1(), "A", "b");
-    }
-  }
-
-  /**
-   * Test for resolving variants of static property access and unary/binary expressions.
-   * <p>
-   * http://code.google.com/p/dart/issues/detail?id=5049
-   */
-  public void test_opAssignPropertyAccess_static() throws Exception {
-    AnalyzeLibraryResult libraryResult = analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "class A {",
-        "  static B get b => new B();",
-        "  static   set b(B x) {}",
-        "}",
-        "class B {",
-        "  B operator +(x) => new B();",
-        "}",
-        "main () {",
-        "  process( A.b );",
-        "  A.b++;",
-        "  ++A.b;",
-        "  A.b += 1;",
-        "  A.b = null;",
-        "}",
-        "process(x) {}",
-        "");
-    assertErrors(libraryResult.getErrors());
-    // print( A.b )
-    {
-      DartPropertyAccess access = findNode(DartPropertyAccess.class, "A.b");
-      // A.b is field "A.b"
-      assertHasFieldElement(access, "A", "b");
-    }
-    // A.b++
-    {
-      DartUnaryExpression unary = findNode(DartUnaryExpression.class, "A.b++");
-      // A.b++ is invocation of method "+"
-      assertHasMethodElement(unary, "B", "+");
-      // A.b is field "A.b"
-      assertHasFieldElement(unary.getArg(), "A", "b");
-    }
-    // ++A.b
-    {
-      DartUnaryExpression unary = findNode(DartUnaryExpression.class, "++A.b");
-      // ++A.b is invocation of method "+"
-      assertHasMethodElement(unary, "B", "+");
-      // A.b is field "A.b"
-      assertHasFieldElement(unary.getArg(), "A", "b");
-    }
-    // A.b += 1
-    {
-      DartBinaryExpression binary = findNode(DartBinaryExpression.class, "A.b += 1");
-      // A.b += 1 is invocation of method "+"
-      assertHasMethodElement(binary, "B", "+");
-      // A.b is field "A.b"
-      assertHasFieldElement(binary.getArg1(), "A", "b");
-    }
-    // A.b = null
-    {
-      DartBinaryExpression binary = findNode(DartBinaryExpression.class, "A.b = null");
-      // A.b = null has no Element
-      assertSame(null, binary.getElement());
-      // A.b is field "A.b"
-      assertHasFieldElement(binary.getArg1(), "A", "b");
-    }
-  }
-
-  /**
-   * Test for resolving variants of top-level property access and unary/binary expressions.
-   * <p>
-   * http://code.google.com/p/dart/issues/detail?id=5049
-   */
-  public void test_opAssignPropertyAccess_topLevel() throws Exception {
-    AnalyzeLibraryResult libraryResult = analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "B get field => new B();",
-        "  set field(B x) {}",
-        "class B {",
-        "  B operator +(x) => new B();",
-        "}",
-        "main () {",
-        "  process( field );",
-        "  field++;",
-        "  ++field;",
-        "  field += 1;",
-        "  field = null;",
-        "}",
-        "process(x) {}",
-        "");
-    assertErrors(libraryResult.getErrors());
-    // print( field )
-    {
-      DartIdentifier access = findNode(DartIdentifier.class, "field );");
-      // "field" is top-level field
-      assertHasFieldElement(access, "<library>", "field");
-    }
-    // field++
-    {
-      DartUnaryExpression unary = findNode(DartUnaryExpression.class, "field++");
-      // field++ is invocation of method "+"
-      assertHasMethodElement(unary, "B", "+");
-      // "field" is top-level field
-      assertHasFieldElement(unary.getArg(), "<library>", "field");
-    }
-    // ++field
-    {
-      DartUnaryExpression unary = findNode(DartUnaryExpression.class, "++field");
-      // ++field is invocation of method "+"
-      assertHasMethodElement(unary, "B", "+");
-      // "field" is top-level field
-      assertHasFieldElement(unary.getArg(), "<library>", "field");
-    }
-    // field += 1
-    {
-      DartBinaryExpression binary = findNode(DartBinaryExpression.class, "field += 1");
-      // field += 1 is invocation of method "+"
-      assertHasMethodElement(binary, "B", "+");
-      // "field" is top-level field
-      assertHasFieldElement(binary.getArg1(), "<library>", "field");
-    }
-    // field = null
-    {
-      DartBinaryExpression binary = findNode(DartBinaryExpression.class, "field = null");
-      // field = null is no Element
-      assertSame(null, binary.getElement());
-      // "field" is top-level field
-      assertHasFieldElement(binary.getArg1(), "<library>", "field");
-    }
-  }
-
-  private static void assertHasFieldElement(DartNode node, String className, String fieldName) {
-    Element element = node.getElement();
-    assertTrue("" + node + " " + element, element instanceof FieldElement);
-    FieldElement fieldElement = (FieldElement) element;
-    assertHasFieldElement(fieldElement, className, fieldName);
-  }
-
-  private static void assertHasFieldElement(FieldElement element, String className, String fieldName) {
-    EnclosingElement enclosingElement = element.getEnclosingElement();
-    String enclosingName;
-    if (enclosingElement instanceof LibraryElement) {
-      enclosingName = "<library>";
-    } else {
-      enclosingName = enclosingElement.getName();
-    }
-    assertEquals(className, enclosingName);
-    //
-    String elementName = element.getName();
-    assertEquals(fieldName, elementName);
-  }
-
-  private static void assertHasMethodElement(DartNode node, String className, String methodName) {
-    Element element = node.getElement();
-    assertTrue("" + node + " " + element, element instanceof MethodElement);
-    MethodElement methodElement = (MethodElement) element;
-    assertMethodElement(methodElement, className, methodName);
-  }
-
-  private static void assertMethodElement(MethodElement element, String className, String methodName) {
-    EnclosingElement enclosingElement = element.getEnclosingElement();
-    String enclosingName;
-    if (enclosingElement instanceof LibraryElement) {
-      enclosingName = "<library>";
-    } else {
-      enclosingName = enclosingElement.getName();
-    }
-    assertEquals(className, enclosingName);
-    //
-    String elementName = element.getName();
-    if (element.getModifiers().isGetter()) {
-      elementName = "get " + elementName;
-    }
-    if (element.getModifiers().isSetter()) {
-      elementName = "set " + elementName;
-    }
-    assertEquals(methodName, elementName);
-  }
-
-  public void test_invokeStaticFieldAsMethod() throws Exception {
-    AnalyzeLibraryResult libraryResult = analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "class C {",
-        "  static foo() { }",
-        "}",
-        "main () {",
-        "  var a = new C().foo();",
-        "}");
-    assertErrors(
-        libraryResult.getErrors(),
-        errEx(TypeErrorCode.IS_STATIC_METHOD_IN, 6, 19, 3));
-  }
-
-  public void test_invokeNonFunction() throws Exception {
-    AnalyzeLibraryResult libraryResult = analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "class C {",
-        "  String foo;",
-        "  method() {",
-        "    foo();",
-        "  }",
-        "}",
-        "method() {",
-        "  String foo;",
-        "  foo();",
-        "  (1 + 5)();",
-        "}");
-    assertErrors(
-        libraryResult.getErrors(),
-        errEx(TypeErrorCode.NOT_A_METHOD_IN, 5, 5, 3),
-        errEx(TypeErrorCode.NOT_A_FUNCTION_TYPE, 10, 3, 3),
-        errEx(TypeErrorCode.NOT_A_FUNCTION_TYPE, 11, 3, 9));
-  }
-
-  /**
-   * <p>
-   * http://code.google.com/p/dart/issues/detail?id=3223
-   */
-  public void test_invokeNonFunction_inferred() throws Exception {
-    AnalyzeLibraryResult libraryResult = analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "method() {",
-        "  var v = 1;",
-        "  v();",
-        "}");
-    assertErrors(libraryResult.getErrors());
-  }
-
-  public void test_invokeNonFunction_getter() throws Exception {
-    AnalyzeLibraryResult libraryResult = analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "class A {",
-        "  int get foo => 0;",
-        "}",
-        "main() {",
-        "  A a = new A();",
-        "  a.foo();",
-        "}");
-    assertErrors(
-        libraryResult.getErrors(),
-        errEx(TypeErrorCode.NOT_A_FUNCTION_TYPE_FIELD, 7, 5, 3));
-  }
-
-  public void test_wrongOperandTypeForUnaryExpression() throws Exception {
-    AnalyzeLibraryResult libraryResult = analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "class C {",
-        "  operator -(String arg) {}",
-        "  operator +(String arg) {}",
-        "}",
-        "method1(arg) {}",
-        "method2() {",
-        "  C foo = new C();",
-        "  method1(++foo);",
-        "  method1(--foo);",
-        "}");
-    assertErrors(
-        libraryResult.getErrors(),
-        errEx(TypeErrorCode.OPERATOR_WRONG_OPERAND_TYPE, 9, 11, 5),
-        errEx(TypeErrorCode.OPERATOR_WRONG_OPERAND_TYPE, 10, 11, 5));
-  }
-
-  /**
-   * Missing value in {@link DartMapLiteralEntry} is parsing error, but should not cause exception.
-   * <p>
-   * http://code.google.com/p/dart/issues/detail?id=3931
-   */
-  public void test_mapLiteralEntry_noValue() throws Exception {
-    AnalyzeLibraryResult libraryResult = analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "main() {",
-        "  var v = {'key' : /*no value*/};",
-        "}",
-        "");
-    // has some errors
-    assertTrue(libraryResult.getErrors().size() != 0);
-  }
-
-  public void test_fieldOverrideWrongType() throws Exception {
-    AnalyzeLibraryResult libraryResult = analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "class A {",
-        "  int foo;",
-        "}",
-        "class B extends A {",
-        "  String foo;",
-        "}");
-    assertErrors(
-        libraryResult.getErrors(),
-        errEx(TypeErrorCode.CANNOT_OVERRIDE_TYPED_MEMBER, 6, 10, 3));
-  }
-
-  public void test_overrideInstanceMember() throws Exception {
-    AnalyzeLibraryResult libraryResult = analyzeLibrary(
-        "class A {",
-        "  var field;",
-        "  method() {}",
-        "}",
-        "class B extends A {",
-        "  static var field;",
-        "  static method() {}",
-        "}");
-    assertErrors(
-        libraryResult.getErrors(),
-        errEx(ResolverErrorCode.CANNOT_OVERRIDE_INSTANCE_MEMBER, 6, 14, 5),
-        errEx(ResolverErrorCode.CANNOT_OVERRIDE_INSTANCE_MEMBER, 7, 10, 6));
-  }
-
-  public void test_overrideStaticMember() throws Exception {
-    AnalyzeLibraryResult libraryResult = analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "class A {",
-        "  static var foo;",
-        "  static bar() {}",
-        "}",
-        "class B extends A {",
-        "  var foo;",
-        "  bar() {}",
-        "}");
-    assertErrors(
-        libraryResult.getErrors(),
-        errEx(TypeErrorCode.OVERRIDING_STATIC_MEMBER, 7, 7, 3),
-        errEx(TypeErrorCode.OVERRIDING_STATIC_MEMBER, 8, 3, 3));
-  }
-
-  public void test_rethrowNotInCatch() throws Exception {
-    AnalyzeLibraryResult libraryResult = analyzeLibrary(
-        "class Object {}",
-        "method() {",
-        "  throw;",
-        "}");
-    assertErrors(
-        libraryResult.getErrors(),
-        errEx(ResolverErrorCode.RETHROW_NOT_IN_CATCH, 3, 3, 5));
-  }
-
-  public void test_externalKeyword_OK() throws Exception {
-    AnalyzeLibraryResult libraryResult = analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "external topFunction();",
-        "external get topGetter;",
-        "external set topSetter(var v);",
-        "class A {",
-        "  external const A.con();",
-        "  external A();",
-        "  external factory A.named();",
-        "  external classMethod();",
-        "  external static classMethodStatic();",
-        "  external get classGetter;",
-        "  external set classSetter(var v);",
-        "}",
-        "");
-    assertErrors(libraryResult.getErrors());
-    // all method-like nodes here are "external"
-    final AtomicInteger methodCounter = new AtomicInteger();
-    testUnit.accept(new ASTVisitor<Void>() {
-      @Override
-      public Void visitMethodDefinition(DartMethodDefinition node) {
-        methodCounter.incrementAndGet();
-        assertTrue(node.getModifiers().isExternal());
-        return null;
-      }
-    });
-    assertEquals(10, methodCounter.get());
-  }
-
-  /**
-   * Modifier "external" can be applied only to method-like elements.
-   */
-  public void test_externalKeyword_bad_field() throws Exception {
-    AnalyzeLibraryResult libraryResult = analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "external var topVar1;",
-        "external int topVar2;",
-        "class A {",
-        "  external var field1;",
-        "  external int field2;",
-        "}",
-        "");
-    assertErrors(
-        libraryResult.getErrors(),
-        errEx(ParserErrorCode.EXTERNAL_ONLY_METHOD, 2, 14, 7),
-        errEx(ParserErrorCode.EXTERNAL_ONLY_METHOD, 3, 14, 7),
-        errEx(ParserErrorCode.EXTERNAL_ONLY_METHOD, 5, 16, 6),
-        errEx(ParserErrorCode.EXTERNAL_ONLY_METHOD, 6, 16, 6));
-  }
-
-  /**
-   * Methods with "external" cannot have body.
-   */
-  public void test_externalKeyword_bad_body() throws Exception {
-    AnalyzeLibraryResult libraryResult = analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "external topFunction() {}",
-        "abstract class A {",
-        "  external A() {}",
-        "  external factory A.named() {}",
-        "  external classMethod() {}",
-        "}",
-        "");
-    assertErrors(
-        libraryResult.getErrors(),
-        errEx(ParserErrorCode.EXTERNAL_METHOD_BODY, 2, 24, 2),
-        errEx(ParserErrorCode.EXTERNAL_METHOD_BODY, 4, 16, 2),
-        errEx(ParserErrorCode.EXTERNAL_METHOD_BODY, 5, 30, 2),
-        errEx(ParserErrorCode.EXTERNAL_METHOD_BODY, 6, 26, 2));
-  }
-
-  public void test_cascade_type() throws Exception {
-    analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "main() {",
-        "  String s = '';",
-        "  var v = s..length;",
-        "}",
-        "");
-    assertInferredElementTypeString(testUnit, "v", "String", INFERRED);
-  }
-
-  /**
-   * There should be no problem reported, because assignment of "a" cascade to "b" with type "B"
-   * implicitly set type of "a" to "B".
-   * <p>
-   * http://code.google.com/p/dart/issues/detail?id=6107
-   */
-  public void test_cascade_inferType_varDeclaration() throws Exception {
-    AnalyzeLibraryResult result = analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "class A {}",
-        "class B extends A {",
-        "  bMethod() {}",
-        "}",
-        "main() {",
-        "  A a = new B();",
-        "  B b = a..bMethod();",
-        "}",
-        "");
-    assertErrors(result.getErrors());
-  }
-
-  /**
-   * There should be no problem reported, because assignment of "a" cascade to "b" with type "B"
-   * implicitly set type of "a" to "B".
-   * <p>
-   * http://code.google.com/p/dart/issues/detail?id=6107
-   */
-  public void test_cascade_inferType_varAssignment() throws Exception {
-    AnalyzeLibraryResult result = analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "class A {}",
-        "class B extends A {",
-        "  bMethod() {}",
-        "}",
-        "main() {",
-        "  A a = new B();",
-        "  B b = null;",
-        "  b = a..bMethod();",
-        "}",
-        "");
-    assertErrors(result.getErrors());
-  }
-
-  /**
-   * We assign "a" to field "Holder.b" of type "B", so implicitly set type of "a" to "B".
-   * <p>
-   * http://code.google.com/p/dart/issues/detail?id=6107
-   */
-  public void test_cascade_inferType_fieldDeclaration() throws Exception {
-    AnalyzeLibraryResult result = analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "class Holder {",
-        "  B b = getA()..bMethod();",
-        "}",
-        "class A {}",
-        "class B extends A {",
-        "  bMethod() {}",
-        "}",
-        "A getA() => new B();",
-        "");
-    assertErrors(result.getErrors());
-  }
-
-  /**
-   * We assign "a" to field "Holder.b" of type "B", so implicitly set type of "a" to "B".
-   * <p>
-   * http://code.google.com/p/dart/issues/detail?id=6107
-   */
-  public void test_cascade_inferType_fieldAssignment() throws Exception {
-    AnalyzeLibraryResult result = analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "class Holder {",
-        "  B b;",
-        "}",
-        "class A {}",
-        "class B extends A {",
-        "  bMethod() {}",
-        "}",
-        "main() {",
-        "  A a = new B();",
-        "  Holder holder = new Holder();",
-        "  holder.b = a..bMethod();",
-        "}",
-        "");
-    assertErrors(result.getErrors());
-  }
-
-  /**
-   * <p>
-   * http://code.google.com/p/dart/issues/detail?id=4315
-   */
-  public void test_cascade_propertyAccess() throws Exception {
-    AnalyzeLibraryResult libraryResult = analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "class A {",
-        "  int f;",
-        "}",
-        "main() {",
-        "  A a = new A();",
-        "  a",
-        "    ..f = 1",
-        "    ..f = 2;",
-        "}",
-        "");
-    assertErrors(libraryResult.getErrors());
-    {
-      DartPropertyAccess access = findNode(DartPropertyAccess.class, "..f = 1");
-      assertNotNull(access.getElement());
-    }
-    {
-      DartPropertyAccess access = findNode(DartPropertyAccess.class, "..f = 2");
-      assertNotNull(access.getElement());
-    }
-  }
-
-  /**
-   * <p>
-   * http://code.google.com/p/dart/issues/detail?id=4315
-   */
-  public void test_cascade_methodInvocation() throws Exception {
-    AnalyzeLibraryResult libraryResult = analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "class A {",
-        "  int m(p) {}",
-        "}",
-        "main() {",
-        "  A a = new A();",
-        "  a",
-        "    ..m(1)",
-        "    ..m(2);",
-        "}",
-        "");
-    assertErrors(libraryResult.getErrors());
-    {
-      DartMethodInvocation invocation = findNode(DartMethodInvocation.class, "..m(1)");
-      assertNotNull(invocation.getElement());
-    }
-    {
-      DartMethodInvocation invocation = findNode(DartMethodInvocation.class, "..m(2)");
-      assertNotNull(invocation.getElement());
-    }
-  }
-
-  /**
-   * Test that we already support cascaded calls in initializers. No implementation was changed.
-   * <p>
-   * http://code.google.com/p/dart/issues/detail?id=6955
-   */
-  public void test_cascade_inInitializer() throws Exception {
-    AnalyzeLibraryResult libraryResult = analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "class A {",
-        "  var f;",
-        "  A() : f = ''..length;",
-        "}",
-        "");
-    assertErrors(libraryResult.getErrors());
-  }
-
-  /**
-   * Source is invalid, but should not cause {@link NullPointerException}.
-   * <p>
-   * http://code.google.com/p/dart/issues/detail?id=4354
-   */
-  public void test_switchCase_withoutExpression() throws Exception {
-    AnalyzeLibraryResult libraryResult = analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "main() {",
-        "  switch (0) {",
-        "    case }",
-        "  }",
-        "}",
-        "");
-    // has some errors, no exception
-    assertTrue(libraryResult.getErrors().size() != 0);
-  }
-
-  /**
-   * <p>
-   * http://code.google.com/p/dart/issues/detail?id=6836
-   */
-  public void test_unresolvedIdentifier_inStatic_notPropertyAccess() throws Exception {
-    AnalyzeLibraryResult libraryResult = analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "process(x) {}",
-        "",
-        "class A {",
-        "  static foo() {",
-        "    unknown = 0;",
-        "  }",
-        "}",
-        "",
-        "main() {",
-        "  unknown = 0;",
-        "  process(unknown);",
-        "}");
-    assertErrors(
-        libraryResult.getErrors(),
-        errEx(TypeErrorCode.CANNOT_BE_RESOLVED, 6, 5, 7),
-        errEx(TypeErrorCode.CANNOT_BE_RESOLVED, 11, 3, 7),
-        errEx(TypeErrorCode.CANNOT_BE_RESOLVED, 12, 11, 7));
-  }
-
-  /**
-   * If "unknown" is separate identifier, it is handled as "this.unknown", but "this" is not
-   * accessible in static context.
-   * <p>
-   * http://code.google.com/p/dart/issues/detail?id=3084
-   */
-  public void test_unresolvedIdentifier_inInstance_notPropertyAccess() throws Exception {
-    AnalyzeLibraryResult libraryResult = analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "process(x) {}",
-        "class A {",
-        "  foo() {",
-        "    unknown = 0;",
-        "    process(unknown);",
-        "  }",
-        "}");
-    assertErrors(
-        libraryResult.getErrors(),
-        errEx(TypeErrorCode.CANNOT_BE_RESOLVED, 5, 5, 7),
-        errEx(TypeErrorCode.CANNOT_BE_RESOLVED, 6, 13, 7));
-  }
-
-  /**
-   * <p>
-   * http://code.google.com/p/dart/issues/detail?id=3084
-   */
-  public void test_unresolvedIdentifier_inStatic_inPropertyAccess() throws Exception {
-    AnalyzeLibraryResult libraryResult = analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "process(x) {}",
-        "main() {",
-        "  Unknown.foo = 0;",
-        "  process(Unknown.foo);",
-        "}");
-    assertErrors(
-        libraryResult.getErrors(),
-        errEx(TypeErrorCode.CANNOT_BE_RESOLVED, 4, 3, 7),
-        errEx(TypeErrorCode.CANNOT_BE_RESOLVED, 5, 11, 7));
-  }
-
-  /**
-   * Unresolved constructor is warning.
-   * <p>
-   * http://code.google.com/p/dart/issues/detail?id=3800
-   */
-  public void test_unresolvedConstructor() throws Exception {
-    AnalyzeLibraryResult libraryResult = analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "class A {}",
-        "main() {",
-        "  new A(); // OK",
-        "  new A.noSuchConstructor(); // warning",
-        "  new B(); // warning",
-        "  new B.noSuchConstructor(); // warning",
-        "}");
-    assertErrors(
-        libraryResult.getErrors(),
-        errEx(TypeErrorCode.NEW_EXPRESSION_NOT_CONSTRUCTOR, 5, 9, 17),
-        errEx(TypeErrorCode.NO_SUCH_TYPE, 6, 7, 1),
-        errEx(TypeErrorCode.NO_SUCH_TYPE, 7, 7, 1),
-        errEx(TypeErrorCode.NEW_EXPRESSION_NOT_CONSTRUCTOR, 7, 9, 17));
-  }
-
-  /**
-   * <p>
-   * http://code.google.com/p/dart/issues/detail?id=4383
-   */
-  public void test_callFieldWithoutGetter_topLevel() throws Exception {
-    AnalyzeLibraryResult libraryResult = analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "set setOnlyField(v) {}",
-        "main() {",
-        "  setOnlyField(0);",
-        "}");
-    assertErrors(
-        libraryResult.getErrors(),
-        errEx(ResolverErrorCode.USE_ASSIGNMENT_ON_SETTER, 4, 3, 12));
-  }
-
-  /**
-   * Every {@link DartExpression} should have {@link Type} set. Just to don't guess this type at
-   * many other points in the Editor.
-   */
-  public void test_typeForEveryExpression_variable() throws Exception {
-    analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "class A {}",
-        "process(x) {}",
-        "main() {",
-        "  A aaa = new A();",
-        "  process(aaa);",
-        "}");
-    testUnit.accept(new ASTVisitor<Void>() {
-      @Override
-      public Void visitIdentifier(DartIdentifier node) {
-        // ignore declaration
-        if (node.getParent() instanceof DartDeclaration) {
-          return null;
-        }
-        // check "aaa"
-        if (node.toString().equals("aaa")) {
-          Type type = node.getType();
-          assertNotNull(type);
-          assertEquals("A", type.toString());
-        }
-        return null;
-      }
-    });
-  }
-
-  /**
-   * Every {@link DartExpression} should have {@link Type} set. Just to don't guess this type at
-   * many other points in the Editor.
-   */
-  public void test_typeForEveryExpression_typeNode() throws Exception {
-    analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "class AAA {",
-        "  static foo() {}",
-        "}",
-        "main() {",
-        "  AAA.foo();",
-        "}");
-    testUnit.accept(new ASTVisitor<Void>() {
-      @Override
-      public Void visitIdentifier(DartIdentifier node) {
-        // ignore declaration
-        if (node.getParent() instanceof DartDeclaration) {
-          return null;
-        }
-        // check "AAA"
-        if (node.toString().equals("AAA")) {
-          Type type = node.getType();
-          assertNotNull(type);
-          assertEquals("AAA", type.toString());
-        }
-        return null;
-      }
-    });
-  }
-
-  /**
-   * <p>
-   * http://code.google.com/p/dart/issues/detail?id=4383
-   */
-  public void test_callFieldWithoutGetter_member() throws Exception {
-    AnalyzeLibraryResult libraryResult = analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "class A {",
-        "  set setOnlyField(v) {}",
-        "  foo() {",
-        "    setOnlyField(0);",
-        "  }",
-        "}",
-        "main() {",
-        "  A a = new A();",
-        "  a.setOnlyField(0);",
-        "}");
-    assertErrors(
-        libraryResult.getErrors(),
-        errEx(TypeErrorCode.USE_ASSIGNMENT_ON_SETTER, 5, 5, 12),
-        errEx(TypeErrorCode.USE_ASSIGNMENT_ON_SETTER, 10, 5, 12));
-  }
-
-  private abstract static class ArgumentsBindingTester {
-    static List<DartExpression> arguments;
-    void doTest(DartUnit unit) {
-      unit.accept(new ASTVisitor<Void>() {
-        int invocationIndex = 0;
-        @Override
-        public Void visitUnqualifiedInvocation(DartUnqualifiedInvocation node) {
-          arguments = node.getArguments();
-          checkArgs(invocationIndex++);
-          return super.visitUnqualifiedInvocation(node);
-        }
-      });
-    }
-    abstract void checkArgs(int invocationIndex);
-    void assertId(int index, String expectedParameterName) {
-      DartExpression argument = arguments.get(index);
-      String idString = argument.getInvocationParameterId().toString();
-      assertEquals("PARAMETER " + expectedParameterName, idString);
-    }
-  }
-
-  public void test_formalParameters_positional_optional() throws Exception {
-    AnalyzeLibraryResult libraryResult = analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "method(var a, var b, [var c = 3, var d = 4]) {}",
-        "main() {",
-        "  method(10, 20);",
-        "  method(10, 20, 30);",
-        "  method(10, 20, 30, 40);",
-        "}");
-    assertErrors(libraryResult.getErrors());
-    new ArgumentsBindingTester() {
-      @Override
-      void checkArgs(int invocationIndex) {
-        switch (invocationIndex) {
-          case 0: {
-            assertId(0, "a");
-            assertId(1, "b");
-            break;
-          }
-          case 1: {
-            assertId(0, "a");
-            assertId(1, "b");
-            assertId(2, "c");
-            break;
-          }
-          case 3: {
-            assertId(0, "a");
-            assertId(1, "b");
-            assertId(2, "c");
-            assertId(3, "d");
-            break;
-          }
-        }
-      }
-    }.doTest(testUnit);
-  }
-
-  public void test_formalParameters_positional_named() throws Exception {
-    AnalyzeLibraryResult libraryResult = analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "method(var a, var b, {var c : 3, var d : 4}) {}",
-        "main() {",
-        "  method(10, 20);",
-        "  method(10, 20, c: 30);",
-        "  method(10, 20, d: 40);",
-        "  method(10, 20, d: 40, c: 30);",
-        "}");
-    assertErrors(libraryResult.getErrors());
-    new ArgumentsBindingTester() {
-      @Override
-      void checkArgs(int invocationIndex) {
-        switch (invocationIndex) {
-          case 0: {
-            assertId(0, "a");
-            assertId(1, "b");
-            break;
-          }
-          case 1: {
-            assertId(0, "a");
-            assertId(1, "b");
-            assertId(2, "c");
-            break;
-          }
-          case 2: {
-            assertId(0, "a");
-            assertId(1, "b");
-            assertId(2, "d");
-            break;
-          }
-          case 3: {
-            assertId(0, "a");
-            assertId(1, "b");
-            assertId(2, "d");
-            assertId(3, "c");
-            break;
-          }
-        }
-      }
-    }.doTest(testUnit);
-  }
-
-  /**
-   * A constructor name always begins with the name of its immediately enclosing class, and may
-   * optionally be followed by a dot and an identifier id. It is a compile-time error if id is the
-   * name of a member declared in the immediately enclosing class.
-   * <p>
-   * http://code.google.com/p/dart/issues/detail?id=3989
-   */
-  public void test_constructorName_sameAsMemberName() throws Exception {
-    AnalyzeLibraryResult libraryResult = analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "class A {",
-        "  A.foo() {}",
-        "  foo() {}",
-        "}");
-    assertErrors(
-        libraryResult.getErrors(),
-        errEx(ResolverErrorCode.CONSTRUCTOR_WITH_NAME_OF_MEMBER, 3, 3, 5));
-  }
-
-  /**
-   * It is a compile-time error if M is not the name of the immediately enclosing class.
-   * It is a static warning if M.id is not a constructor name.
-   */
-  public void test_constructorName_factory_notEnclosingClassName() throws Exception {
-    AnalyzeLibraryResult libraryResult = analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "class A {}",
-        "class B {",
-        "  factory A() {}",
-        "  factory A.name() {}",
-        "  factory B() {}",
-        "  factory B.name() {}",
-        "}");
-    assertErrors(
-        libraryResult.getErrors(),
-        errEx(ResolverErrorCode.CONSTRUCTOR_NAME_NOT_ENCLOSING_CLASS, 4, 11, 1),
-        errEx(ResolverErrorCode.CONSTRUCTOR_NAME_NOT_ENCLOSING_CLASS, 5, 11, 1),
-        errEx(ResolverErrorCode.CONSTRUCTOR_NAME_NOT_ENCLOSING_CLASS_ID, 5, 11, 6));
-  }
-
-  /**
-   * <p>
-   * http://code.google.com/p/dart/issues/detail?id=3904
-   */
-  public void test_reifiedClasses() throws Exception {
-    AnalyzeLibraryResult libraryResult = analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "class A {}",
-        "process(x) {}",
-        "main() {",
-        "  process(A);",
-        "}");
-    assertErrors(libraryResult.getErrors());
-  }
-
-  /**
-   * <p>
-   * http://code.google.com/p/dart/issues/detail?id=3968
-   */
-  public void test_redirectingFactoryConstructor() throws Exception {
-    AnalyzeLibraryResult libraryResult = analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "class A {",
-        "  A() {}",
-        "  A.named() {}",
-        "}",
-        "",
-        "class B {",
-        "  factory B.foo() = A;",
-        "  factory B.bar() = A.named;",
-        "}",
-        "");
-    assertErrors(libraryResult.getErrors());
-    // prepare "class A"
-    ClassElement elementA = findNode(DartClass.class, "class A").getElement();
-    Type typeA = elementA.getType();
-    // = A;
-    {
-      DartTypeNode typeNode = findNode(DartTypeNode.class, "A;");
-      Type type = typeNode.getType();
-      assertSame(typeA, type);
-    }
-    // = A.named;
-    {
-      DartTypeNode typeNode = findNode(DartTypeNode.class, "A.named;");
-      Type type = typeNode.getType();
-      assertSame(typeA, type);
-      // .named
-      DartIdentifier nameNode = findNode(DartIdentifier.class, "named;");
-      Element nameElement = nameNode.getElement();
-      assertNotNull(nameElement);
-      assertSame(elementA.lookupConstructor("named"), nameElement);
-    }
-  }
-
-  public void test_redirectingFactoryConstructor_cycle() throws Exception {
-    AnalyzeLibraryResult libraryResult = analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "class A {",
-        "  factory A.nameA() = C.nameC;",
-        "}",
-        "class B {",
-        "  factory B.nameB() = A.nameA;",
-        "}",
-        "class C {",
-        "  factory C.nameC() = B.nameB;",
-        "}",
-        "");
-    assertErrors(
-        libraryResult.getErrors(),
-        errEx(ResolverErrorCode.REDIRECTION_CONSTRUCTOR_CYCLE, 3, 11, 7),
-        errEx(ResolverErrorCode.REDIRECTION_CONSTRUCTOR_CYCLE, 6, 11, 7),
-        errEx(ResolverErrorCode.REDIRECTION_CONSTRUCTOR_CYCLE, 9, 11, 7));
-  }
-
-  public void test_redirectingFactoryConstructor_notConst_fromConst() throws Exception {
-    AnalyzeLibraryResult libraryResult = analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "class A {",
-        "  A.named() {}",
-        "}",
-        "",
-        "class B {",
-        "  const factory B.bar() = A.named;",
-        "}",
-        "");
-    assertErrors(
-        libraryResult.getErrors(),
-        errEx(ResolverErrorCode.REDIRECTION_CONSTRUCTOR_TARGET_MUST_BE_CONST, 7, 29, 5));
-  }
-
-  public void test_redirectingFactoryConstructor_shouldBeSubType() throws Exception {
-    AnalyzeLibraryResult libraryResult = analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "class A {",
-        "  A() {}",
-        "  A.named(p0) {}",
-        "}",
-        "",
-        "class B {",
-        "  factory B.foo(p0) = A;",
-        "  factory B.bar() = A.named;",
-        "}",
-        "");
-    assertErrors(
-        libraryResult.getErrors(),
-        errEx(TypeErrorCode.REDIRECTION_CONSTRUCTOR_TARGET_MUST_BE_SUBTYPE, 8, 23, 1),
-        errEx(TypeErrorCode.REDIRECTION_CONSTRUCTOR_TARGET_MUST_BE_SUBTYPE, 9, 23, 5));
-  }
-
-  public void test_redirectingFactoryConstructor_shouldBeSubType2() throws Exception {
-    AnalyzeLibraryResult libraryResult = analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "class A<T> {",
-        "  A.named(T t) {}",
-        "}",
-        "",
-        "class B<T> {",
-        "  factory B.foo(T t) = A<T>.named;",
-        "}",
-        "class B2<T, V> {",
-        "  factory B2.foo(V v) = A<V>.named;",
-        "}",
-        "");
-    assertErrors(libraryResult.getErrors());
-  }
-
-  public void test_redirectingFactoryConstructor_shouldBeSubType3() throws Exception {
-    AnalyzeLibraryResult libraryResult = analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "class A<T> {",
-        "  A(A<T> p) {}",
-        "}",
-        "",
-        "class B<T> {",
-        "  factory B.foo(A<T> p) = A;",
-        "}",
-        "");
-    assertErrors(libraryResult.getErrors());
-  }
-
-  public void test_redirectingFactoryConstructor_notSubType_typeParameterBounds() throws Exception {
-    AnalyzeLibraryResult libraryResult = analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "class A1<T extends String> {",
-        "  A1() {}",
-        "}",
-        "class A2<T> {",
-        "  A2() {}",
-        "}",
-        "",
-        "class B {",
-        "  factory B.name1() = A1<String>;",
-        "  factory B.name2() = A1<int>;",
-        "  factory B.name3() = A2<String>;",
-        "  factory B.name4() = A2<int>;",
-        "}",
-        "");
-    assertErrors(
-        libraryResult.getErrors(),
-        errEx(TypeErrorCode.TYPE_NOT_ASSIGNMENT_COMPATIBLE, 11, 26, 3));
-  }
-
-  /**
-   * <p>
-   * http://code.google.com/p/dart/issues/detail?id=4778
-   */
-  public void test_unqualifiedAccessToGenericTypeField() throws Exception {
-    AnalyzeLibraryResult libraryResult = analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "class Game {}",
-        "class GameRenderer<G extends Game> {",
-        "  G get game => null;",
-        "}",
-        "class SpaceShooterGame extends Game {",
-        "  int score;",
-        "}",
-        "class SpaceShooterRenderer extends GameRenderer<SpaceShooterGame> {",
-        "  someMethod() {",
-        "    var a = game.score;",
-        "  }",
-        "}",
-        "");
-    assertErrors(libraryResult.getErrors());
-  }
-
-  /**
-   * <p>
-   * http://code.google.com/p/dart/issues/detail?id=4900
-   */
-  public void test_forInLoop_fieldAsVariable() throws Exception {
-      AnalyzeLibraryResult result = analyzeLibrary(
-          "// filler filler filler filler filler filler filler filler filler filler",
-          "var v;",
-          "get l => v;",
-          "set l(x) {v = x;}",
-          "main() {",
-          "  for (l in [1, 2, 3]) {",
-          "    process(l);",
-          "  }",
-          "}",
-          "process(x) {}",
-          "");
-      assertErrors(result.getErrors());
-  }
-
-  /**
-   * Don't report "no such member" if class implements "noSuchMethod" method.
-   */
-  public void test_dontReport_ifHas_noSuchMember_method() throws Exception {
-    String[] lines = {
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "class A {",
-        "  noSuchMethod(Invocation invocation) {}",
-        "}",
-        "class B extends A {}",
-        "class C {}",
-        "main() {",
-        "  new A().notExistingMethod();",
-        "  new B().notExistingMethod();",
-        "  new C().notExistingMethod();",
-        "}",
-        "process(x) {}",
-        ""};
-    // report by default
-    {
-      AnalyzeLibraryResult result = analyzeLibrary(lines);
-      assertErrors(
-          result.getErrors(),
-          errEx(TypeErrorCode.INTERFACE_HAS_NO_METHOD_NAMED, 8, 11, 17),
-          errEx(TypeErrorCode.INTERFACE_HAS_NO_METHOD_NAMED, 9, 11, 17),
-          errEx(TypeErrorCode.INTERFACE_HAS_NO_METHOD_NAMED, 10, 11, 17));
-    }
-    // don't report
-    {
-      compilerConfiguration = new DefaultCompilerConfiguration(new CompilerOptions() {
-        @Override
-        public boolean reportNoMemberWhenHasInterceptor() {
-          return false;
-        }
-      });
-      AnalyzeLibraryResult result = analyzeLibrary(lines);
-      assertErrors(
-          result.getErrors(),
-          errEx(TypeErrorCode.INTERFACE_HAS_NO_METHOD_NAMED, 10, 11, 17));
-    }
-  }
-
-  /**
-   * Don't report "no such member" if class implements "noSuchMethod" method.
-   */
-  public void test_dontReport_ifHas_noSuchMember_getter() throws Exception {
-    String[] lines = {
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "class A {",
-        "  noSuchMethod(Invocation invocation) {}",
-        "}",
-        "class B extends A {}",
-        "class C {}",
-        "main() {",
-        "  process( new A().notExistingGetter );",
-        "  process( new B().notExistingGetter );",
-        "  process( new C().notExistingGetter );",
-        "}",
-        "process(x) {}",
-        ""};
-    // report by default
-    {
-      AnalyzeLibraryResult result = analyzeLibrary(lines);
-      assertErrors(
-          result.getErrors(),
-          errEx(TypeErrorCode.NOT_A_MEMBER_OF, 8, 20, 17),
-          errEx(TypeErrorCode.NOT_A_MEMBER_OF, 9, 20, 17),
-          errEx(TypeErrorCode.NOT_A_MEMBER_OF, 10, 20, 17));
-    }
-    // don't report
-    {
-      compilerConfiguration = new DefaultCompilerConfiguration(new CompilerOptions() {
-        @Override
-        public boolean reportNoMemberWhenHasInterceptor() {
-          return false;
-        }
-      });
-      AnalyzeLibraryResult result = analyzeLibrary(lines);
-      assertErrors(result.getErrors(), errEx(TypeErrorCode.NOT_A_MEMBER_OF, 10, 20, 17));
-    }
-  }
-
-  /**
-   * Don't report "is not a function type" if class implements "noSuchMethod" method.
-   */
-  public void test_dontReport_ifHas_noSuchMember_isNotFunction() throws Exception {
-    String[] lines = {
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "class A {",
-        "  noSuchMethod(Invocation invocation) {}",
-        "}",
-        "class B extends A {}",
-        "class C {}",
-        "main() {",
-        "  A a = new A();",
-        "  B b = new B();",
-        "  C c = new C();",
-        "  a();",
-        "  b();",
-        "  c();",
-        "}",
-        ""};
-    // report by default
-    {
-      AnalyzeLibraryResult result = analyzeLibrary(lines);
-      assertErrors(
-          result.getErrors(),
-          errEx(TypeErrorCode.NOT_A_FUNCTION_TYPE, 11, 3, 1),
-          errEx(TypeErrorCode.NOT_A_FUNCTION_TYPE, 12, 3, 1),
-          errEx(TypeErrorCode.NOT_A_FUNCTION_TYPE, 13, 3, 1));
-    }
-    // don't report
-    {
-      compilerConfiguration = new DefaultCompilerConfiguration(new CompilerOptions() {
-        @Override
-        public boolean reportNoMemberWhenHasInterceptor() {
-          return false;
-        }
-      });
-      AnalyzeLibraryResult result = analyzeLibrary(lines);
-      assertErrors(
-          result.getErrors(),
-          errEx(TypeErrorCode.NOT_A_FUNCTION_TYPE, 13, 3, 1));
-    }
-  }
-
-  /**
-   * <p>
-   * http://code.google.com/p/dart/issues/detail?id=5084
-   */
-  public void test_duplicateSuperInterface_errorInClassImplements() throws Exception {
-    AnalyzeLibraryResult result = analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "class A {}",
-        "class B implements A, A {}",
-        "");
-    assertErrors(result.getErrors(), errEx(ResolverErrorCode.DUPLICATE_IMPLEMENTS_TYPE, 3, 23, 1));
-  }
-
-  /**
-   * It is a compile-time error if the superclass of a class C appears in the implements clause of C.
-   * <p>
-   * http://code.google.com/p/dart/issues/detail?id=7469
-   */
-  public void test_superClass_imImplementsClause() throws Exception {
-    AnalyzeLibraryResult result = analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "class A {}",
-        "class B extends A implements A {}",
-        "");
-    assertErrors(result.getErrors(), errEx(ResolverErrorCode.SUPER_CLASS_IN_IMPLEMENTS, 3, 30, 1));
-  }
-
-  /**
-   * We should report only "no such type", but not duplicate.
-   * <p>
-   * http://code.google.com/p/dart/issues/detail?id=5084
-   */
-  public void test_duplicateSuperInterface_whenNoSuchType() throws Exception {
-    AnalyzeLibraryResult result = analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "class B implements X, Y {}",
-        "");
-    assertErrors(
-        result.getErrors(),
-        errEx(ResolverErrorCode.NO_SUCH_TYPE, 2, 20, 1),
-        errEx(ResolverErrorCode.NO_SUCH_TYPE, 2, 23, 1));
-  }
-
-  /**
-   * <p>
-   * http://code.google.com/p/dart/issues/detail?id=5082
-   */
-  public void test_argumentDefinitionTest_type() throws Exception {
-    AnalyzeLibraryResult result = analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "foo(p) {",
-        "  ?p;",
-        "}",
-        "");
-    assertErrors(result.getErrors());
-    DartUnaryExpression unary = findNode(DartUnaryExpression.class, "?p");
-    Type type = unary.getType();
-    assertNotNull(type);
-    assertEquals("bool", type.toString());
-  }
-
-  /**
-   * <p>
-   * http://code.google.com/p/dart/issues/detail?id=5082
-   */
-  public void test_argumentDefinitionTest_shouldBeFormalParameter() throws Exception {
-    AnalyzeLibraryResult result = analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "foo(p) {",
-        "  var v;",
-        "  ?p;",
-        "  ?v;",
-        "}",
-        "");
-    assertErrors(
-        result.getErrors(),
-        errEx(ResolverErrorCode.FORMAL_PARAMETER_NAME_EXPECTED, 5, 4, 1));
-  }
-
-  /**
-   * <p>
-   * http://code.google.com/p/dart/issues/detail?id=5148
-   */
-  public void test_errorIfNoBodyForStaticMethod() throws Exception {
-    AnalyzeLibraryResult result = analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "class A {",
-        "  static foo();",
-        "}",
-        "");
-    assertErrors(
-        result.getErrors(),
-        errEx(ResolverErrorCode.STATIC_METHOD_MUST_HAVE_BODY, 3, 3, 13));
-  }
-
-  /**
-   * <p>
-   * http://code.google.com/p/dart/issues/detail?id=5162
-   */
-  public void test_initializeFinalInstanceVariable_atDeclaration_inInitializer() throws Exception {
-    AnalyzeLibraryResult result = analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "class A {",
-        "  final f = 0;",
-        "  A() : f = 1 {}",
-        "}",
-        "");
-    assertErrors(
-        result.getErrors(),
-        errEx(ResolverErrorCode.DUPLICATE_INITIALIZATION, 4, 9, 5));
-  }
-
-  public void test_getOverridden_method() throws Exception {
-    analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "class A {",
-        "  foo() => 1;",
-        "}",
-        "class B extends A {",
-        "  foo() => 2;",
-        "}",
-        "");
-    DartMethodDefinition node = findNode(DartMethodDefinition.class, "foo() => 2");
-    Set<Element> superElements = node.getElement().getOverridden();
-    assertClassMembers(superElements, "method A.foo");
-  }
-
-  public void test_getOverridden_methodAbstract() throws Exception {
-    analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "class A {",
-        "  foo();",
-        "}",
-        "");
-    DartMethodDefinition node = findNode(DartMethodDefinition.class, "foo();");
-    Set<Element> superElements = node.getElement().getOverridden();
-    assertTrue(superElements.isEmpty());
-  }
-
-  public void test_getOverridden_field_withGetterSetter() throws Exception {
-    analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "class A {",
-        "  var foo;",
-        "}",
-        "class B extends A {",
-        "  get foo => 0;",
-        "  set foo(x) {}",
-        "}",
-        "");
-    // getter
-    {
-      DartMethodDefinition node = findNode(DartMethodDefinition.class, "get foo");
-      Set<Element> superElements = node.getElement().getOverridden();
-      assertClassMembers(superElements, "field A.foo");
-    }
-    // setter
-    {
-      DartMethodDefinition node = findNode(DartMethodDefinition.class, "set foo");
-      Set<Element> superElements = node.getElement().getOverridden();
-      assertClassMembers(superElements, "field A.foo");
-    }
-  }
-
-  public void test_getOverridden_field_withGetter() throws Exception {
-    analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "class A {",
-        "  var foo;",
-        "}",
-        "class B extends A {",
-        "  get foo => 0;",
-        "  set foo(x) {}",
-        "}",
-        "");
-    // getter
-    {
-      DartMethodDefinition node = findNode(DartMethodDefinition.class, "get foo");
-      Set<Element> superElements = node.getElement().getOverridden();
-      assertClassMembers(superElements, "field A.foo");
-    }
-  }
-
-  public void test_getOverridden_field_withSetter() throws Exception {
-    analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "class A {",
-        "  var foo;",
-        "}",
-        "class B extends A {",
-        "  set foo(x) {}",
-        "}",
-        "");
-    // setter
-    {
-      DartMethodDefinition node = findNode(DartMethodDefinition.class, "set foo");
-      Set<Element> superElements = node.getElement().getOverridden();
-      assertClassMembers(superElements, "field A.foo");
-    }
-  }
-
-  public void test_getOverridden_getterSetter_withField() throws Exception {
-    analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "class A {",
-        "  get foo => 0;",
-        "  set foo(x) {}",
-        "}",
-        "class B extends A {",
-        "  var foo = 42;",
-        "}",
-        "");
-    DartField node = findNode(DartField.class, "foo = 42");
-    Set<Element> superElements = node.getElement().getOverridden();
-    assertClassMembers(superElements, "field A.foo");
-  }
-
-  public void test_getOverridden_getter_withField() throws Exception {
-    analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "class A {",
-        "  get foo => 0;",
-        "}",
-        "class B extends A {",
-        "  var foo = 42;",
-        "}",
-        "");
-    DartField node = findNode(DartField.class, "foo = 42");
-    Set<Element> superElements = node.getElement().getOverridden();
-    assertClassMembers(superElements, "field A.foo");
-  }
-
-  public void test_getOverridden_setter_withField() throws Exception {
-    analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "class A {",
-        "  set foo(x) {}",
-        "}",
-        "class B extends A {",
-        "  var foo = 42;",
-        "}",
-        "");
-    DartField node = findNode(DartField.class, "foo = 42");
-    Set<Element> superElements = node.getElement().getOverridden();
-    assertClassMembers(superElements, "field A.setter foo");
-  }
-
-  public void test_getOverridden_setter_withSetter() throws Exception {
-    analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "class A {",
-        "  set foo(x) {} // A",
-        "}",
-        "class B extends A {",
-        "  set foo(x) {} // B",
-        "}",
-        "");
-    DartField node = findNode(DartField.class, "set foo(x) {} // B");
-    Set<Element> superElements = node.getElement().getOverridden();
-    assertClassMembers(superElements, "field A.setter foo");
-  }
-
-  private static void assertClassMembers(Set<Element> superElements, String... expectedNames) {
-    Set<String> superNames = Sets.newHashSet();
-    for (Element element : superElements) {
-      String name = element.getEnclosingElement().getName() + "." + element.getName();
-      if (element instanceof FieldElement) {
-        superNames.add("field " + name);
-      }
-      if (element instanceof MethodElement) {
-        superNames.add("method " + name);
-      }
-    }
-    for (String name : expectedNames) {
-      assertTrue(name, superNames.remove(name));
-    }
-    assertTrue(superNames.toString(), superNames.isEmpty());
-  }
-
-  public void test_fieldAccess_declared_noGetter() throws Exception {
-    AnalyzeLibraryResult result = analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "class A {",
-        "  static set f(x) {}",
-        "}",
-        "main() {",
-        "  print(A.f);",
-        "}",
-        "");
-    assertErrors(result.getErrors(), errEx(ResolverErrorCode.FIELD_DOES_NOT_HAVE_A_GETTER, 6, 11, 1));
-  }
-
-  public void test_fieldAccess_notDeclared() throws Exception {
-    AnalyzeLibraryResult result = analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "class A {",
-        "}",
-        "main() {",
-        "  print(A.f);",
-        "}",
-        "");
-    assertErrors(result.getErrors(), errEx(TypeErrorCode.CANNOT_BE_RESOLVED, 5, 11, 1));
-  }
-
-  public void test_fieldAssign_declared_noSetter() throws Exception {
-    AnalyzeLibraryResult result = analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "class A {",
-        "  static get f => 0;",
-        "}",
-        "main() {",
-        "  A.f = 0;",
-        "}",
-        "");
-    assertErrors(result.getErrors(), errEx(ResolverErrorCode.FIELD_DOES_NOT_HAVE_A_SETTER, 6, 5, 1));
-  }
-
-  public void test_fieldAssign_notDeclared() throws Exception {
-    AnalyzeLibraryResult result = analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "class A {",
-        "}",
-        "main() {",
-        "  A.f = 0;",
-        "}",
-        "");
-    assertErrors(result.getErrors(), errEx(TypeErrorCode.CANNOT_BE_RESOLVED, 5, 5, 1));
-  }
-
-  public void test_field_unqualifiedAccess_read() throws Exception {
-    AnalyzeLibraryResult result = analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "class A {",
-        "  set f(x) {}",
-        "  run() {",
-        "    var v = f;",
-        "  }",
-        "}",
-        "");
-    assertErrors(result.getErrors(), errEx(ResolverErrorCode.FIELD_DOES_NOT_HAVE_A_GETTER, 5, 13, 1));
-  }
-
-  public void test_field_unqualifiedAccess_write() throws Exception {
-    AnalyzeLibraryResult result = analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "class A {",
-        "  get f => 0;",
-        "  run() {",
-        "    f = 1;",
-        "  }",
-        "}",
-        "");
-    assertErrors(result.getErrors(), errEx(ResolverErrorCode.FIELD_DOES_NOT_HAVE_A_SETTER, 5, 5, 1));
-  }
-
-  public void test_typeVariableScope_staticField() throws Exception {
-    AnalyzeLibraryResult result = analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "class A<T> {",
-        "  static T v;",
-        "}",
-        "");
-    assertErrors(
-        result.getErrors(),
-        errEx(ResolverErrorCode.TYPE_VARIABLE_IN_STATIC_CONTEXT, 3, 10, 1));
-  }
-
-  public void test_typeVariableScope_staticMethod() throws Exception {
-    AnalyzeLibraryResult result = analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "class A<T> {",
-        "  static foo() {",
-        "    T v = null;",
-        "  }",
-        "}",
-        "");
-    assertErrors(
-        result.getErrors(),
-        errEx(ResolverErrorCode.TYPE_VARIABLE_IN_STATIC_CONTEXT, 4, 5, 1));
-  }
-
-  public void test_typeVariableScope_instanceField() throws Exception {
-    AnalyzeLibraryResult result = analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "class A<T> {",
-        "  final List<T> values = new List<T>();",
-        "}",
-        "");
-    assertErrors(result.getErrors());
-  }
-
-  public void test_unresolvedMethod_inFactoryConstructor() throws Exception {
-    AnalyzeLibraryResult result = analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "class A {",
-        "  factory A() {",
-        "    foo();",
-        "  }",
-        "}",
-        "");
-    assertErrors(
-        result.getErrors(),
-        errEx(ResolverErrorCode.CANNOT_RESOLVE_METHOD, 4, 5, 3));
-  }
-
-  /**
-   * Developers unfamiliar with Dart frequently write (x/y).toInt() instead of x ~/ y. The editor
-   * should recognize that pattern.
-   * <p>
-   * http://code.google.com/p/dart/issues/detail?id=5652
-   */
-  public void test_useEffectiveIntegerDivision_int() throws Exception {
-    AnalyzeLibraryResult result = analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "main() {",
-        "  int x = 7;",
-        "  int y = 2;",
-        "  print( (x / y).toInt() );",
-        "}",
-        "");
-    assertErrors(result.getErrors(), errEx(TypeErrorCode.USE_INTEGER_DIVISION, 5, 10, 15));
-  }
-
-  /**
-   * We need to report warning only when arguments are integers.
-   * <p>
-   * http://code.google.com/p/dart/issues/detail?id=5652
-   */
-  public void test_useEffectiveIntegerDivision_num() throws Exception {
-    AnalyzeLibraryResult result = analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "main() {",
-        "  num x = 7;",
-        "  num y = 2;",
-        "  print( (x / y).toInt() );",
-        "}",
-        "");
-    assertErrors(result.getErrors());
-  }
-
-  /**
-   * <p>
-   * http://code.google.com/p/dart/issues/detail?id=5157
-   */
-  public void test_trySubTypeMember_forInferredType() throws Exception {
-    compilerConfiguration = new DefaultCompilerConfiguration(new CompilerOptions() {
-      @Override
-      public boolean typeChecksForInferredTypes() {
-        return true;
-      }
-    });
-    AnalyzeLibraryResult result = analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "class Event {}",
-        "class MouseEvent extends Event {",
-        "  int clientX;",
-        "  void stop() {}",
-        "}",
-        "typedef Listener(Event event);",
-        "class Button {",
-        "  addListener(Listener listener) {}",
-        "}",
-        "main() {",
-        "  Button button = new Button();",
-        "  button.addListener((event) {",
-        "    event.clientX;",
-        "    event.stop();",
-        "  });",
-        "}",
-        "");
-    assertErrors(result.getErrors());
-  }
-
-  /**
-   * We should resolve sub-type member only if there is only sub-type with such member.
-   * <p>
-   * http://code.google.com/p/dart/issues/detail?id=6776
-   */
-  public void test_trySubTypeMember_moreThanOneMember() throws Exception {
-    compilerConfiguration = new DefaultCompilerConfiguration(new CompilerOptions() {
-      @Override
-      public boolean typeChecksForInferredTypes() {
-        return true;
-      }
-    });
-    AnalyzeLibraryResult result = analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "class Event {}",
-        "class MouseEvent extends Event {",
-        "  int clientX;",
-        "}",
-        "class ScreenEvent extends Event {",
-        "  int clientX;",
-        "}",
-        "typedef Listener(Event event);",
-        "class Button {",
-        "  addListener(Listener listener) {}",
-        "}",
-        "main() {",
-        "  Button button = new Button();",
-        "  button.addListener((event) {",
-        "    event.clientX;",
-        "  });",
-        "}",
-        "");
-    // don't report error, because there IS member, we just don't know which one
-    assertErrors(result.getErrors());
-  }
-
-  /**
-   * <p>
-   * http://code.google.com/p/dart/issues/detail?id=6491
-   */
-  public void test_annotationOnGetter() throws Exception {
-    AnalyzeLibraryResult result = analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "const myAnnotation = 0;",
-        "class A {",
-        "  @myAnnotation bool get isEmpty => true;",
-        "}",
-        "");
-    assertErrors(result.getErrors());
-  }
-
-  public void test_resolveRefInComment_ofClass() throws Exception {
-    AnalyzeLibraryResult result = analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "/** This class [A] has method [foo]. */",
-        "class A {",
-        "  foo() {}",
-        "}",
-        "");
-    assertErrors(result.getErrors());
-    // [A]
-    {
-      DartCommentRefName node = findNode(DartCommentRefName.class, "A]");
-      ClassElement element = (ClassElement) node.getElement();
-      assertEquals("A", element.getName());
-    }
-    // [foo]
-    {
-      DartCommentRefName node = findNode(DartCommentRefName.class, "foo]");
-      MethodElement element = (MethodElement) node.getElement();
-      assertEquals("foo", element.getName());
-    }
-  }
-
-  public void test_resolveRefInComment_ofFunction() throws Exception {
-    AnalyzeLibraryResult result = analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "class A {}",
-        "/** This function has parameter [aaa] of type [A] ans also [bbb]. */",
-        "foo(A aaa, bbb) {}",
-        "");
-    assertErrors(result.getErrors());
-    // [aaa]
-    {
-      DartCommentRefName node = findNode(DartCommentRefName.class, "aaa]");
-      VariableElement element = (VariableElement) node.getElement();
-      assertSame(ElementKind.PARAMETER, ElementKind.of(element));
-      assertEquals("aaa", element.getName());
-    }
-    // [A]
-    {
-      DartCommentRefName node = findNode(DartCommentRefName.class, "A]");
-      ClassElement element = (ClassElement) node.getElement();
-      assertEquals("A", element.getName());
-    }
-    // [bbb]
-    {
-      DartCommentRefName node = findNode(DartCommentRefName.class, "bbb]");
-      VariableElement element = (VariableElement) node.getElement();
-      assertSame(ElementKind.PARAMETER, ElementKind.of(element));
-      assertEquals("bbb", element.getName());
-    }
-  }
-
-  public void test_resolveRefInComment_ofMethod() throws Exception {
-    AnalyzeLibraryResult result = analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "class A {",
-        "  var fff;",
-        "  /** Initializes [fff] and then calls [bar]. */",
-        "  foo() {}",
-        "  bar() {}",
-        "}",
-        "");
-    assertErrors(result.getErrors());
-    // [fff]
-    {
-      DartCommentRefName node = findNode(DartCommentRefName.class, "fff]");
-      FieldElement element = (FieldElement) node.getElement();
-      assertEquals("fff", element.getName());
-    }
-    // [bar]
-    {
-      DartCommentRefName node = findNode(DartCommentRefName.class, "bar]");
-      MethodElement element = (MethodElement) node.getElement();
-      assertEquals("bar", element.getName());
-    }
-  }
-
-  public void test_resolveNewInComment() throws Exception {
-    AnalyzeLibraryResult result = analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "class A {",
-        "  A() {}",
-        "  A.named() {}",
-        "}",
-        "/** Creates [A] using [new A] or [new A.named] constructors. */",
-        "foo() {}",
-        "");
-    assertErrors(result.getErrors());
-    // [new A]
-    {
-      DartCommentNewName node = findNode(DartCommentNewName.class, "new A]");
-      assertEquals("", node.getConstructorElement().getName());
-      assertEquals("A", node.getClassElement().getName());
-    }
-    // [new A.named]
-    {
-      DartCommentNewName node = findNode(DartCommentNewName.class, "new A.named]");
-      assertEquals("named", node.getConstructorElement().getName());
-      assertEquals("A", node.getClassElement().getName());
-    }
-  }
-
-  public void test_notGenerativeConstructor_default() throws Exception {
-    AnalyzeLibraryResult result = analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "class A {",
-        "  factory A() {",
-        "    return null;",
-        "  }",
-        "}",
-        "class B extends A {",
-        "  B() : super() {}", // explicit call of super constructor
-        "}",
-        "class C extends A {",
-        "  C() {}", // implicit call of super constructor
-        "}",
-        "class D extends A {", // implicit call of super constructor
-        "}",
-        "");
-    assertErrors(result.getErrors(),
-        errEx(ResolverErrorCode.NOT_GENERATIVE_SUPER_CONSTRUCTOR, 8, 9, 7),
-        errEx(ResolverErrorCode.NOT_GENERATIVE_SUPER_CONSTRUCTOR, 11, 3, 1),
-        errEx(ResolverErrorCode.NOT_GENERATIVE_SUPER_CONSTRUCTOR, 13, 7, 1));
-  }
-
-  public void test_notGenerativeConstructor_explicitNamed() throws Exception {
-    AnalyzeLibraryResult result = analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "class A {",
-        "  factory A.named() {",
-        "    return null;",
-        "  }",
-        "}",
-        "class B extends A {",
-        "  B() : super.named() {}", // explicit call of super constructor
-        "}",
-        "");
-    assertErrors(result.getErrors(),
-        errEx(ResolverErrorCode.NOT_GENERATIVE_SUPER_CONSTRUCTOR, 8, 9, 13));
-  }
-
-  /**
-   * <p>
-   * http://code.google.com/p/dart/issues/detail?id=6718
-   */
-  public void test_initializerInMethod() throws Exception {
-    AnalyzeLibraryResult result = analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "class A {",
-        "  var x;",
-        "  B() : x = 0 {}",
-        "}",
-        "");
-    assertErrors(result.getErrors(),
-        errEx(ResolverErrorCode.INITIALIZER_ONLY_IN_GENERATIVE_CONSTRUCTOR, 4, 9, 5));
-  }
-
-  public void test_variableReferencesItselfInInitializer() throws Exception {
-    AnalyzeLibraryResult result = analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "main() {",
-        "  var x = x;",
-        "}",
-        "");
-    assertErrors(result.getErrors(),
-        errEx(ResolverErrorCode.VARIABLE_REFERENCES_SAME_NAME_IN_INITIALIZER, 3, 11, 1));
-  }
-
-  public void test_ForEachStatement_method() throws Exception {
-    AnalyzeLibraryResult result = analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "class A {",
-        "  Iterator<int> iterator() {}",
-        "}",
-        "main() {",
-        "  A a = new A();",
-        "  for (int v in a) {}",
-        "}",
-        "");
-    assertErrors(result.getErrors());
-  }
-
-  public void test_ForEachStatement_negative_method_invalidReturnType() throws Exception {
-    AnalyzeLibraryResult result = analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "class A {",
-        "  int iterator() {}",
-        "}",
-        "main() {",
-        "  A a = new A();",
-        "  for (int v in a) {}",
-        "}",
-        "");
-    assertErrors(
-        result.getErrors(),
-        errEx(TypeErrorCode.FOR_IN_WITH_INVALID_ITERATOR_RETURN_TYPE, 7, 17, 1));
-  }
-
-  /**
-   * It was negative test, but in the new <code>Iterator</code> field should be also supported.
-   */
-  public void test_ForEachStatement_field() throws Exception {
-    AnalyzeLibraryResult result = analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "class A {",
-        "  Iterator iterator;",
-        "}",
-        "main() {",
-        "  A a = new A();",
-        "  for (int v in a) {}",
-        "}",
-        "");
-    assertErrors(result.getErrors());
-//    Map<String, ClassNodeElement> fieldNotMethod = loadSource(
-//        "class A {",
-//        "  int iterator;",
-//        "}",
-//        "class B {",
-//        "  main() { for (int i in new A()) {}}",
-//        "}");
-//    analyzeClasses(fieldNotMethod, TypeErrorCode.FOR_IN_WITH_ITERATOR_FIELD);
-  }
-
-  public void test_ForEachStatement_negative_field_invalidReturnType() throws Exception {
-    AnalyzeLibraryResult result = analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "class A {",
-        "  int iterator;",
-        "}",
-        "main() {",
-        "  A a = new A();",
-        "  for (int v in a) {}",
-        "}",
-        "");
-    assertErrors(result.getErrors(),
-        errEx(TypeErrorCode.FOR_IN_WITH_INVALID_ITERATOR_RETURN_TYPE, 7, 17, 1));
-  }
-
-  public void test_builtInIdentifier_asType() throws Exception {
-    AnalyzeLibraryResult result = analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "main() {",
-        "  abstract v_abstract;",
-        "}",
-        "");
-    assertErrors(result.getErrors(),
-        errEx(ResolverErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE, 3, 3, 8));
-  }
-
-  public void test_builtInIdentifier_asParameterizedType() throws Exception {
-    AnalyzeLibraryResult result = analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "main() {",
-        "  abstract<int> v_01;",
-        "  as<int> v_02;",
-        "  export<int> v_03;",
-        "  external<int> v_04;",
-        "  factory<int> v_05;",
-        "  get<int> v_06;",
-        "  implements<int> v_07;",
-        "  import<int> v_08;",
-        "  library<int> v_09;",
-        "  operator<int> v_q0;",
-        "  part<int> v_11;",
-        "  set<int> v_12;",
-        "  static<int> v_13;",
-        "  typedef<int> v_14;",
-        "}",
-        "");
-    List<DartCompilationError> errors = result.getErrors();
-    assertEquals(14, errors.size());
-    for (DartCompilationError error : errors) {
-      assertSame(TypeErrorCode.NO_SUCH_TYPE, error.getErrorCode());
-      assertEquals(3, error.getColumnNumber());
-    }
-  }
-
-  public void test_superConstructorInvocation_wrongPlace() throws Exception {
-    AnalyzeLibraryResult result = analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "topLevelMethod() : super() {}",
-        "",
-        "class A {",
-        "  m() : super() {}",
-        "}",
-        "");
-    assertErrors(
-        result.getErrors(),
-        errEx(ResolverErrorCode.SUPER_OUTSIDE_OF_CONSTRUCTOR, 2, 20, 7),
-        errEx(ResolverErrorCode.SUPER_OUTSIDE_OF_CONSTRUCTOR, 5, 9, 7));
-  }
-
-  /**
-   * Test that we set {@link ConstructorElement} for {@link DartSuperConstructorInvocation}.
-   */
-  public void test_superConstructorInvocation_resolveElement() throws Exception {
-    analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "abstract class A {",
-        "  A.named() {}",
-        "}",
-        "abstract class B extends A {",
-        "  B() : super.named();",
-        "}",
-        "");
-    DartIdentifier nameInInvocation = findNode(DartIdentifier.class, "named();");
-    DartSuperConstructorInvocation invocation = (DartSuperConstructorInvocation) nameInInvocation.getParent();
-    ConstructorNodeElement expectedElement = invocation.getElement();
-    assertNotNull(expectedElement);
-    assertSame(nameInInvocation.getElement(), expectedElement);
-  }
-
-  public void test_mixin_1() throws Exception {
-    AnalyzeLibraryResult result = analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "class A {",
-        "  foo() {}",
-        "}",
-        "class B extends Object with A {", // no unimplemented methods warning
-        "}",
-        "main() {",
-        "  B b = new B();",
-        "  A a = b;", // no 'not assignable' warning
-        "}",
-        "");
-    assertErrors(result.getErrors());
-  }
-
-  /**
-   * <p>
-   * http://code.google.com/p/dart/issues/detail?id=8022
-   */
-  public void test_mixin_notObjectSuperclass() throws Exception {
-    AnalyzeLibraryResult result = analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "class A {}",
-        "class B extends A {}",
-        "typedef C = Object with B;",
-        "class D extends Object with B {}",
-        "");
-    assertErrors(
-        result.getErrors(),
-        errEx(ResolverErrorCode.ONLY_OBJECT_MIXIN_SUPERCLASS, 4, 25, 1),
-        errEx(ResolverErrorCode.ONLY_OBJECT_MIXIN_SUPERCLASS, 5, 29, 1));
-  }
-
-  /**
-   * <p>
-   * http://code.google.com/p/dart/issues/detail?id=8025
-   */
-  public void test_mixin_withConstructor() throws Exception {
-    AnalyzeLibraryResult result = analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "class M { M(); }",
-        "typedef A = Object with M;",
-        "class B extends Object with M {}",
-        "");
-    assertErrors(
-        result.getErrors(),
-        errEx(ResolverErrorCode.CANNOT_MIXIN_CLASS_WITH_CONSTRUCTOR, 3, 25, 1),
-        errEx(ResolverErrorCode.CANNOT_MIXIN_CLASS_WITH_CONSTRUCTOR, 4, 29, 1));
-  }
-
-  /**
-   * <p>
-   * http://code.google.com/p/dart/issues/detail?id=8059
-   */
-  public void test_mixin_withSuperInvocation() throws Exception {
-    AnalyzeLibraryResult result = analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "class M { foo() => super.toString(); }",
-        "typedef A = Object with M;",
-        "class B extends Object with M {}",
-        "");
-    assertErrors(
-        result.getErrors(),
-        errEx(ResolverErrorCode.CANNOT_MIXIN_CLASS_WITH_SUPER, 3, 25, 1),
-        errEx(ResolverErrorCode.CANNOT_MIXIN_CLASS_WITH_SUPER, 4, 29, 1));
-  }
-
-  /**
-   * <p>
-   * http://code.google.com/p/dart/issues/detail?id=8705
-   */
-  public void test_mixin_useInScope() throws Exception {
-    AnalyzeLibraryResult result = analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "class M { foo() {} }",
-        "class A extends Object with M {",
-        "  bar() {",
-        "    foo();",
-        "  }",
-        "}",
-        "");
-    assertErrors(result.getErrors());
-  }
-
-  /**
-   * 20130122. Currently it is not allowed to have mixin with superclass other than Object.
-   */
-  public void _test_mixin_dontAddSupertypes() throws Exception {
-    AnalyzeLibraryResult result = analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "class A {",
-        "  methodA() {}",
-        "}",
-        "class B extends A {",
-        "  methodB() {}",
-        "}",
-        "class C extends Object with B {",
-        "}",
-        "main() {",
-        "  C c = new C();",
-        "  A a = c;", // 'not assignable' warning - mixing is only "B" content
-        "  B b = c;", // OK
-        "  c.methodB();", // OK
-        "  c.methodA();", // 'no such member' warning - mixing is only "B" content
-        "}",
-        "");
-    assertErrors(
-        result.getErrors(),
-        errEx(TypeErrorCode.TYPE_NOT_ASSIGNMENT_COMPATIBLE, 12, 9, 1),
-        errEx(TypeErrorCode.INTERFACE_HAS_NO_METHOD_NAMED, 15, 5, 7));
-  }
-
-  public void test_mixin_dontAddSupertypes2() throws Exception {
-    AnalyzeLibraryResult result = analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "abstract class A {",
-        "  methodA();",
-        "}",
-        "abstract class B implements A {",
-        "  methodB() {}",
-        "}",
-        "class C extends Object with B {", // no unimplemented methods warning
-        "}",
-        "main() {",
-        "  C c = new C();",
-        "  A a = c;", // 'not assignable' warning - mixing is only "B" content
-        "  B b = c;", // OK
-        "  c.methodB();", // OK
-        "  c.methodA();", // 'no such member' warning - mixing is only "B" content
-        "}",
-        "");
-    assertErrors(
-        result.getErrors(),
-        errEx(TypeErrorCode.TYPE_NOT_ASSIGNMENT_COMPATIBLE, 12, 9, 1),
-        errEx(TypeErrorCode.INTERFACE_HAS_NO_METHOD_NAMED, 15, 5, 7));
-  }
-
-  /**
-   * 20130122. Currently it is not allowed to have mixin with superclass other than Object.
-   */
-  public void _test_mixin_dontAddSupertypes3() throws Exception {
-    AnalyzeLibraryResult result = analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "class A {",
-        "  foo() {}",
-        "}",
-        "class B extends A {",
-        "}",
-        "abstract class C {",
-        "  foo();",
-        "}",
-        "class D extends C with B {", // "foo" is not implemented, because NOT inherited from A
-        "}",
-        "");
-    assertErrors(
-        result.getErrors(),
-        errEx(TypeErrorCode.CONCRETE_CLASS_WITH_UNIMPLEMENTED_MEMBERS, 10, 7, 1));
-  }
-
-  /**
-   * 20130122. Currently it is not allowed to have mixin with superclass other than Object.
-   */
-  public void _test_mixin_dontLookSupertype_getter() throws Exception {
-    AnalyzeLibraryResult result = analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "class A {",
-        "  get fA => 42;",
-        "}",
-        "class B extends A {",
-        "  get fB => 42;",
-        "}",
-        "class C extends Object with B {",
-        "}",
-        "main() {",
-        "  C c = new C();",
-        "  print(c.fB);",
-        "  print(c.fA);",
-        "}",
-        "");
-    assertErrors(
-        result.getErrors(),
-        errEx(TypeErrorCode.NOT_A_MEMBER_OF, 13, 11, 2));
-  }
-
-  /**
-   * 20130122. Currently it is not allowed to have mixin with superclass other than Object.
-   */
-  public void _test_mixin_dontLookSupertype_setter() throws Exception {
-    AnalyzeLibraryResult result = analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "class A {",
-        "  set fA(x) {}",
-        "}",
-        "class B extends A {",
-        "  set fB(x) {}",
-        "}",
-        "class C extends Object with B {",
-        "}",
-        "main() {",
-        "  C c = new C();",
-        "  c.fB = 1;",
-        "  c.fA = 2;",
-        "}",
-        "");
-    assertErrors(
-        result.getErrors(),
-        errEx(TypeErrorCode.NOT_A_MEMBER_OF, 13, 5, 2));
-  }
-
-  public void test_mixin_disallowMixinApplication_asMixin() throws Exception {
-    AnalyzeLibraryResult result = analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "typedef M = Object with M;",
-        "");
-    assertErrors(
-        result.getErrors(),
-        errEx(ResolverErrorCode.CANNOT_MIXIN_CLASS_WITH_MIXINS, 2, 25, 1));
-  }
-
-  public void test_StringPlus() throws Exception {
-    AnalyzeLibraryResult result = analyzeLibrary(
-        "// filler filler filler filler filler filler filler filler filler filler",
-        "main() {",
-        "  var v1 = '1' + '2';",
-        "  var v2 = '1' + 2;",
-        "}",
-        "");
-    assertErrors(
-        result.getErrors(),
-        errEx(TypeErrorCode.TYPE_NOT_ASSIGNMENT_COMPATIBLE, 4, 18, 1));
-  }
-}
diff --git a/compiler/javatests/com/google/dart/compiler/type/TypeAnalyzerTest.java b/compiler/javatests/com/google/dart/compiler/type/TypeAnalyzerTest.java
deleted file mode 100644
index c2cc676f..0000000
--- a/compiler/javatests/com/google/dart/compiler/type/TypeAnalyzerTest.java
+++ /dev/null
@@ -1,1202 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.type;
-
-import com.google.dart.compiler.parser.Token;
-import com.google.dart.compiler.resolver.ClassElement;
-import com.google.dart.compiler.resolver.ClassNodeElement;
-import com.google.dart.compiler.resolver.CyclicDeclarationException;
-import com.google.dart.compiler.resolver.TypeErrorCode;
-
-import java.util.EnumSet;
-import java.util.Map;
-
-/**
- * Test of static type analysis. This is mostly a test of {@link TypeAnalyzer}, but this test also
- * exercises code in com.google.dart.compiler.resolver.
- */
-public class TypeAnalyzerTest extends TypeAnalyzerTestCase {
-
-  /**
-   * There  was problem that cyclic class declaration caused infinite loop.
-   * <p>
-   * http://code.google.com/p/dart/issues/detail?id=348
-   */
-  public void test_cyclicDeclaration() {
-    Map<String, ClassNodeElement> source = loadSource(
-        "class Foo extends Bar {",
-        "}",
-        "class Bar extends Foo {",
-        "}");
-    analyzeClasses(source);
-    // Foo and Bar have cyclic declaration
-    ClassElement classFoo = source.get("Foo");
-    ClassElement classBar = source.get("Bar");
-    assertEquals(classFoo, classBar.getSupertype().getElement());
-    assertEquals(classBar, classFoo.getSupertype().getElement());
-  }
-
-  public void test_operator_indexAssign() {
-    Map<String, ClassNodeElement> source = loadSource(
-        "class A {",
-        "int operator []=(int index, var value) {}",
-        "}");
-    analyzeClasses(source, TypeErrorCode.OPERATOR_INDEX_ASSIGN_VOID_RETURN_TYPE);
-  }
-
-  public void testArrayLiteral() {
-    analyze("['x'];");
-    analyze("<String>['x'];");
-    analyzeFail("<int>['x'];", TypeErrorCode.TYPE_NOT_ASSIGNMENT_COMPATIBLE);
-    analyzeFail("<String>['x', 1];", TypeErrorCode.TYPE_NOT_ASSIGNMENT_COMPATIBLE);
-    analyze("List<String> strings = ['x'];");
-    analyze("List<String> strings = <String>['x'];");
-    analyze("List array = ['x'];");
-    analyze("List array = <String>['x'];");
-    analyze("List<int> ints = ['x'];");
-    analyzeFail("List<int> ints = <String>['x'];", TypeErrorCode.TYPE_NOT_ASSIGNMENT_COMPATIBLE);
-  }
-
-  public void testBadInitializers() {
-    analyzeFail("int i = .0;", TypeErrorCode.TYPE_NOT_ASSIGNMENT_COMPATIBLE);
-    analyzeFail("int j = 1.0;", TypeErrorCode.TYPE_NOT_ASSIGNMENT_COMPATIBLE);
-  }
-
-  public void testBinaryOperators() {
-    ClassElement cls = loadClass("class_with_operators.dart", "ClassWithOperators");
-    analyzeIn(cls, "i = o[0]", 0);
-    analyzeIn(cls, "s = o[0]", 1);
-    analyzeIn(cls, "o['fisk']", 1);
-    analyzeIn(cls, "i && o", 2);
-    analyzeIn(cls, "b && o", 1);
-    analyzeIn(cls, "i && b", 1);
-    analyzeIn(cls, "b && b", 0);
-    analyzeIn(cls, "i || o", 2);
-    analyzeIn(cls, "b || o", 1);
-    analyzeIn(cls, "i || b", 1);
-    analyzeIn(cls, "b || b", 0);
-
-    EnumSet<Token> userOperators = EnumSet.of(Token.ADD,
-                                              Token.SUB,
-                                              Token.MUL,
-                                              Token.DIV,
-                                              Token.TRUNC,
-                                              Token.MOD,
-                                              Token.LT,
-                                              Token.GT,
-                                              Token.LTE,
-                                              Token.GTE);
-    for (Token op : userOperators) {
-      String expression;
-      expression = String.format("untyped %s untyped", op.getSyntax());
-      analyzeIn(cls, expression, 0);
-      expression = String.format("o = untyped %s untyped", op.getSyntax());
-      analyzeIn(cls, expression, 0);
-      expression = String.format("s = untyped %s untyped", op.getSyntax());
-      analyzeIn(cls, expression, 0);
-      expression = String.format("o %s untyped", op.getSyntax());
-      analyzeIn(cls, expression, 0);
-      expression = String.format("o = o %s untyped", op.getSyntax());
-      analyzeIn(cls, expression, 0);
-      expression = String.format("s = o %s untyped", op.getSyntax());
-      analyzeIn(cls, expression, 1);
-      expression = String.format("o %s null", op.getSyntax());
-      analyzeIn(cls, expression, 0);
-      expression = String.format("o = o %s null", op.getSyntax());
-      analyzeIn(cls, expression, 0);
-      expression = String.format("s = o %s null", op.getSyntax());
-      analyzeIn(cls, expression, 1);
-      expression = String.format("o %s o", op.getSyntax());
-      analyzeIn(cls, expression, 0);
-      expression = String.format("o = o %s o", op.getSyntax());
-      analyzeIn(cls, expression, 0);
-      expression = String.format("s = o %s o", op.getSyntax());
-      analyzeIn(cls, expression, 1);
-      if (!op.equals(Token.ADD)) {
-        expression = String.format("o %s s", op.getSyntax());
-        analyzeIn(cls, expression, 1);
-      }
-      expression = String.format("o %s i", op.getSyntax());
-      analyzeIn(cls, expression, 1);
-    }
-
-    EnumSet<Token> equalityOperators = EnumSet.of(Token.EQ,
-                                                  Token.NE);
-    for (Token op : equalityOperators) {
-      String expression;
-      expression = String.format("untyped %s untyped", op.getSyntax());
-      analyzeIn(cls, expression, 0);
-      expression = String.format("b = untyped %s untyped", op.getSyntax());
-      analyzeIn(cls, expression, 0);
-      expression = String.format("s = untyped %s untyped", op.getSyntax());
-      analyzeIn(cls, expression, 1);
-      expression = String.format("i = untyped %s untyped", op.getSyntax());
-      analyzeIn(cls, expression, 1);
-
-      expression = String.format("o %s o", op.getSyntax());
-      analyzeIn(cls, expression, 0);
-      expression = String.format("b = o %s o", op.getSyntax());
-      analyzeIn(cls, expression, 0);
-      expression = String.format("s = o %s o", op.getSyntax());
-      analyzeIn(cls, expression, 1);
-      expression = String.format("i = o %s o", op.getSyntax());
-      analyzeIn(cls, expression, 1);
-
-      expression = String.format("o %s s", op.getSyntax());
-      analyzeIn(cls, expression, 0);
-      expression = String.format("b = o %s s", op.getSyntax());
-      analyzeIn(cls, expression, 0);
-      expression = String.format("s = o %s s", op.getSyntax());
-      analyzeIn(cls, expression, 1);
-      expression = String.format("i = o %s s", op.getSyntax());
-      analyzeIn(cls, expression, 1);
-    }
-
-    EnumSet<Token> compoundAssignmentOperators =
-        EnumSet.of(Token.ASSIGN_ADD,
-                   Token.ASSIGN_SUB,
-                   Token.ASSIGN_MUL,
-                   Token.ASSIGN_DIV,
-                   Token.ASSIGN_MOD,
-                   Token.ASSIGN_TRUNC);
-
-    for (Token op : compoundAssignmentOperators) {
-      String expression;
-      expression = String.format("o %s untyped", op.getSyntax());
-      analyzeIn(cls, expression, 0);
-      expression = String.format("o %s null", op.getSyntax());
-      analyzeIn(cls, expression, 0);
-      expression = String.format("o %s o", op.getSyntax());
-      analyzeIn(cls, expression, 0);
-      expression = String.format("o %s i", op.getSyntax());
-      analyzeIn(cls, expression, 1);
-      if (!op.equals(Token.ASSIGN_ADD)) {
-        expression = String.format("s %s untyped", op.getSyntax());
-        analyzeIn(cls, expression, 1);
-        expression = String.format("s %s null", op.getSyntax());
-        analyzeIn(cls, expression, 1);
-        expression = String.format("s %s o", op.getSyntax());
-        analyzeIn(cls, expression, 1);
-      }
-    }
-
-    analyzeIn(cls, "untyped is String", 0);
-    analyzeIn(cls, "b = untyped is String", 0);
-    analyzeIn(cls, "s = untyped is String", 1);
-    analyzeIn(cls, "s is String", 0);
-    analyzeIn(cls, "b = s is String", 0);
-    analyzeIn(cls, "s = s is String", 1);
-
-    analyzeIn(cls, "untyped is !String", 0);
-    analyzeIn(cls, "b = untyped is !String", 0);
-    analyzeIn(cls, "s = untyped is !String", 1);
-    analyzeIn(cls, "s is !String", 0);
-    analyzeIn(cls, "b = s is !String", 0);
-    analyzeIn(cls, "s = s is !String", 1);
-
-    analyzeFail("1 == !'s';", TypeErrorCode.TYPE_NOT_ASSIGNMENT_COMPATIBLE);
-  }
-
-  public void testBitOperators() {
-    Map<String, ClassNodeElement> source = loadSource(
-        "class ClassWithBitops {",
-        "  num n;",
-        "  int i;",
-        "  double d;",
-        "  ClassWithBitops o;",
-        "  num foo() { return 42; }",
-        "  int operator |(int arg) { return arg; }",
-        "  int operator &(int arg) { return arg; }",
-        "  int operator ^(int arg) { return arg; }",
-        "  int operator >>(int arg) { return arg; }",
-        "  int operator <<(int arg) { return arg; }",
-        "  int operator ~() { return 1; }",
-        "}");
-    ClassElement cls = source.get("ClassWithBitops");
-    analyzeClasses(source);
-
-    EnumSet<Token> operators = EnumSet.of(Token.BIT_AND,
-                                          Token.BIT_OR,
-                                          Token.BIT_XOR,
-                                          Token.SHL,
-                                          Token.SAR);
-    for (Token operator : operators) {
-      analyzeIn(cls, String.format("n %s n" , operator), 0);
-      analyzeIn(cls, String.format("foo() %s i" , operator), 0);
-      analyzeIn(cls, String.format("o %s i" , operator), 0);
-      analyzeIn(cls, String.format("n = d %s i", operator), 1);
-      analyzeIn(cls, String.format("d = o %s i", operator), 1);
-      analyzeIn(cls, String.format("d = n %s i", operator), 1);
-      analyzeIn(cls, String.format("n %s o" , operator), 1);
-    }
-
-    EnumSet<Token> assignOperators = EnumSet.of(Token.ASSIGN_BIT_AND,
-                                                Token.ASSIGN_BIT_OR,
-                                                Token.ASSIGN_BIT_XOR,
-                                                Token.ASSIGN_SHL,
-                                                Token.ASSIGN_SAR);
-    for (Token operator : assignOperators) {
-      analyzeIn(cls, String.format("n %s n" , operator), 0);
-      analyzeIn(cls, String.format("n %s i" , operator), 0);
-      analyzeIn(cls, String.format("d %s i", operator), 1);
-      analyzeIn(cls, String.format("o %s i", operator), 1);
-      analyzeIn(cls, String.format("n %s o" , operator), 1);
-    }
-
-    analyzeIn(cls, "i = ~o", 0);
-    analyzeIn(cls, "i = ~n", 0);
-    analyzeIn(cls, "d = ~n", 1);
-  }
-
-  public void testConditionalExpression() {
-    analyze("true ? 1 : 2;");
-    analyze("null ? 1 : 2;");
-    analyzeFail("0 ? 1 : 2;",
-      TypeErrorCode.TYPE_NOT_ASSIGNMENT_COMPATIBLE);
-    analyzeFail("'' ? 1 : 2;",
-      TypeErrorCode.TYPE_NOT_ASSIGNMENT_COMPATIBLE);
-    analyzeFail("{ int i; true ? i = 2.7 : 2; }",
-      TypeErrorCode.TYPE_NOT_ASSIGNMENT_COMPATIBLE);
-    analyzeFail("{ int i; true ? 2 : i = 2.7; }",
-      TypeErrorCode.TYPE_NOT_ASSIGNMENT_COMPATIBLE);
-    analyze("{ int i; i = true ? 2.7 : 2; }");
-  }
-
-  public void testConstructorForwarding() {
-    Map<String, ClassNodeElement> classes = loadSource(
-        "class MissingArgument {",
-        "  MissingArgument() : this.bar();",
-        "  MissingArgument.bar(int i) {}",
-        "}",
-        "class IntArgument {",
-        "  IntArgument() : this.bar(1);",
-        "  IntArgument.bar(int i) {}",
-        "}",
-        "class ExtraIntArgument {",
-        "  ExtraIntArgument() : this.bar(1, 1);",
-        "  ExtraIntArgument.bar(int i) {}",
-        "}",
-        "class StringArgument {",
-        "  StringArgument() : this.bar('');",
-        "  StringArgument.bar(int i) {}",
-        "}",
-        "class NullArgument {",
-        "  NullArgument() : this.bar(null);",
-        "  NullArgument.bar(int i) {}",
-        "}",
-        "class OptionalParameter {",
-        "  OptionalParameter() : this.bar();",
-        "  OptionalParameter.bar([int i = null]) {}",
-        "  OptionalParameter.foo() : this.bar('');",
-        "}");
-    analyzeClass(classes.get("MissingArgument"), 1);
-    analyzeClass(classes.get("IntArgument"), 0);
-    analyzeClass(classes.get("ExtraIntArgument"), 1);
-    analyzeClass(classes.get("StringArgument"), 1);
-    analyzeClass(classes.get("NullArgument"), 0);
-    analyzeClass(classes.get("OptionalParameter"), 1);
-  }
-
-  public void testCyclicTypeVariable() {
-    Map<String, ClassNodeElement> classes = loadSource(
-        "abstract class A<T> { }",
-        "typedef funcType<T>(T arg);",
-        "class B<T extends T> {}",
-        "class C<T extends A<T>> {}",
-        "class D<T extends funcType<T>> {}");
-    analyzeClasses(classes,
-        TypeErrorCode.CYCLIC_REFERENCE_TO_TYPE_VARIABLE);
-    ClassNodeElement B = classes.get("B");
-    analyzeClass(B, 1);
-    assertEquals(1, B.getType().getArguments().size());
-    ClassNodeElement C = classes.get("C");
-    analyzeClass(C, 0);
-    assertEquals(1, C.getType().getArguments().size());
-    ClassNodeElement D = classes.get("D");
-    analyzeClass(D, 0);
-    assertEquals(1, D.getType().getArguments().size());
-
-  }
-
-  public void testDoWhileStatement() {
-    analyze("do {} while (true);");
-    analyze("do {} while (null);");
-    analyzeFail("do {} while (0);",
-      TypeErrorCode.TYPE_NOT_ASSIGNMENT_COMPATIBLE);
-    analyzeFail("do {} while ('');",
-      TypeErrorCode.TYPE_NOT_ASSIGNMENT_COMPATIBLE);
-    analyzeFail("do { int i = 0.5; } while (true);",
-      TypeErrorCode.TYPE_NOT_ASSIGNMENT_COMPATIBLE);
-    analyzeFail("do { int i = 0.5; } while (null);",
-      TypeErrorCode.TYPE_NOT_ASSIGNMENT_COMPATIBLE);
-  }
-
-  public void testFieldAccess() {
-    ClassElement element = loadFile("class_with_supertypes.dart").get("ClassWithSupertypes");
-    assertNotNull("unable to locate ClassWithSupertypes", element);
-    analyzeIn(element, "field = 1", 0);
-    analyzeIn(element, "staticField = 1", 0);
-    analyzeIn(element, "fieldInSuperclass = 1", 0);
-    analyzeIn(element, "staticFieldInSuperclass = 1", 0);
-
-    analyzeIn(element, "field = field", 0);
-    analyzeIn(element, "field = staticField", 0);
-    analyzeIn(element, "field = fieldInSuperclass", 0);
-    analyzeIn(element, "field = staticFieldInSuperclass", 0);
-    analyzeIn(element, "field = fieldInInterface", 0);
-    analyzeIn(element, "field = staticFieldInInterface", 0);
-
-    analyzeIn(element, "field = 1", 0);
-    analyzeIn(element, "staticField = 1", 0);
-    analyzeIn(element, "fieldInSuperclass = 1", 0);
-    analyzeIn(element, "staticFieldInSuperclass = 1", 0);
-
-    analyzeIn(element, "field = ''", 1);
-    analyzeIn(element, "staticField = ''", 1);
-    analyzeIn(element, "fieldInSuperclass = ''", 1);
-    analyzeIn(element, "staticFieldInSuperclass = ''", 1);
-
-    analyzeIn(element, "field.noSuchField", 1);
-    analyzeIn(element, "staticField.noSuchField", 1);
-    analyzeIn(element, "fieldInSuperclass.noSuchField", 1);
-    analyzeIn(element, "staticFieldInSuperclass.noSuchField", 1);
-    analyzeIn(element, "fieldInInterface.noSuchField", 1);
-    analyzeIn(element, "staticFieldInInterface.noSuchField", 1);
-
-    analyzeIn(element, "new ClassWithSupertypes()", 0); // concrete class with abstract members
-    analyzeIn(element, "field = new ClassWithSupertypes().field", 0);
-    analyzeIn(element, "field = new ClassWithSupertypes().staticField", 1);
-    analyzeIn(element, "field = new ClassWithSupertypes().fieldInSuperclass", 0);
-    analyzeIn(element, "field = new ClassWithSupertypes().staticFieldInSuperclass", 1);
-    analyzeIn(element, "field = new ClassWithSupertypes().fieldInInterface", 0);
-    analyzeIn(element, "field = new ClassWithSupertypes().staticFieldInInterface", 1);
-
-    analyzeIn(element, "new ClassWithSupertypes().field = 1", 0);
-    analyzeIn(element, "new ClassWithSupertypes().staticField = 1", 1);
-    analyzeIn(element, "new ClassWithSupertypes().fieldInSuperclass = 1", 0);
-    analyzeIn(element, "new ClassWithSupertypes().staticFieldInSuperclass = 1", 1);
-    // Enable this test when constness is propagated:
-    // analyzeIn(element, "new ClassWithSupertypes().fieldInInterface = 1", 1);
-    analyzeIn(element, "new ClassWithSupertypes().staticFieldInInterface = 1", 1);
-  }
-
-  public void testFieldInitializers() {
-    Map<String, ClassNodeElement> classes = loadSource(
-        "class Good {",
-        "  String string;",
-        "  int i;",
-        "  Good() : string = '', i = 1;",
-        "  Good.name() : string = null, i = null;",
-        "  Good.untyped(x) : string = x, i = x;",
-        "  Good.string(String s) : string = s, i = 0;",
-        "}",
-        "class Bad {",
-        "  String string;",
-        "  int i;",
-        "  Bad() : string = 1, i = '';",
-        "  Bad.string(String s) : string = s, i = s;",
-        "}");
-    analyzeClass(classes.get("Good"), 0);
-    analyzeClass(classes.get("Bad"), 3);
-  }
-
-  public void testForStatement() {
-    analyze("for (;true;) {}");
-    analyze("for (;null;) {}");
-    analyzeFail("for (;0;) {}",
-      TypeErrorCode.TYPE_NOT_ASSIGNMENT_COMPATIBLE);
-    analyzeFail("for (;'';) {}",
-      TypeErrorCode.TYPE_NOT_ASSIGNMENT_COMPATIBLE);
-
-    // Foreach tests
-    analyze("{ List<String> strings = ['1','2','3']; for (String s in strings) {} }");
-    analyzeFail("{ List<int> ints = [1,2,3]; for (String s in ints) {} }",
-        TypeErrorCode.TYPE_NOT_ASSIGNMENT_COMPATIBLE);
-    analyzeFail("for (String s in true) {}", TypeErrorCode.INTERFACE_HAS_NO_METHOD_NAMED);
-  }
-
-  public void testFunctionObjectLiterals() {
-    analyze("{ bool b = () {}(); }");
-    analyze("{ int i = () {}(); }");
-    analyze("Function f = () {};");
-  }
-
-  public void testFunctionTypeAlias() {
-    Map<String, ClassNodeElement> classes = loadSource(
-        "typedef void VoidFunction();",
-        "typedef String StringFunction();",
-        "typedef String IntToStringFunction(int i);",
-        "class Foo {",
-        "  VoidFunction voidFunction;",
-        "  StringFunction stringFunction;",
-        "  IntToStringFunction intToStringFunction;",
-        "  Foo foo;",
-        "  String string;",
-        "  int i;",
-        "}");
-    analyzeClasses(classes);
-    ClassElement foo = classes.get("Foo");
-    analyzeIn(foo, "voidFunction()", 0);
-    analyzeIn(foo, "voidFunction(1)", 1);
-    analyzeIn(foo, "this.voidFunction()", 0);
-    analyzeIn(foo, "this.voidFunction(1)", 1);
-    analyzeIn(foo, "foo.voidFunction()", 0);
-    analyzeIn(foo, "foo.voidFunction(1)", 1);
-    analyzeIn(foo, "(voidFunction)()", 0);
-    analyzeIn(foo, "(voidFunction)(1)", 1);
-    analyzeIn(foo, "(this.voidFunction)()", 0);
-    analyzeIn(foo, "(this.voidFunction)(1)", 1);
-    analyzeIn(foo, "(foo.voidFunction)()", 0);
-    analyzeIn(foo, "(foo.voidFunction)(1)", 1);
-
-    analyzeIn(foo, "string = stringFunction()", 0);
-    analyzeIn(foo, "i = stringFunction()", 1);
-    analyzeIn(foo, "string = this.stringFunction()", 0);
-    analyzeIn(foo, "i = this.stringFunction()", 1);
-    analyzeIn(foo, "string = foo.stringFunction()", 0);
-    analyzeIn(foo, "i = foo.stringFunction()", 1);
-    analyzeIn(foo, "string = (stringFunction)()", 0);
-    analyzeIn(foo, "i = (stringFunction)()", 1);
-    analyzeIn(foo, "string = (this.stringFunction)()", 0);
-    analyzeIn(foo, "i = (this.stringFunction)()", 1);
-    analyzeIn(foo, "string = (foo.stringFunction)()", 0);
-    analyzeIn(foo, "i = (foo.stringFunction)()", 1);
-
-    analyzeIn(foo, "voidFunction = stringFunction", 0);
-    analyzeIn(foo, "stringFunction = intToStringFunction", 1);
-    analyzeIn(foo, "stringFunction = () { return ''; }", 0);
-    analyzeIn(foo, "intToStringFunction = () { return ''; }", 1);
-  }
-
-  public void testFunctionTypes() {
-    checkFunctionStatement("String foo() {};", "() -> String");
-    checkFunctionStatement("Object foo() {};", "() -> Object");
-    checkFunctionStatement("String foo(int i, bool b) {};", "(int, bool) -> String");
-  }
-
-  public void testGetAllSupertypes()
-      throws CyclicDeclarationException {
-    Map<String, ClassNodeElement> classes = loadSource(
-        "class A extends B<String> {",
-        "}",
-        "class B<T> extends C<G<T>> implements I<int>, I1<T> {",
-        "}",
-        "class C<U> {",
-        "}",
-        "abstract class I<S> extends I2<bool> {",
-        "}",
-        "class G<V> {",
-        "}",
-        "abstract class I1<W> {",
-        "}",
-        "abstract class I2<X> {",
-        "}",
-        "class D implements I2<int> {",
-        "}",
-        "class E extends D implements I2<int> {",
-        "}");
-    analyzeClasses(classes);
-    assertEquals("[]", object.getAllSupertypes().toString());
-    assertEquals("[B<String>, I<int>, I1<String>, I2<bool>, C<G<String>>, Object]",
-                 classes.get("A").getAllSupertypes().toString());
-    assertEquals("[I<int>, I1<B.T>, I2<bool>, C<G<B.T>>, Object]",
-                 classes.get("B").getAllSupertypes().toString());
-    assertEquals("[Object]", classes.get("C").getAllSupertypes().toString());
-    assertEquals("[I2<bool>, Object]", classes.get("I").getAllSupertypes().toString());
-    assertEquals("[Object]", classes.get("G").getAllSupertypes().toString());
-    assertEquals("[Object]", classes.get("I1").getAllSupertypes().toString());
-    assertEquals("[Object]", classes.get("I2").getAllSupertypes().toString());
-    assertEquals("[I2<int>, Object]", classes.get("D").getAllSupertypes().toString());
-    assertEquals("[I2<int>, D, I2<int>, Object]", classes.get("E").getAllSupertypes().toString());
-  }
-
-  public void testIdentifiers() {
-    analyze("{ int i; i = 2; }");
-    analyze("{ int j, k; j = 1; k = 3; }");
-    analyzeFail("{ int i; i = 'string'; }", TypeErrorCode.TYPE_NOT_ASSIGNMENT_COMPATIBLE);
-    analyzeFail("{ int j, k; k = 'string'; }",
-        TypeErrorCode.TYPE_NOT_ASSIGNMENT_COMPATIBLE);
-    analyzeFail("{ int j, k; j = 'string'; }",
-        TypeErrorCode.TYPE_NOT_ASSIGNMENT_COMPATIBLE);
-  }
-
-  public void testIfStatement() {
-    analyze("if (true) {}");
-    analyze("if (null) {}");
-    analyzeFail("if (0) {}",
-    TypeErrorCode.TYPE_NOT_ASSIGNMENT_COMPATIBLE);
-    analyzeFail("if ('') {}",
-      TypeErrorCode.TYPE_NOT_ASSIGNMENT_COMPATIBLE);
-    analyzeFail("{ int i = 27; if (true) { i = 2.7; } else {} }",
-      TypeErrorCode.TYPE_NOT_ASSIGNMENT_COMPATIBLE);
-    analyzeFail("{ int i = 27; if (true) {} else { i = 2.7; } }",
-      TypeErrorCode.TYPE_NOT_ASSIGNMENT_COMPATIBLE);
-  }
-
-  public void testImplementsAndOverrides() {
-    analyzeClasses(loadSource(
-        "abstract class Interface {",
-        "  void foo(int x);",
-        "  void bar();",
-        "}",
-        // Abstract class not reported until first instantiation.
-        "abstract class Class implements Interface {",
-        "  Class() {}",
-        "  String bar() { return null; }",
-        "}",
-        // Abstract class not reported until first instantiation.
-        "abstract class SubClass extends Class {",
-        "  SubClass() : super() {}",
-        "  Object bar() { return null; }",
-        "}",
-        "class SubSubClass extends Class {",
-        "  num bar() { return null; }", // CANNOT_OVERRIDE_METHOD_NOT_SUBTYPE
-        "  void foo(String x) {}", // CANNOT_OVERRIDE_METHOD_NOT_SUBTYPE
-        "}",
-        "class Usage {",
-        "  m() {",
-        "  }",
-        "}"),
-        TypeErrorCode.CANNOT_OVERRIDE_METHOD_NOT_SUBTYPE,
-        TypeErrorCode.CANNOT_OVERRIDE_METHOD_NOT_SUBTYPE);
-  }
-
-  public void testImplementsAndOverrides2() {
-    analyzeClasses(loadSource(
-        "abstract class Interface {",
-        "  void foo(int x);",
-        "}",
-        // Abstract class not reported until first instantiation.
-        "class Class implements Interface {",
-        "  Class() {}",
-        "  void foo(String x) {}", // CANNOT_OVERRIDE_METHOD_NOT_SUBTYPE
-        "}"),
-        TypeErrorCode.CANNOT_OVERRIDE_METHOD_NOT_SUBTYPE);
-  }
-
-  public void testInitializedFields() {
-    Map<String, ClassNodeElement> classes = loadSource(
-        "class GoodField {",
-        "  static final int i = 1;",
-        "}");
-    analyzeClass(classes.get("GoodField"), 0);
-
-    // Note, the TypeAnalyzer doesn't get a chance
-    // to get its hands on bad initializers anymore
-    // due to type checking in CompileTimeConstVisitor.
-  }
-
-  public void testInitializedLocals() {
-    analyze("void f([int x = 1]) {}");
-    analyzeFail("void f([int x = '']) {}", TypeErrorCode.TYPE_NOT_ASSIGNMENT_COMPATIBLE);
-
-    analyze("{ int x = 1; }");
-    analyzeFail("{ int x = ''; }", TypeErrorCode.TYPE_NOT_ASSIGNMENT_COMPATIBLE);
-  }
-
-  public void testInitializers() {
-    analyze("int i = 1;");
-    analyze("double d1 = .0;");
-    analyze("double d2 = 1.0;");
-    analyze("int x = null;");
-  }
-
-  public void testLabels() {
-    // Labels should be inside a function or method to be used
-
-    // break
-    analyze("foo() { L: for (;true;) { break L; } }");
-    analyze("foo() { int x; List<int> c; L: for (x  in c) { break L; } }");
-    analyze("foo() { List<int> c; L: for (var x  in c) { break L; } }");
-    analyze("foo() { L: while (true) { break L; } }");
-    analyze("foo() { L: do { break L; } while (true); }");
-
-    analyze("foo() { L: for (;true;) { for (;true;) { break L; } } }");
-    analyze("foo() { int x; List<int> c; L: for (x  in c) { for (;true;) { break L; } } }");
-    analyze("foo() { List<int> c; L: for (var x  in c) { for (;true;) { break L; } } }");
-    analyze("foo() { L: while (true) { for (;true;) { break L; } } }");
-    analyze("foo() { L: do { for (;true;) { break L; } } while (true); }");
-
-    // continue
-    analyze("foo() { L: for (;true;) { continue L; } }");
-    analyze("foo() { int x; List<int> c; L: for (x  in c) { continue L; } }");
-    analyze("foo() { List<int> c; L: for (var x  in c)  { continue L; } }");
-    analyze("foo() { L: do { continue L; } while (true); }");
-
-    analyze("foo() { L: for (;true;) { for (;true;) { continue L; } } }");
-    analyze(
-      "foo() { int x; List<int> c; L: for (x  in c) { for (;true;) { continue L; } } }");
-    analyze("foo() { List<int> c; L: for (var x  in c)  { for (;true;) { continue L; } } }");
-    analyze("foo() { L: while (true) { for (;true;) { continue L; } } }");
-    analyze("foo() { L: do { for (;true;) { continue L; } } while (true); }");
-
-    // corner cases
-    analyze("foo() { L: break L; }");
-
-    // TODO(zundel): Not type errors, but warnings.
-    analyze("foo() { L: for (;true;) { } }");
-    analyze("foo() { while (true) { L: var a; } }");
-  }
-
-  public void testLiterals() {
-    checkSimpleType(intElement.getType(), "1");
-    checkSimpleType(doubleElement.getType(), ".0");
-    checkSimpleType(doubleElement.getType(), "1.0");
-    checkSimpleType(bool.getType(), "true");
-    checkSimpleType(bool.getType(), "false");
-    checkSimpleType(string.getType(), "'fisk'");
-    checkSimpleType(string.getType(), "'f${null}sk'");
-  }
-
-  public void testMapLiteral() {
-    analyze("{ var x = {\"key\": 42}; }");
-    analyze("{ var x = {'key': 42}; }");
-    analyze("{ var x = <num>{'key': 42}; }");
-    analyze("{ var x = <int>{'key': 42}; }");
-    analyze("{ var x = <num>{'key': 0.42}; }");
-    analyze("{ var x = <num>{'key': 42}; }");
-    analyzeFail("{ var x = <int>{'key': 0.42}; }",
-      TypeErrorCode.TYPE_NOT_ASSIGNMENT_COMPATIBLE);
-    analyzeFail("{ int i; var x = {'key': i = 0.42}; }",
-      TypeErrorCode.TYPE_NOT_ASSIGNMENT_COMPATIBLE);
-    analyze("{ var x = const {\"key\": 42}; }");
-    analyze("{ var x = const {'key': 42}; }");
-    analyze("{ var x = const <num>{'key': 42}; }");
-    analyze("{ var x = const <int>{'key': 42}; }");
-    analyze("{ var x = const <num>{'key': 0.42}; }");
-    analyze("{ var x = const <num>{'key': 42}; }");
-    analyzeFail("{ var x = const <int>{'key': 0.42}; }",
-      TypeErrorCode.TYPE_NOT_ASSIGNMENT_COMPATIBLE);
-    analyzeFail("{ int i; var x = const {'key': i = 0.42}; }",
-      TypeErrorCode.TYPE_NOT_ASSIGNMENT_COMPATIBLE);
-    analyzeFail("{Map<num, num> x = const <num>{}; }",
-      TypeErrorCode.TYPE_NOT_ASSIGNMENT_COMPATIBLE);
-  }
-
-  public void testMethodInvocationArgumentCount() {
-    loadFile("class_with_methods.dart");
-    final String header = "{ ClassWithMethods c; ";
-
-    analyzeFail(header + "c.untypedNoArgumentMethod(1); }",
-      TypeErrorCode.EXTRA_ARGUMENT);
-    analyzeFail(header + "c.untypedOneArgumentMethod(); }",
-      TypeErrorCode.MISSING_ARGUMENT);
-    analyzeFail(header + "c.untypedOneArgumentMethod(1, 1); }",
-      TypeErrorCode.EXTRA_ARGUMENT);
-    analyzeFail(header + "c.untypedTwoArgumentMethod(); }",
-        TypeErrorCode.MISSING_ARGUMENT);
-    analyzeFail(header + "c.untypedTwoArgumentMethod(1, 2, 3); }",
-      TypeErrorCode.EXTRA_ARGUMENT);
-    analyzeFail(header + "c.intNoArgumentMethod(1); }",
-      TypeErrorCode.EXTRA_ARGUMENT);
-    analyzeFail(header + "c.intOneArgumentMethod(); }",
-        TypeErrorCode.MISSING_ARGUMENT);
-    analyzeFail(header + "c.intOneArgumentMethod(1, 1); }",
-      TypeErrorCode.EXTRA_ARGUMENT);
-    analyzeFail(header + "c.intTwoArgumentMethod(); }",
-        TypeErrorCode.MISSING_ARGUMENT);
-    analyzeFail(header + "c.intTwoArgumentMethod(1, 2, 3); }",
-      TypeErrorCode.EXTRA_ARGUMENT);
-    analyze(header + "c.untypedField(); }");
-  }
-
-  public void testMethodInvocations() {
-    loadFile("class_with_methods.dart");
-    final String header = "{ ClassWithMethods c; int i, j; ";
-
-    analyze(header + "int k = c.untypedNoArgumentMethod(); }");
-    analyze(header + "ClassWithMethods x = c.untypedNoArgumentMethod(); }");
-
-    analyze(header + "int k = c.untypedOneArgumentMethod(c); }");
-    analyze(header + "ClassWithMethods x = c.untypedOneArgumentMethod(1); }");
-    analyze(header + "int k = c.untypedOneArgumentMethod('string'); }");
-    analyze(header + "int k = c.untypedOneArgumentMethod(i); }");
-
-    analyze(header + "int k = c.untypedTwoArgumentMethod(1, 'string'); }");
-    analyze(header + "int k = c.untypedTwoArgumentMethod(i, j); }");
-    analyze(header + "ClassWithMethods x = c.untypedTwoArgumentMethod(i, c); }");
-
-    analyze(header + "int k = c.intNoArgumentMethod(); }");
-    analyzeFail(header + "ClassWithMethods x = c.intNoArgumentMethod(); }",
-        TypeErrorCode.TYPE_NOT_ASSIGNMENT_COMPATIBLE);
-
-    analyzeFail(header + "int k = c.intOneArgumentMethod(c); }",
-        TypeErrorCode.TYPE_NOT_ASSIGNMENT_COMPATIBLE);
-    analyzeFail(header + "ClassWithMethods x = c.intOneArgumentMethod(1); }",
-        TypeErrorCode.TYPE_NOT_ASSIGNMENT_COMPATIBLE);
-    analyzeFail(header + "int k = c.intOneArgumentMethod('string'); }",
-      TypeErrorCode.TYPE_NOT_ASSIGNMENT_COMPATIBLE);
-    analyze(header + "int k = c.intOneArgumentMethod(i); }");
-
-    analyzeFail(header + "int k = c.intTwoArgumentMethod(1, 'string'); }",
-      TypeErrorCode.TYPE_NOT_ASSIGNMENT_COMPATIBLE);
-    analyze(header + "int k = c.intTwoArgumentMethod(i, j); }");
-    analyzeFail(header + "ClassWithMethods x = c.intTwoArgumentMethod(i, j); }",
-        TypeErrorCode.TYPE_NOT_ASSIGNMENT_COMPATIBLE);
-  }
-
-  public void testNamedFunctionTypeAlias() {
-    loadFile("named_function_type_alias.dart");
-    analyze("VoidFunction f = () {};");
-  }
-
-  public void testOddStuff() {
-    Map<String, ClassNodeElement> classes = analyzeClasses(loadSource(
-        "class Class {",
-        "  Class() {}",
-        "  var field;",
-        "  void m() {}",
-        "  static void f() {}",
-        "  static g(int i) {}",
-        "}"));
-    ClassElement cls = classes.get("Class");
-    analyzeIn(cls, "m().foo()", 1);
-    analyzeIn(cls, "m().x", 1);
-    analyzeIn(cls, "m()", 0);
-    analyzeIn(cls, "(m)().foo()", 1);
-    analyzeIn(cls, "(m)().x", 1);
-    analyzeIn(cls, "(m)()", 0);
-    analyzeIn(cls, "field = m()", 1);
-    analyzeIn(cls, "field = Class.f()", 1);
-    analyzeIn(cls, "field = (Class.f)()", 1);
-    analyzeIn(cls, "Class.f()", 0);
-    analyzeIn(cls, "(Class.f)()", 0);
-    analyzeIn(cls, "field = Class.g('x')", 1);
-    analyzeIn(cls, "field = (Class.g)('x')", 1);
-    analyzeIn(cls, "field = Class.g(0)", 0);
-    analyzeIn(cls, "field = (Class.g)(0)", 0);
-    analyzeFail("fisk: while (true) fisk++;", TypeErrorCode.CANNOT_BE_RESOLVED);
-    analyzeFail("new Class().m().x;", TypeErrorCode.VOID);
-    analyzeFail("(new Class().m)().x;", TypeErrorCode.VOID);
-  }
-
-  public void testParameterAccess() {
-    analyze("{ f(int x) { x = 1; } }");
-    analyzeFail("{ f(String x) { x = 1; } }",
-      TypeErrorCode.TYPE_NOT_ASSIGNMENT_COMPATIBLE);
-    analyze("{ f(int x, int y) { x = y; } }");
-    analyzeFail("{ f(String x, int y) { x = y; } }",
-      TypeErrorCode.TYPE_NOT_ASSIGNMENT_COMPATIBLE);
-    analyze("{ f(x, int y) { x = y; } }");
-    analyze("{ f(x, int y) { x = y; } }");
-    analyzeFail("{ f(String x) { x = 1;} }",
-      TypeErrorCode.TYPE_NOT_ASSIGNMENT_COMPATIBLE);
-  }
-
-  public void testParameterInitializers() {
-    Map<String, ClassNodeElement> classes = loadSource(
-        "class C1 { int i; C1(this.i) {} }",
-        "class C2 { String s; C2(int this.s) {} }",
-        "class C3 { int i; C3(double this.i) {} }",
-        "class C4 { int i; C4(num this.i) {} }");
-    analyzeClass(classes.get("C1"), 0);
-    analyzeClass(classes.get("C2"), 1);
-    analyzeClass(classes.get("C3"), 1);
-    analyzeClass(classes.get("C4"), 0);
-  }
-
-  public void testPropertyAccess() {
-    ClassElement cls = loadClass("classes_with_properties.dart", "ClassWithProperties");
-    analyzeIn(cls, "null", 0);
-    analyzeIn(cls, "noSuchField", 1);
-    analyzeIn(cls, "noSuchMethod()", 1);
-    analyzeIn(cls, "x.noSuchField", 0);
-    analyzeIn(cls, "x.noSuchMethod()", 0);
-    analyzeIn(cls, "x.x.noSuchField", 0);
-    analyzeIn(cls, "x.x.noSuchMethod()", 0);
-    analyzeIn(cls, "x.a.noSuchField", 0);
-    analyzeIn(cls, "x.a.noSuchMethod()", 0);
-    String[] typedFields = { "a", "b", "c"};
-    for (String field : typedFields) {
-      analyzeIn(cls, field + ".noSuchField", 1);
-      analyzeIn(cls, field + ".noSuchMethod()", 1);
-      analyzeIn(cls, field + ".a", 0);
-      analyzeIn(cls, field + ".a()", 1);
-    }
-  }
-
-  public void testReturn() {
-    analyzeFail(returnWithType("int", "'string'"),
-      TypeErrorCode.TYPE_NOT_ASSIGNMENT_COMPATIBLE);
-    analyze(returnWithType("", "'string'"));
-    analyze(returnWithType("Object", "'string'"));
-    analyze(returnWithType("String", "'string'"));
-    analyze(returnWithType("String", null));
-    analyze(returnWithType("int", null));
-    analyze(returnWithType("void", ""));
-    analyzeFail(returnWithType("void", 1), TypeErrorCode.TYPE_NOT_ASSIGNMENT_COMPATIBLE);
-    analyze(returnWithType("void", null));
-    analyzeFail(returnWithType("String", ""), TypeErrorCode.MISSING_RETURN_VALUE);
-    analyze("String foo() {};"); // Should probably fail, http://b/4484060.
-  }
-
-  public void testSuper() {
-    ClassElement sub = loadClass("covariant_class.dart", "Sub");
-    checkAssignIn(sub, "B", "field", 0);
-    checkAssignIn(sub, "C", "field", 1);
-    checkAssignIn(sub, "D", "field", 1);
-
-    checkAssignIn(sub, "B", "super.field", 0);
-    checkAssignIn(sub, "C", "super.field", 0);
-    checkAssignIn(sub, "D", "super.field", 1);
-
-    checkAssignIn(sub, "B", "accessor", 0);
-    checkAssignIn(sub, "C", "accessor", 1);
-    checkAssignIn(sub, "D", "accessor", 1);
-
-    checkAssignIn(sub, "B", "super.accessor", 0);
-    checkAssignIn(sub, "C", "super.accessor", 0);
-    checkAssignIn(sub, "D", "super.accessor", 1);
-
-    analyzeIn(sub, "accessor = b", 0);
-    analyzeIn(sub, "accessor = c", 1);
-    analyzeIn(sub, "accessor = d", 1);
-
-    analyzeIn(sub, "super.accessor = b", 0);
-    analyzeIn(sub, "super.accessor = c", 0);
-    analyzeIn(sub, "super.accessor = d", 1);
-
-    checkAssignIn(sub, "B", "method()", 0);
-    checkAssignIn(sub, "C", "method()", 1);
-    checkAssignIn(sub, "D", "method()", 1);
-
-    checkAssignIn(sub, "B", "super.untypedMethod()", 0);
-    checkAssignIn(sub, "C", "super.untypedMethod()", 0);
-    checkAssignIn(sub, "D", "super.untypedMethod()", 0);
-
-    checkAssignIn(sub, "B", "super.untypedField", 0);
-    checkAssignIn(sub, "C", "super.untypedField", 0);
-    checkAssignIn(sub, "D", "super.untypedField", 0);
-
-    checkAssignIn(sub, "B", "super.untypedAccessor", 0);
-    checkAssignIn(sub, "C", "super.untypedAccessor", 0);
-    checkAssignIn(sub, "D", "super.untypedAccessor", 0);
-
-    analyzeIn(sub, "super.untypedAccessor = b", 0);
-    analyzeIn(sub, "super.untypedAccessor = c", 0);
-    analyzeIn(sub, "super.untypedAccessor = d", 0);
-
-    checkAssignIn(sub, "B", "super.untypedMethod()", 0);
-    checkAssignIn(sub, "C", "super.untypedMethod()", 0);
-    checkAssignIn(sub, "D", "super.untypedMethod()", 0);
-  }
-
-  public void testSuperConstructorInvocation() {
-    Map<String, ClassNodeElement> classes = loadSource(
-        "class Super {",
-        "  Super(int x) {}",
-        "  Super.foo() {}",
-        "  Super.bar([int i = null]) {}",
-        "}",
-        "class BadSub extends Super {",
-        "  BadSub() : super('x') {}",
-        "  BadSub.foo() : super.foo('x') {}",
-        "  BadSub.bar() : super() {}",
-        "  BadSub.baz() : super.foo(null) {}",
-        "  BadSub.fisk() : super.bar('') {}",
-        "  BadSub.hest() : super.bar(1, 2) {}",
-        "}",
-        "class NullSub extends Super {",
-        "  NullSub() : super(null) {}",
-        "  NullSub.foo() : super.bar(null) {}",
-        "  NullSub.bar() : super.bar() {}",
-        "}",
-        "class IntSub extends Super {",
-        "  IntSub() : super(1) {}",
-        "  IntSub.foo() : super.bar(1) {}",
-        "}",
-        // The following works fine, but was claimed to be a bug:
-        "class A {",
-        "  int value;",
-        "  A([this.value = 3]) {}",
-        "}",
-        "class B extends A {",
-        "  B() : super() {}",
-        "}");
-    analyzeClass(classes.get("Super"), 0);
-    analyzeClass(classes.get("BadSub"), 6);
-    analyzeClass(classes.get("NullSub"), 0);
-    analyzeClass(classes.get("IntSub"), 0);
-    analyzeClass(classes.get("A"), 0);
-    analyzeClass(classes.get("B"), 0);
-  }
-
-  public void testSwitch() {
-    analyze("{ int i = 27; switch(i) { case i: break; } }");
-    analyzeFail(
-        "{ switch(true) { case 1: break; case 'foo': break; }}",
-        TypeErrorCode.TYPE_NOT_ASSIGNMENT_COMPATIBLE);
-    analyzeFail(
-        "{ int i = 27; switch(true) { case false: i = 2.7; }}",
-        TypeErrorCode.TYPE_NOT_ASSIGNMENT_COMPATIBLE);
-  }
-
-  public void testThis() {
-    Map<String, ClassNodeElement> classes = loadFile("class_with_supertypes.dart");
-    ClassElement superclass = classes.get("Superclass");
-    assertNotNull("unable to locate Superclass", superclass);
-    ClassElement subclass = classes.get("ClassWithSupertypes");
-    assertNotNull("unable to locate ClassWithSupertypes", subclass);
-    analyzeIn(superclass, "() { String x = this; }", 1);
-    analyzeIn(superclass, "() { var x = this; }", 0);
-    analyzeIn(superclass, "() { ClassWithSupertypes x = this; }", 0);
-    analyzeIn(superclass, "() { Superclass x = this; }", 0);
-    analyzeIn(superclass, "() { Interface x = this; }", 1);
-    analyzeIn(subclass, "() { Interface x = this; }", 0);
-  }
-
-  public void testTryCatchFinally() {
-    analyze("try { } catch (_) { } finally { }");
-    analyzeFail("try { int i = 4.2; } catch (_) { } finally { }",
-      TypeErrorCode.TYPE_NOT_ASSIGNMENT_COMPATIBLE);
-    analyzeFail("try { } catch (_) { int i = 4.2; } finally { }",
-      TypeErrorCode.TYPE_NOT_ASSIGNMENT_COMPATIBLE);
-    analyzeFail("try { } catch (_) { } finally { int i = 4.2; }",
-      TypeErrorCode.TYPE_NOT_ASSIGNMENT_COMPATIBLE);
-  }
-
-  public void testTypeVariables() {
-    ClassElement cls = loadFile("class_with_type_parameter.dart").get("ClassWithTypeParameter");
-    assertNotNull("unable to locate ClassWithTypeParameter", cls);
-    analyzeIn(cls, "aField = tField", 0);
-    analyzeIn(cls, "bField = tField", 0);
-    analyzeIn(cls, "tField = aField", 0);
-    analyzeIn(cls, "tField = bField", 0);
-    analyzeIn(cls, "tField = null", 0);
-    analyzeIn(cls, "tField = 1", 1);
-    analyzeIn(cls, "tField = ''", 1);
-    analyzeIn(cls, "tField = true", 1);
-
-    analyzeIn(cls, "() { A a = null; T t = a; }()", 0);
-    analyzeIn(cls, "() { B b = null; T t = b; }()", 0);
-    analyzeIn(cls, "() { T t = null; A a = t; }()", 0);
-    analyzeIn(cls, "() { T t = null; B b = t; }()", 0);
-    analyzeIn(cls, "() { T t = 1; }()", 1);
-    analyzeIn(cls, "() { T t = ''; }()", 1);
-    analyzeIn(cls, "() { T t = true; }()", 1);
-  }
-
-  public void testUnaryOperators() {
-    Map<String, ClassNodeElement> source = loadSource(
-        "class Foo {",
-        "  Foo foo;",
-        "  bool b;",
-        "  int i;",
-        "  Foo operator +(int operand) { return this; }",
-        "  Foo operator -(int operand) { return this; }",
-        "}",
-        "class Bar {",
-        "  Bar bar;",
-        "  Bar operator +(Bar operand) { return this; }",
-        "  Bar operator -(Bar operand) { return this; }",
-        "}",
-        "class Baz<T extends Foo> {",
-        "  T baz;",
-        "}",
-        "class Qux<T> { ",
-        "  T qux; ",
-        "  void x() { }",
-        "  y() { }",
-        "}",
-        "class X {",
-        "  X x;",
-        "  Z operator +(int operand) { return null; }",
-        "  Z operator -(int operand) { return null; }",
-        "}",
-        "class Y extends X { Y y; }",
-        "class Z extends X { Z z; }"
-        );
-    analyzeClasses(source);
-    ClassElement foo = source.get("Foo");
-    ClassElement bar = source.get("Bar");
-    ClassElement baz = source.get("Baz");
-    ClassElement qux = source.get("Qux");
-    ClassElement y = source.get("Y");
-    ClassElement z = source.get("Z");
-    for (Token op : EnumSet.of(Token.DEC, Token.INC)) {
-      analyzeIn(foo, String.format("%sfoo", op), 0);
-      analyzeIn(foo, String.format("i = %sfoo", op), 1);
-      analyzeIn(bar, String.format("%sbar", op), 1);
-      analyzeIn(baz, String.format("%sbaz", op), 0);
-      analyzeIn(qux, String.format("%squx", op), 1);
-    }
-    analyzeIn(z, "z = x++", 0);
-    analyzeIn(z, "z = ++x", 0);
-    analyzeIn(z, "z = x--", 0);
-    analyzeIn(z, "z = --x", 0);
-    analyzeIn(y, "y = x++", 0);
-    analyzeIn(y, "y = ++x", 1);
-    analyzeIn(y, "y = x--", 0);
-    analyzeIn(y, "y = --x", 1);
-
-    analyzeIn(foo, "b = !b", 0);
-    analyzeIn(foo, "foo = !foo", 2);
-    analyzeIn(foo, "b = !i", 1);
-    analyzeIn(foo, "foo = !b", 1);
-    analyzeIn(qux, "-x()", 1);
-    analyzeIn(qux, "-y()", 0);
-  }
-
-  public void testUnqualified() {
-    ClassElement element = loadClass("class_with_methods.dart", "ClassWithMethods");
-    checkAssignIn(element, "var", "intNoArgumentMethod()", 0);
-    checkAssignIn(element, "var", "intOneArgumentMethod(1)", 0);
-    checkAssignIn(element, "var", "intOneArgumentMethod('')", 1);
-    checkAssignIn(element, "int", "intNoArgumentMethod()", 0);
-    checkAssignIn(element, "int", "intOneArgumentMethod(1)", 0);
-    checkAssignIn(element, "int", "intOneArgumentMethod('')", 1);
-    checkAssignIn(element, "String", "intNoArgumentMethod()", 1);
-    checkAssignIn(element, "String", "intOneArgumentMethod(1)", 1);
-    checkAssignIn(element, "String", "intOneArgumentMethod('')", 2);
-
-    checkAssignIn(element, "var", "functionField()", 0);
-    checkAssignIn(element, "int", "functionField()", 0);
-    checkAssignIn(element, "String", "functionField()", 0);
-
-    checkAssignIn(element, "var", "functionField(1)", 0);
-    checkAssignIn(element, "int", "functionField('x')", 0);
-    checkAssignIn(element, "String", "functionField(2.2)", 0);
-
-
-    checkAssignIn(element, "var", "untypedField()", 0);
-    checkAssignIn(element, "int", "untypedField()", 0);
-    checkAssignIn(element, "String", "untypedField()", 0);
-
-    checkAssignIn(element, "var", "untypedField(1)", 0);
-    checkAssignIn(element, "int", "untypedField('x')", 0);
-    checkAssignIn(element, "String", "untypedField(2.2)", 0);
-
-    checkAssignIn(element, "var", "intField()", 1);
-    checkAssignIn(element, "int", "intField()", 1);
-    checkAssignIn(element, "String", "intField()", 1);
-
-    checkAssignIn(element, "var", "intField(1)", 1);
-    checkAssignIn(element, "int", "intField('x')", 1);
-    checkAssignIn(element, "String", "intField(2.2)", 1);
-
-    analyzeIn(element, "(x) { x(); }", 0);
-    analyzeIn(element, "(int x) { x(); }", 1);
-    analyzeIn(element, "(int x()) { int i = x(); }", 0);
-    analyzeIn(element, "(int x(String s)) { int i = x(1); }", 1);
-    analyzeIn(element, "(int x(String s)) { int i = x(''); }", 0);
-  }
-
-  public void testUnqualifiedGeneric() {
-    ClassElement element = loadClass("generic_class_with_supertypes.dart",
-                                     "GenericClassWithSupertypes");
-
-    checkAssignIn(element, "var", "localField", 0);
-    checkAssignIn(element, "T1", "localField", 0);
-    checkAssignIn(element, "T2", "localField", 1);
-
-    checkAssignIn(element, "var", "superField", 0);
-    checkAssignIn(element, "T1", "superField", 1);
-    checkAssignIn(element, "T2", "superField", 0);
-
-    checkAssignIn(element, "var", "interfaceField", 0);
-    checkAssignIn(element, "T1", "interfaceField", 0);
-    checkAssignIn(element, "T2", "interfaceField", 1);
-
-    checkAssignIn(element, "var", "localMethod(t2)", 0);
-    checkAssignIn(element, "T1", "localMethod(t2)", 0);
-    checkAssignIn(element, "T2", "localMethod(t2)", 1);
-
-    checkAssignIn(element, "var", "superMethod(t1)", 0);
-    checkAssignIn(element, "T1", "superMethod(t1)", 1);
-    checkAssignIn(element, "T2", "superMethod(t1)", 0);
-
-    checkAssignIn(element, "var", "interfaceMethod(t1)", 0);
-    checkAssignIn(element, "T1", "interfaceMethod(t1)", 0);
-    checkAssignIn(element, "T2", "interfaceMethod(t1)", 1);
-  }
-
-  public void testUnresolved() {
-    ClassElement element = loadClass("class_with_supertypes.dart", "ClassWithSupertypes");
-    analyzeIn(element, "this.field", 0);
-    analyzeIn(element, "null", 0);
-    analyzeIn(element, "noSuchField", 1);
-    analyzeIn(element, "noSuchMethod()", 1);
-    analyzeIn(element, "method()", 0);
-    analyzeIn(element, "field", 0);
-    analyzeIn(element, "this.noSuchField", 1);
-    analyzeIn(element, "this.noSuchMethod()", 1);
-    analyzeIn(element, "this.method()", 0);
-    analyzeIn(element, "staticMethod()", 0);
-    analyzeIn(element, "staticField", 0);
-    analyzeIn(element, "this.staticMethod()", 1);
-    analyzeIn(element, "this.staticField", 1);
-    analyzeIn(element, "ClassWithSupertypes.staticMethod()", 0);
-    analyzeIn(element, "ClassWithSupertypes.staticField", 0);
-    analyzeIn(element, "methodInSuperclass()", 0);
-    analyzeIn(element, "fieldInSuperclass", 0);
-    analyzeIn(element, "staticMethodInSuperclass()", 0);
-    analyzeIn(element, "staticFieldInSuperclass", 0);
-    analyzeIn(element, "this.methodInSuperclass()", 0);
-    analyzeIn(element, "this.fieldInSuperclass", 0);
-    analyzeIn(element, "this.staticMethodInSuperclass()", 1);
-    analyzeIn(element, "this.staticFieldInSuperclass", 1);
-    analyzeIn(element, "Superclass.staticMethodInSuperclass()", 0);
-    analyzeIn(element, "Superclass.staticFieldInSuperclass", 0);
-    analyzeIn(element, "methodInInterface()", 0);
-    analyzeIn(element, "fieldInInterface", 0);
-    analyzeIn(element, "this.methodInInterface()", 0);
-    analyzeIn(element, "this.fieldInInterface", 0);
-    analyzeIn(element, "staticFieldInInterface", 0);
-    analyzeIn(element, "Interface.staticFieldInInterface", 0);
-    analyzeIn(element, "this.staticFieldInInterface", 1);
-  }
-
-  public void testUnresolvedIdentifier() {
-    setExpectedTypeErrorCount(3);
-    checkType(typeProvider.getDynamicType(), "y");
-    checkExpectedTypeErrorCount();
-  }
-
-  public void testVoid() {
-    // Return a value from a void function.
-    analyze("void f() { return; }");
-    analyze("void f() { return null; }");
-    analyze("void f() { return f(); }");
-    analyzeFail("void f() { return 1; }", TypeErrorCode.TYPE_NOT_ASSIGNMENT_COMPATIBLE);
-    analyze("void f() { var x; return x; }");
-
-    // No-arg return from non-void function.
-    analyzeFail("int f() { return; }", TypeErrorCode.MISSING_RETURN_VALUE);
-    analyze("f() { return; }");
-
-    // Calling a method on a void expression, property access.
-    analyzeFail("void f() { f().m(); }", TypeErrorCode.VOID);
-    analyzeFail("void f() { f().x; }", TypeErrorCode.VOID);
-
-    // Passing a void argument to a method.
-    analyzeFail("{ void f() {} m(x) {} m(f()); }", TypeErrorCode.VOID);
-
-    // Assigning a void expression to a variable.
-    analyzeFail("{ void f() {} int x = f(); }", TypeErrorCode.VOID);
-    analyzeFail("{ void f() {} int x; x = f(); }", TypeErrorCode.VOID);
-    analyzeFail("{ void f() {} int x; x += f(); }", TypeErrorCode.VOID);
-
-    // Misc.
-    analyzeFail("{ void f() {} 1 + f(); }", TypeErrorCode.VOID);
-    analyzeFail("{ void f() {} f() + 1; }", TypeErrorCode.VOID);
-    analyzeFail("{ void f() {} var x; x && f(); }", TypeErrorCode.VOID);
-    analyzeFail("{ void f() {} !f(); }", TypeErrorCode.VOID);
-    analyzeFail("{ void f() {} -f(); }", TypeErrorCode.VOID);
-    // We seem to throw away prefix-plus in the parser:
-    // analyzeFail("{ void f() {} +f(); }", TypeErrorCode.VOID);
-    analyzeFail("{ void f() {} var x; x == f(); }", TypeErrorCode.VOID);
-    analyzeFail("{ void f() {} while (f()); }", TypeErrorCode.VOID);
-    analyzeFail("{ void f() {}; ({ 'x': f() }); }", TypeErrorCode.VOID);
-  }
-
-  public void testWhileStatement() {
-    analyze("while (true) {}");
-    analyze("while (null) {}");
-    analyzeFail("while (0) {}",
-      TypeErrorCode.TYPE_NOT_ASSIGNMENT_COMPATIBLE);
-    analyzeFail("while ('') {}",
-      TypeErrorCode.TYPE_NOT_ASSIGNMENT_COMPATIBLE);
-  }
-}
diff --git a/compiler/javatests/com/google/dart/compiler/type/TypeAnalyzerTestCase.java b/compiler/javatests/com/google/dart/compiler/type/TypeAnalyzerTestCase.java
deleted file mode 100644
index ab903c7..0000000
--- a/compiler/javatests/com/google/dart/compiler/type/TypeAnalyzerTestCase.java
+++ /dev/null
@@ -1,357 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.type;
-
-import com.google.common.base.Joiner;
-import com.google.common.collect.Maps;
-import com.google.common.collect.Sets;
-import com.google.common.io.CharStreams;
-import com.google.dart.compiler.ErrorCode;
-import com.google.dart.compiler.ast.DartClass;
-import com.google.dart.compiler.ast.DartExprStmt;
-import com.google.dart.compiler.ast.DartExpression;
-import com.google.dart.compiler.ast.DartField;
-import com.google.dart.compiler.ast.DartFieldDefinition;
-import com.google.dart.compiler.ast.DartFunctionExpression;
-import com.google.dart.compiler.ast.DartFunctionTypeAlias;
-import com.google.dart.compiler.ast.DartNode;
-import com.google.dart.compiler.ast.DartStatement;
-import com.google.dart.compiler.ast.DartUnit;
-import com.google.dart.compiler.ast.LibraryUnit;
-import com.google.dart.compiler.parser.DartParser;
-import com.google.dart.compiler.resolver.ClassElement;
-import com.google.dart.compiler.resolver.ClassNodeElement;
-import com.google.dart.compiler.resolver.CoreTypeProvider;
-import com.google.dart.compiler.resolver.Element;
-import com.google.dart.compiler.resolver.Elements;
-import com.google.dart.compiler.resolver.FunctionAliasElement;
-import com.google.dart.compiler.resolver.LibraryElement;
-import com.google.dart.compiler.resolver.MemberBuilder;
-import com.google.dart.compiler.resolver.MockLibraryUnit;
-import com.google.dart.compiler.resolver.ResolutionContext;
-import com.google.dart.compiler.resolver.Resolver;
-import com.google.dart.compiler.resolver.Resolver.ResolveElementsVisitor;
-import com.google.dart.compiler.resolver.Scope;
-import com.google.dart.compiler.resolver.SupertypeResolver;
-import com.google.dart.compiler.resolver.TopLevelElementBuilder;
-import com.google.dart.compiler.util.DartSourceString;
-
-import java.io.IOError;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.util.Arrays;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-
-/**
- * Base class for static type analysis tests.
- */
-public abstract class TypeAnalyzerTestCase extends TypeTestCase {
-  private class MockCoreTypeProvider implements CoreTypeProvider {
-    private final Type voidType = Types.newVoidType();
-    private final DynamicType dynamicType = Types.newDynamicType();
-
-    @Override
-    public InterfaceType getArrayType(Type elementType) {
-      return list.getType().subst(Arrays.asList(elementType), list.getTypeParameters());
-    }
-
-    @Override
-    public InterfaceType getBoolType() {
-      return bool.getType();
-    }
-
-    @Override
-    public InterfaceType getDoubleType() {
-      return doubleElement.getType();
-    }
-
-    @Override
-    public DynamicType getDynamicType() {
-      return dynamicType;
-    }
-
-    @Override
-    public InterfaceType getFunctionType() {
-      return function.getType();
-    }
-
-    @Override
-    public InterfaceType getIntType() {
-      return intElement.getType();
-    }
-
-    @Override
-    public InterfaceType getIteratorType(Type elementType) {
-      InterfaceType iteratorType = iterElement.getType();
-      return iteratorType.subst(Arrays.asList(elementType), iterElement.getTypeParameters());
-    }
-
-    @Override
-    public InterfaceType getMapType(Type key, Type value) {
-      InterfaceType mapType = map.getType();
-      return mapType.subst(Arrays.asList(key, value),
-                           mapType.getElement().getTypeParameters());
-    }
-
-    @Override
-    public Type getNullType() {
-      return getDynamicType();
-    }
-
-    @Override
-    public InterfaceType getNumType() {
-      return number.getType();
-    }
-
-    @Override
-    public InterfaceType getObjectType() {
-      return object.getType();
-    }
-
-    @Override
-    public InterfaceType getStringType() {
-      return string.getType();
-    }
-
-    @Override
-    public Type getVoidType() {
-      return voidType;
-    }
-    
-    @Override
-    public InterfaceType getTypeType() {
-      return type.getType();
-    }
-  }
-  private class MockScope extends Scope {
-    private MockScope() {
-      super("test mock scope", null);
-    }
-
-    @Override
-    public Element findLocalElement(String name) {
-      return coreElements.get(name);
-    }
-
-  }
-  protected final CoreTypeProvider typeProvider = new MockCoreTypeProvider();
-  private Resolver resolver = new Resolver(context, getMockScope("<test toplevel>"), typeProvider);
-
-  private final Types types = Types.getInstance(typeProvider);
-
-  private HashSet<ClassElement> diagnosedAbstractClasses = new HashSet<ClassElement>();
-
-  protected DartStatement analyze(String statement) {
-    DartStatement node = parseStatement(statement);
-    analyzeNode(node);
-    return node;
-  }
-
-  protected ClassElement analyzeClass(ClassNodeElement cls, int expectedErrorCount) {
-    setExpectedTypeErrorCount(expectedErrorCount);
-    analyzeToplevel(cls.getNode());
-    checkExpectedTypeErrorCount(cls.getName());
-    return cls;
-  }
-
-  protected Map<String, ClassNodeElement> analyzeClasses(Map<String, ClassNodeElement> classes,
-                                                   ErrorCode... codes) {
-    setExpectedTypeErrorCount(codes.length);
-    for (ClassNodeElement cls : classes.values()) {
-      analyzeToplevel(cls.getNode());
-    }
-    List<ErrorCode> errorCodes = context.getErrorCodes();
-    assertEquals(Arrays.toString(codes), errorCodes.toString());
-    errorCodes.clear();
-    checkExpectedTypeErrorCount();
-    return classes;
-  }
-
-  protected void analyzeFail(String statement, ErrorCode errorCode) {
-    try {
-      analyze(statement);
-      fail("Test unexpectedly passed.  Expected ErrorCode: " + errorCode);
-    } catch (TestTypeError error) {
-      assertEquals(errorCode, error.getErrorCode());
-    }
-  }
-
-  protected Type analyzeIn(ClassElement element, String expression, int expectedErrorCount) {
-    DartExpression node = parseExpression(expression);
-    ResolutionContext resolutionContext =
-        new ResolutionContext(getMockScope("<test expression>"), context,
-                              typeProvider).extend(element);
-    ResolveElementsVisitor visitor =
-        resolver.new ResolveElementsVisitor(resolutionContext, element,
-                                            Elements.methodElement(null, null));
-    setExpectedTypeErrorCount(expectedErrorCount);
-    node.accept(visitor);
-    Type type = node.accept(makeTypeAnalyzer(element));
-    checkExpectedTypeErrorCount(expression);
-    return type;
-  }
-
-  private Type analyzeNode(DartNode node) {
-    ResolutionContext resolutionContext =
-        new ResolutionContext(getMockScope("<test node>"), context, typeProvider);
-    ResolveElementsVisitor visitor =
-        resolver.new ResolveElementsVisitor(resolutionContext, null,
-                                            Elements.methodElement(null, null));
-    node.accept(visitor);
-    return node.accept(makeTypeAnalyzer(Elements.dynamicElement()));
-  }
-
-  private Type analyzeToplevel(DartNode node) {
-    return node.accept(makeTypeAnalyzer(Elements.dynamicElement()));
-  }
-
-  private String assign(String type, String expression) {
-    return String.format("() { %s x = %s; }", type, expression);
-  }
-
-  protected Type checkAssignIn(ClassElement element, String type, String expression, int errorCount) {
-    return analyzeIn(element, assign(type, expression), errorCount);
-  }
-
-  protected void checkFunctionStatement(String statement, String printString) {
-    DartExprStmt node = (DartExprStmt) analyze(statement);
-    DartFunctionExpression expression = (DartFunctionExpression) node.getExpression();
-    Element element = expression.getElement();
-    FunctionType type = (FunctionType) element.getType();
-    assertEquals(printString, type.toString());
-  }
-
-  protected void checkSimpleType(Type type, String expression) {
-    assertSame(type, typeOf(expression));
-    setExpectedTypeErrorCount(1); // x is unresolved.
-    assertSame(type, typeOf("x = " + expression));
-    checkExpectedTypeErrorCount();
-  }
-
-  protected void checkType(Type type, String expression) {
-    assertEquals(type, typeOf(expression));
-    assertEquals(type, typeOf("x = " + expression));
-  }
-
-  private Scope getMockScope(String name) {
-    LibraryUnit libraryUnit = MockLibraryUnit.create();
-    return new Scope(name, libraryUnit.getElement(), new MockScope());
-  }
-
-  private DartParser getParser(String string) {
-    DartSourceString source = new DartSourceString("<source string>", string);
-    return new DartParser(source, string, false, Sets.<String>newHashSet(), listener, null);
-  }
-
-  private String getResource(String name) {
-    String packageName = getClass().getPackage().getName().replace('.', '/');
-    String resouceName = packageName + "/" + name;
-    InputStream stream = getClass().getClassLoader().getResourceAsStream(resouceName);
-    if (stream == null) {
-      throw new AssertionError("Missing resource: " + resouceName);
-    }
-    InputStreamReader reader = new InputStreamReader(stream);
-    try {
-      return CharStreams.toString(reader); // Also closes the reader.
-    } catch (IOException e) {
-      throw new IOError(e);
-    }
-  }
-
-  @Override
-  Types getTypes() {
-    return types;
-  }
-
-  protected ClassElement loadClass(String file, String name) {
-    ClassElement cls = loadFile(file).get(name);
-    assertNotNull("unable to locate " + name, cls);
-    return cls;
-  }
-
-  protected Map<String, ClassNodeElement> loadFile(final String name) {
-    String source = getResource(name);
-    return loadSource(source);
-  }
-
-  protected Map<String, ClassNodeElement> loadSource(String source) {
-    Map<String, ClassNodeElement> classes = Maps.newLinkedHashMap();
-    DartUnit unit = parseUnit(source);
-    Scope scope = getMockScope("<test toplevel>");
-    LibraryElement libraryElement = scope.getLibrary();
-    libraryElement.getScope().declareElement("Object", object);
-    unit.setLibrary(libraryElement.getLibraryUnit());
-    TopLevelElementBuilder elementBuilder = new TopLevelElementBuilder();
-    elementBuilder.exec(unit.getLibrary(), unit, context);
-    for (DartNode node : unit.getTopLevelNodes()) {
-      if (node instanceof DartClass) {
-        DartClass classNode = (DartClass) node;
-        ClassNodeElement classElement = classNode.getElement();
-        String className = classElement.getName();
-        coreElements.put(className, classElement);
-        classes.put(className, classElement);
-      } else if (node instanceof DartFieldDefinition) {
-        DartFieldDefinition fieldNode = (DartFieldDefinition) node;
-        for (DartField field : fieldNode.getFields()) {
-          Element fieldElement = field.getElement();
-          coreElements.put(fieldElement.getName(), fieldElement);
-        }
-      } else {
-        DartFunctionTypeAlias alias = (DartFunctionTypeAlias) node;
-        FunctionAliasElement element = alias.getElement();
-        coreElements.put(element.getName(), element);
-      }
-    }
-    SupertypeResolver supertypeResolver = new SupertypeResolver();
-    supertypeResolver.exec(unit, context, scope, typeProvider);
-    MemberBuilder memberBuilder = new MemberBuilder();
-    memberBuilder.exec(unit, context, scope, typeProvider);
-    resolver.exec(unit);
-    return classes;
-  }
-
-  protected Map<String, ClassNodeElement> loadSource(String firstLine, String secondLine,
-                                               String... rest) {
-    return loadSource(Joiner.on('\n').join(firstLine, secondLine, (Object[]) rest).toString());
-  }
-
-  private TypeAnalyzer.Analyzer makeTypeAnalyzer(ClassElement element) {
-    TypeAnalyzer.Analyzer analyzer =
-        new TypeAnalyzer.Analyzer(context, typeProvider, diagnosedAbstractClasses);
-    analyzer.setCurrentClass(element.getType());
-    analyzer.pushBasicBlockContext();
-    return analyzer;
-  }
-
-  private DartExpression parseExpression(String source) {
-    return getParser(source).parseExpression();
-  }
-
-  private DartStatement parseStatement(String source) {
-    return getParser(source).parseStatement();
-  }
-
-  private DartUnit parseUnit(String string) {
-   // DartSourceString source = new DartSourceString("<source string>", string);
-    return getParser(string).parseUnit();
-  }
-
-  protected String returnWithType(String type, Object expression) {
-    return String.format("%s foo() { return %s; }", type, String.valueOf(expression));
-  }
-
-  @Override
-  protected void tearDown() {
-    resolver = null;
-    diagnosedAbstractClasses = null;
-  }
-
-  private Type typeOf(String expression) {
-    return analyzeNode(parseExpression(expression));
-  }
-}
diff --git a/compiler/javatests/com/google/dart/compiler/type/TypeTest.java b/compiler/javatests/com/google/dart/compiler/type/TypeTest.java
deleted file mode 100644
index cbb60e9..0000000
--- a/compiler/javatests/com/google/dart/compiler/type/TypeTest.java
+++ /dev/null
@@ -1,107 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.type;
-
-
-import org.junit.Assert;
-
-import java.util.Arrays;
-import java.util.List;
-
-public class TypeTest extends TypeTestCase {
-  private final Types types = Types.getInstance(null);
-
-  @Override
-  Types getTypes() {
-    return types;
-  }
-
-  public void testToString() {
-    Assert.assertEquals("Object", itype(object).toString());
-    Assert.assertEquals("List<Object>", objectList.toString());
-    Assert.assertEquals("Map<Object, Object>", objectMap.toString());
-    Assert.assertEquals("ReverseMap<Object, Object>", reverseObjectMap.toString());
-
-    Assert.assertEquals("CLASS Object", object.toString());
-    Assert.assertEquals("CLASS List", list.toString());
-    Assert.assertEquals("CLASS Map", map.toString());
-    Assert.assertEquals("CLASS ReverseMap", reverseMap.toString());
-
-    Assert.assertEquals("Object", object.getType().toString());
-    Assert.assertEquals("List<E>", list.getType().toString());
-    Assert.assertEquals("Map<K, V>", map.getType().toString());
-    Assert.assertEquals("ReverseMap<K, V>", reverseMap.getType().toString());
-  }
-
-  public void testRaw() {
-    Assert.assertFalse(itype(object).isRaw());
-    Assert.assertFalse(objectList.isRaw());
-    Assert.assertFalse(objectMap.isRaw());
-    Assert.assertFalse(reverseObjectMap.isRaw());
-
-    Assert.assertTrue(itype(list).isRaw());
-    Assert.assertTrue(itype(list, itype(object), itype(object)).isRaw());
-
-    Assert.assertFalse(itype(list, objectMap).isRaw());
-  }
-
-  public void testAsInstanceOf() {
-    Assert.assertEquals(itype(object), types.asInstanceOf(objectList, object));
-    Assert.assertEquals(objectList, types.asInstanceOf(objectList, list));
-
-    Assert.assertNull(types.asInstanceOf(objectList, map));
-
-    Assert.assertNull(types.asInstanceOf(itype(object), list));
-
-    Assert.assertEquals(intStringMap, types.asInstanceOf(stringIntReverseMap, map));
-
-    Assert.assertFalse(stringIntMap.equals(types.asInstanceOf(stringIntReverseMap, map)));
-
-    Assert.assertEquals(itype(list), types.asInstanceOf(itype(list), list));
-  }
-
-  public void testSubst() {
-    List<Type> vars = Arrays.<Type>asList(typeVar("K", itype(object)), typeVar("V", itype(object)));
-    Type canonMap = map.getType();
-    Type substMap = canonMap.subst(vars, map.getTypeParameters());
-    checkNotAssignable(canonMap, substMap);
-    Assert.assertFalse(canonMap.equals(substMap));
-    Assert.assertFalse(substMap.equals(canonMap));
-
-    List<Type> args = Arrays.<Type>asList(itype(string), itype(intElement));
-    Assert.assertTrue(types.isSubtype(canonMap.subst(args, map.getTypeParameters()), stringIntMap));
-    Assert.assertTrue(types.isSubtype(substMap.subst(args, vars), stringIntMap));
-
-    TypeVariable tv = typeVar("T", itype(object));
-    Assert.assertSame(tv, tv.subst(vars, args));
-  }
-
-  public void testEquals() {
-    Assert.assertEquals(object.getType(), itype(object));
-    Assert.assertNotSame(object.getType(), itype(object));
-    Assert.assertFalse(object.getType().equals(map.getTypeParameters().get(0)));
-  }
-
-  public void testIsSubtype() {
-    checkSubtype(itype(object), itype(object));
-
-    checkStrictSubtype(itype(string), itype(object));
-    checkStrictSubtype(itype(intElement), itype(object));
-    checkNotAssignable(itype(string), itype(intElement));
-
-
-    checkStrictSubtype(objectList, itype(object));
-
-    checkStrictSubtype(objectMap, itype(object));
-
-    checkStrictSubtype(reverseObjectMap, itype(object));
-    checkStrictSubtype(reverseObjectMap, objectMap);
-
-    checkNotAssignable(objectMap, objectList);
-    checkNotAssignable(reverseObjectMap, objectList);
-    checkNotAssignable(objectMap, objectList);
-    checkNotAssignable(reverseObjectMap, objectList);
-  }
-}
diff --git a/compiler/javatests/com/google/dart/compiler/type/TypeTestCase.java b/compiler/javatests/com/google/dart/compiler/type/TypeTestCase.java
deleted file mode 100644
index fae289a..0000000
--- a/compiler/javatests/com/google/dart/compiler/type/TypeTestCase.java
+++ /dev/null
@@ -1,199 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.type;
-
-import com.google.common.collect.Maps;
-import com.google.dart.compiler.DartCompilationError;
-import com.google.dart.compiler.DartCompilerListener;
-import com.google.dart.compiler.ErrorCode;
-import com.google.dart.compiler.SubSystem;
-import com.google.dart.compiler.ast.DartBlock;
-import com.google.dart.compiler.ast.DartFunction;
-import com.google.dart.compiler.ast.DartIdentifier;
-import com.google.dart.compiler.ast.DartInitializer;
-import com.google.dart.compiler.ast.DartMethodDefinition;
-import com.google.dart.compiler.ast.DartParameter;
-import com.google.dart.compiler.ast.DartStatement;
-import com.google.dart.compiler.ast.DartTypeNode;
-import com.google.dart.compiler.ast.Modifiers;
-import com.google.dart.compiler.resolver.ClassElement;
-import com.google.dart.compiler.resolver.Element;
-import com.google.dart.compiler.resolver.Elements;
-import com.google.dart.compiler.resolver.MethodNodeElement;
-import com.google.dart.compiler.resolver.TypeVariableElement;
-import com.google.dart.compiler.testing.TestCompilerContext;
-
-import junit.framework.TestCase;
-
-import org.junit.Assert;
-
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.LinkedHashMap;
-import java.util.Map;
-
-/**
- * Common superclass for type tests.
- */
-abstract class TypeTestCase extends TestCase {
-
-  final Map<String, Element> coreElements = Maps.newHashMap();
-  final ClassElement object = element("Object", null);
-  final ClassElement function = element("Function", itype(object));
-  final ClassElement number = element("num", itype(object));
-  final ClassElement intElement = element("int", itype(number));
-  final ClassElement doubleElement = element("double", itype(number));
-  final ClassElement bool = element("bool", itype(object));
-  final ClassElement string = element("String", itype(object));
-  final ClassElement iterElement = element("Iterator", itype(object), typeVar("E", itype(object)));
-  final ClassElement list = makeListElement();
-  final ClassElement map = element("Map", itype(object),
-                                   typeVar("K", itype(object)), typeVar("V", itype(object)));
-  final ClassElement stackTrace = element("StackTrace", itype(object));
-  final ClassElement reverseMap = makeReverseMap(map);
-  final InterfaceType objectList = itype(list, itype(object));
-  final InterfaceType objectMap = itype(map, itype(object), itype(object));
-  final InterfaceType reverseObjectMap = itype(reverseMap, itype(object), itype(object));
-  final InterfaceType stringIntMap = itype(map, itype(string), itype(intElement));
-  final InterfaceType intStringMap = itype(map, itype(intElement), itype(string));
-  final InterfaceType stringIntReverseMap = itype(reverseMap, itype(string), itype(intElement));
-  final FunctionType returnObject = ftype(function, itype(object), null, null);
-  final FunctionType returnString = ftype(function, itype(string), null, null);
-  final FunctionType objectToObject = ftype(function, itype(object), null, null, itype(object));
-  final FunctionType objectToString = ftype(function, itype(string), null, null, itype(object));
-  final FunctionType stringToObject = ftype(function, itype(object), null, null, itype(string));
-  final FunctionType stringAndIntToBool = ftype(function, itype(bool),
-                                                null, null, itype(string), itype(intElement));
-  final FunctionType stringAndIntToMap = ftype(function, stringIntMap,
-                                               null, null, itype(string), itype(intElement));
-  final ClassElement type = element("Type", itype(object));
-  private int expectedTypeErrors = 0;
-  private int foundTypeErrors = 0;
-
-  abstract Types getTypes();
-
-  ClassElement makeListElement() {
-    final TypeVariable typeVar = typeVar("E", itype(object));
-    final ClassElement element = element("List", itype(object), typeVar);
-    DartTypeNode returnTypeNode = new DartTypeNode(new DartIdentifier("Iterator"),
-        Arrays.asList(new DartTypeNode(new DartIdentifier("E"))));
-
-    DartMethodDefinition iteratorMethod = DartMethodDefinition.create(
-        new DartIdentifier("iterator"), new DartFunction(Collections.<DartParameter> emptyList(),
-            -1, -1, -1, 0, new DartBlock(Collections.<DartStatement> emptyList()), returnTypeNode),
-        Modifiers.NONE, Collections.<DartInitializer> emptyList());
-    MethodNodeElement iteratorMethodElement = Elements.methodFromMethodNode(iteratorMethod, element);
-    Type returnType = Types.interfaceType(iterElement, Arrays.<Type>asList(typeVar));
-    FunctionType functionType = ftype(function, returnType, Collections.<String,Type>emptyMap(),
-         null);
-    Elements.setType(iteratorMethodElement, functionType);
-    Elements.addMethod(element, iteratorMethodElement);
-    return element;
-  }
-
-  protected void setExpectedTypeErrorCount(int count) {
-    checkExpectedTypeErrorCount();
-    expectedTypeErrors = count;
-    foundTypeErrors  = 0;
-  }
-
-  protected void checkExpectedTypeErrorCount(String message) {
-    assertEquals(message, expectedTypeErrors, foundTypeErrors);
-  }
-
-  protected void checkExpectedTypeErrorCount() {
-    checkExpectedTypeErrorCount(null);
-  }
-
-  static TypeVariable typeVar(String name, Type bound) {
-    TypeVariableElement element = Elements.typeVariableElement(name, bound);
-    return new TypeVariableImplementation(element);
-  }
-
-  private ClassElement makeReverseMap(ClassElement map) {
-    TypeVariable K = typeVar("K", itype(object));
-    TypeVariable V = typeVar("V", itype(object));
-    return element("ReverseMap", itype(map, V, K), K, V);
-  }
-
-  static InterfaceType itype(ClassElement element, Type... arguments) {
-    return new InterfaceTypeImplementation(element, Arrays.asList(arguments));
-  }
-
-  static FunctionType ftype(ClassElement element, Type returnType,
-                            Map<String, Type> namedParameterTypes, Type rest, Type... arguments) {
-    return FunctionTypeImplementation.of(element, Arrays.asList(arguments), null, namedParameterTypes,
-                                         rest, returnType);
-  }
-
-  static Map<String, Type> named(Object... pairs) {
-    Map<String, Type> named = new LinkedHashMap<String, Type>();
-    for (int i = 0; i < pairs.length; i++) {
-      Type type = (Type) pairs[i++];
-      String name = (String) pairs[i];
-      named.put(name, type);
-    }
-    return named;
-  }
-
-  ClassElement element(String name, InterfaceType supertype, TypeVariable... parameters) {
-    ClassElement element = Elements.classNamed(name);
-    element.setSupertype(supertype);
-    element.setType(itype(element, parameters));
-    coreElements.put(name, element);
-    return element;
-  }
-
-  void checkSubtype(Type t, Type s) {
-    Assert.assertTrue(getTypes().isSubtype(t, s));
-  }
-
-  void checkStrictSubtype(Type t, Type s) {
-    checkSubtype(t, s);
-    checkNotSubtype(s, t);
-  }
-
-  void checkNotSubtype(Type t, Type s) {
-    Assert.assertFalse(getTypes().isSubtype(t, s));
-  }
-
-  void checkNotAssignable(Type t, Type s) {
-    checkNotSubtype(t, s);
-    checkNotSubtype(s, t);
-  }
-
-  final DartCompilerListener listener = new DartCompilerListener.Empty() {
-    @Override
-    public void onError(DartCompilationError event) {
-      throw new AssertionError(event);
-    }
-  };
-
-  final TestCompilerContext context = new TestCompilerContext() {
-    @Override
-    public void onError(DartCompilationError event) {
-      if (event.getErrorCode().getSubSystem() == SubSystem.STATIC_TYPE) {
-        getErrorCodes().add(event.getErrorCode());
-        foundTypeErrors++;
-        if (expectedTypeErrors - foundTypeErrors < 0) {
-          throw new TestTypeError(event);
-        }
-      }
-    }
-  };
-
-  static class TestTypeError extends RuntimeException {
-    final DartCompilationError event;
-
-    TestTypeError(DartCompilationError event) {
-      super(String.valueOf(event));
-      this.event = event;
-    }
-
-    ErrorCode getErrorCode() {
-      return event.getErrorCode();
-    }
-  }
-}
diff --git a/compiler/javatests/com/google/dart/compiler/type/TypeTests.java b/compiler/javatests/com/google/dart/compiler/type/TypeTests.java
deleted file mode 100644
index e8c2a27..0000000
--- a/compiler/javatests/com/google/dart/compiler/type/TypeTests.java
+++ /dev/null
@@ -1,27 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.type;
-
-import junit.extensions.TestSetup;
-import junit.framework.Test;
-import junit.framework.TestSuite;
-
-public class TypeTests extends TestSetup {
-
-  public TypeTests(Test test) {
-    super(test);
-  }
-
-  public static Test suite() {
-    TestSuite suite = new TestSuite("Type system of dartc");
-
-    suite.addTestSuite(TypeTest.class);
-    suite.addTestSuite(FunctionTypeTest.class);
-    suite.addTestSuite(TypeAnalyzerTest.class);
-    suite.addTestSuite(TypeAnalyzerCompilerTest.class);
-
-    return suite;
-  }
-}
diff --git a/compiler/javatests/com/google/dart/compiler/type/class_with_methods.dart b/compiler/javatests/com/google/dart/compiler/type/class_with_methods.dart
deleted file mode 100644
index 5f0f424..0000000
--- a/compiler/javatests/com/google/dart/compiler/type/class_with_methods.dart
+++ /dev/null
@@ -1,17 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-abstract class ClassWithMethods {
-  untypedNoArgumentMethod();
-  untypedOneArgumentMethod(argument);
-  untypedTwoArgumentMethod(argument1, argument2);
-
-  int intNoArgumentMethod();
-  int intOneArgumentMethod(int argument);
-  int intTwoArgumentMethod(int argument1, int argument2);
-
-  Function functionField;
-  var untypedField;
-  int intField;
-}
diff --git a/compiler/javatests/com/google/dart/compiler/type/class_with_operators.dart b/compiler/javatests/com/google/dart/compiler/type/class_with_operators.dart
deleted file mode 100644
index 79819b2..0000000
--- a/compiler/javatests/com/google/dart/compiler/type/class_with_operators.dart
+++ /dev/null
@@ -1,61 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-class ClassWithOperators {
-  ClassWithOperators o;
-  int i;
-  String s;
-  bool b;
-  var untyped;
-
-  ClassWithOperators() {}
-
-  int operator[] (int i) {
-    return 0;
-  }
-
-  ClassWithOperators operator +(ClassWithOperators operand) {
-    return this;
-  }
-
-  ClassWithOperators operator -(ClassWithOperators operand) {
-    return this;
-  }
-
-  ClassWithOperators operator *(ClassWithOperators operand) {
-    return this;
-  }
-
-  ClassWithOperators operator /(ClassWithOperators operand) {
-    return this;
-  }
-
-  ClassWithOperators operator ~/(ClassWithOperators operand) {
-    return this;
-  }
-
-  ClassWithOperators operator %(ClassWithOperators operand) {
-    return this;
-  }
-
-  ClassWithOperators operator <(ClassWithOperators operand) {
-    return this;
-  }
-
-  ClassWithOperators operator >(ClassWithOperators operand) {
-    return this;
-  }
-
-  ClassWithOperators operator <=(ClassWithOperators operand) {
-    return this;
-  }
-
-  ClassWithOperators operator >=(ClassWithOperators operand) {
-    return this;
-  }
-
-  bool operator ==(other) {
-    return false;
-  }
-}
diff --git a/compiler/javatests/com/google/dart/compiler/type/class_with_supertypes.dart b/compiler/javatests/com/google/dart/compiler/type/class_with_supertypes.dart
deleted file mode 100644
index 32a67a3..0000000
--- a/compiler/javatests/com/google/dart/compiler/type/class_with_supertypes.dart
+++ /dev/null
@@ -1,27 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-abstract class Interface {
-  void methodInInterface();
-  int fieldInInterface;
-  static final int staticFieldInInterface = 1;
-}
-
-class Superclass {
-  Superclass() {}
-
-  void methodInSuperclass() {}
-  int fieldInSuperclass;
-  static void staticMethodInSuperclass() {}
-  static int staticFieldInSuperclass;
-}
-
-class ClassWithSupertypes extends Superclass implements Interface {
-  ClassWithSupertypes() : super() {}
-
-  void method() {}
-  int field;
-  static void staticMethod() {}
-  static int staticField;
-}
diff --git a/compiler/javatests/com/google/dart/compiler/type/class_with_type_parameter.dart b/compiler/javatests/com/google/dart/compiler/type/class_with_type_parameter.dart
deleted file mode 100644
index f61bf4a..0000000
--- a/compiler/javatests/com/google/dart/compiler/type/class_with_type_parameter.dart
+++ /dev/null
@@ -1,13 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-abstract class A {}
-
-abstract class B extends A {}
-
-class ClassWithTypeParameter<T extends B> {
-  A aField;
-  B bField;
-  T tField;
-}
diff --git a/compiler/javatests/com/google/dart/compiler/type/classes_with_properties.dart b/compiler/javatests/com/google/dart/compiler/type/classes_with_properties.dart
deleted file mode 100644
index b126779..0000000
--- a/compiler/javatests/com/google/dart/compiler/type/classes_with_properties.dart
+++ /dev/null
@@ -1,35 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-class A {
-  A a;
-  B b;
-  C c;
-  void m() {}
-  var x;
-}
-
-class B {
-  A a;
-  B b;
-  C c;
-  void m() {}
-  var x;
-}
-
-class C {
-  A a;
-  B b;
-  C c;
-  void m() {}
-  var x;
-}
-
-class ClassWithProperties {
-  A a;
-  B b;
-  C c;
-  void m() {}
-  var x;
-}
diff --git a/compiler/javatests/com/google/dart/compiler/type/covariant_class.dart b/compiler/javatests/com/google/dart/compiler/type/covariant_class.dart
deleted file mode 100644
index f38bb42..0000000
--- a/compiler/javatests/com/google/dart/compiler/type/covariant_class.dart
+++ /dev/null
@@ -1,43 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-abstract class A {
-}
-
-abstract class B extends A {
-}
-
-abstract class C extends A {
-}
-
-abstract class D {
-}
-
-class Super {
-  A field;
-  A get accessor { return null; }
-  void set accessor(A newValue) { }
-  A method() { return null; }
-  
-  var untypedField;
-  get untypedAccessor { return null; }
-  set untypedAccessor(newValue) { }
-  untypedMethod() { return null; }
-}
-
-class Sub extends Super {
-  B field;
-  B get accessor { return null; }
-  void set accessor(B newValue) { }
-  B method() { return null; }
-  
-  B untypedField;
-  B get untypedAccessor { return null; }
-  set untypedAccessor(B newValue) { }
-  B untypedMethod() { return null; }
-  
-  B b;
-  C c;
-  D d;
-}
diff --git a/compiler/javatests/com/google/dart/compiler/type/generic_class_with_supertypes.dart b/compiler/javatests/com/google/dart/compiler/type/generic_class_with_supertypes.dart
deleted file mode 100644
index c0ccbb9..0000000
--- a/compiler/javatests/com/google/dart/compiler/type/generic_class_with_supertypes.dart
+++ /dev/null
@@ -1,20 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-abstract class Interface<I1, I2> {
-  I1 interfaceField;
-  I1 interfaceMethod(I2 arg);
-}
-
-class Superclass<S1, S2> {
-  S1 superField;
-  S1 superMethod(S2 arg) { return null; }
-}
-
-class GenericClassWithSupertypes<T1, T2> extends Superclass<T2, T1> implements Interface<T1, T1> {
-  T1 localField;
-  T1 localMethod(T2 arg) { return null; }
-  T2 t2;
-  T1 t1;
-}
diff --git a/compiler/javatests/com/google/dart/compiler/type/named_function_type_alias.dart b/compiler/javatests/com/google/dart/compiler/type/named_function_type_alias.dart
deleted file mode 100644
index d9fc3c26..0000000
--- a/compiler/javatests/com/google/dart/compiler/type/named_function_type_alias.dart
+++ /dev/null
@@ -1,5 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-typedef void VoidFunction();
diff --git a/compiler/javatests/com/google/dart/compiler/util/PathsTest.java b/compiler/javatests/com/google/dart/compiler/util/PathsTest.java
deleted file mode 100644
index 669f13b..0000000
--- a/compiler/javatests/com/google/dart/compiler/util/PathsTest.java
+++ /dev/null
@@ -1,132 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.util;
-
-import junit.framework.TestCase;
-
-import java.io.File;
-import java.net.URI;
-
-public class PathsTest extends TestCase {
-
-  public void testRelativePathToFile_inChildDir_1() {
-    testPathToFile("mylib.lib", "childDir/other.lib", "childDir/other.lib");
-  }
-
-  public void testRelativePathToFile_inChildDir_2() {
-    testPathToFile("dir/mylib.lib", "childDir/other.lib", "dir/childDir/other.lib");
-  }
-
-  public void testRelativePathToFile_inParentDir_1() {
-    testPathToFile("mylib.lib", "../other.lib", "../other.lib");
-  }
-
-  public void testRelativePathToFile_inParentDir_2() {
-    testPathToFile("dir/mylib.lib", "../other.lib", "other.lib");
-  }
-
-  public void testRelativePathToFile_inSameDir_1() {
-    testPathToFile("mylib.lib", "other.lib", "other.lib");
-  }
-
-  public void testRelativePathToFile_inSameDir_2() {
-    testPathToFile("dir/mylib.lib", "other.lib", "dir/other.lib");
-  }
-
-  public void testRelativePathToFile_inSiblingDir_1() {
-    testPathToFile("mylib.lib", "../alt/other.lib", "../alt/other.lib");
-  }
-
-  public void testRelativePathToFile_inSiblingDir_2() {
-    testPathToFile("dir/mylib.lib", "../alt/other.lib", "alt/other.lib");
-  }
-
-  private void testPathToFile(String baseFilePath, String relPath,
-      String expectedPath) {
-    
-    File baseFile1 = new File(baseFilePath);
-    File actual1 = Paths.relativePathToFile(baseFile1, relPath);
-    String expectedPath1 = expectedPath;
-    assertEquals(expectedPath1, actual1.getPath());
-    
-    File baseFile2 = baseFile1.getAbsoluteFile();
-    File actual2 = Paths.relativePathToFile(baseFile2, relPath);
-    String expectedPath2 = URI.create(actual1.getAbsolutePath()).normalize().getPath();
-    assertEquals(expectedPath2, actual2.getPath());
-  }
-
-  //==========================================================================
-
-  public void testRelativePathFor_inChildDir_1() {
-    testPathFor("mylib.lib", "childDir/other.lib", "childDir/other.lib");
-  }
-
-  public void testRelativePathFor_inChildDir_2() {
-    testPathFor("dir/mylib.lib", "dir/childDir/other.lib", "childDir/other.lib");
-  }
-
-  public void testRelativePathFor_inParentDir_1() {
-    testPathFor("mylib.lib", "../other.lib", "../other.lib");
-  }
-
-  public void testRelativePathFor_inParentDir_2() {
-    testPathFor("dir/mylib.lib", "other.lib", "../other.lib");
-  }
-
-  public void testRelativePathFor_inParentDir_3() {
-    testPathFor("grandDir/dir/mylib.lib", "grandDir/other.lib", "../other.lib");
-  }
-
-  public void testRelativePathFor_inSameDir_1() {
-    testPathFor("mylib.lib", "other.lib", "other.lib");
-  }
-
-  public void testRelativePathFor_inSameDir_2() {
-    testPathFor("dir/mylib.lib", "dir/other.lib", "other.lib");
-  }
-
-  public void testRelativePathFor_inSameDir_3() {
-    testPathFor("grandDir/dir/mylib.lib", "grandDir/dir/other.lib", "other.lib");
-  }
-
-  public void testRelativePathFor_inSameDir_4() {
-    testPathFor("grandDir/dir/amylib.lib", "grandDir/dir/aother.lib", "aother.lib");
-  }
-
-  public void testRelativePathFor_inSameDir_5() {
-    testPathFor("grandDir/dir/abmylib.lib", "grandDir/dir/abother.lib", "abother.lib");
-  }
-
-  public void testRelativePathFor_inSiblingDir_1() {
-    testPathFor("mylib.lib", "../otherdir/other.lib", "../otherdir/other.lib");
-  }
-
-  public void testRelativePathFor_inSiblingDir_2() {
-    testPathFor("dir/mylib.lib", "otherdir/other.lib", "../otherdir/other.lib");
-  }
-
-  public void testRelativePathFor_inSiblingDir_3() {
-    testPathFor("grandDir/dir/mylib.lib", "grandDir/otherdir/other.lib", "../otherdir/other.lib");
-  }
-
-  public void testRelativePathFor_inSiblingDir_4() {
-    testPathFor("src/mylib.lib", "src-dir/other.lib", "../src-dir/other.lib");
-  }
-
-  private void testPathFor(String baseFilePath, String relFilePath,
-      String expected) {
-    
-    File baseFile1 = new File(baseFilePath);
-    File relativeFile1 = new File(relFilePath);
-    String actual1 = Paths.relativePathFor(baseFile1, relativeFile1);
-    assertEquals(expected, actual1);
-    
-    File baseFile2 = baseFile1.getAbsoluteFile();
-    File relativeFile2 = relativeFile1.getAbsoluteFile();
-    String actual2 = Paths.relativePathFor(baseFile2, relativeFile2);
-    assertEquals(expected, actual2);
-  }
-
-}
diff --git a/compiler/javatests/com/google/dart/compiler/util/UtilTests.java b/compiler/javatests/com/google/dart/compiler/util/UtilTests.java
deleted file mode 100644
index c6a0199..0000000
--- a/compiler/javatests/com/google/dart/compiler/util/UtilTests.java
+++ /dev/null
@@ -1,24 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.compiler.util;
-
-import junit.extensions.TestSetup;
-import junit.framework.Test;
-import junit.framework.TestSuite;
-
-public class UtilTests extends TestSetup {
-
-  public UtilTests(Test test) {
-    super(test);
-  }
-
-  public static Test suite() {
-    TestSuite suite = new TestSuite("Utilities for dartc");
-
-    suite.addTestSuite(PathsTest.class);
-
-    return suite;
-  }
-}
diff --git a/compiler/javatests/com/google/dart/corelib/SharedTestCase.java b/compiler/javatests/com/google/dart/corelib/SharedTestCase.java
deleted file mode 100644
index 47054d7..0000000
--- a/compiler/javatests/com/google/dart/corelib/SharedTestCase.java
+++ /dev/null
@@ -1,285 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.corelib;
-
-import com.google.dart.compiler.AnalysisError;
-import com.google.dart.compiler.CommandLineOptions.CompilerOptions;
-import com.google.dart.compiler.CompilerConfiguration;
-import com.google.dart.compiler.DartArtifactProvider;
-import com.google.dart.compiler.DartCompilationError;
-import com.google.dart.compiler.DartCompiler;
-import com.google.dart.compiler.DartCompilerListener;
-import com.google.dart.compiler.DefaultCompilerConfiguration;
-import com.google.dart.compiler.DefaultDartArtifactProvider;
-import com.google.dart.compiler.DefaultLibrarySource;
-import com.google.dart.compiler.ErrorSeverity;
-import com.google.dart.compiler.LibrarySource;
-import com.google.dart.compiler.Source;
-import com.google.dart.compiler.SubSystem;
-import com.google.dart.compiler.UrlLibrarySource;
-
-import junit.framework.AssertionFailedError;
-import junit.framework.Test;
-import junit.framework.TestCase;
-import junit.framework.TestSuite;
-
-import org.kohsuke.args4j.CmdLineException;
-import org.kohsuke.args4j.CmdLineParser;
-
-import java.io.ByteArrayOutputStream;
-import java.io.CharArrayReader;
-import java.io.CharArrayWriter;
-import java.io.File;
-import java.io.IOException;
-import java.io.PrintStream;
-import java.io.Reader;
-import java.io.Writer;
-import java.net.URI;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Enumeration;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.atomic.AtomicInteger;
-import java.util.regex.Pattern;
-
-/**
- * Wrapper around test that are shared between compiler and runtime (test.py).
- * <p>
- * Sometimes, when fixing a known issue, a test that was previously crashing or failing may start
- * passing. This will show up as a test failure because the status file has wrong information.
- * Please update the status file.
- */
-public abstract class SharedTestCase extends TestCase {
-  private static final Pattern SEPARATOR = Pattern.compile("\\t");
-
-  private final Set<String> outcomes;
-  private final boolean isNegative;
-  private final String[] arguments;
-  private final boolean regularCompile;
-  private final AtomicInteger compilationErrorCount = new AtomicInteger(0);
-  private final AtomicInteger typeErrorCount = new AtomicInteger(0);
-  private final AtomicInteger warningCount = new AtomicInteger(0);
-
-  SharedTestCase(String name, Set<String> outcomes, boolean isNegative, boolean regularCompile,
-                 String[] arguments) {
-    super(name);
-    this.outcomes = outcomes;
-    this.isNegative = isNegative;
-    this.regularCompile = regularCompile;
-    this.arguments = arguments;
-  }
-
-  /**
-   * This constructor is provided for compatibility with Eclipse (for running
-   * a single test case).
-   */
-  public SharedTestCase(String name) {
-    super(name = scrubName(name));
-    TestSuite suite = SharedTests.suite();
-    Enumeration<Test> tests = suite.tests();
-    SharedTestCase test = null;
-    while (tests.hasMoreElements()) {
-      SharedTestCase current = (SharedTestCase) tests.nextElement();
-      if (current.getScrubbedName().equals(name)) {
-        test = current;
-        break;
-      }
-    }
-    if (test == null) {
-      throw new IllegalArgumentException("Test '" +name + "' was not found.");
-    }
-    this.outcomes = test.outcomes;
-    this.isNegative = test.isNegative;
-    this.regularCompile = test.regularCompile;
-    this.arguments = test.arguments;
-  }
-
-  private static String scrubName(String name) {
-    int i = name.indexOf('[');
-    if (i == -1) {
-      return name;
-    }
-    return name.substring(0, i - 1);
-  }
-
-  @Override
-  public String getName() {
-    List<String> remarks = new ArrayList<String>();
-    if (isNegative) {
-      remarks.add("negative");
-    }
-    for (String outcome : outcomes) {
-      if (!outcome.equals("pass")) {
-        remarks.add(outcome);
-      }
-    }
-    if (remarks.isEmpty()) {
-      return super.getName();
-    } else {
-      return super.getName() + " " + remarks;
-    }
-  }
-
-  String getScrubbedName() {
-    return super.getName();
-  }
-
-  @Override
-  public void runBare() {
-    ByteArrayOutputStream byteOutput = new ByteArrayOutputStream();
-    PrintStream outputStream = new PrintStream(byteOutput);
-    try {
-      invokeCompiler();
-    } catch (AnalysisError e) {
-      outputStream.close();
-      analyzeError(e, byteOutput.toString());
-      return;
-    } catch (Throwable t) {
-      outputStream.close();
-      analyzeCrash(t);
-      return;
-    }
-    outputStream.close();
-    analyzeNormalCompletion();
-  }
-
-  private void invokeCompiler() throws CmdLineException, IOException, AnalysisError {
-    CmdLineParser cmdLineParser = null;
-    CompilerOptions compilerOptions = new CompilerOptions();
-    cmdLineParser = new CmdLineParser(compilerOptions);
-    cmdLineParser.parseArgument(arguments);
-    CompilerConfiguration config = new DefaultCompilerConfiguration(compilerOptions);
-    DartArtifactProvider provider = getArtifactProvider(config.getOutputDirectory());
-    DartCompilerListener listener = getListener();
-    List<String> sourceFiles = compilerOptions.getSourceFiles();
-    assertEquals("incorrect number of source files " + sourceFiles, 1, sourceFiles.size());
-    File sourceFile = new File(sourceFiles.get(0));
-    LibrarySource lib;
-    if (sourceFile.getName().endsWith(".dart")) {
-      lib = new DefaultLibrarySource(sourceFile, null);
-    } else {
-      lib = new UrlLibrarySource(sourceFile);
-    }
-    DartCompiler.compileLib(lib, config, provider, listener);
-    if (compilationErrorCount.get() != 0 || typeErrorCount.get() != 0 || warningCount.get() != 0) {
-      throw new AnalysisError(sourceFile.getPath());
-    }
-  }
-
-  private DartArtifactProvider getArtifactProvider(File outputDirectory) {
-    final DartArtifactProvider provider = new DefaultDartArtifactProvider(outputDirectory);
-    return new DartArtifactProvider() {
-      ConcurrentHashMap<URI, CharArrayWriter> artifacts =
-          new ConcurrentHashMap<URI, CharArrayWriter>();
-
-      @Override
-      public boolean isOutOfDate(Source source, Source base, String extension) {
-        return true;
-      }
-
-      @Override
-      public Writer getArtifactWriter(Source source, String part, String extension) {
-        URI uri = getArtifactUri(source, part, extension);
-        CharArrayWriter writer = new CharArrayWriter();
-        CharArrayWriter existing = artifacts.putIfAbsent(uri, writer);
-        return (existing == null) ? writer : existing;
-      }
-
-
-      @Override
-      public URI getArtifactUri(Source source, String part, String extension) {
-        return provider.getArtifactUri(source, part, extension);
-      }
-
-      @Override
-      public Reader getArtifactReader(Source source, String part, String extension)
-          throws IOException {
-        URI uri = getArtifactUri(source, part, extension);
-        CharArrayWriter writer = artifacts.get(uri);
-        if (writer != null) {
-          return new CharArrayReader(writer.toCharArray());
-        }
-        return provider.getArtifactReader(source, part, extension);
-      }
-    };
-  }
-
-  private DartCompilerListener getListener() {
-    DartCompilerListener listener = new DartCompilerListener.Empty() {
-      @Override
-      public void onError(DartCompilationError event) {
-        if (event.getErrorCode().getSubSystem() == SubSystem.STATIC_TYPE) {
-          typeErrorCount.incrementAndGet();
-        } else if (event.getErrorCode().getErrorSeverity() == ErrorSeverity.ERROR) {
-          compilationErrorCount.incrementAndGet();
-        } else if (event.getErrorCode().getErrorSeverity() == ErrorSeverity.WARNING) {
-          warningCount.incrementAndGet();
-        }
-        maybeThrow(event);
-      }
-
-      private void maybeThrow(DartCompilationError event) {
-        if (isNegative) {
-          return;
-        }
-        if (outcomes.contains("pass")) {
-          // It is easier to debug a failing regular test if we throw an exception.
-          throw new AssertionError(event);
-        }
-      }
-    };
-    return listener;
-  }
-
-  private void analyzeNormalCompletion() {
-    if (isNegative) {
-      if (!outcomes.contains("fail")) {
-        fail("Negative test didn't cause an error");
-      }
-    } else {
-      if (!outcomes.contains("pass")) {
-        fail("Test passed unexpectly, please update status file");
-      }
-    }
-  }
-
-  private void analyzeCrash(Throwable t) {
-    if (outcomes.contains("crash")) {
-      return;
-    }
-    String message = outcomes.contains("fail") ? "Failing test crashed" : "Test crashed unexpectly";
-    AssertionFailedError error = new AssertionFailedError(message);
-    error.initCause(t);
-    throw error;
-  }
-
-  private void analyzeError(AnalysisError e, String log) {
-    if (isNegative) {
-      if (!outcomes.contains("pass")) {
-        fail("Negative test is passing, please update status file");
-      }
-    } else {
-      if (!outcomes.contains("fail")) {
-        fail(log + e.getLocalizedMessage());
-      }
-    }
-  }
-
-  static Test getInstance(String line, boolean regularCompile) {
-    String[] fields = SEPARATOR.split(line);
-    if (fields.length <= 3) {
-      fail("Line is not parsable: " + line);
-    }
-    String name = fields[0];
-    Set<String> outcomes = new HashSet<String>(Arrays.<String>asList(fields[1].split(",")));
-    boolean isNegative = fields[2].equals("True");
-    String[] arguments = new String[fields.length - 3];
-    System.arraycopy(fields, 3, arguments, 0, arguments.length);
-    return new SharedTestCase(name, outcomes, isNegative, regularCompile, arguments) {};
-  }
-}
diff --git a/compiler/javatests/com/google/dart/corelib/SharedTests.java b/compiler/javatests/com/google/dart/corelib/SharedTests.java
deleted file mode 100644
index 7557f88..0000000
--- a/compiler/javatests/com/google/dart/corelib/SharedTests.java
+++ /dev/null
@@ -1,108 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.corelib;
-
-import com.google.common.io.CharStreams;
-import com.google.common.io.LineReader;
-
-import junit.extensions.TestSetup;
-import junit.framework.Test;
-import junit.framework.TestCase;
-import junit.framework.TestSuite;
-
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-
-/**
- * JUnit wrapper around test.py. This wrapper allows you to run most test.py tests from inside your
- * favorite IDE, to ease debugging.
- * <p>
- * If you followed the instructions in compiler/eclipse.workspace/README.txt, this test should just
- * work inside Eclipse.
- * <p>
- * If you just want to run a single test, launch this class as a JUnit test and stop it once it has
- * listed all the tests. Then right click on the desired test and select Run or Debug.
- */
-public class SharedTests extends TestSetup {
-  private final static String TEST_PY =
-      System.getProperty("com.google.dart.corelib.SharedTests.test_py", "../tools/test.py");
-
-  private static final String[] listTests = {
-      TEST_PY,
-      "--compiler=dartc",
-      "--runtime=none",
-      "--mode=release",
-      "--progress=silent",
-      "--list"};
-
-  public SharedTests(Test test) {
-    super(test);
-  }
-
-  public static TestSuite suite() {
-    return new SuiteBuilder().buildSuite();
-  }
-
-  protected static class SuiteBuilder {
-    protected TestSuite buildSuite() {
-      TestSuite suite = new TestSuite("Shared Dart tests");
-      File file = new File(listTests[0]);
-      if (!file.canExecute()) {
-        return configurationProblem(suite, file.getPath() + " is not executable");
-      }
-      ProcessBuilder builder = new ProcessBuilder(listTests);
-      try {
-        Process process = builder.start();
-        InputStream inputStream = process.getInputStream();
-        StringBuilder sb = new StringBuilder();
-        try {
-          InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
-          LineReader lineReader = new LineReader(inputStreamReader);
-          String line;
-          while ((line = lineReader.readLine()) != null) {
-            if (!line.startsWith("dartc/")) {
-              suite.addTest(SharedTestCase.getInstance(line, false));
-            } else if (line.startsWith("dartc/client/")) {
-              suite.addTest(SharedTestCase.getInstance(line, true));
-            }
-          }
-        } finally {
-          inputStream.close();
-          process.getOutputStream().close();
-          InputStreamReader inputStreamReader = new InputStreamReader(process.getErrorStream());
-          CharStreams.copy(inputStreamReader, sb);
-          process.getErrorStream().close();
-        }
-        process.waitFor();
-        if (process.exitValue() != 0) {
-          sb.insert(0, file.getPath());
-          sb.insert(0, " returned non-zero exit code.\n");
-          return configurationProblem(suite, sb.toString());
-        }
-      } catch (IOException e) {
-        throw new AssertionError(e);
-      } catch (InterruptedException e) {
-        throw new AssertionError(e);
-      }
-      return suite;
-    }
-
-    /**
-     * Errors reported during suite construction are hard to read. This method creates a test that
-     * will always fail with an error message that shows up in the Eclipse JUnit UI.
-     */
-    protected TestSuite configurationProblem(TestSuite suite, final String message) {
-      suite.addTest(new TestCase("Configuration problem") {
-        @Override
-        public void runBare() throws Throwable {
-          fail(message);
-        }
-      });
-      return suite;
-    }
-  }
-}
diff --git a/compiler/javatests/com/google/dart/corelib/TestSharedTests.java b/compiler/javatests/com/google/dart/corelib/TestSharedTests.java
deleted file mode 100644
index f922ca7..0000000
--- a/compiler/javatests/com/google/dart/corelib/TestSharedTests.java
+++ /dev/null
@@ -1,40 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-package com.google.dart.corelib;
-
-import junit.framework.Test;
-import junit.framework.TestCase;
-import junit.framework.TestSuite;
-
-/**
- * Test the configuration of SharedTests but without running all the tests.
- * This test is designed to be run from test.py which normally skips SharedTests.
- */
-public class TestSharedTests extends SharedTests {
-
-  public TestSharedTests(Test test) {
-    super(test);
-  }
-
-  public static TestSuite suite() {
-    final TestSuite suite = new TestSuite("Shared Dart tests configuration");
-
-    new SuiteBuilder() {
-      @Override
-      protected TestSuite configurationProblem(TestSuite ignored, String message) {
-        return super.configurationProblem(suite, message);
-      }
-    }.buildSuite();
-
-    if (suite.countTestCases() == 0) {
-      suite.addTest(new TestCase("configuration is fine") {
-        @Override
-        public void runBare() throws Throwable {
-        }
-      });
-    }
-    return suite;
-  }
-}
diff --git a/compiler/scripts/analyzer_metrics.sh b/compiler/scripts/analyzer_metrics.sh
deleted file mode 100755
index 8d13051..0000000
--- a/compiler/scripts/analyzer_metrics.sh
+++ /dev/null
@@ -1,127 +0,0 @@
-#!/bin/bash
-#
-# Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-# for details. All rights reserved. Use of this source code is governed by a
-# BSD-style license that can be found in the LICENSE file.
-
-# Collects compiler statics for a given Dart app and spits them out
-# Creates sample-full.txt, sample-incr-zero.txt, sample-incr-one.txt,
-# and out_compile_samples/ in the working direcetory, which are left
-# around for later examination. These files will be destroyed on
-# script re-run
-
-DART_PARAMS="--metrics "
-RUNS=3
-ONE_DELTA=""
-DART_ANALYZER=$(which dart_analyzer)
-SAMPLE_DIR="."
-PREFIX="sample"
-SCRIPT_DIR=$(dirname $0)
-
-source $SCRIPT_DIR/metrics_math.sh
-
-function printHelp() {
-  exitValue=${1:1}
-  echo "Generate average and standard deviation compiler stats on a full compile, zero-delta compile,"
-  echo "and optional one-delta compile."
-  echo ""
-  echo "  Usage:"
-  echo "  -a=, --app=         The dart app file to test (required)."
-  echo "  -r=, --runs=        Set the number of compile samples to be executed. Defaults to $RUNS"
-  echo "  -d=, --one-delta=   The filename, relative to DART_APP, to touch in order to trigger a one-delta compile."
-  echo "  -o=, --output=      Directory location of sample storage"
-  echo "  --analyzer=            Override PATH location for analyzer script"
-  echo "  -p, --stats-prefix= Adds prefix to each output file (default: sample-[full|incri-[one|zero]]).txt)"
-  echo "  -h, --help          What you see is what you get."
-  echo "  DART_APP            Path to dart .app file to compile (depricated)"
-  exit $exitValue
-}
-
-if [ $# -eq 0 ]; then
-  printHelp;
-fi
-
-for i in $*
-do
-  case $i in
-    --runs=*|-r=*)
-      RUNS=${i#*=};;
-    --one-delta=*|-d=*)
-      ONE_DELTA=${i#*=};;
-    --analyzer=*)
-      ANALYZER=${i#*=};;
-    --output=*|-o=*)
-      SAMPLE_DIR=${i#*=};;
-    --stats-prefix=*|-p=*)
-      if [ "" = "${i#*=}" ]; then
-        echo "prefix cannot be empty"
-        printHelp 1;
-      fi
-      PREFIX=${i#*=};;
-    --app=*|-a=*)
-      APP=${i#*=};;
-    --help|-h)
-      printHelp 0;;
-    -*)
-      echo "Parameter $i not recognized"
-      printHelp 1;;
-    *)
-      break;;
-  esac
-done
-
-if [ "" = "$ANALYZER" ] || [ ! -x $ANALYZER ]; then
-  echo "Error: Location of 'dart_analyzer' not found."
-  printHelp 1
-fi
-
-if [ "" = "$SAMPLE_DIR" ] || [ ! -d $SAMPLE_DIR ]; then
-  echo "Error: Invalid directory for samples location: $SAMPLE_DIR"
-  printHelp 1
-fi
-
-OUT_DIR=$SAMPLE_DIR/out_compile_samples
-DART_PARAMS+="-out $OUT_DIR "
-
-if [ "" = "$APP" ]; then
-  APP=$(echo $@ | sed -n 's/.*\s\(\S*\.app\).*/\1/p')
-fi
-if [ "" = "$APP" ] || [ ! -r $APP ]; then
-  echo "Error: Must specify app file, got: $APP"
-  printHelp 1
-fi
-
-APP_RELATIVE=`dirname $APP`
-if [ "" != "$ONE_DELTA" ]; then
-  ONE_DELTA="$APP_RELATIVE/$ONE_DELTA"
-  if [ ! -r $ONE_DELTA ]; then
-    echo "Error, one_delta file, $ONE_DELTA, does not exist"
-    printHelp
-  fi
-fi
-
-SAMPLE_FULL=$SAMPLE_DIR/$PREFIX-full.txt
-SAMPLE_INCR_ZERO=$SAMPLE_DIR/$PREFIX-incr-zero.txt
-SAMPLE_INCR_ONE=$SAMPLE_DIR/$PREFIX-incr-one.txt
-
-#clean up
-rm -Rf $SAMPLE_FULL $SAMPLE_INCR_ZERO $SAMPLE_INCR_ONE
-
-for ((i=0;i<$RUNS;i++)) do 
-  echo "Run $i"
-  rm -Rf $OUT_DIR
-  $ANALYZER $DART_PARAMS $APP >> $SAMPLE_FULL
-  $ANALYZER $DART_PARAMS $APP >> $SAMPLE_INCR_ZERO
-  if [ -e $ONE_DELTA ] && [ "" != "$ONE_DELTA" ]; then
-    touch $ONE_DELTA
-    $ANALYZER $DART_PARAMS $APP >> $SAMPLE_INCR_ONE
-  fi
-done
-
-sample_file "full-compile" "Compile-time-total-ms" "$SAMPLE_FULL"
-sample_file "zero-delta-compile" "Compile-time-total-ms" "$SAMPLE_INCR_ZERO"
-if [ -e $ONE_DELTA ] && [ "" != "$ONE_DELTA" ]; then
-  sample_file "one-delta-compile" "Compile-time-total-ms" "$SAMPLE_INCR_ONE"
-fi
-
-
diff --git a/compiler/scripts/analyzer_series_test.sh b/compiler/scripts/analyzer_series_test.sh
deleted file mode 100755
index dcb388b..0000000
--- a/compiler/scripts/analyzer_series_test.sh
+++ /dev/null
@@ -1,226 +0,0 @@
-#!/bin/bash
-#
-# Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-# for details. All rights reserved. Use of this source code is governed by a
-# BSD-style license that can be found in the LICENSE file.
-
-# Compares a series of compiler reivsions against a target application for
-# statistic collection. Outputs a gnuplot consumable table.
-
-APP=""
-REV=""
-ONE_DELTA=""
-BASE_PATH=$(pwd)
-SCRIPT_PATH=$(dirname $0)
-SCRIPT_PATH=$(cd $SCRIPT_PATH; pwd)
-RUNS=10
-COUNT=50
-LOW_REV=""
-
-function printHelp() {
-  exitValue=${1:1}
-  echo "Compare performance of multiple compiler revisions against a given target application."
-  echo "Creates a cache of pre-built compiler revisions in compiler/revs/ for later comparison."
-  echo "The target output of this script is a gnuplot consumable list of stats (for now), located"
-  echo "in tmp_performance_comparisons/compiler_plots.dat."
-  echo ""
-  echo "  Usage:"
-  echo "  -a=, --app=         The dart app file to test (required)."
-  echo "  -d=, --one-delta=   The filename, relative to app, to touch in order to trigger a one-delta compile."
-  echo "  -r=, --revision=    The compiler revision to start comparing against (default to current repository revision)."
-  echo "  -c=, --count=       The number of compiler revisions test against.  Default 50."
-  echo "  -l=, --low-rev=     Alternative to --count; set the lowest revision to run to"
-  echo "  -n=, --runs=        How many times each compiler is run against the target application."
-  echo "  -h, --help          What you see is what you get."
-  exit $exitValue
-}
-
-function failTest() {
-  if [ ! $1 -eq 0 ]; then
-    echo $2
-    exit $1
-  fi
-}
-
-RESPONSE[0]="Performance: Better"
-RESPONSE[1]="Performance: No Change"
-RESPONSE[2]="Performance: Worse"
-
-function calcStat() {
-  # Assume we're always making improvments, S2 will be presented as a larger value
-  LINEMATCH_DEV="s/${1}: .*stdev: \([0-9]*\).*/\1/p"
-  LINEMATCH_VALUE="s/${1}: average: \([0-9]*\).*/\1/p"
-  S1_DEV=$(sed -n -e "$LINEMATCH_DEV" $STAT1)
-  if [ "" != "$S1_DEV" ]; then
-    S1_VALUE=$(sed -n -e "$LINEMATCH_VALUE" $STAT1)
-    echo -ne "\t"$S1_VALUE"\t"$S1_DEV >> $PLOTS
-  else
-    echo -ne "\t-1\t-1" >> $PLOTS
-  fi
-  return 0
-}
-
-function calcStats() {
-  echo -n $1 >> $PLOTS
-  calcStat full-compile
-  calcStat zero-delta-compile
-  calcStat one-delta-compile
-  echo "" >> $PLOTS
-}
-
-if [ $# -eq 0 ]; then
-  printHelp;
-fi
-
-for i in $*
-do
-  case $i in
-    --one-delta=*|-d=*)
-      ONE_DELTA=${i#*=}
-      COMPARE_OPTIONS+="--one-delta=$ONE_DELTA ";;
-    --app=*|-a=*)
-      APP=${i#*=};;
-    --revision=*|-r=*)
-      REV=${i#*=};;
-    --count=*|-c=*)
-      COUNT=${i#*=}
-      LOW_REV="";;
-    --runs=*|-n=*)
-      RUNS=${i#*=};;
-    --low-rev=*|-l=*)
-      LOW_REV=${i#*=}
-      COUNT=0;;
-    --help|-h)
-      printHelp 0;;
-    *)
-      echo "Parameter $i not recognized"
-      printHelp 1;;
-  esac
-done
-
-COMPARE_OPTIONS+="-r=$RUNS "
-
-if ((RUNS > 0)); then
-  if [ "" = "$APP" ] || [ ! -r $APP ]; then
-    echo "Required --app" " got: $APP"
-    printHelp 1
-  fi
-  APP=$( cd "$( dirname "$APP" )" && pwd )/$( basename "$APP")
-  COMPARE_OPTIONS+="--app=$APP "
-else
-  echo "Building up compiler cache"
-  APP="Compiler cache"
-fi
-
-ROOT_OF_REPO=$BASE_PATH
-TEST_DIR=$BASE_PATH
-while true; do
-  ls -d .gclient > /dev/null 2>&1
-  if [ $? -eq 0 ]; then
-    echo "Root found: $ROOT_OF_REPO"
-    break;
-  fi
-  if [ "$TEST_DIR" = "/" ]; then
-    failTest 1 "Hit the root directory; no .git/ found?!"
-  fi
-  ROOT_OF_REPO=$TEST_DIR
-  cd ..
-  TEST_DIR=$(pwd)
-done
-
-# Make a temporary directory in the current path and checkout the revision
-TMP_DIR=$ROOT_OF_REPO/compiler/tmp_performance_comparisons
-mkdir -p $TMP_DIR
-
-LOG_FILE=$TMP_DIR/compiler_compare.log
-PLOTS=$TMP_DIR/compiler_plots.dat
-STAT1=$TMP_DIR/compiler_metrics.txt
-COMPARE_OPTIONS+="--output=$TMP_DIR "
-
-# zero out files
-echo "" > $LOG_FILE
-
-# switch to tmp for remainder of building
-cd $TMP_DIR
-gclient config https://dart.googlecode.com/svn/branches/bleeding_edge/deps/compiler.deps >> $LOG_FILE 2>&1
-failTest $? "Error calling gclient config"
-
-if [ "" == "$REV" ]; then
-  echo "No revision specified; checking out head for test"
-  REV=`svn info https://dart.googlecode.com/svn/branches/bleeding_edge/deps/compiler.deps | sed -n -e 's/Revision: \([0-9]*\)/\1/p'`
-  echo "Head revision = $REV"
-fi
-
-function failStats() {
-  echo -e "$1\t-1\t0\t-1\t0\t-1\t0" >> $PLOTS
-  return 0;
-}
-
-function compileRevision() {
-  REVISION=$1
-  PREBUILT_DIR=$ROOT_OF_REPO/analyzer/revs/$REVISION/prebuilt
-  PREBUILT_BIN=$PREBUILT_DIR/analyzer/bin/dart_analyzer
-  if [ ! -x $PREBUILT_BIN ]; then
-    echo "No prebuilt, building and caching"
-    echo "Checking out clean version of $REVISION; will take some time. Look at $LOG_FILE for progress"
-    date
-    cd $TMP_DIR
-    gclient sync -t --revision=$REVISION  >> $LOG_FILE 2>&1
-    failTest $? "Error calling gclient sync"
-    echo "Run hooks"
-    gclient runhooks >> $LOG_FILE 2>&1
-
-    echo "Compiling clean version of dart_analyzer"
-    date
-    cd compiler
-    ../tools/build.py --mode release >> $LOG_FILE 2>&1
-    if [ ! $? -eq 0 ]; then
-      echo "error compiling"
-      failStats $REVISION
-      return 1;
-    fi
-
-    # Give the metrics system a backwards compatible way of getting to the
-    # artifacts that it needs.
-    cd ..
-    mkdir -p $ROOT_OF_REPO/compiler/revs/$REVISION/prebuilt
-    cd $ROOT_OF_REPO/compiler/revs/$REVISION/prebuilt
-    COMPILER_OUTDIR=$TMP_DIR/compiler/out/Release_ia32
-    cp -r $COMPILER_OUTDIR/compiler ./compiler
-  else
-    echo "Cached prebuilt of $REVISION!"
-  fi
-
-  # Short circuit if we're just filling in the build cache
-  if [ $RUNS -eq 0 ]; then
-    echo "run in compile only mode, no stats generating"
-    return 0;
-  fi
-
-  # Do the second test
-  echo "Running test with dart_analyzer $REVISION!"
-  date
-  echo $SCRIPT_PATH/analyzer_metrics.sh --stats-prefix=$REVISION --analyzer=$PREBUILT_DIR/analyzer/bin/dart_analyzer $COMPARE_OPTIONS >> $LOG_FILE 2>&1
-  $SCRIPT_PATH/analyzer_metrics.sh --stats-prefix=$REVISION --analyzer=$PREBUILT_DIR/analyzer/bin/dart_analyzer $COMPARE_OPTIONS > $STAT1
-  if [ ! $? -eq 0 ]; then
-    echo "error sampling"
-    failStats $REVISION
-    return 2;
-  fi
-
-  # Output the reivision to the PLOTS file; newline added after stats
-  calcStats $REVISION
-}
-
-echo -e "#Rev\tFull-ms\tdev\tZeroD\tdev\tOneD\tdev" > $PLOTS
-if [ "$LOW_REV" ]; then
-  COUNT=$(( REV - LOW_REV + 1 ))
-else
-  LOW_REV=$(( REV - COUNT + 1 ))
-fi
-for (( i = REV ; i >= LOW_REV ; i-- ))
-do
-  echo "["$( basename "$APP")": "$((REV - i + 1))"/"$COUNT", rev:$i]"
-  compileRevision $i
-done
-
diff --git a/compiler/scripts/dart_analyzer.bat b/compiler/scripts/dart_analyzer.bat
deleted file mode 100644
index acdb4ca..0000000
--- a/compiler/scripts/dart_analyzer.bat
+++ /dev/null
@@ -1,139 +0,0 @@
-@echo off
-rem #!/bin/bash --posix
-rem Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-rem for details. All rights reserved. Use of this source code is governed by a
-rem BSD-style license that can be found in the LICENSE file.
-rem 
-rem stop if any of the steps fails
-rem set -e
-rem 
-
-rem SCRIPT_DIR=$(dirname $0)
-set SCRIPT_DIR=%~dp0
-if %SCRIPT_DIR:~-1%==\ set SCRIPT_DIR=%SCRIPT_DIR:~0,-1%
-
-rem DART_ANALYZER_HOME=$(dirname $SCRIPT_DIR)
-for %%I in ("%SCRIPT_DIR%\..") do set "DART_ANALYZER_HOME=%%~fI"
-if %DART_ANALYZER_HOME:~-1%==\ set DART_ANALYZER_HOME=%DART_ANALYZER_HOME:~0,-1%
-
-set FOUND_BATCH=0
-set FOUND_SDK=0
-for %%a in (%*) do (
-  if [%%a] == [--batch] set FOUND_BATCH=1
-  if [%%a] == [-b] set FOUND_BATCH=1
-  if [%%a] == [--dart-sdk]  set FOUND_SDK=1
-)
-
-rem FOUND_BATCH=0
-rem FOUND_SDK=0
-rem for ARG in "$@"
-rem do
-rem   case $ARG in
-rem     -batch|--batch)
-rem       FOUND_BATCH=1
-rem       ;;
-rem     --dart-sdk)
-rem       FOUND_SDK=1
-rem       ;;
-rem     *)
-rem       ;;
-rem   esac
-rem done
-rem 
-
-setlocal EnableDelayedExpansion
-set DART_SDK=""
-if [%FOUND_SDK%] == [0] (
-  if exist "%DART_ANALYZER_HOME%\lib\core\core.dart" (
-    set DART_SDK=--dart-sdk "%DART_ANALYZER_HOME%"
-  ) else (
-    for /f %%i in ('echo %DART_ANALYZER_HOME%') do set DART_SDK_HOME=%%~dpi\dart-sdk
-    if exist "!DART_SDK_HOME!" (
-      set DART_SDK=--dart-sdk !DART_SDK_HOME!
-    ) else (
-      for /f %%j in ('call echo !DART_SDK_HOME!') do set DART_SDK_HOME=%%~dpj\dart-sdk
-      if exist "!DART_SDK_HOME!" (
-        set DART_SDK=--dart-sdk !DART_SDK_HOME!
-      ) else (
-        echo Couldn't find Dart SDK. Specify with --dart-sdk cmdline argument
-      )
-    )
-  )
-)
-endlocal & set "DART_SDK=%DART_SDK%" & set "DART_SDK_HOME=%DART_SDK_HOME%"
-
-rem DART_SDK=""
-rem if [ $FOUND_SDK = 0 ] ; then
-rem   if [ -f $DART_ANALYZER_HOME/lib/core/core.dart ] ; then
-rem     DART_SDK="--dart-sdk $DART_ANALYZER_HOME"
-rem   else
-rem     DART_SDK_HOME=$(dirname $DART_ANALYZER_HOME)/dart-sdk
-rem     if [ -d $DART_SDK_HOME ] ; then
-rem       DART_SDK="--dart-sdk $DART_SDK_HOME"
-rem     else
-rem       DART_SDK_HOME=$(dirname $DART_SDK_HOME)/dart-sdk
-rem       if [ -d $DART_SDK_HOME ] ; then
-rem         DART_SDK="--dart-sdk $DART_SDK_HOME"
-rem       else
-rem         echo "Couldn't find Dart SDK. Specify with --dart-sdk cmdline argument"
-rem       fi
-rem     fi
-rem   fi
-rem fi
-rem 
-
-if exist "%DART_SDK_HOME%\util\analyzer\dart_analyzer.jar" (
-  set DART_ANALYZER_LIBS=%DART_SDK_HOME%\util\analyzer
-) else if exist "%DART_ANALYZER_HOME%\util\analyzer\dart_analyzer.jar" (
-  set DART_ANALYZER_LIBS=%DART_ANALYZER_HOME%\util\analyzer
-) else (
-  echo Configuration problem. Couldn't find dart_analyzer.jar.
-  exit /b 1
-)
-
-rem if [ -f $DART_SDK_HOME/util/analyzer/dart_analyzer.jar ] ; then
-rem   DART_ANALYZER_LIBS=$DART_SDK_HOME/util/analyzer
-rem elif [ -f $DART_ANALYZER_HOME/util/analyzer/dart_analyzer.jar ] ; then
-rem   DART_ANALYZER_LIBS=$DART_ANALYZER_HOME/util/analyzer
-rem else
-rem   echo "Configuration problem. Couldn't find dart_analyzer.jar."
-rem   exit 1
-rem fi
-
-rem 
-rem if [ -x /usr/libexec/java_home ]; then
-rem   export JAVA_HOME=$(/usr/libexec/java_home -v '1.6+')
-rem fi
-rem 
-
-setlocal EnableDelayedExpansion
-set EXTRA_JVMARGS=-Xss2M 
-if [%FOUND_BATCH%] == [1] (
-  set EXTRA_JVMARGS=!EXTRA_JVMARGS! -client
-)
-endlocal & set "EXTRA_JVMARGS=%EXTRA_JVMARGS%"
-
-rem EXTRA_JVMARGS="-Xss2M "
-rem OS=`uname | tr [A-Z] [a-z]`
-rem if [ "$OS" == "darwin" ] ; then
-rem   # Bump up the heap on Mac VMs, some of which default to 128M or less.
-rem   # Users can specify DART_JVMARGS in the environment to override
-rem   # this setting. Force to 32 bit client vm. 64 bit and server VM make for 
-rem   # poor performance.
-rem   EXTRA_JVMARGS+=" -Xmx256M -client -d32 "
-rem else
-rem   # On other architectures
-rem   # -batch invocations will do better with a server vm
-rem   # invocations for analyzing a single file do better with a client vm
-rem   if [ $FOUND_BATCH = 0 ] ; then
-rem     EXTRA_JVMARGS+=" -client "
-rem   fi
-rem fi
-rem 
-
-java %EXTRA_JVMARGS% %DART_JVMARGS% -ea -classpath "@CLASSPATH@" ^
-  com.google.dart.compiler.DartCompiler %DART_SDK% %*
-
-rem exec java $EXTRA_JVMARGS $DART_JVMARGS -ea -classpath "@CLASSPATH@" \
-rem   com.google.dart.compiler.DartCompiler ${DART_SDK} $@
-rem 
diff --git a/compiler/scripts/generate_my_projects.py b/compiler/scripts/generate_my_projects.py
deleted file mode 100755
index ff5800bb..0000000
--- a/compiler/scripts/generate_my_projects.py
+++ /dev/null
@@ -1,61 +0,0 @@
-#!/usr/bin/env python
-# Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-# for details. All rights reserved. Use of this source code is governed by a
-# BSD-style license that can be found in the LICENSE file.
-
-import os
-import sys
-
-
-def Main():
-  def normjoin(*args):
-    return os.path.normpath(os.path.join(*args))
-
-  compiler = normjoin(sys.argv[0], os.pardir, os.pardir)
-  editor = normjoin(compiler, os.pardir, 'editor')
-
-  locations = {
-    'compiler': compiler,
-    'editor': editor,
-  }
-
-  generate_source_list_calls = [
-    # The paths are relative to dart/compiler/
-    {
-        "name" : "java",
-        "output" : "%(compiler)s/sources" % locations,
-        "path" : "java",
-    },
-    {
-        "name" : "javatests",
-        "output" : "%(compiler)s/test_sources" % locations,
-        "path" : "javatests",
-    },
-    # The paths are relative to dart/editor/
-    {
-        "name" : "plugin_engine_java",
-        "output" : "%(editor)s/plugin_engine_sources" % locations,
-        "path" : "tools/plugins/com.google.dart.engine",
-    },
-    {
-        "name" : "plugin_command_analyze_java",
-        "output" : "%(editor)s/plugin_command_analyze_sources" % locations,
-        "path" : "tools/plugins/com.google.dart.command.analyze",
-    },
-  ]
-
-  for call_options in generate_source_list_calls:
-    command = ("python %(compiler)s/generate_source_list.py " % locations +
-              "%(name)s %(output)s %(path)s" % call_options)
-    exit_code = os.system(command)
-    if exit_code:
-      return exit_code
-
-  if '--no-gyp' in sys.argv:
-    print '--no-gyp is deprecated.'
-
-  return 0
-
-
-if __name__ == '__main__':
-  sys.exit(Main())
diff --git a/compiler/scripts/metrics_math.sh b/compiler/scripts/metrics_math.sh
deleted file mode 100644
index 5bf1104..0000000
--- a/compiler/scripts/metrics_math.sh
+++ /dev/null
@@ -1,59 +0,0 @@
-#!/bin/bash
-#
-# Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-# for details. All rights reserved. Use of this source code is governed by a
-# BSD-style license that can be found in the LICENSE file.
-
-# This file is repsonsible for performing the averag and standard deviation
-# for a specific metrics over a given set of metrics in a file.
-# This should be included in other compiler scripts, or used through
-# sample_metrics.sh
-
-AVERAGE=0
-STDEV=0
-COUNT=0
-
-function do_math_return() {
-  local sum=0
-  local count=0
-  local time
-  for time in $2
-  do
-    sum=$(echo "$sum + $time" | bc -l)
-    (( count++ ))
-  done
-  average=$(echo "$sum / $count" | bc -l)
-  #echo "count=$count, sum=$sum, average=$average"
-
-  #go over the numbers, take the difference from the average and squart, then square root / count.
-  sum_dev=0
-  for time in $2
-  do
-    step=$(echo "$time - $average" | bc -l)
-    sum_dev=$(echo "$sum_dev + $step^2" | bc -l)
-  done
-
-    step=$(echo "$sum_dev / $count" | bc -l)
-  OUT="sqrt(${step})"
-  standard_dev=$(echo $OUT | bc -l | sed 's/\([0-9]*\.[0-9][0-9]\)[0-9]*/\1/')
-  average=$(echo $average | sed 's/\([0-9]*\.[0-9][0-9]\)[0-9]*/\1/')
-  AVERAGE=$average
-  STDEV=$standard_dev
-  COUNT=$count
-}
-
-function do_math() {
-  do_math_return "$1" "$2"
-  echo "$1: average: $AVERAGE stdev: $STDEV count: $COUNT"
-}
-
-function sample_file_return() {
-  TIMES=$(sed -n "s/$2\S*\s*:\s*\(\([0-9]*\)\(\.[0-9]*\)\?\)/\1/p" $3)
-  do_math_return "$1" "$TIMES"
-  SAMPLE_LINE="$1: average: $AVERAGE stdev: $STDEV count: $COUNT"
-}
-
-function sample_file() {
-  TIMES=$(sed -n "s/$2\S*\s*:\s*\(\([0-9]*\)\(\.[0-9]*\)\?\)/\1/p" $3)
-  do_math "$1" "$TIMES"
-}
diff --git a/compiler/scripts/sample_metrics.sh b/compiler/scripts/sample_metrics.sh
deleted file mode 100755
index 11702ff..0000000
--- a/compiler/scripts/sample_metrics.sh
+++ /dev/null
@@ -1,18 +0,0 @@
-#!/bin/bash
-#
-# Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-# for details. All rights reserved. Use of this source code is governed by a
-# BSD-style license that can be found in the LICENSE file.
-
-# Given a file that contains one or more of DartC metrics, check the
-# for a specific metric, compute its average and deviation, and print
-# it to the stdout.
-
-source metrics_math.sh
-
-if [ ! $# -eq 3 ]; then
-  echo $(basename $0) "\"OutputHeader\" \"CompilerStatToMatch\" metrics.txt";
-  exit 1;
-fi
-
-sample_file "$1" "$2" "$3"
diff --git a/compiler/tests/dartc/dartc.status b/compiler/tests/dartc/dartc.status
deleted file mode 100644
index a43c667..0000000
--- a/compiler/tests/dartc/dartc.status
+++ /dev/null
@@ -1,20 +0,0 @@
-# Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-# for details. All rights reserved. Use of this source code is governed by a
-# BSD-style license that can be found in the LICENSE file.
-
-# This directory creates a single java junit test, with name dartc/junit_tests.
-# This status file is only used to exclude all components except dartc
-# from performing the test, in the test.py script.
-
-# The individual file and directory exclusions are hardcoded into the scripts
-# client/tests/dartc/testcfg.py and client/tests/dartc/test_config.dart.
-# The component exclusions are hardcoded into test.dart.
-
-compiler/vm/*: Skip
-
-
-# Already tested through test.py.
-corelib/SharedTests: Skip
-
-[ $compiler == dart2js || $compiler == none ]
-*: Skip
diff --git a/compiler/tests/dartc/test_config.dart b/compiler/tests/dartc/test_config.dart
deleted file mode 100644
index ccda857..0000000
--- a/compiler/tests/dartc/test_config.dart
+++ /dev/null
@@ -1,15 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library junit_dartc_test_config;
-
-import "../../../tools/testing/dart/test_suite.dart";
-
-class JUnitDartcTestSuite extends JUnitTestSuite {
-  JUnitDartcTestSuite(Map configuration)
-      : super(configuration,
-              'dartc/junit_tests',
-              'compiler/javatests/com/google/dart',
-              'compiler/tests/dartc/dartc.status');
-}
diff --git a/dart.gyp b/dart.gyp
index 70d9da6..12d8604 100644
--- a/dart.gyp
+++ b/dart.gyp
@@ -9,7 +9,6 @@
       'type': 'none',
       'dependencies': [
         'analyzer',
-        'compiler',
         'create_sdk',
         'dart2js',
         'editor',
@@ -20,14 +19,6 @@
       ],
     },
     {
-      'target_name': 'compiler',
-      'type': 'none',
-      'dependencies': [
-        'compiler/dart-compiler.gyp:dart_analyzer',
-      ],
-      'actions': []
-    },
-    {
       # This is the target that is built on the VM build bots.  It
       # must depend on anything that is required by the VM test
       # suites.
@@ -59,7 +50,6 @@
         'utils/compiler/compiler.gyp:dart2js',
         'utils/pub/pub.gyp:pub',
         'analyzer',
-        'compiler',
       ],
       'actions': [
         {
@@ -72,7 +62,6 @@
             '<(SHARED_INTERMEDIATE_DIR)/dart2js.dart.snapshot',
             '<(SHARED_INTERMEDIATE_DIR)/utils_wrapper.dart.snapshot',
             '<(SHARED_INTERMEDIATE_DIR)/pub.dart.snapshot',
-            '<(PRODUCT_DIR)/analyzer/bin/dart_analyzer',
             '<(PRODUCT_DIR)/dartanalyzer/dartanalyzer.jar',
           ],
           'outputs': [
diff --git a/pkg/docgen/example/test.dart b/pkg/docgen/example/test.dart
deleted file mode 100755
index d93b63f..0000000
--- a/pkg/docgen/example/test.dart
+++ /dev/null
@@ -1,60 +0,0 @@
-// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-/**
- * This library is used solely for testing during development and is not
- * intended to be run by the testing machines.
- */
-// TODO(tmandel): Remove this file once docgen is ready for more clear tests.
-library DummyLibrary;
-
-import 'dart:json';
-import 'dart:math';
-
-/// Doc comment for top-level variable.
-int _variable1 = 0;
-
-void set variable1(int abc) => _variable1 = abc;
-
-abstract class B {
-
-}
-
-/**
- * Doc comment for class A.
- */
-/*
- * Normal comment for class A.
- */
-class A implements B {
-
-  /**
-   * Markdown _test_ for **class** [A] 
-   */
-  int _someNumber;
-
-  A() {
-    _someNumber = 12;
-  }
-
-  int get someNumber => _someNumber;
-
-  void doThis(int a) {
-    print(a);
-  }
-
-  int multi(int a) {
-    return a * _someNumber;
-  } 
-
-}
-
-main() {
-  A a = new A();
-  print(a.someNumber);
-}
-
-A getA(int testInt, [String testString="default"]) {
-  return new A();
-}
\ No newline at end of file
diff --git a/pkg/docgen/lib/docgen.dart b/pkg/docgen/lib/docgen.dart
index 2844d28..8a182b0 100644
--- a/pkg/docgen/lib/docgen.dart
+++ b/pkg/docgen/lib/docgen.dart
@@ -50,8 +50,12 @@
 /// Resolves reference links in doc comments.
 markdown.Resolver linkResolver;
 
-/// Index of all the qualified names documented. 
-Set<String> qualifiedNameIndex = new Set<String>();
+/// Index of all indexable items. This also ensures that no class is 
+/// created more than once. 
+Map<String, Indexable> entityMap = new Map<String, Indexable>();
+
+/// This is set from the command line arguments flag --include-private 
+bool _includePrivate = false;
 
 /**
  * Docgen constructor initializes the link resolver for markdown parsing.
@@ -68,6 +72,7 @@
 Future<bool> docgen(List<String> files, {String packageRoot,
     bool outputToYaml: true, bool includePrivate: false, bool includeSdk: false,
     bool parseSdk: false, bool append: false}) {
+  _includePrivate = includePrivate;
   if (!append) {
     var dir = new Directory('docs');
     if (dir.existsSync()) dir.deleteSync(recursive: true);
@@ -93,8 +98,7 @@
         throw new StateError('No library mirrors were created.');
       }
       _documentLibraries(mirrorSystem.libraries.values,
-          includeSdk: includeSdk, includePrivate: includePrivate,
-          outputToYaml: outputToYaml, append: append);
+          includeSdk: includeSdk, outputToYaml: outputToYaml, append: append);
 
       return true;
     });
@@ -196,50 +200,93 @@
 /**
  * Creates documentation for filtered libraries.
  */
-void _documentLibraries(List<LibraryMirror> libraries,
-    {bool includeSdk: false, bool includePrivate: false, 
-    bool outputToYaml: true, bool append: false}) {
-  libraries.forEach((lib) {
+void _documentLibraries(List<LibraryMirror> libs,
+    {bool includeSdk: false, bool outputToYaml: true, bool append: false}) {
+  libs.forEach((lib) {
     // Files belonging to the SDK have a uri that begins with 'dart:'.
     if (includeSdk || !lib.uri.toString().startsWith('dart:')) {
-      var library = generateLibrary(lib, includePrivate: includePrivate);
-      _writeLibraryToFile(library, outputToYaml);
+      var library = generateLibrary(lib);
+      entityMap[library.qualifiedName] = library;
     }
   });
-  // Outputs a text file with a list of files available after creating all
-  // the libraries. This will help the viewer know what files are available
+  // After everything is created, do a pass through all classes to make sure no
+  // intermediate classes created by mixins are included. 
+  entityMap.values.where((e) => e is Class).forEach((c) => c.makeValid());
+  // Everything is a subclass of Object, therefore empty the list to avoid a
+  // giant list of subclasses to be printed out. 
+  entityMap['dart.core.Object'].subclasses.clear();
+  
+  var filteredEntities = entityMap.values.where(_isVisible);
+  // Output libraries and classes to file after all information is generated.
+  filteredEntities.where((e) => e is Class || e is Library).forEach((output) {
+    _writeIndexableToFile(output, outputToYaml);
+  });
+  // Outputs a text file with a list of libraries available after creating all
+  // the libraries. This will help the viewer know what libraries are available
   // to read in.
-  _writeToFile(listDir('docs').join('\n').replaceAll('docs/', ''),
-      'library_list.txt', append: append);
+  _writeToFile(filteredEntities.where((e) => e is Library)
+      .map((e) => e.qualifiedName).join('\n'), 'library_list.txt', 
+      append: append);
   // Outputs all the qualified names documented. This will help generate search
   // results. 
-  _writeToFile(qualifiedNameIndex.join('\n'), 'index.txt', append: append);
+  _writeToFile(filteredEntities.map((e) => e.qualifiedName).join('\n'), 
+      'index.txt', append: append);
 }
 
-Library generateLibrary(dart2js.Dart2JsLibraryMirror library,
-  {bool includePrivate: false}) {
+Library generateLibrary(dart2js.Dart2JsLibraryMirror library) {
   _currentLibrary = library;
-  var result = new Library(library.qualifiedName, _getComment(library),
-      _getVariables(library.variables, includePrivate),
-      _getMethods(library.functions, includePrivate),
-      _getClasses(library.classes, includePrivate));
+  var result = new Library(library.qualifiedName, _commentToHtml(library),
+      _variables(library.variables),
+      _methods(library.functions),
+      _classes(library.classes), _isPrivate(library));
   logger.fine('Generated library for ${result.name}');
   return result;
 }
 
-void _writeLibraryToFile(Library result, bool outputToYaml) {
+void _writeIndexableToFile(Indexable result, bool outputToYaml) {
   if (outputToYaml) {
-    _writeToFile(getYamlString(result.toMap()), '${result.name}.yaml');
+    _writeToFile(getYamlString(result.toMap()), '${result.qualifiedName}.yaml');
   } else {
-    _writeToFile(stringify(result.toMap()), '${result.name}.json');
+    _writeToFile(stringify(result.toMap()), '${result.qualifiedName}.json');
   }
+}
 
+/**
+ * Returns true if a library name starts with an underscore, and false 
+ * otherwise.
+ * 
+ * An example that starts with _ is _js_helper.
+ * An example that contains ._ is dart._collection.dev
+ */
+// This is because LibraryMirror.isPrivate returns `false` all the time. 
+bool _isLibraryPrivate(LibraryMirror mirror) {
+  if (mirror.simpleName.startsWith('_') || mirror.simpleName.contains('._')) {
+    return true;
+  }
+  return false;
+}
+
+/**
+ * A declaration is private if itself is private, or the owner is private. 
+ */
+bool _isPrivate(DeclarationMirror mirror) {
+  if (mirror is LibraryMirror) {
+    return _isLibraryPrivate(mirror);
+  } else if (mirror.owner is LibraryMirror) {
+    return (mirror.isPrivate || _isLibraryPrivate(mirror.owner));
+  } else { 
+    return (mirror.isPrivate || _isPrivate(mirror.owner));
+  }
+}
+
+bool _isVisible(Indexable item) {
+  return _includePrivate || !item.isPrivate;
 }
 
 /**
  * Returns a list of meta annotations assocated with a mirror.
  */
-List<String> _getAnnotations(DeclarationMirror mirror) {
+List<String> _annotations(DeclarationMirror mirror) {
   var annotations = mirror.metadata.where((e) =>
       e is dart2js.Dart2JsConstructedConstantMirror);
   return annotations.map((e) => e.type.qualifiedName).toList();
@@ -249,7 +296,7 @@
  * Returns any documentation comments associated with a mirror with
  * simple markdown converted to html.
  */
-String _getComment(DeclarationMirror mirror) {
+String _commentToHtml(DeclarationMirror mirror) {
   String commentText;
   mirror.metadata.forEach((metadata) {
     if (metadata is CommentInstanceMirror) {
@@ -289,17 +336,18 @@
 /**
  * Returns a map of [Variable] objects constructed from [mirrorMap].
  */
-Map<String, Variable> _getVariables(Map<String, VariableMirror> mirrorMap,
-    bool includePrivate) {
+Map<String, Variable> _variables(Map<String, VariableMirror> mirrorMap) {
   var data = {};
   // TODO(janicejl): When map to map feature is created, replace the below with
   // a filter. Issue(#9590).
   mirrorMap.forEach((String mirrorName, VariableMirror mirror) {
-    if (includePrivate || !mirror.isPrivate) {
-      _currentMember = mirror;
-      data[mirrorName] = new Variable(mirrorName, mirror.isFinal, 
-          mirror.isStatic, mirror.isConst, _type(mirror.type),
-          _getComment(mirror), _getAnnotations(mirror), mirror.qualifiedName);
+    _currentMember = mirror;
+    if (_includePrivate || !_isPrivate(mirror)) {
+      entityMap[mirror.qualifiedName] = new Variable(mirrorName, mirror.isFinal,
+         mirror.isStatic, mirror.isConst, _type(mirror.type),
+         _commentToHtml(mirror), _annotations(mirror), mirror.qualifiedName,
+         _isPrivate(mirror), mirror.owner.qualifiedName);
+      data[mirrorName] = entityMap[mirror.qualifiedName];
     }
   });
   return data;
@@ -308,104 +356,58 @@
 /**
  * Returns a map of [Method] objects constructed from [mirrorMap].
  */
-Map<String, Map<String, Method>> _getMethods
-    (Map<String, MethodMirror> mirrorMap, bool includePrivate) {
-
-  var setters = {};
-  var getters = {};
-  var constructors = {};
-  var operators = {};
-  var methods = {};
-  
+MethodGroup _methods(Map<String, MethodMirror> mirrorMap) {
+  var group = new MethodGroup();
   mirrorMap.forEach((String mirrorName, MethodMirror mirror) {
-    if (includePrivate || !mirror.isPrivate) {
-      var method = new Method(mirrorName, mirror.isStatic, mirror.isAbstract,
-          mirror.isConstConstructor, _type(mirror.returnType), 
-          _getComment(mirror), _getParameters(mirror.parameters), 
-          _getAnnotations(mirror), mirror.qualifiedName);
-      _currentMember = mirror;
-      if (mirror.isSetter) {
-        setters[mirrorName] = method;
-      } else if (mirror.isGetter) {
-        getters[mirrorName] = method;
-      } else if (mirror.isConstructor) {
-        constructors[mirrorName] = method;
-      } else if (mirror.isOperator) {
-        operators[mirrorName] = method;
-      } else if (mirror.isRegularMethod) {
-         methods[mirrorName] = method;
-      } else {
-        throw new ArgumentError('$mirrorName - no method type match');
-      }
+    if (_includePrivate || !_isPrivate(mirror)) {
+      group.addMethod(mirror);
     }
   });
-  return {
-    'setters': setters,
-    'getters': getters,
-    'constructors': constructors,
-    'operators': operators,
-    'methods': methods
-  };
+  return group;
 } 
 
 /**
+ * Returns the [Class] for the given [mirror] has already been created, and if 
+ * it does not exist, creates it.
+ */
+Class _class(ClassMirror mirror) {
+  var clazz = entityMap[mirror.qualifiedName];
+  if (clazz == null) {
+    var superclass = mirror.superclass != null ? 
+        _class(mirror.superclass) : null;
+    var interfaces = 
+        mirror.superinterfaces.map((interface) => _class(interface));
+    clazz = new Class(mirror.simpleName, superclass, _commentToHtml(mirror), 
+        interfaces.toList(), _variables(mirror.variables),
+        _methods(mirror.methods), _annotations(mirror), _generics(mirror), 
+        mirror.qualifiedName, _isPrivate(mirror), mirror.owner.qualifiedName);
+    entityMap[mirror.qualifiedName] = clazz;
+  }
+  return clazz;
+}
+
+/**
  * Returns a map of [Class] objects constructed from [mirrorMap].
  */
-Map<String, Class> _getClasses(Map<String, ClassMirror> mirrorMap,
-    bool includePrivate) {
-  
-  var abstractClasses = {};
-  var classes = {};
-  var typedefs = {};
-  var errors = {};
-  
+ClassGroup _classes(Map<String, ClassMirror> mirrorMap) {
+  var group = new ClassGroup();
   mirrorMap.forEach((String mirrorName, ClassMirror mirror) {    
-    if (includePrivate || !mirror.isPrivate) {
-      var superclass = (mirror.superclass != null) ?
-          mirror.superclass.qualifiedName : '';
-      var interfaces =
-          mirror.superinterfaces.map((interface) => interface.qualifiedName);
-      var clazz = new Class(mirrorName, superclass, _getComment(mirror), 
-          interfaces.toList(), _getVariables(mirror.variables, includePrivate),
-          _getMethods(mirror.methods, includePrivate),
-          _getAnnotations(mirror), _getGenerics(mirror), mirror.qualifiedName);
-      _currentClass = mirror;
-      
-      if (isError(mirror.qualifiedName)) {
-        errors[mirrorName] = clazz;
-      } else if (mirror.isTypedef) {
-        typedefs[mirrorName] = new Typedef(mirrorName, 
-            mirror.value.returnType.qualifiedName,  _getComment(mirror), 
-            _getGenerics(mirror), _getParameters(mirror.value.parameters),
-            _getAnnotations(mirror), mirror.qualifiedName);
-      } else if (mirror.isAbstract) {
-        abstractClasses[mirrorName] = clazz;
-      } else if (mirror.isClass) {
-        classes[mirrorName] = clazz;
-      } else {
-        throw new ArgumentError('$mirrorName - no class type match. ');
-      }
-    }
+      group.addClass(mirror);
   });
-  return {
-    'abstract': abstractClasses, 
-    'class': classes,
-    'typedef': typedefs,
-    'error': errors
-  };
+  return group;
 }
 
 /**
  * Returns a map of [Parameter] objects constructed from [mirrorList].
  */
-Map<String, Parameter> _getParameters(List<ParameterMirror> mirrorList) {
+Map<String, Parameter> _parameters(List<ParameterMirror> mirrorList) {
   var data = {};
   mirrorList.forEach((ParameterMirror mirror) {
     _currentMember = mirror;
     data[mirror.simpleName] = new Parameter(mirror.simpleName, 
         mirror.isOptional, mirror.isNamed, mirror.hasDefaultValue, 
         _type(mirror.type), mirror.defaultValue, 
-        _getAnnotations(mirror));
+        _annotations(mirror));
   });
   return data;
 }
@@ -413,7 +415,7 @@
 /**
  * Returns a map of [Generic] objects constructed from the class mirror. 
  */
-Map<String, Generic> _getGenerics(ClassMirror mirror) {
+Map<String, Generic> _generics(ClassMirror mirror) {
   return new Map.fromIterable(mirror.typeVariables, 
       key: (e) => e.toString(), 
       value: (e) => new Generic(e.toString(), e.upperBound.qualifiedName));
@@ -482,14 +484,17 @@
 class Indexable {
   String name;
   String qualifiedName;
+  bool isPrivate;
   
   /// Documentation comment with converted markdown.
   String comment;
   
-  Indexable(this.name, this.comment, String qualifiedName) {
-    this.qualifiedName = qualifiedName;
-    qualifiedNameIndex.add(qualifiedName);
-  }
+  /// Qualified Name of the owner of this Indexable Item.
+  /// For Library, owner will be ""; 
+  String owner;
+  
+  Indexable(this.name, this.comment, this.qualifiedName, this.isPrivate,
+      this.owner);
 }
 
 /**
@@ -501,23 +506,24 @@
   Map<String, Variable> variables;
 
   /// Top-level functions in the library.
-  Map<String, Map<String, Method>> functions;
+  MethodGroup functions;
   
   /// Classes defined within the library
-  Map<String, Class> classes;
+  ClassGroup classes;
 
   Library(String name, String comment, this.variables,
-      this.functions, this.classes) : super(name, comment, name) {}
+      this.functions, this.classes, bool isPrivate) : super(name, comment, 
+          name, isPrivate, "") {}
 
   /// Generates a map describing the [Library] object.
   Map toMap() => {
-      'name': name,
-      'qualifiedname': qualifiedName,
-      'comment': comment,
-      'variables': recurseMap(variables),
-      'functions': recurseMap(functions),
-      'classes': recurseMap(classes)
-    };
+    'name': name,
+    'qualifiedname': qualifiedName,
+    'comment': comment,
+    'variables': recurseMap(variables),
+    'functions': functions.toMap(),
+    'classes': classes.toMap()
+  };
 }
 
 /**
@@ -526,38 +532,182 @@
 class Class extends Indexable {
 
   /// List of the names of interfaces that this class implements.
-  List<String> interfaces;
+  List<Class> interfaces = [];
+  
+  /// Names of classes that extends or implements this class. 
+  Set<String> subclasses = new Set<String>();
 
   /// Top-level variables in the class.
   Map<String, Variable> variables;
+  
+  /// Inherited variables in the class.
+  Map<String, Variable> inheritedVariables = {};
 
   /// Methods in the class.
-  Map<String, Map<String, Method>> methods;
+  MethodGroup methods;
+  
+  /// Inherited methods in the class.
+  MethodGroup inheritedMethods = new MethodGroup();
   
   /// Generic infomation about the class. 
   Map<String, Generic> generics;
   
-  String superclass;
+  Class superclass;
 
   /// List of the meta annotations on the class.
   List<String> annotations;
   
   Class(String name, this.superclass, String comment, this.interfaces, 
       this.variables, this.methods, this.annotations, this.generics,
-      String qualifiedName) : super(name, comment, qualifiedName) {}
+      String qualifiedName, bool isPrivate, String owner) : super(name, comment,
+          qualifiedName, isPrivate, owner) {}
 
+  /**
+   * Returns a list of all the parent classes. 
+   */
+  List<Class> parent() {
+    var parent = superclass == null ? [] : [superclass];
+    parent.addAll(interfaces);
+    return parent;
+  }
+  
+  /**
+   * Add all inherited variables and methods from the provided superclass.
+   * If [_includePrivate] is true, it also adds the variables and methods from 
+   * the superclass. 
+   */
+  void addInherited(Class superclass) {
+    inheritedVariables.addAll(superclass.inheritedVariables);
+    if (_isVisible(superclass)) {
+      inheritedVariables.addAll(superclass.variables);
+    }
+    inheritedMethods.addInherited(superclass);
+  }
+  
+  /**
+   * Add the subclass to the class. 
+   * 
+   * If [this] is private, it will add the subclass to the list of subclasses in
+   * the superclasses. 
+   */
+  void addSubclass(Class subclass) {
+    if (!_includePrivate && isPrivate) {
+      if (superclass != null) superclass.addSubclass(subclass);
+      interfaces.forEach((interface) {
+        interface.addSubclass(subclass);
+      });
+    } else {
+      subclasses.add(subclass.qualifiedName);
+    }
+  }
+  
+  /**
+   * Check that the class exists in the owner library.
+   *  
+   * If it does not exist in the owner library, it is a mixin applciation and 
+   * should be removed. 
+   */
+  void makeValid() {
+    var library = entityMap[owner];
+    if (!library.classes.containsKey(name)) {
+      this.isPrivate = true;
+      // Since we are now making the mixin a private class, make all elements 
+      // with the mixin as an owner private too. 
+      entityMap.values.where((e) => e.owner == qualifiedName)
+        .forEach((element) => element.isPrivate = true);
+      // Move the subclass up to the next public superclass
+      subclasses.forEach((subclass) => addSubclass(entityMap[subclass]));
+    }
+  }
+  
+  /** 
+   * If a class extends a private superclass, find the closest public superclass
+   * of the private superclass. 
+   */
+  String validSuperclass() {
+    if (superclass == null) return 'dart.core.Object';
+    if (_isVisible(superclass)) return superclass.qualifiedName;
+    return superclass.validSuperclass();
+  }
+  
   /// Generates a map describing the [Class] object.
   Map toMap() => {
-      'name': name,
-      'qualifiedname': qualifiedName,
-      'comment': comment,
-      'superclass': superclass,
-      'implements': new List.from(interfaces),
-      'variables': recurseMap(variables),
-      'methods': recurseMap(methods),
-      'annotations': new List.from(annotations),
-      'generics': recurseMap(generics)
-    };
+    'name': name,
+    'qualifiedname': qualifiedName,
+    'comment': comment,
+    'superclass': validSuperclass(),
+    'implements': new List.from(interfaces.where(_isVisible)
+        .map((e) => e.qualifiedName)),
+    'subclass': new List.from(subclasses),
+    'variables': recurseMap(variables),
+    'inheritedvariables': recurseMap(inheritedVariables),
+    'methods': methods.toMap(),
+    'inheritedmethods': inheritedMethods.toMap(),
+    'annotations': new List.from(annotations),
+    'generics': recurseMap(generics)
+  };
+}
+
+/**
+ * A container to categorize classes into the following groups: abstract 
+ * classes, regular classes, typedefs, and errors. 
+ */
+class ClassGroup {
+  Map<String, Class> abstractClasses = {};
+  Map<String, Class> regularClasses = {};
+  Map<String, Typedef> typedefs = {};
+  Map<String, Class> errors = {};
+  
+  void addClass(ClassMirror mirror) {
+    _currentClass = mirror;
+    var clazz = _class(mirror);
+   
+    // Adding inherited parent variables and methods. 
+    clazz.parent().forEach((parent) {
+      if (_isVisible(clazz)) {
+        parent.addSubclass(clazz);
+      }
+      clazz.addInherited(parent);
+    });
+    
+    if (isError(mirror.qualifiedName)) {
+      errors[mirror.simpleName] = clazz;
+    } else if (mirror.isTypedef) {
+      if (_includePrivate || !mirror.isPrivate) {
+        entityMap[mirror.qualifiedName] = new Typedef(mirror.simpleName, 
+            mirror.value.returnType.qualifiedName, _commentToHtml(mirror), 
+            _generics(mirror), _parameters(mirror.value.parameters),
+            _annotations(mirror), mirror.qualifiedName,  _isPrivate(mirror), 
+            mirror.owner.qualifiedName);
+        typedefs[mirror.simpleName] = entityMap[mirror.qualifiedName];
+      }
+    } else if (mirror.isAbstract) {
+      abstractClasses[mirror.simpleName] = clazz;
+    } else if (mirror.isClass) {
+      regularClasses[mirror.simpleName] = clazz;
+    } else {
+      throw new ArgumentError('${mirror.simpleName} - no class type match. ');
+    }
+  }
+  
+  /**
+   * Checks if the given name is a key for any of the Class Maps. 
+   */
+  bool containsKey(String name) {
+    return abstractClasses.containsKey(name) ||
+        regularClasses.containsKey(name) ||
+        errors.containsKey(name);
+  }
+  
+  Map toMap() => {
+    'abstract': new List.from(abstractClasses.values
+        .where(_isVisible).map((e) => e.qualifiedName)),
+    'class': new List.from(regularClasses.values
+        .where(_isVisible).map((e) => e.qualifiedName)),
+    'typedef': recurseMap(typedefs),
+    'error': new List.from(errors.values
+        .where(_isVisible).map((e) => e.qualifiedName))
+  };
 }
 
 class Typedef extends Indexable {
@@ -573,17 +723,18 @@
   
   Typedef(String name, this.returnType, String comment, this.generics, 
       this.parameters, this.annotations,
-      String qualifiedName) : super(name, comment, qualifiedName) {}
+      String qualifiedName, bool isPrivate, String owner) : super(name, comment,
+          qualifiedName, isPrivate, owner) {}
   
   Map toMap() => {
-      'name': name,
-      'qualifiedname': qualifiedName,
-      'comment': comment,
-      'return': returnType,
-      'parameters': recurseMap(parameters),
-      'annotations': new List.from(annotations),
-      'generics': recurseMap(generics)
-    };
+    'name': name,
+    'qualifiedname': qualifiedName,
+    'comment': comment,
+    'return': returnType,
+    'parameters': recurseMap(parameters),
+    'annotations': new List.from(annotations),
+    'generics': recurseMap(generics)
+  };
 }
 
 /**
@@ -600,20 +751,20 @@
   List<String> annotations;
   
   Variable(String name, this.isFinal, this.isStatic, this.isConst, this.type, 
-      String comment, this.annotations, String qualifiedName) : super(name, 
-          comment, qualifiedName);
+      String comment, this.annotations, String qualifiedName, bool isPrivate,
+      String owner) : super(name, comment, qualifiedName, isPrivate, owner);
   
   /// Generates a map describing the [Variable] object.
   Map toMap() => {
-      'name': name,
-      'qualifiedname': qualifiedName,
-      'comment': comment,
-      'final': isFinal.toString(),
-      'static': isStatic.toString(),
-      'constant': isConst.toString(),
-      'type': new List.filled(1, type.toMap()),
-      'annotations': new List.from(annotations)
-    };
+    'name': name,
+    'qualifiedname': qualifiedName,
+    'comment': comment,
+    'final': isFinal.toString(),
+    'static': isStatic.toString(),
+    'constant': isConst.toString(),
+    'type': new List.filled(1, type.toMap()),
+    'annotations': new List.from(annotations)
+  };
 }
 
 /**
@@ -634,21 +785,77 @@
   
   Method(String name, this.isStatic, this.isAbstract, this.isConst, 
       this.returnType, String comment, this.parameters, this.annotations,
-      String qualifiedName) 
-      : super(name, comment, qualifiedName);
+      String qualifiedName, bool isPrivate, String owner) : super(name, comment,
+          qualifiedName, isPrivate, owner);
   
   /// Generates a map describing the [Method] object.
   Map toMap() => {
-      'name': name,
-      'qualifiedname': qualifiedName,
-      'comment': comment,
-      'static': isStatic.toString(),
-      'abstract': isAbstract.toString(),
-      'constant': isConst.toString(),
-      'return': new List.filled(1, returnType.toMap()),
-      'parameters': recurseMap(parameters),
-      'annotations': new List.from(annotations)
-    };
+    'name': name,
+    'qualifiedname': qualifiedName,
+    'comment': comment,
+    'static': isStatic.toString(),
+    'abstract': isAbstract.toString(),
+    'constant': isConst.toString(),
+    'return': new List.filled(1, returnType.toMap()),
+    'parameters': recurseMap(parameters),
+    'annotations': new List.from(annotations)
+  };
+}
+
+/**
+ * A container to categorize methods into the following groups: setters, 
+ * getters, constructors, operators, regular methods. 
+ */
+class MethodGroup {
+  Map<String, Method> setters = {};
+  Map<String, Method> getters = {};
+  Map<String, Method> constructors = {};
+  Map<String, Method> operators = {};
+  Map<String, Method> regularMethods = {};
+  
+  void addMethod(MethodMirror mirror) {
+    var method = new Method(mirror.simpleName, mirror.isStatic, 
+        mirror.isAbstract, mirror.isConstConstructor, _type(mirror.returnType), 
+        _commentToHtml(mirror), _parameters(mirror.parameters), 
+        _annotations(mirror), mirror.qualifiedName, _isPrivate(mirror),
+        mirror.owner.qualifiedName);
+    entityMap[mirror.qualifiedName] = method;
+    _currentMember = mirror;
+    if (mirror.isSetter) {
+      setters[mirror.simpleName] = method;
+    } else if (mirror.isGetter) {
+      getters[mirror.simpleName] = method;
+    } else if (mirror.isConstructor) {
+      constructors[mirror.simpleName] = method;
+    } else if (mirror.isOperator) {
+      operators[mirror.simpleName] = method;
+    } else if (mirror.isRegularMethod) {
+      regularMethods[mirror.simpleName] = method;
+    } else {
+      throw new ArgumentError('${mirror.simpleName} - no method type match');
+    }
+  }
+  
+  void addInherited(Class parent) {
+    setters.addAll(parent.inheritedMethods.setters);
+    getters.addAll(parent.inheritedMethods.getters);
+    operators.addAll(parent.inheritedMethods.operators);
+    regularMethods.addAll(parent.inheritedMethods.regularMethods);
+    if (_isVisible(parent)) {
+      setters.addAll(parent.methods.setters);
+      getters.addAll(parent.methods.getters);
+      operators.addAll(parent.methods.operators);
+      regularMethods.addAll(parent.methods.regularMethods);
+    }
+  }
+  
+  Map toMap() => {
+    'setters': recurseMap(setters),
+    'getters': recurseMap(getters),
+    'constructors': recurseMap(constructors),
+    'operators': recurseMap(operators),
+    'methods': recurseMap(regularMethods)
+  };
 }
 
 /**
@@ -671,14 +878,14 @@
   
   /// Generates a map describing the [Parameter] object.
   Map toMap() => {
-      'name': name,
-      'optional': isOptional.toString(),
-      'named': isNamed.toString(),
-      'default': hasDefaultValue.toString(),
-      'type': new List.filled(1, type.toMap()),
-      'value': defaultValue,
-      'annotations': new List.from(annotations)
-    };
+    'name': name,
+    'optional': isOptional.toString(),
+    'named': isNamed.toString(),
+    'default': hasDefaultValue.toString(),
+    'type': new List.filled(1, type.toMap()),
+    'value': defaultValue,
+    'annotations': new List.from(annotations)
+  };
 }
 
 /**
@@ -691,9 +898,9 @@
   Generic(this.name, this.type);
   
   Map toMap() => {
-      'name': name,
-      'type': type
-    };
+    'name': name,
+    'type': type
+  };
 }
 
 /**
@@ -733,7 +940,7 @@
   Type(this.outer, this.inner);
   
   Map toMap() => {
-      'outer': outer,
-      'inner': new List.from(inner.map((e) => e.toMap()))
-    };
+    'outer': outer,
+    'inner': new List.from(inner.map((e) => e.toMap()))
+  };
 }
\ No newline at end of file
diff --git a/pkg/docgen/test/single_library_test.dart b/pkg/docgen/test/single_library_test.dart
index 1462c63..0ca4b09 100644
--- a/pkg/docgen/test/single_library_test.dart
+++ b/pkg/docgen/test/single_library_test.dart
@@ -49,23 +49,35 @@
         .then(expectAsync1((mirrorSystem) {
           var testLibraryUri = new Uri(scheme: 'file', 
               path: path.absolute(fileName));
-          var library = generateLibrary(mirrorSystem.libraries[testLibraryUri], 
-              includePrivate: false);
+          var library = generateLibrary(mirrorSystem.libraries[testLibraryUri]);
           expect(library is Library, isTrue);
           
-          var classTypes = library.classes.values;
-          expect(classTypes.every((e) => e is Map), isTrue);
+          var classTypes = library.classes;
+          expect(classTypes is ClassGroup, isTrue);
           
           var classes = [];
-          classTypes.forEach((e) => classes.addAll(e.values));
+          classes.addAll(classTypes.abstractClasses.values);
+          classes.addAll(classTypes.regularClasses.values);
+          classes.addAll(classTypes.errors.values);
           expect(classes.every((e) => e is Class), isTrue);
           
+          expect(classTypes.typedefs.values.every((e) => e is Typedef), isTrue);
+          
           var classMethodTypes = [];
-          classes.forEach((e) => classMethodTypes.addAll(e.methods.values));
-          expect(classMethodTypes.every((e) => e is Map), isTrue);
+          classes.forEach((e) {
+            classMethodTypes.add(e.methods);
+            classMethodTypes.add(e.inheritedMethods);
+          });
+          expect(classMethodTypes.every((e) => e is MethodGroup), isTrue);
 
           var classMethods = [];
-          classMethodTypes.forEach((e) => classMethods.addAll(e.values));
+          classMethodTypes.forEach((e) {
+            classMethods.addAll(e.setters.values);
+            classMethods.addAll(e.getters.values);
+            classMethods.addAll(e.constructors.values);
+            classMethods.addAll(e.operators.values);
+            classMethods.addAll(e.regularMethods.values);
+          });
           expect(classMethods.every((e) => e is Method), isTrue);
           
           var methodParameters = [];
@@ -74,11 +86,15 @@
           });
           expect(methodParameters.every((e) => e is Parameter), isTrue);
           
-          var functionTypes = library.functions.values;
-          expect(functionTypes.every((e) => e is Map), isTrue);
+          var functionTypes = library.functions;
+          expect(functionTypes is MethodGroup, isTrue);
           
           var functions = [];
-          functionTypes.forEach((e) => functions.addAll(e.values));
+          functions.addAll(functionTypes.setters.values);
+          functions.addAll(functionTypes.getters.values);
+          functions.addAll(functionTypes.constructors.values);
+          functions.addAll(functionTypes.operators.values);
+          functions.addAll(functionTypes.regularMethods.values);
           expect(functions.every((e) => e is Method), isTrue);
           
           var functionParameters = [];
diff --git a/pkg/pkg.status b/pkg/pkg.status
index 4a3e6b8..7eeb233 100644
--- a/pkg/pkg.status
+++ b/pkg/pkg.status
@@ -60,7 +60,7 @@
 analyzer_experimental/test/generated/ast_test: Fail, Slow # Issue 11230
 stack_trace/test/trace_test: Pass, Timeout # Issue 11645
 
-[ $compiler == dartc || $compiler == dartanalyzer || $compiler == dart2analyzer]
+[ $compiler == dartanalyzer || $compiler == dart2analyzer]
 # These tests are runtime negative but statically positive, so we skip
 # them in the analyzer.
 unittest/test/mock_regexp_negative_test: Skip
diff --git a/pkg/unittest/pubspec.yaml b/pkg/unittest/pubspec.yaml
index aa32b1d..aab71ab 100644
--- a/pkg/unittest/pubspec.yaml
+++ b/pkg/unittest/pubspec.yaml
@@ -4,6 +4,5 @@
 homepage: http://www.dartlang.org
 documentation: http://api.dartlang.org/docs/pkg/unittest
 dependencies:
-  json: any
   meta: any
   stack_trace: any
diff --git a/pkg/unittest/test/unittest_test_utils.dart b/pkg/unittest/test/unittest_test_utils.dart
index ab83927..7b171f1 100644
--- a/pkg/unittest/test/unittest_test_utils.dart
+++ b/pkg/unittest/test/unittest_test_utils.dart
@@ -46,6 +46,8 @@
 
   TestConfiguration(this._port);
 
+  void onInit() {}
+
   void onSummary(int passed, int failed, int errors, List<TestCase> results,
       String uncaughtError) {
     _result = buildStatusString(passed, failed, errors, results,
diff --git a/runtime/bin/socket_patch.dart b/runtime/bin/socket_patch.dart
index 0bcf75f..4d9225d 100644
--- a/runtime/bin/socket_patch.dart
+++ b/runtime/bin/socket_patch.dart
@@ -490,7 +490,9 @@
         if (i == ERROR_EVENT) {
           reportError(nativeGetError(), "");
         } else if (!isClosed) {
-          handler();
+          // If the connection is closed right after it's accepted, there's a
+          // chance the close-handler is not set.
+          if (handler != null) handler();
         }
       }
     }
diff --git a/runtime/bin/vmservice/.gitignore b/runtime/bin/vmservice/.gitignore
new file mode 100644
index 0000000..b183031
--- /dev/null
+++ b/runtime/bin/vmservice/.gitignore
@@ -0,0 +1,2 @@
+.buildlog
+pubspec.lock
diff --git a/runtime/bin/vmservice/running_isolate.dart b/runtime/bin/vmservice/running_isolate.dart
index 540c5ea..6c7749a 100644
--- a/runtime/bin/vmservice/running_isolate.dart
+++ b/runtime/bin/vmservice/running_isolate.dart
@@ -6,11 +6,11 @@
 
 class RunningIsolate implements ServiceRequestRouter {
   final SendPort sendPort;
-  String id = 'Unknown';
+  String name = 'Unknown';
 
   RunningIsolate(this.sendPort);
 
-  Future sendMessage(String request) {
+  Future sendMessage(List request) {
     final completer = new Completer.sync();
     final receivePort = new ReceivePort();
     sendServiceMessage(sendPort, receivePort, request);
@@ -25,24 +25,31 @@
     return completer.future;
   }
 
-  bool route(ServiceRequest request) {
-    // Do nothing for now.
-    return false;
+  Future route(ServiceRequest request) {
+    // Send message to isolate.
+    var message = request.toServiceCallMessage();
+    return sendMessage(message).then((response) {
+      request.setResponse(response);
+      return new Future.value(request);
+    });
   }
 
-  void sendIdRequest() {
-    var request = JSON.stringify({'p': ['id'], 'k': [], 'v': []});
-    sendMessage(request).then(_handleIdResponse);
+  void _sendNameRequest() {
+    var request = new ServiceRequest();
+    request.parse(Uri.parse('/name'));
+    sendMessage(request.toServiceCallMessage()).then(_handleNameResponse);
   }
 
-  void _handleIdResponse(responseString) {
-    var response;
+  void _handleNameResponse(String responseString) {
     try {
-      response = JSON.parse(responseString);
+      var response = JSON.parse(responseString);
+      name = response['name'];
     } catch (e) {
-      id = 'Error retrieving isolate id.';
+      name = 'Error retrieving isolate name.';
       return;
     }
-    id = response['id'];
+    if (name == null) {
+      name = 'Error retrieving isolate name.';
+    }
   }
 }
diff --git a/runtime/bin/vmservice/running_isolates.dart b/runtime/bin/vmservice/running_isolates.dart
index 7e81f7c..57e56fb 100644
--- a/runtime/bin/vmservice/running_isolates.dart
+++ b/runtime/bin/vmservice/running_isolates.dart
@@ -15,7 +15,7 @@
     }
     var ri = new RunningIsolate(sp);
     isolates[sp.hashCode] = ri;
-    ri.sendIdRequest();
+    ri._sendNameRequest();
   }
 
   void isolateShutdown(SendPort sp) {
@@ -31,7 +31,7 @@
     isolates.forEach((sp, ri) {
       members.add({
         'id': sp,
-        'name': ri.id
+        'name': ri.name
         });
     });
     result['type'] = 'IsolateList';
@@ -39,32 +39,37 @@
     request.setResponse(JSON.stringify(result));
   }
 
-  bool route(ServiceRequest request) {
+  Future route(ServiceRequest request) {
     if (request.pathSegments.length == 0) {
-      return false;
+      return null;
     }
     if (request.pathSegments[0] != 'isolates') {
-      return false;
+      return null;
     }
     if (request.pathSegments.length == 1) {
       // Requesting list of running isolates.
       _isolateCollectionRequest(request);
-      return true;
+      return new Future.value(request);
     }
     var isolateId;
     try {
       isolateId = int.parse(request.pathSegments[1]);
     } catch (e) {
       request.setErrorResponse('Could not parse isolate id: $e');
-      return true;
+      return new Future.value(request);
     }
     var isolate = isolates[isolateId];
     if (isolate == null) {
       request.setErrorResponse('Cannot find isolate id: $isolateId');
-      return true;
+      return new Future.value(request);
     }
     // Consume '/isolates/isolateId'
     request.pathSegments.removeRange(0, 2);
+    if (request.pathSegments.length == 0) {
+      // The request is now empty.
+      request.setErrorResponse('No request for isolate: /isolates/$isolateId');
+      return new Future.value(request);
+    }
     return isolate.route(request);
   }
 }
diff --git a/runtime/bin/vmservice/server.dart b/runtime/bin/vmservice/server.dart
index cf603f3..9eed701 100644
--- a/runtime/bin/vmservice/server.dart
+++ b/runtime/bin/vmservice/server.dart
@@ -34,14 +34,20 @@
       // Did not understand the request uri.
       serviceRequest.setErrorResponse('Invalid request uri: ${request.uri}');
     } else {
-      r = service.runningIsolates.route(serviceRequest);
-      if (!r) {
+      var f = service.runningIsolates.route(serviceRequest);
+      if (f != null) {
+        f.then((_) {
+          request.response.headers.contentType = jsonContentType;
+          request.response.write(serviceRequest.response);
+          request.response.close();
+        }).catchError((e) { });
+        return;
+      } else {
         // Nothing responds to this type of request.
         serviceRequest.setErrorResponse('No route for: $path');
       }
     }
 
-    // Send response back over HTTP.
     request.response.headers.contentType = jsonContentType;
     request.response.write(serviceRequest.response);
     request.response.close();
@@ -62,4 +68,3 @@
     });
   }
 }
-
diff --git a/runtime/bin/vmservice/service_request.dart b/runtime/bin/vmservice/service_request.dart
index 83f26db..04bf397 100644
--- a/runtime/bin/vmservice/service_request.dart
+++ b/runtime/bin/vmservice/service_request.dart
@@ -31,17 +31,14 @@
     return true;
   }
 
-  String toServiceCallMessage() {
-    return JSON.stringify({
-      'p': pathSegments,
-      'k': parameters.keys.toList(),
-      'v': parameters.values.toList()
-    });
+  List toServiceCallMessage() {
+    return [pathSegments, parameters.keys.toList(), parameters.values.toList()];
   }
 
   void setErrorResponse(String error) {
     _response = JSON.stringify({
-        'error': error,
+        'type': 'error',
+        'msg': error,
         'pathSegments': pathSegments,
         'parameters': parameters
     });
diff --git a/runtime/bin/vmservice/service_request_router.dart b/runtime/bin/vmservice/service_request_router.dart
index 6bb5de5..c889c85 100644
--- a/runtime/bin/vmservice/service_request_router.dart
+++ b/runtime/bin/vmservice/service_request_router.dart
@@ -5,5 +5,5 @@
 part of vmservice;
 
 abstract class ServiceRequestRouter {
-  bool route(ServiceRequest request);
+  Future route(ServiceRequest request);
 }
diff --git a/runtime/bin/vmservice_impl.cc b/runtime/bin/vmservice_impl.cc
index fba6a98..69c2d48 100644
--- a/runtime/bin/vmservice_impl.cc
+++ b/runtime/bin/vmservice_impl.cc
@@ -162,6 +162,8 @@
 
   result = LoadResources(library);
   SHUTDOWN_ON_ERROR(result);
+  result = Dart_CompileAll();
+  SHUTDOWN_ON_ERROR(result);
 
   port_ = Dart_GetMainPortId();
 
diff --git a/runtime/lib/mirrors.cc b/runtime/lib/mirrors.cc
index 98806b1..176aecb 100644
--- a/runtime/lib/mirrors.cc
+++ b/runtime/lib/mirrors.cc
@@ -298,17 +298,23 @@
   const Object& decl = Object::Handle(decl_ref.referent());
 
   Class& klass = Class::Handle();
+  Library& library = Library::Handle();
+
   if (decl.IsClass()) {
     klass ^= decl.raw();
+    library = klass.library();
   } else if (decl.IsFunction()) {
     klass = Function::Cast(decl).origin();
+    library = klass.library();
   } else if (decl.IsField()) {
     klass = Field::Cast(decl).origin();
+    library = klass.library();
+  } else if (decl.IsLibrary()) {
+    library ^= decl.raw();
   } else {
     return Object::empty_array().raw();
   }
 
-  const Library& library = Library::Handle(klass.library());
   const Object& metadata = Object::Handle(library.GetMetadata(decl));
   if (metadata.IsError()) {
     ThrowInvokeError(Error::Cast(metadata));
diff --git a/runtime/tests/vm/vm.status b/runtime/tests/vm/vm.status
index 9e45e89..67e2d09 100644
--- a/runtime/tests/vm/vm.status
+++ b/runtime/tests/vm/vm.status
@@ -27,7 +27,7 @@
 [ $runtime == drt ]
 dart/isolate_mirror_local_test: Skip
 
-[ $compiler == dart2js || $compiler == dartc ]
+[ $compiler == dart2js ]
 dart/isolate_mirror*: Skip # compilers not aware of dart:mirrors
 dart/byte_array_test: Skip # compilers not aware of byte arrays
 dart/byte_array_optimized_test: Skip # compilers not aware of byte arrays
diff --git a/runtime/vm/assembler.cc b/runtime/vm/assembler.cc
index dc33ed5..f123820 100644
--- a/runtime/vm/assembler.cc
+++ b/runtime/vm/assembler.cc
@@ -15,13 +15,11 @@
 
 DEFINE_FLAG(bool, code_comments, false,
             "Include comments into code and disassembly");
-// TODO(zra): Remove once far branches are enabled automatically on a
-// per-function basis.
 #if defined(TARGET_ARCH_ARM) || defined(TARGET_ARCH_MIPS)
-DEFINE_FLAG(bool, use_far_branches, false, "Enable far branches");
+DEFINE_FLAG(bool, use_far_branches, false,
+            "Enable far branches for ARM and MIPS");
 #endif
 
-
 static uword NewContents(intptr_t capacity) {
   Zone* zone = Isolate::Current()->current_zone();
   uword result = zone->AllocUnsafe(capacity);
diff --git a/runtime/vm/assembler.h b/runtime/vm/assembler.h
index 102afc8..3006c1d 100644
--- a/runtime/vm/assembler.h
+++ b/runtime/vm/assembler.h
@@ -13,8 +13,6 @@
 
 namespace dart {
 
-// TODO(zra): Remove once far branches are enabled automatically on a
-// per-function basis.
 #if defined(TARGET_ARCH_ARM) || defined(TARGET_ARCH_MIPS)
 DECLARE_FLAG(bool, use_far_branches);
 #endif
diff --git a/runtime/vm/assembler_arm.cc b/runtime/vm/assembler_arm.cc
index d08f3db..e722032 100644
--- a/runtime/vm/assembler_arm.cc
+++ b/runtime/vm/assembler_arm.cc
@@ -6,8 +6,9 @@
 #if defined(TARGET_ARCH_ARM)
 
 #include "vm/assembler.h"
-#include "vm/simulator.h"
+#include "vm/longjump.h"
 #include "vm/runtime_entry.h"
+#include "vm/simulator.h"
 #include "vm/stack_frame.h"
 #include "vm/stub_code.h"
 
@@ -1719,7 +1720,6 @@
 
 
 static bool CanEncodeBranchOffset(int32_t offset) {
-  offset -= Instr::kPCReadOffset;
   ASSERT(Utils::IsAligned(offset, 4));
   return Utils::IsInt(Utils::CountOneBits(kBranchOffsetMask), offset);
 }
@@ -1728,8 +1728,13 @@
 int32_t Assembler::EncodeBranchOffset(int32_t offset, int32_t inst) {
   // The offset is off by 8 due to the way the ARM CPUs read PC.
   offset -= Instr::kPCReadOffset;
-  ASSERT(Utils::IsAligned(offset, 4));
-  ASSERT(Utils::IsInt(Utils::CountOneBits(kBranchOffsetMask), offset));
+
+  if (!CanEncodeBranchOffset(offset)) {
+    ASSERT(!use_far_branches());
+    const Error& error = Error::Handle(LanguageError::New(
+        String::Handle(String::New("Branch offset overflow"))));
+    Isolate::Current()->long_jump_base()->Jump(1, error);
+  }
 
   // Properly preserve only the bits supported in the instruction.
   offset >>= 2;
@@ -1804,14 +1809,14 @@
 void Assembler::EmitBranch(Condition cond, Label* label, bool link) {
   if (label->IsBound()) {
     const int32_t dest = label->Position() - buffer_.Size();
-    if (FLAG_use_far_branches && !CanEncodeBranchOffset(dest)) {
+    if (use_far_branches() && !CanEncodeBranchOffset(dest)) {
       EmitFarBranch(cond, label->Position(), link);
     } else {
       EmitType5(cond, dest, link);
     }
   } else {
     const int position = buffer_.Size();
-    if (FLAG_use_far_branches) {
+    if (use_far_branches()) {
       const int32_t dest = label->position_;
       EmitFarBranch(cond, dest, link);
     } else {
@@ -1829,7 +1834,7 @@
   while (label->IsLinked()) {
     const int32_t position = label->Position();
     int32_t dest = bound_pc - position;
-    if (FLAG_use_far_branches && !CanEncodeBranchOffset(dest)) {
+    if (use_far_branches() && !CanEncodeBranchOffset(dest)) {
       // Far branches are enabled and we can't encode the branch offset.
 
       // Grab instructions that load the offset.
@@ -1851,7 +1856,7 @@
       buffer_.Store<int32_t>(position, patched_movw);
       buffer_.Store<int32_t>(position + 1 * Instr::kInstrSize, patched_movt);
       label->position_ = DecodeLoadImmediate(movt, movw);
-    } else if (FLAG_use_far_branches && CanEncodeBranchOffset(dest)) {
+    } else if (use_far_branches() && CanEncodeBranchOffset(dest)) {
       // Far branches are enabled, but we can encode the branch offset.
 
       // Grab instructions that load the offset, and the branch.
diff --git a/runtime/vm/assembler_arm.h b/runtime/vm/assembler_arm.h
index d9cb891..8449603 100644
--- a/runtime/vm/assembler_arm.h
+++ b/runtime/vm/assembler_arm.h
@@ -297,10 +297,11 @@
 
 class Assembler : public ValueObject {
  public:
-  Assembler()
+  explicit Assembler(bool use_far_branches = false)
       : buffer_(),
         object_pool_(GrowableObjectArray::Handle()),
         prologue_offset_(-1),
+        use_far_branches_(use_far_branches),
         comments_() { }
   ~Assembler() { }
 
@@ -317,6 +318,10 @@
   }
   const GrowableObjectArray& object_pool() const { return object_pool_; }
 
+  bool use_far_branches() const {
+    return FLAG_use_far_branches || use_far_branches_;
+  }
+
   void FinalizeInstructions(const MemoryRegion& region) {
     buffer_.FinalizeInstructions(region);
   }
@@ -733,6 +738,8 @@
   GrowableObjectArray& object_pool_;  // Objects and patchable jump targets.
   int32_t prologue_offset_;
 
+  const bool use_far_branches_;
+
   int32_t AddObject(const Object& obj);
   int32_t AddExternalLabel(const ExternalLabel* label);
 
@@ -849,7 +856,7 @@
 
   void EmitFarBranch(Condition cond, int32_t offset, bool link);
   void EmitBranch(Condition cond, Label* label, bool link);
-  static int32_t EncodeBranchOffset(int32_t offset, int32_t inst);
+  int32_t EncodeBranchOffset(int32_t offset, int32_t inst);
   static int DecodeBranchOffset(int32_t inst);
   int32_t EncodeTstOffset(int32_t offset, int32_t inst);
   int DecodeTstOffset(int32_t inst);
diff --git a/runtime/vm/assembler_ia32.h b/runtime/vm/assembler_ia32.h
index 3103b5d..83b1c49 100644
--- a/runtime/vm/assembler_ia32.h
+++ b/runtime/vm/assembler_ia32.h
@@ -307,11 +307,14 @@
 
 class Assembler : public ValueObject {
  public:
-  Assembler()
+  explicit Assembler(bool use_far_branches = false)
       : buffer_(),
         object_pool_(GrowableObjectArray::Handle()),
         prologue_offset_(-1),
-        comments_() { }
+        comments_() {
+    // This mode is only needed and implemented for MIPS and ARM.
+    ASSERT(!use_far_branches);
+  }
   ~Assembler() { }
 
   static const bool kNearJump = true;
diff --git a/runtime/vm/assembler_mips.cc b/runtime/vm/assembler_mips.cc
index 47b423f..7f06822 100644
--- a/runtime/vm/assembler_mips.cc
+++ b/runtime/vm/assembler_mips.cc
@@ -6,6 +6,7 @@
 #if defined(TARGET_ARCH_MIPS)
 
 #include "vm/assembler.h"
+#include "vm/longjump.h"
 #include "vm/runtime_entry.h"
 #include "vm/simulator.h"
 #include "vm/stack_frame.h"
@@ -48,9 +49,13 @@
 }
 
 
-static int32_t EncodeBranchOffset(int32_t offset, int32_t instr) {
-  ASSERT(Utils::IsAligned(offset, 4));
-  ASSERT(Utils::IsInt(18, offset));
+int32_t Assembler::EncodeBranchOffset(int32_t offset, int32_t instr) {
+  if (!CanEncodeBranchOffset(offset)) {
+    ASSERT(!use_far_branches());
+    const Error& error = Error::Handle(LanguageError::New(
+        String::Handle(String::New("Branch offset overflow"))));
+    Isolate::Current()->long_jump_base()->Jump(1, error);
+  }
 
   // Properly preserve only the bits supported in the instruction.
   offset >>= 2;
@@ -106,6 +111,7 @@
 
 
 void Assembler::EmitFarJump(int32_t offset, bool link) {
+  ASSERT(use_far_branches());
   const uint16_t low = Utils::Low16Bits(offset);
   const uint16_t high = Utils::High16Bits(offset);
   buffer_.EmitFixup(new PatchFarJump());
@@ -179,7 +185,7 @@
     // Relative destination from an instruction after the branch.
     const int32_t dest =
         label->Position() - (buffer_.Size() + Instr::kInstrSize);
-    if (FLAG_use_far_branches && !CanEncodeBranchOffset(dest)) {
+    if (use_far_branches() && !CanEncodeBranchOffset(dest)) {
       EmitFarBranch(b, rs, rt, label->Position());
     } else {
       const uint16_t dest_off = EncodeBranchOffset(dest, 0);
@@ -187,7 +193,7 @@
     }
   } else {
     const int position = buffer_.Size();
-    if (FLAG_use_far_branches) {
+    if (use_far_branches()) {
       const uint32_t dest_off = label->position_;
       EmitFarBranch(b, rs, rt, dest_off);
     } else {
@@ -204,7 +210,7 @@
     // Relative destination from an instruction after the branch.
     const int32_t dest =
         label->Position() - (buffer_.Size() + Instr::kInstrSize);
-    if (FLAG_use_far_branches && !CanEncodeBranchOffset(dest)) {
+    if (use_far_branches() && !CanEncodeBranchOffset(dest)) {
       EmitFarRegImmBranch(b, rs, label->Position());
     } else {
       const uint16_t dest_off = EncodeBranchOffset(dest, 0);
@@ -212,7 +218,7 @@
     }
   } else {
     const int position = buffer_.Size();
-    if (FLAG_use_far_branches) {
+    if (use_far_branches()) {
       const uint32_t dest_off = label->position_;
       EmitFarRegImmBranch(b, rs, dest_off);
     } else {
@@ -230,7 +236,7 @@
     // Relative destination from an instruction after the branch.
     const int32_t dest =
         label->Position() - (buffer_.Size() + Instr::kInstrSize);
-    if (FLAG_use_far_branches && !CanEncodeBranchOffset(dest)) {
+    if (use_far_branches() && !CanEncodeBranchOffset(dest)) {
       EmitFarFpuBranch(kind, label->Position());
     } else {
       const uint16_t dest_off = EncodeBranchOffset(dest, 0);
@@ -241,7 +247,7 @@
     }
   } else {
     const int position = buffer_.Size();
-    if (FLAG_use_far_branches) {
+    if (use_far_branches()) {
       const uint32_t dest_off = label->position_;
       EmitFarFpuBranch(kind, dest_off);
     } else {
@@ -279,7 +285,7 @@
     int32_t position = label->Position();
     int32_t dest = bound_pc - (position + Instr::kInstrSize);
 
-    if (FLAG_use_far_branches && !CanEncodeBranchOffset(dest)) {
+    if (use_far_branches() && !CanEncodeBranchOffset(dest)) {
       // Far branches are enabled and we can't encode the branch offset.
 
       // Grab the branch instruction. We'll need to flip it later.
@@ -304,7 +310,7 @@
       buffer_.Store<int32_t>(position + 2 * Instr::kInstrSize, encoded_high);
       buffer_.Store<int32_t>(position + 3 * Instr::kInstrSize, encoded_low);
       label->position_ = DecodeLoadImmediate(low, high);
-    } else if (FLAG_use_far_branches && CanEncodeBranchOffset(dest)) {
+    } else if (use_far_branches() && CanEncodeBranchOffset(dest)) {
       // We assembled a far branch, but we don't need it. Replace with a near
       // branch.
 
diff --git a/runtime/vm/assembler_mips.h b/runtime/vm/assembler_mips.h
index 2d45ef7..d7e96c4 100644
--- a/runtime/vm/assembler_mips.h
+++ b/runtime/vm/assembler_mips.h
@@ -145,10 +145,11 @@
 
 class Assembler : public ValueObject {
  public:
-  Assembler()
+  explicit Assembler(bool use_far_branches = false)
       : buffer_(),
         object_pool_(GrowableObjectArray::Handle()),
         prologue_offset_(-1),
+        use_far_branches_(use_far_branches),
         delay_slot_available_(false),
         in_delay_slot_(false),
         comments_() { }
@@ -169,6 +170,10 @@
     buffer_.FinalizeInstructions(region);
   }
 
+  bool use_far_branches() const {
+    return FLAG_use_far_branches || use_far_branches_;
+  }
+
   // Set up a stub frame so that the stack traversal code can easily identify
   // a stub frame.
   void EnterStubFrame(bool uses_pp = false);
@@ -1094,6 +1099,7 @@
   GrowableObjectArray& object_pool_;  // Objects and patchable jump targets.
   int prologue_offset_;
 
+  const bool use_far_branches_;
   bool delay_slot_available_;
   bool in_delay_slot_;
 
@@ -1194,6 +1200,7 @@
          func << kCop1FnShift);
   }
 
+  int32_t EncodeBranchOffset(int32_t offset, int32_t instr);
 
   void EmitFarJump(int32_t offset, bool link);
   void EmitFarBranch(Opcode b, Register rs, Register rt, int32_t offset);
diff --git a/runtime/vm/assembler_x64.h b/runtime/vm/assembler_x64.h
index 165642b..17324c0 100644
--- a/runtime/vm/assembler_x64.h
+++ b/runtime/vm/assembler_x64.h
@@ -321,11 +321,14 @@
 
 class Assembler : public ValueObject {
  public:
-  Assembler()
+  explicit Assembler(bool use_far_branches = false)
       : buffer_(),
         object_pool_(GrowableObjectArray::Handle()),
         prologue_offset_(-1),
-        comments_() { }
+        comments_() {
+    // This mode is only needed and implemented for MIPS and ARM.
+    ASSERT(!use_far_branches);
+  }
   ~Assembler() { }
 
   static const bool kNearJump = true;
diff --git a/runtime/vm/code_generator.h b/runtime/vm/code_generator.h
index c3a7ed6..511676c 100644
--- a/runtime/vm/code_generator.h
+++ b/runtime/vm/code_generator.h
@@ -63,6 +63,7 @@
   V(IntegerToDouble)                                                           \
   V(BinarySmiOp)                                                               \
   V(BinaryMintOp)                                                              \
+  V(UnaryMintOp)                                                               \
   V(ShiftMintOp)                                                               \
   V(BinaryDoubleOp)                                                            \
   V(InstanceSetter)                                                            \
diff --git a/runtime/vm/compiler.cc b/runtime/vm/compiler.cc
index 6cf9ce2..5f14950 100644
--- a/runtime/vm/compiler.cc
+++ b/runtime/vm/compiler.cc
@@ -252,303 +252,331 @@
   bool is_compiled = false;
   Isolate* isolate = Isolate::Current();
   HANDLESCOPE(isolate);
-  const intptr_t prev_deopt_id = isolate->deopt_id();
-  isolate->set_deopt_id(0);
-  LongJump* old_base = isolate->long_jump_base();
-  LongJump bailout_jump;
-  isolate->set_long_jump_base(&bailout_jump);
-  if (setjmp(*bailout_jump.Set()) == 0) {
-    FlowGraph* flow_graph = NULL;
-    // TimerScope needs an isolate to be properly terminated in case of a
-    // LongJump.
-    {
-      TimerScope timer(FLAG_compiler_stats,
-                       &CompilerStats::graphbuilder_timer,
-                       isolate);
-      Array& ic_data_array = Array::Handle();
-      if (optimized) {
-        ASSERT(function.HasCode());
-        // Extract type feedback before the graph is built, as the graph
-        // builder uses it to attach it to nodes.
-        ASSERT(function.deoptimization_counter() <
-               FLAG_deoptimization_counter_threshold);
-        const Code& unoptimized_code =
-            Code::Handle(function.unoptimized_code());
-        ic_data_array = unoptimized_code.ExtractTypeFeedbackArray();
-      }
 
-      // Build the flow graph.
-      FlowGraphBuilder builder(parsed_function,
-                               ic_data_array,
-                               NULL,  // NULL = not inlining.
-                               osr_id);
-      flow_graph = builder.BuildGraph();
-    }
-
-    if (FLAG_print_flow_graph ||
-        (optimized && FLAG_print_flow_graph_optimized)) {
-      if (osr_id == Isolate::kNoDeoptId) {
-        FlowGraphPrinter::PrintGraph("Before Optimizations", flow_graph);
-      } else {
-        FlowGraphPrinter::PrintGraph("For OSR", flow_graph);
-      }
-    }
-
-    if (optimized) {
-      TimerScope timer(FLAG_compiler_stats,
-                       &CompilerStats::ssa_timer,
-                       isolate);
-      // Transform to SSA (virtual register 0 and no inlining arguments).
-      flow_graph->ComputeSSA(0, NULL);
-      DEBUG_ASSERT(flow_graph->VerifyUseLists());
-      if (FLAG_print_flow_graph || FLAG_print_flow_graph_optimized) {
-        FlowGraphPrinter::PrintGraph("After SSA", flow_graph);
-      }
-    }
-
-
-    // Collect all instance fields that are loaded in the graph and
-    // have non-generic type feedback attached to them that can
-    // potentially affect optimizations.
-    GrowableArray<const Field*> guarded_fields(10);
-    if (optimized) {
-      TimerScope timer(FLAG_compiler_stats,
-                       &CompilerStats::graphoptimizer_timer,
-                       isolate);
-
-      FlowGraphOptimizer optimizer(flow_graph, &guarded_fields);
-      optimizer.ApplyICData();
-      DEBUG_ASSERT(flow_graph->VerifyUseLists());
-
-      // Optimize (a << b) & c patterns. Must occur before
-      // 'SelectRepresentations' which inserts conversion nodes.
-      // TODO(srdjan): Moved before inlining until environment use list can
-      // be used to detect when shift-left is outside the scope of bit-and.
-      optimizer.TryOptimizeLeftShiftWithBitAndPattern();
-      DEBUG_ASSERT(flow_graph->VerifyUseLists());
-
-      // Inlining (mutates the flow graph)
-      if (FLAG_use_inlining) {
+  // We may reattempt compilation if the function needs to be assembled using
+  // far branches on ARM and MIPS. In the else branch of the setjmp call,
+  // done is set to false, and use_far_branches is set to true if there is a
+  // longjmp from the ARM or MIPS assemblers. In all other paths through this
+  // while loop, done is set to true. use_far_branches is always false on ia32
+  // and x64.
+  bool done = false;
+  // static to evade gcc's longjmp variable smashing checks.
+  static bool use_far_branches = false;
+  while (!done) {
+    const intptr_t prev_deopt_id = isolate->deopt_id();
+    isolate->set_deopt_id(0);
+    LongJump* old_base = isolate->long_jump_base();
+    LongJump bailout_jump;
+    isolate->set_long_jump_base(&bailout_jump);
+    if (setjmp(*bailout_jump.Set()) == 0) {
+      FlowGraph* flow_graph = NULL;
+      // TimerScope needs an isolate to be properly terminated in case of a
+      // LongJump.
+      {
         TimerScope timer(FLAG_compiler_stats,
-                         &CompilerStats::graphinliner_timer);
-        FlowGraphInliner inliner(flow_graph, &guarded_fields);
-        inliner.Inline();
-        // Use lists are maintained and validated by the inliner.
-        DEBUG_ASSERT(flow_graph->VerifyUseLists());
+                         &CompilerStats::graphbuilder_timer,
+                         isolate);
+        Array& ic_data_array = Array::Handle();
+        if (optimized) {
+          ASSERT(function.HasCode());
+          // Extract type feedback before the graph is built, as the graph
+          // builder uses it to attach it to nodes.
+          ASSERT(function.deoptimization_counter() <
+                 FLAG_deoptimization_counter_threshold);
+          const Code& unoptimized_code =
+              Code::Handle(function.unoptimized_code());
+          ic_data_array = unoptimized_code.ExtractTypeFeedbackArray();
+        }
+
+        // Build the flow graph.
+        FlowGraphBuilder builder(parsed_function,
+                                 ic_data_array,
+                                 NULL,  // NULL = not inlining.
+                                 osr_id);
+        flow_graph = builder.BuildGraph();
       }
 
-      // Propagate types and eliminate more type tests.
-      if (FLAG_propagate_types) {
-        FlowGraphTypePropagator propagator(flow_graph);
-        propagator.Propagate();
-        DEBUG_ASSERT(flow_graph->VerifyUseLists());
-      }
-
-      // Use propagated class-ids to optimize further.
-      optimizer.ApplyClassIds();
-      DEBUG_ASSERT(flow_graph->VerifyUseLists());
-
-      // Do optimizations that depend on the propagated type information.
-      optimizer.Canonicalize();
-      DEBUG_ASSERT(flow_graph->VerifyUseLists());
-
-      BranchSimplifier::Simplify(flow_graph);
-      DEBUG_ASSERT(flow_graph->VerifyUseLists());
-
-      IfConverter::Simplify(flow_graph);
-      DEBUG_ASSERT(flow_graph->VerifyUseLists());
-
-      if (FLAG_constant_propagation) {
-        ConstantPropagator::Optimize(flow_graph);
-        DEBUG_ASSERT(flow_graph->VerifyUseLists());
-        // A canonicalization pass to remove e.g. smi checks on smi constants.
-        optimizer.Canonicalize();
-        DEBUG_ASSERT(flow_graph->VerifyUseLists());
-        // Canonicalization introduced more opportunities for constant
-        // propagation.
-        ConstantPropagator::Optimize(flow_graph);
-        DEBUG_ASSERT(flow_graph->VerifyUseLists());
-      }
-
-      // Propagate types and eliminate even more type tests.
-      if (FLAG_propagate_types) {
-        // Recompute types after constant propagation to infer more precise
-        // types for uses that were previously reached by now eliminated phis.
-        FlowGraphTypePropagator propagator(flow_graph);
-        propagator.Propagate();
-        DEBUG_ASSERT(flow_graph->VerifyUseLists());
-      }
-
-      // Unbox doubles. Performed after constant propagation to minimize
-      // interference from phis merging double values and tagged
-      // values comming from dead paths.
-      optimizer.SelectRepresentations();
-      DEBUG_ASSERT(flow_graph->VerifyUseLists());
-
-      if (FLAG_common_subexpression_elimination ||
-          FLAG_loop_invariant_code_motion) {
-        flow_graph->ComputeBlockEffects();
-      }
-
-      if (FLAG_common_subexpression_elimination) {
-        if (DominatorBasedCSE::Optimize(flow_graph)) {
-          DEBUG_ASSERT(flow_graph->VerifyUseLists());
-          // Do another round of CSE to take secondary effects into account:
-          // e.g. when eliminating dependent loads (a.x[0] + a.x[0])
-          // TODO(fschneider): Change to a one-pass optimization pass.
-          DominatorBasedCSE::Optimize(flow_graph);
-          DEBUG_ASSERT(flow_graph->VerifyUseLists());
+      if (FLAG_print_flow_graph ||
+          (optimized && FLAG_print_flow_graph_optimized)) {
+        if (osr_id == Isolate::kNoDeoptId) {
+          FlowGraphPrinter::PrintGraph("Before Optimizations", flow_graph);
+        } else {
+          FlowGraphPrinter::PrintGraph("For OSR", flow_graph);
         }
       }
-      if (FLAG_loop_invariant_code_motion &&
-          (function.deoptimization_counter() <
-           FLAG_deoptimization_counter_licm_threshold)) {
-        LICM licm(flow_graph);
-        licm.Optimize();
-        DEBUG_ASSERT(flow_graph->VerifyUseLists());
-      }
-      flow_graph->RemoveRedefinitions();
 
-      if (FLAG_range_analysis) {
+      if (optimized) {
+        TimerScope timer(FLAG_compiler_stats,
+                         &CompilerStats::ssa_timer,
+                         isolate);
+        // Transform to SSA (virtual register 0 and no inlining arguments).
+        flow_graph->ComputeSSA(0, NULL);
+        DEBUG_ASSERT(flow_graph->VerifyUseLists());
+        if (FLAG_print_flow_graph || FLAG_print_flow_graph_optimized) {
+          FlowGraphPrinter::PrintGraph("After SSA", flow_graph);
+        }
+      }
+
+
+      // Collect all instance fields that are loaded in the graph and
+      // have non-generic type feedback attached to them that can
+      // potentially affect optimizations.
+      GrowableArray<const Field*> guarded_fields(10);
+      if (optimized) {
+        TimerScope timer(FLAG_compiler_stats,
+                         &CompilerStats::graphoptimizer_timer,
+                         isolate);
+
+        FlowGraphOptimizer optimizer(flow_graph, &guarded_fields);
+        optimizer.ApplyICData();
+        DEBUG_ASSERT(flow_graph->VerifyUseLists());
+
+        // Optimize (a << b) & c patterns. Must occur before
+        // 'SelectRepresentations' which inserts conversion nodes.
+        // TODO(srdjan): Moved before inlining until environment use list can
+        // be used to detect when shift-left is outside the scope of bit-and.
+        optimizer.TryOptimizeLeftShiftWithBitAndPattern();
+        DEBUG_ASSERT(flow_graph->VerifyUseLists());
+
+        // Inlining (mutates the flow graph)
+        if (FLAG_use_inlining) {
+          TimerScope timer(FLAG_compiler_stats,
+                           &CompilerStats::graphinliner_timer);
+          FlowGraphInliner inliner(flow_graph, &guarded_fields);
+          inliner.Inline();
+          // Use lists are maintained and validated by the inliner.
+          DEBUG_ASSERT(flow_graph->VerifyUseLists());
+        }
+
+        // Propagate types and eliminate more type tests.
         if (FLAG_propagate_types) {
-          // Propagate types after store-load-forwarding. Some phis may have
-          // become smi phis that can be processed by range analysis.
           FlowGraphTypePropagator propagator(flow_graph);
           propagator.Propagate();
           DEBUG_ASSERT(flow_graph->VerifyUseLists());
         }
-        // We have to perform range analysis after LICM because it
-        // optimistically moves CheckSmi through phis into loop preheaders
-        // making some phis smi.
-        optimizer.InferSmiRanges();
+
+        // Use propagated class-ids to optimize further.
+        optimizer.ApplyClassIds();
         DEBUG_ASSERT(flow_graph->VerifyUseLists());
-      }
 
-      if (FLAG_constant_propagation) {
-        // Constant propagation can use information from range analysis to
-        // find unreachable branch targets.
-        ConstantPropagator::OptimizeBranches(flow_graph);
-        DEBUG_ASSERT(flow_graph->VerifyUseLists());
-      }
-
-      if (FLAG_propagate_types) {
-        // Recompute types after code movement was done to ensure correct
-        // reaching types for hoisted values.
-        FlowGraphTypePropagator propagator(flow_graph);
-        propagator.Propagate();
-        DEBUG_ASSERT(flow_graph->VerifyUseLists());
-      }
-
-      // Optimize try-blocks.
-      TryCatchAnalyzer::Optimize(flow_graph);
-
-      // Detach environments from the instructions that can't deoptimize.
-      // Do it before we attempt to perform allocation sinking to minimize
-      // amount of materializations it has to perform.
-      optimizer.EliminateEnvironments();
-
-      // Attempt to sink allocations of temporary non-escaping objects to
-      // the deoptimization path.
-      AllocationSinking* sinking = NULL;
-      if (FLAG_allocation_sinking &&
-          (flow_graph->graph_entry()->SuccessorCount()  == 1)) {
-        // TODO(fschneider): Support allocation sinking with try-catch.
-        sinking = new AllocationSinking(flow_graph);
-        sinking->Optimize();
-      }
-
-      // Ensure that all phis inserted by optimization passes have consistent
-      // representations.
-      optimizer.SelectRepresentations();
-
-      if (optimizer.Canonicalize()) {
-        // To fully remove redundant boxing (e.g. BoxDouble used only in
-        // environments and UnboxDouble instructions) instruction we
-        // first need to replace all their uses and then fold them away.
-        // For now we just repeat Canonicalize twice to do that.
-        // TODO(vegorov): implement a separate representation folding pass.
+        // Do optimizations that depend on the propagated type information.
         optimizer.Canonicalize();
-      }
-      DEBUG_ASSERT(flow_graph->VerifyUseLists());
+        DEBUG_ASSERT(flow_graph->VerifyUseLists());
 
-      if (sinking != NULL) {
-        // Remove all MaterializeObject instructions inserted by allocation
-        // sinking from the flow graph and let them float on the side referenced
-        // only from environments. Register allocator will consider them
-        // as part of a deoptimization environment.
-        sinking->DetachMaterializations();
-      }
+        BranchSimplifier::Simplify(flow_graph);
+        DEBUG_ASSERT(flow_graph->VerifyUseLists());
 
-      // Perform register allocation on the SSA graph.
-      FlowGraphAllocator allocator(*flow_graph);
-      allocator.AllocateRegisters();
+        IfConverter::Simplify(flow_graph);
+        DEBUG_ASSERT(flow_graph->VerifyUseLists());
 
-      if (FLAG_print_flow_graph || FLAG_print_flow_graph_optimized) {
-        FlowGraphPrinter::PrintGraph("After Optimizations", flow_graph);
-      }
-    }
+        if (FLAG_constant_propagation) {
+          ConstantPropagator::Optimize(flow_graph);
+          DEBUG_ASSERT(flow_graph->VerifyUseLists());
+          // A canonicalization pass to remove e.g. smi checks on smi constants.
+          optimizer.Canonicalize();
+          DEBUG_ASSERT(flow_graph->VerifyUseLists());
+          // Canonicalization introduced more opportunities for constant
+          // propagation.
+          ConstantPropagator::Optimize(flow_graph);
+          DEBUG_ASSERT(flow_graph->VerifyUseLists());
+        }
 
-    Assembler assembler;
-    FlowGraphCompiler graph_compiler(&assembler,
-                                     *flow_graph,
-                                     optimized);
-    {
-      TimerScope timer(FLAG_compiler_stats,
-                       &CompilerStats::graphcompiler_timer,
-                       isolate);
-      graph_compiler.CompileGraph();
-    }
-    {
-      TimerScope timer(FLAG_compiler_stats,
-                       &CompilerStats::codefinalizer_timer,
-                       isolate);
-      const Code& code = Code::Handle(
-          Code::FinalizeCode(function, &assembler, optimized));
-      code.set_is_optimized(optimized);
-      graph_compiler.FinalizePcDescriptors(code);
-      graph_compiler.FinalizeDeoptInfo(code);
-      graph_compiler.FinalizeStackmaps(code);
-      graph_compiler.FinalizeVarDescriptors(code);
-      graph_compiler.FinalizeExceptionHandlers(code);
-      graph_compiler.FinalizeComments(code);
-      graph_compiler.FinalizeStaticCallTargetsTable(code);
+        // Propagate types and eliminate even more type tests.
+        if (FLAG_propagate_types) {
+          // Recompute types after constant propagation to infer more precise
+          // types for uses that were previously reached by now eliminated phis.
+          FlowGraphTypePropagator propagator(flow_graph);
+          propagator.Propagate();
+          DEBUG_ASSERT(flow_graph->VerifyUseLists());
+        }
 
-      if (optimized) {
-        if (osr_id == Isolate::kNoDeoptId) {
-          CodePatcher::PatchEntry(Code::Handle(function.CurrentCode()));
-          if (FLAG_trace_compiler) {
-            OS::Print("--> patching entry %#"Px"\n",
-                      Code::Handle(function.unoptimized_code()).EntryPoint());
+        // Unbox doubles. Performed after constant propagation to minimize
+        // interference from phis merging double values and tagged
+        // values comming from dead paths.
+        optimizer.SelectRepresentations();
+        DEBUG_ASSERT(flow_graph->VerifyUseLists());
+
+        if (FLAG_common_subexpression_elimination ||
+            FLAG_loop_invariant_code_motion) {
+          flow_graph->ComputeBlockEffects();
+        }
+
+        if (FLAG_common_subexpression_elimination) {
+          if (DominatorBasedCSE::Optimize(flow_graph)) {
+            DEBUG_ASSERT(flow_graph->VerifyUseLists());
+            // Do another round of CSE to take secondary effects into account:
+            // e.g. when eliminating dependent loads (a.x[0] + a.x[0])
+            // TODO(fschneider): Change to a one-pass optimization pass.
+            DominatorBasedCSE::Optimize(flow_graph);
+            DEBUG_ASSERT(flow_graph->VerifyUseLists());
           }
         }
-        function.SetCode(code);
-
-        for (intptr_t i = 0; i < guarded_fields.length(); i++) {
-          const Field& field = *guarded_fields[i];
-          field.RegisterDependentCode(code);
+        if (FLAG_loop_invariant_code_motion &&
+            (function.deoptimization_counter() <
+             FLAG_deoptimization_counter_licm_threshold)) {
+          LICM licm(flow_graph);
+          licm.Optimize();
+          DEBUG_ASSERT(flow_graph->VerifyUseLists());
         }
-      } else {
-        function.set_unoptimized_code(code);
-        function.SetCode(code);
-        ASSERT(CodePatcher::CodeIsPatchable(code));
+        flow_graph->RemoveRedefinitions();
+
+        if (FLAG_range_analysis) {
+          if (FLAG_propagate_types) {
+            // Propagate types after store-load-forwarding. Some phis may have
+            // become smi phis that can be processed by range analysis.
+            FlowGraphTypePropagator propagator(flow_graph);
+            propagator.Propagate();
+            DEBUG_ASSERT(flow_graph->VerifyUseLists());
+          }
+          // We have to perform range analysis after LICM because it
+          // optimistically moves CheckSmi through phis into loop preheaders
+          // making some phis smi.
+          optimizer.InferSmiRanges();
+          DEBUG_ASSERT(flow_graph->VerifyUseLists());
+        }
+
+        if (FLAG_constant_propagation) {
+          // Constant propagation can use information from range analysis to
+          // find unreachable branch targets.
+          ConstantPropagator::OptimizeBranches(flow_graph);
+          DEBUG_ASSERT(flow_graph->VerifyUseLists());
+        }
+
+        if (FLAG_propagate_types) {
+          // Recompute types after code movement was done to ensure correct
+          // reaching types for hoisted values.
+          FlowGraphTypePropagator propagator(flow_graph);
+          propagator.Propagate();
+          DEBUG_ASSERT(flow_graph->VerifyUseLists());
+        }
+
+        // Optimize try-blocks.
+        TryCatchAnalyzer::Optimize(flow_graph);
+
+        // Detach environments from the instructions that can't deoptimize.
+        // Do it before we attempt to perform allocation sinking to minimize
+        // amount of materializations it has to perform.
+        optimizer.EliminateEnvironments();
+
+        // Attempt to sink allocations of temporary non-escaping objects to
+        // the deoptimization path.
+        AllocationSinking* sinking = NULL;
+        if (FLAG_allocation_sinking &&
+            (flow_graph->graph_entry()->SuccessorCount()  == 1)) {
+          // TODO(fschneider): Support allocation sinking with try-catch.
+          sinking = new AllocationSinking(flow_graph);
+          sinking->Optimize();
+        }
+
+        // Ensure that all phis inserted by optimization passes have consistent
+        // representations.
+        optimizer.SelectRepresentations();
+
+        if (optimizer.Canonicalize()) {
+          // To fully remove redundant boxing (e.g. BoxDouble used only in
+          // environments and UnboxDouble instructions) instruction we
+          // first need to replace all their uses and then fold them away.
+          // For now we just repeat Canonicalize twice to do that.
+          // TODO(vegorov): implement a separate representation folding pass.
+          optimizer.Canonicalize();
+        }
+        DEBUG_ASSERT(flow_graph->VerifyUseLists());
+
+        if (sinking != NULL) {
+          // Remove all MaterializeObject instructions inserted by allocation
+          // sinking from the flow graph and let them float on the side
+          // referenced only from environments. Register allocator will consider
+          // them as part of a deoptimization environment.
+          sinking->DetachMaterializations();
+        }
+
+        // Perform register allocation on the SSA graph.
+        FlowGraphAllocator allocator(*flow_graph);
+        allocator.AllocateRegisters();
+
+        if (FLAG_print_flow_graph || FLAG_print_flow_graph_optimized) {
+          FlowGraphPrinter::PrintGraph("After Optimizations", flow_graph);
+        }
       }
+
+      Assembler assembler(use_far_branches);
+      FlowGraphCompiler graph_compiler(&assembler,
+                                       *flow_graph,
+                                       optimized);
+      {
+        TimerScope timer(FLAG_compiler_stats,
+                         &CompilerStats::graphcompiler_timer,
+                         isolate);
+        graph_compiler.CompileGraph();
+      }
+      {
+        TimerScope timer(FLAG_compiler_stats,
+                         &CompilerStats::codefinalizer_timer,
+                         isolate);
+        const Code& code = Code::Handle(
+            Code::FinalizeCode(function, &assembler, optimized));
+        code.set_is_optimized(optimized);
+        graph_compiler.FinalizePcDescriptors(code);
+        graph_compiler.FinalizeDeoptInfo(code);
+        graph_compiler.FinalizeStackmaps(code);
+        graph_compiler.FinalizeVarDescriptors(code);
+        graph_compiler.FinalizeExceptionHandlers(code);
+        graph_compiler.FinalizeComments(code);
+        graph_compiler.FinalizeStaticCallTargetsTable(code);
+
+        if (optimized) {
+          if (osr_id == Isolate::kNoDeoptId) {
+            CodePatcher::PatchEntry(Code::Handle(function.CurrentCode()));
+            if (FLAG_trace_compiler) {
+              OS::Print("--> patching entry %#"Px"\n",
+                  Code::Handle(function.unoptimized_code()).EntryPoint());
+            }
+          }
+          function.SetCode(code);
+
+          for (intptr_t i = 0; i < guarded_fields.length(); i++) {
+            const Field& field = *guarded_fields[i];
+            field.RegisterDependentCode(code);
+          }
+        } else {
+          function.set_unoptimized_code(code);
+          function.SetCode(code);
+          ASSERT(CodePatcher::CodeIsPatchable(code));
+        }
+      }
+      is_compiled = true;
+      done = true;
+    } else {
+      // We bailed out.
+      const Error& bailout_error = Error::Handle(
+          isolate->object_store()->sticky_error());
+
+      ASSERT(bailout_error.IsLanguageError());
+      const LanguageError& le = LanguageError::CheckedHandle(
+          isolate->object_store()->sticky_error());
+      const String& msg = String::Handle(le.message());
+      if (msg.Equals("Branch offset overflow")) {
+        done = false;
+        ASSERT(!use_far_branches);
+        use_far_branches = true;
+      } else {
+        // If not for a branch offset overflow, we only bail out from
+        // generating ssa code.
+        if (FLAG_trace_bailout) {
+          OS::Print("%s\n", bailout_error.ToErrorCString());
+        }
+        done = true;
+        ASSERT(optimized);
+      }
+
+      isolate->object_store()->clear_sticky_error();
+      is_compiled = false;
     }
-    is_compiled = true;
-  } else {
-    // We bailed out.
-    Error& bailout_error = Error::Handle(
-        isolate->object_store()->sticky_error());
-    isolate->object_store()->clear_sticky_error();
-    if (FLAG_trace_bailout) {
-      OS::Print("%s\n", bailout_error.ToErrorCString());
-    }
-    // We only bail out from generating ssa code.
-    ASSERT(optimized);
-    is_compiled = false;
+    // Reset global isolate state.
+    isolate->set_long_jump_base(old_base);
+    isolate->set_deopt_id(prev_deopt_id);
   }
-  // Reset global isolate state.
-  isolate->set_long_jump_base(old_base);
-  isolate->set_deopt_id(prev_deopt_id);
+  use_far_branches = false;
   return is_compiled;
 }
 
diff --git a/runtime/vm/dart_api_impl.cc b/runtime/vm/dart_api_impl.cc
index 4b91917..cc20314 100644
--- a/runtime/vm/dart_api_impl.cc
+++ b/runtime/vm/dart_api_impl.cc
@@ -2136,6 +2136,20 @@
   return Api::NewError("Invalid length passed in to access array elements");   \
 
 
+static Dart_Handle CopyBytes(const TypedData& array,
+                             intptr_t offset,
+                             uint8_t* native_array,
+                             intptr_t length) {
+  ASSERT(array.IsTypedData());
+  ASSERT(array.ElementSizeInBytes() == 1);
+  NoGCScope no_gc;
+  memmove(native_array,
+          reinterpret_cast<uint8_t*>(array.DataAddr(offset)),
+          length);
+  return Api::Success();
+}
+
+
 DART_EXPORT Dart_Handle Dart_ListGetAsBytes(Dart_Handle list,
                                             intptr_t offset,
                                             uint8_t* native_array,
@@ -2146,14 +2160,32 @@
   if (obj.IsTypedData()) {
     const TypedData& array = TypedData::Cast(obj);
     if (array.ElementSizeInBytes() == 1) {
-      if (Utils::RangeCheck(offset, length, array.Length())) {
-        NoGCScope no_gc;
-        memmove(native_array,
-                reinterpret_cast<uint8_t*>(array.DataAddr(offset)),
-                length);
-        return Api::Success();
+      if (!Utils::RangeCheck(offset, length, array.Length())) {
+        return Api::NewError(
+            "Invalid length passed in to access list elements");
       }
-      return Api::NewError("Invalid length passed in to access list elements");
+      return CopyBytes(array, offset, native_array, length);
+    }
+  }
+  if (RawObject::IsTypedDataViewClassId(obj.GetClassId())) {
+    const Instance& view = Instance::Cast(obj);
+    if (TypedDataView::ElementSizeInBytes(view) == 1) {
+      intptr_t view_length = Smi::Value(TypedDataView::Length(view));
+      if (!Utils::RangeCheck(offset, length, view_length)) {
+        return Api::NewError(
+            "Invalid length passed in to access list elements");
+      }
+      const Instance& data = Instance::Handle(TypedDataView::Data(view));
+      if (data.IsTypedData()) {
+        const TypedData& array = TypedData::Cast(data);
+        if (array.ElementSizeInBytes() == 1) {
+          intptr_t data_offset =
+              Smi::Value(TypedDataView::OffsetInBytes(view)) + offset;
+          // Range check already performed on the view object.
+          ASSERT(Utils::RangeCheck(data_offset, length, array.Length()));
+          return CopyBytes(array, data_offset, native_array, length);
+        }
+      }
     }
   }
   if (obj.IsArray()) {
@@ -2193,6 +2225,7 @@
       const Array& args = Array::Handle(isolate, Array::New(kNumArgs));
       args.SetAt(0, instance);  // Set up the receiver as the first argument.
       for (int i = 0; i < length; i++) {
+        HANDLESCOPE(isolate);
         intobj = Integer::New(offset + i);
         args.SetAt(1, intobj);
         result = DartEntry::InvokeFunction(function, args);
diff --git a/runtime/vm/dart_api_impl_test.cc b/runtime/vm/dart_api_impl_test.cc
index 84fbc0c..f84b492 100644
--- a/runtime/vm/dart_api_impl_test.cc
+++ b/runtime/vm/dart_api_impl_test.cc
@@ -832,6 +832,39 @@
 }
 
 
+TEST_CASE(TypedDataViewListGetAsBytes) {
+  const int kSize = 1000;
+
+  const char* kScriptChars =
+      "import 'dart:typed_data';\n"
+      "List main(int size) {\n"
+      "  var a = new Int8List(size);\n"
+      "  var view = new Int8List.view(a.buffer, 0, size);\n"
+      "  return view;\n"
+      "}\n";
+  // Create a test library and Load up a test script in it.
+  Dart_Handle lib = TestCase::LoadTestScript(kScriptChars, NULL);
+
+  // Test with a typed data view object.
+  Dart_Handle dart_args[1];
+  dart_args[0] = Dart_NewInteger(kSize);
+  Dart_Handle view_obj = Dart_Invoke(lib, NewString("main"), 1, dart_args);
+  EXPECT_VALID(view_obj);
+  for (intptr_t i = 0; i < kSize; ++i) {
+    EXPECT_VALID(Dart_ListSetAt(view_obj, i, Dart_NewInteger(i & 0xff)));
+  }
+  uint8_t* data = new uint8_t[kSize];
+  EXPECT_VALID(Dart_ListGetAsBytes(view_obj, 0, data, kSize));
+  for (intptr_t i = 0; i < kSize; ++i) {
+    EXPECT_EQ(i & 0xff, data[i]);
+  }
+
+  Dart_Handle result = Dart_ListGetAsBytes(view_obj, 0, data, kSize + 1);
+  EXPECT(Dart_IsError(result));
+  delete[] data;
+}
+
+
 TEST_CASE(TypedDataAccess) {
   EXPECT_EQ(Dart_TypedData_kInvalid,
             Dart_GetTypeOfTypedData(Dart_True()));
diff --git a/runtime/vm/dart_entry.cc b/runtime/vm/dart_entry.cc
index 36822f1..b956c8d 100644
--- a/runtime/vm/dart_entry.cc
+++ b/runtime/vm/dart_entry.cc
@@ -32,7 +32,7 @@
                                      const Array& arguments,
                                      const Array& arguments_descriptor) {
   const Context& context =
-      Context::ZoneHandle(Isolate::Current()->object_store()->empty_context());
+      Context::Handle(Isolate::Current()->object_store()->empty_context());
   ASSERT(context.isolate() == Isolate::Current());
   return InvokeFunction(function, arguments, arguments_descriptor, context);
 }
diff --git a/runtime/vm/disassembler.cc b/runtime/vm/disassembler.cc
index 4b1f381..627f0de 100644
--- a/runtime/vm/disassembler.cc
+++ b/runtime/vm/disassembler.cc
@@ -7,6 +7,7 @@
 #include "vm/assembler.h"
 #include "vm/globals.h"
 #include "vm/os.h"
+#include "vm/json_stream.h"
 
 namespace dart {
 
@@ -36,4 +37,42 @@
   va_end(args);
 }
 
+
+void DisassembleToJSONStream::ConsumeInstruction(char* hex_buffer,
+                                                 intptr_t hex_size,
+                                                 char* human_buffer,
+                                                 intptr_t human_size,
+                                                 uword pc) {
+  uint8_t* pc_ptr = reinterpret_cast<uint8_t*>(pc);
+  stream_->OpenObject();
+  stream_->PrintProperty("type", "DisassembledInstruction");
+  stream_->PrintfProperty("pc", "%p", pc_ptr);
+  stream_->PrintProperty("hex", hex_buffer);
+  stream_->PrintProperty("human", human_buffer);
+  stream_->CloseObject();
+}
+
+
+void DisassembleToJSONStream::Print(const char* format, ...) {
+  va_list args;
+  va_start(args, format);
+  intptr_t len = OS::VSNPrint(NULL, 0, format, args);
+  va_end(args);
+  char* p = reinterpret_cast<char*>(malloc(len+1));
+  va_start(args, format);
+  intptr_t len2 = OS::VSNPrint(p, len, format, args);
+  va_end(args);
+  ASSERT(len == len2);
+  for (intptr_t i = 0; i < len; i++) {
+    if (p[i] == '\n' || p[i] == '\r') {
+      p[i] = ' ';
+    }
+  }
+  stream_->OpenObject();
+  stream_->PrintProperty("type", "DisassembledInstructionComment");
+  stream_->PrintProperty("comment", p);
+  stream_->CloseObject();
+  free(p);
+}
+
 }  // namespace dart
diff --git a/runtime/vm/disassembler.h b/runtime/vm/disassembler.h
index 1f2a22c..893f0e8 100644
--- a/runtime/vm/disassembler.h
+++ b/runtime/vm/disassembler.h
@@ -13,6 +13,7 @@
 
 // Froward declaration.
 class MemoryRegion;
+class JSONStream;
 
 // Disassembly formatter interface, which consumes the
 // disassembled instructions in any desired form.
@@ -54,6 +55,28 @@
 };
 
 
+// Disassemble into a JSONStream.
+class DisassembleToJSONStream : public DisassemblyFormatter {
+ public:
+  explicit DisassembleToJSONStream(JSONStream* stream) : DisassemblyFormatter(),
+      stream_(stream) { }
+  ~DisassembleToJSONStream() { }
+
+  virtual void ConsumeInstruction(char* hex_buffer,
+                                  intptr_t hex_size,
+                                  char* human_buffer,
+                                  intptr_t human_size,
+                                  uword pc);
+
+  virtual void Print(const char* format, ...) PRINTF_ATTRIBUTE(2, 3);
+
+ private:
+  JSONStream* stream_;
+  DISALLOW_ALLOCATION();
+  DISALLOW_COPY_AND_ASSIGN(DisassembleToJSONStream);
+};
+
+
 // Disassemble instructions.
 class Disassembler : public AllStatic {
  public:
diff --git a/runtime/vm/flow_graph.cc b/runtime/vm/flow_graph.cc
index 0a86e09..0d80ae7 100644
--- a/runtime/vm/flow_graph.cc
+++ b/runtime/vm/flow_graph.cc
@@ -33,6 +33,7 @@
     reverse_postorder_(),
     block_effects_(NULL),
     licm_allowed_(true),
+    use_far_branches_(false),
     loop_headers_(NULL),
     loop_invariant_loads_(NULL) {
   DiscoverBlocks();
diff --git a/runtime/vm/flow_graph.h b/runtime/vm/flow_graph.h
index 615cef1..57fe60f 100644
--- a/runtime/vm/flow_graph.h
+++ b/runtime/vm/flow_graph.h
@@ -41,7 +41,7 @@
 };
 
 
-// Class to incapsulate the construction and manipulation of the flow graph.
+// Class to encapsulate the construction and manipulation of the flow graph.
 class FlowGraph : public ZoneAllocated {
  public:
   FlowGraph(const FlowGraphBuilder& builder,
@@ -163,6 +163,11 @@
   // after this point.
   void disallow_licm() { licm_allowed_ = false; }
 
+  bool use_far_branches() const { return use_far_branches_; }
+  void set_use_far_branches(bool value) {
+    use_far_branches_ = value;
+  }
+
   const ZoneGrowableArray<BlockEntryInstr*>& loop_headers() {
     if (loop_headers_ == NULL) {
       loop_headers_ = ComputeLoops();
@@ -249,6 +254,8 @@
   BlockEffects* block_effects_;
   bool licm_allowed_;
 
+  bool use_far_branches_;
+
   ZoneGrowableArray<BlockEntryInstr*>* loop_headers_;
   ZoneGrowableArray<BitVector*>* loop_invariant_loads_;
 };
diff --git a/runtime/vm/flow_graph_compiler_ia32.cc b/runtime/vm/flow_graph_compiler_ia32.cc
index fb965ed..6857292 100644
--- a/runtime/vm/flow_graph_compiler_ia32.cc
+++ b/runtime/vm/flow_graph_compiler_ia32.cc
@@ -44,8 +44,7 @@
 
 bool FlowGraphCompiler::SupportsUnboxedMints() {
   // Support unboxed mints when SSE 4.1 is available.
-  return FLAG_unbox_mints && CPUFeatures::sse4_1_supported() &&
-         !FLAG_throw_on_javascript_int_overflow;
+  return FLAG_unbox_mints && CPUFeatures::sse4_1_supported();
 }
 
 
diff --git a/runtime/vm/heap_histogram.cc b/runtime/vm/heap_histogram.cc
index 09fd5cd..bfd7e61 100644
--- a/runtime/vm/heap_histogram.cc
+++ b/runtime/vm/heap_histogram.cc
@@ -7,6 +7,7 @@
 #include "platform/assert.h"
 #include "vm/flags.h"
 #include "vm/object.h"
+#include "vm/json_stream.h"
 
 namespace dart {
 
@@ -38,8 +39,8 @@
   major_gc_count_ = 0;
   table_length_ = 512;
   table_ = reinterpret_cast<Element*>(
-    calloc(table_length_, sizeof(Element)));  // NOLINT 
-  for (int index = 0; index < table_length_; index++) {
+    calloc(table_length_, sizeof(Element)));  // NOLINT
+  for (intptr_t index = 0; index < table_length_; index++) {
     table_[index].class_id_ = index;
   }
 }
@@ -51,13 +52,13 @@
 
 
 void ObjectHistogram::RegisterClass(const Class& cls) {
-  int class_id = cls.id();
+  intptr_t class_id = cls.id();
   if (class_id < table_length_) return;
   // Resize the table.
-  int new_table_length = table_length_ * 2;
+  intptr_t new_table_length = table_length_ * 2;
   Element* new_table = reinterpret_cast<Element*>(
           realloc(table_, new_table_length * sizeof(Element)));  // NOLINT
-  for (int i = table_length_; i < new_table_length; i++) {
+  for (intptr_t i = table_length_; i < new_table_length; i++) {
     new_table[i].class_id_ = i;
     new_table[i].count_ = 0;
     new_table[i].size_ = 0;
@@ -81,30 +82,43 @@
 }
 
 
-void ObjectHistogram::Print() {
-  OS::Print("Printing Object Histogram\n");
-  OS::Print("____bytes___count_description____________\n");
-  // First count the number of non empty entries.
-  int length = 0;
-  for (int index = 0; index < table_length_; index++) {
+ObjectHistogram::Element** ObjectHistogram::GetSortedArray(
+      intptr_t* array_length) {
+  intptr_t length = 0;
+  for (intptr_t index = 0; index < table_length_; index++) {
     if (table_[index].count_ > 0) length++;
   }
   // Then add them to a new array and sort.
   Element** array = reinterpret_cast<Element**>(
     calloc(length, sizeof(Element*)));  // NOLINT
-  int pos = 0;
-  for (int index = 0; index < table_length_; index++) {
+  intptr_t pos = 0;
+  for (intptr_t index = 0; index < table_length_; index++) {
     if (table_[index].count_ > 0) array[pos++] = &table_[index];
   }
   typedef int (*CmpFunc)(const void*, const void*);
   qsort(array, length, sizeof(Element*),  // NOLINT
         reinterpret_cast<CmpFunc>(compare));
 
+  *array_length = length;
+  return array;
+}
+
+void ObjectHistogram::Print() {
+  OS::Print("Printing Object Histogram\n");
+  OS::Print("____bytes___count_description____________\n");
+  // First count the number of non empty entries.
+
+  intptr_t length = 0;
+  Element** array = NULL;
+
+  array = GetSortedArray(&length);
+  ASSERT(array != NULL);
+
   // Finally print the sorted array.
   Class& cls = Class::Handle();
   String& str = String::Handle();
   Library& lib = Library::Handle();
-  for (pos = 0; pos < length; pos++) {
+  for (intptr_t pos = 0; pos < length; pos++) {
     Element* e = array[pos];
     if (e->count_ > 0) {
       cls = isolate_->class_table()->At(e->class_id_);
@@ -130,4 +144,62 @@
   free(array);
 }
 
+void ObjectHistogram::PrintToJSONStream(JSONStream* stream) {
+  intptr_t length = 0;
+  Element** array = NULL;
+
+  array = GetSortedArray(&length);
+  ASSERT(array != NULL);
+
+  // Finally print the sorted array.
+  Class& cls = Class::Handle();
+  String& str = String::Handle();
+  Library& lib = Library::Handle();
+
+  intptr_t size_sum = 0;
+  intptr_t count_sum = 0;
+  stream->OpenObject();
+  stream->PrintProperty("type", "ObjectHistogram");
+  stream->OpenArray("properties");
+  stream->PrintValue("size");
+  stream->PrintValue("count");
+  stream->CloseArray();
+  stream->OpenArray("members");
+  for (intptr_t pos = 0; pos < length; pos++) {
+    Element* e = array[pos];
+    if (e->count_ > 0) {
+      cls = isolate_->class_table()->At(e->class_id_);
+      str = cls.Name();
+      lib = cls.library();
+      stream->OpenObject();
+      stream->PrintProperty("type", "ObjectHistogramEntry");
+      // It should not be possible to overflow here because the total
+      // size of the heap is bounded and we are dividing the value
+      // by the number of major gcs that have occurred.
+      size_sum += (e->size_ / major_gc_count_);
+      count_sum += (e->count_ / major_gc_count_);
+      stream->PrintProperty("size", e->size_ / major_gc_count_);
+      stream->PrintProperty("count", e->count_ / major_gc_count_);
+      stream->PrintProperty("name", str.ToCString());
+      if (lib.IsNull()) {
+        stream->PrintProperty("category", "");
+      } else {
+        str = lib.url();
+        stream->PrintProperty("category", str.ToCString());
+      }
+      stream->CloseObject();
+    }
+  }
+  stream->CloseArray();
+  stream->OpenObject("sums");
+  stream->PrintProperty("size", size_sum);
+  stream->PrintProperty("count", count_sum);
+  stream->CloseObject();
+  stream->CloseObject();
+
+  // Deallocate the array for sorting.
+  free(array);
+}
+
+
 }  // namespace dart
diff --git a/runtime/vm/heap_histogram.h b/runtime/vm/heap_histogram.h
index 13e0a38..46f6dc1 100644
--- a/runtime/vm/heap_histogram.h
+++ b/runtime/vm/heap_histogram.h
@@ -12,6 +12,8 @@
 
 namespace dart {
 
+class JSONStream;
+
 DECLARE_FLAG(bool, print_object_histogram);
 
 // ObjectHistogram is used to compute an average object histogram over
@@ -33,6 +35,8 @@
   // Print the histogram on stdout.
   void Print();
 
+  void PrintToJSONStream(JSONStream* stream);
+
  private:
   // Add obj to histogram
   void Add(RawObject* obj);
@@ -52,6 +56,10 @@
   // Compare function for sorting result.
   static int compare(const Element** a, const Element** b);
 
+  // This function returns a malloced array. Caller is responsible for calling
+  // free().
+  Element** GetSortedArray(intptr_t* array_length);
+
   intptr_t major_gc_count_;
   intptr_t table_length_;
   Element* table_;
diff --git a/runtime/vm/intermediate_language.cc b/runtime/vm/intermediate_language.cc
index 2a94baa..7db5a64 100644
--- a/runtime/vm/intermediate_language.cc
+++ b/runtime/vm/intermediate_language.cc
@@ -1076,7 +1076,11 @@
 
 
 bool BinarySmiOpInstr::CanDeoptimize() const {
-  if (FLAG_throw_on_javascript_int_overflow) return true;
+  if (FLAG_throw_on_javascript_int_overflow && (Smi::kBits > 32)) {
+    // If Smi's are bigger than 32-bits, then the instruction could deoptimize
+    // if the result is too big.
+    return true;
+  }
   switch (op_kind()) {
     case Token::kBIT_AND:
     case Token::kBIT_OR:
diff --git a/runtime/vm/intermediate_language.h b/runtime/vm/intermediate_language.h
index 2492bfa..df369bf 100644
--- a/runtime/vm/intermediate_language.h
+++ b/runtime/vm/intermediate_language.h
@@ -14,6 +14,8 @@
 
 namespace dart {
 
+DECLARE_FLAG(bool, throw_on_javascript_int_overflow);
+
 class BitVector;
 class BlockEntryInstr;
 class BufferFormatter;
@@ -5807,7 +5809,8 @@
   virtual void PrintOperandsTo(BufferFormatter* f) const;
 
   virtual bool CanDeoptimize() const {
-    return (op_kind() == Token::kADD) || (op_kind() == Token::kSUB);
+    return FLAG_throw_on_javascript_int_overflow ||
+        (op_kind() == Token::kADD) || (op_kind() == Token::kSUB);
   }
 
   virtual Representation representation() const {
@@ -5921,7 +5924,9 @@
 
   virtual void PrintOperandsTo(BufferFormatter* f) const;
 
-  virtual bool CanDeoptimize() const { return false; }
+  virtual bool CanDeoptimize() const {
+    return FLAG_throw_on_javascript_int_overflow;
+  }
 
   virtual Representation representation() const {
     return kUnboxedMint;
diff --git a/runtime/vm/intermediate_language_ia32.cc b/runtime/vm/intermediate_language_ia32.cc
index b6c0a89..c196ff5 100644
--- a/runtime/vm/intermediate_language_ia32.cc
+++ b/runtime/vm/intermediate_language_ia32.cc
@@ -24,6 +24,7 @@
 DECLARE_FLAG(int, optimization_counter_threshold);
 DECLARE_FLAG(bool, propagate_ic_data);
 DECLARE_FLAG(bool, use_osr);
+DECLARE_FLAG(bool, throw_on_javascript_int_overflow);
 
 // Generic summary for call instructions that have all arguments pushed
 // on the stack and return the result in a fixed register EAX.
@@ -648,6 +649,32 @@
 }
 
 
+static void EmitJavascriptIntOverflowCheck(FlowGraphCompiler* compiler,
+                                           Label* overflow,
+                                           XmmRegister result,
+                                           Register tmp) {
+  // Compare upper half.
+  Label check_lower, done;
+  __ pextrd(tmp, result, Immediate(1));
+  __ cmpl(tmp, Immediate(0x00200000));
+  __ j(GREATER, overflow);
+  __ j(NOT_EQUAL, &check_lower);
+
+  __ pextrd(tmp, result, Immediate(0));
+  __ cmpl(tmp, Immediate(0));
+  __ j(ABOVE, overflow);
+
+  __ Bind(&check_lower);
+  __ pextrd(tmp, result, Immediate(1));
+  __ cmpl(tmp, Immediate(-0x00200000));
+  __ j(LESS, overflow);
+  // Anything in the lower part would make the number bigger than the lower
+  // bound, so we are done.
+
+  __ Bind(&done);
+}
+
+
 static Condition TokenKindToMintCondition(Token::Kind kind) {
   switch (kind) {
     case Token::kEQ: return EQUAL;
@@ -4273,11 +4300,15 @@
     case Token::kBIT_AND:
     case Token::kBIT_OR:
     case Token::kBIT_XOR: {
-      const intptr_t kNumTemps = 0;
+      const intptr_t kNumTemps =
+          FLAG_throw_on_javascript_int_overflow ? 1 : 0;
       LocationSummary* summary =
           new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
       summary->set_in(0, Location::RequiresFpuRegister());
       summary->set_in(1, Location::RequiresFpuRegister());
+      if (FLAG_throw_on_javascript_int_overflow) {
+        summary->set_temp(0, Location::RequiresRegister());
+      }
       summary->set_out(Location::SameAsFirstInput());
       return summary;
     }
@@ -4306,6 +4337,10 @@
 
   ASSERT(locs()->out().fpu_reg() == left);
 
+  Label* deopt = NULL;
+  if (FLAG_throw_on_javascript_int_overflow) {
+    deopt = compiler->AddDeoptStub(deopt_id(), kDeoptBinaryMintOp);
+  }
   switch (op_kind()) {
     case Token::kBIT_AND: __ andpd(left, right); break;
     case Token::kBIT_OR:  __ orpd(left, right); break;
@@ -4314,8 +4349,10 @@
     case Token::kSUB: {
       Register lo = locs()->temp(0).reg();
       Register hi = locs()->temp(1).reg();
-      Label* deopt  = compiler->AddDeoptStub(deopt_id(),
-                                             kDeoptBinaryMintOp);
+      if (!FLAG_throw_on_javascript_int_overflow) {
+        deopt  = compiler->AddDeoptStub(deopt_id(), kDeoptBinaryMintOp);
+      }
+
       Label done, overflow;
       __ pextrd(lo, right, Immediate(0));  // Lower half
       __ pextrd(hi, right, Immediate(1));  // Upper half
@@ -4340,6 +4377,10 @@
     }
     default: UNREACHABLE();
   }
+  if (FLAG_throw_on_javascript_int_overflow) {
+    Register tmp = locs()->temp(0).reg();
+    EmitJavascriptIntOverflowCheck(compiler, deopt, left, tmp);
+  }
 }
 
 
@@ -4410,12 +4451,17 @@
   __ movq(left, Address(ESP, 0));
   __ addl(ESP, Immediate(2 * kWordSize));
   __ Bind(&done);
+  if (FLAG_throw_on_javascript_int_overflow) {
+    Register tmp = locs()->temp(0).reg();
+    EmitJavascriptIntOverflowCheck(compiler, deopt, left, tmp);
+  }
 }
 
 
 LocationSummary* UnaryMintOpInstr::MakeLocationSummary() const {
   const intptr_t kNumInputs = 1;
-  const intptr_t kNumTemps = 0;
+  const intptr_t kNumTemps =
+      FLAG_throw_on_javascript_int_overflow ? 1 : 0;
   LocationSummary* summary =
       new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
   summary->set_in(0, Location::RequiresFpuRegister());
@@ -4428,8 +4474,17 @@
   ASSERT(op_kind() == Token::kBIT_NOT);
   XmmRegister value = locs()->in(0).fpu_reg();
   ASSERT(value == locs()->out().fpu_reg());
+  Label* deopt = NULL;
+  if (FLAG_throw_on_javascript_int_overflow) {
+    deopt = compiler->AddDeoptStub(deopt_id(),
+                                   kDeoptUnaryMintOp);
+  }
   __ pcmpeqq(XMM0, XMM0);  // Generate all 1's.
   __ pxor(value, XMM0);
+  if (FLAG_throw_on_javascript_int_overflow) {
+    Register tmp = locs()->temp(0).reg();
+    EmitJavascriptIntOverflowCheck(compiler, deopt, value, tmp);
+  }
 }
 
 
diff --git a/runtime/vm/intermediate_language_x64.cc b/runtime/vm/intermediate_language_x64.cc
index f93fc93..f839f76 100644
--- a/runtime/vm/intermediate_language_x64.cc
+++ b/runtime/vm/intermediate_language_x64.cc
@@ -2151,20 +2151,16 @@
 }
 
 
-static void Emit54BitOverflowCheck(FlowGraphCompiler* compiler,
-                                   Label* overflow,
-                                   Register result) {
-  if (FLAG_throw_on_javascript_int_overflow) {
+static void EmitJavascriptOverflowCheck(FlowGraphCompiler* compiler,
+                                        Range* range,
+                                        Label* overflow,
+                                        Register result) {
+  if (!range->IsWithin(-0x20000000000000LL, 0x20000000000000LL)) {
     ASSERT(overflow != NULL);
-    __ movq(TMP, result);  // result is a tagged Smi.
-    // Bits 55...64 must be all 0 or all 1. (It would be bit 54, but result
-    // is tagged.)
-    __ shlq(result, Immediate(64 - 55));
-    __ sarq(result, Immediate(64 - 55));
-    __ cmpq(result, TMP);
-    __ j(NOT_EQUAL, overflow);  // 54-bit overflow.
-    __ cmpq(result, Immediate(-0x1FFFFFFFFFFFFFLL - 1));
-    __ j(EQUAL, overflow);  // The most negative 54-bit int is also disallowed.
+    __ cmpq(result, Immediate(-0x20000000000000LL));
+    __ j(LESS, overflow);
+    __ cmpq(result, Immediate(0x20000000000000LL));
+    __ j(GREATER, overflow);
   }
 }
 
@@ -2208,7 +2204,9 @@
       // Shift for result now we know there is no overflow.
       __ shlq(left, Immediate(value));
     }
-    Emit54BitOverflowCheck(compiler, deopt, result);
+    if (FLAG_throw_on_javascript_int_overflow) {
+      EmitJavascriptOverflowCheck(compiler, shift_left->range(), deopt, result);
+    }
     return;
   }
 
@@ -2238,7 +2236,9 @@
       __ SmiUntag(right);
       __ shlq(left, right);
     }
-    Emit54BitOverflowCheck(compiler, deopt, result);
+    if (FLAG_throw_on_javascript_int_overflow) {
+      EmitJavascriptOverflowCheck(compiler, shift_left->range(), deopt, result);
+    }
     return;
   }
 
@@ -2289,7 +2289,9 @@
     // Shift for result now we know there is no overflow.
     __ shlq(left, right);
   }
-  Emit54BitOverflowCheck(compiler, deopt, result);
+  if (FLAG_throw_on_javascript_int_overflow) {
+    EmitJavascriptOverflowCheck(compiler, shift_left->range(), deopt, result);
+  }
 }
 
 
@@ -2488,7 +2490,9 @@
         UNREACHABLE();
         break;
     }
-    Emit54BitOverflowCheck(compiler, deopt, result);
+    if (FLAG_throw_on_javascript_int_overflow) {
+      EmitJavascriptOverflowCheck(compiler, range(), deopt, result);
+    }
     return;
   }  // locs()->in(1).IsConstant().
 
@@ -2531,7 +2535,9 @@
         UNREACHABLE();
         break;
     }
-    Emit54BitOverflowCheck(compiler, deopt, result);
+    if (FLAG_throw_on_javascript_int_overflow) {
+      EmitJavascriptOverflowCheck(compiler, range(), deopt, result);
+    }
     return;
   }  // locs()->in(1).IsStackSlot().
 
@@ -2661,7 +2667,9 @@
       UNREACHABLE();
       break;
   }
-  Emit54BitOverflowCheck(compiler, deopt, result);
+  if (FLAG_throw_on_javascript_int_overflow) {
+    EmitJavascriptOverflowCheck(compiler, range(), deopt, result);
+  }
 }
 
 
@@ -3839,7 +3847,9 @@
                                             kDeoptUnaryOp);
       __ negq(value);
       __ j(OVERFLOW, deopt);
-      Emit54BitOverflowCheck(compiler, deopt, value);
+      if (FLAG_throw_on_javascript_int_overflow) {
+        EmitJavascriptOverflowCheck(compiler, range(), deopt, value);
+      }
       break;
     }
     case Token::kBIT_NOT:
@@ -3900,7 +3910,9 @@
   __ shlq(temp, Immediate(1));
   __ j(OVERFLOW, &do_call, Assembler::kNearJump);
   __ SmiTag(result);
-  Emit54BitOverflowCheck(compiler, &do_call, result);
+  if (FLAG_throw_on_javascript_int_overflow) {
+    EmitJavascriptOverflowCheck(compiler, range(), &do_call, result);
+  }
   __ jmp(&done);
   __ Bind(&do_call);
   ASSERT(instance_call()->HasICData());
@@ -3946,7 +3958,9 @@
   __ shlq(temp, Immediate(1));
   __ j(OVERFLOW, deopt);
   __ SmiTag(result);
-  Emit54BitOverflowCheck(compiler, deopt, result);
+  if (FLAG_throw_on_javascript_int_overflow) {
+    EmitJavascriptOverflowCheck(compiler, range(), deopt, result);
+  }
 }
 
 
diff --git a/runtime/vm/isolate.cc b/runtime/vm/isolate.cc
index bb51d0d..e7b375d 100644
--- a/runtime/vm/isolate.cc
+++ b/runtime/vm/isolate.cc
@@ -153,6 +153,7 @@
   return success;
 }
 
+
 RawFunction* IsolateMessageHandler::ResolveCallbackFunction() {
   ASSERT(isolate_->object_store()->unhandled_exception_handler() != NULL);
   String& callback_name = String::Handle(isolate_);
diff --git a/runtime/vm/json_stream.cc b/runtime/vm/json_stream.cc
index df60bc5..045fced 100644
--- a/runtime/vm/json_stream.cc
+++ b/runtime/vm/json_stream.cc
@@ -84,6 +84,23 @@
 }
 
 
+void JSONStream::PrintfValue(const char* format, ...) {
+  PrintCommaIfNeeded();
+
+  va_list args;
+  va_start(args, format);
+  intptr_t len = OS::VSNPrint(NULL, 0, format, args);
+  va_end(args);
+  char* p = reinterpret_cast<char*>(malloc(len+1));
+  va_start(args, format);
+  intptr_t len2 = OS::VSNPrint(p, len+1, format, args);
+  va_end(args);
+  ASSERT(len == len2);
+  buffer_->Printf("\"%s\"", p);
+  free(p);
+}
+
+
 void JSONStream::PrintValue(const Object& o, bool ref) {
   PrintCommaIfNeeded();
   o.PrintToJSONStream(this, ref);
@@ -114,6 +131,22 @@
 }
 
 
+void JSONStream::PrintfProperty(const char* name, const char* format, ...) {
+  PrintPropertyName(name);
+  va_list args;
+  va_start(args, format);
+  intptr_t len = OS::VSNPrint(NULL, 0, format, args);
+  va_end(args);
+  char* p = reinterpret_cast<char*>(malloc(len+1));
+  va_start(args, format);
+  intptr_t len2 = OS::VSNPrint(p, len+1, format, args);
+  va_end(args);
+  ASSERT(len == len2);
+  buffer_->Printf("\"%s\"", p);
+  free(p);
+}
+
+
 void JSONStream::PrintProperty(const char* name, const Object& o, bool ref) {
   PrintPropertyName(name);
   PrintValue(o, ref);
diff --git a/runtime/vm/json_stream.h b/runtime/vm/json_stream.h
index 7650c9b..8afea7a 100644
--- a/runtime/vm/json_stream.h
+++ b/runtime/vm/json_stream.h
@@ -28,12 +28,15 @@
   void PrintValue(intptr_t i);
   void PrintValue(double d);
   void PrintValue(const char* s);
+  void PrintfValue(const char* format, ...) PRINTF_ATTRIBUTE(2, 3);
   void PrintValue(const Object& o, bool ref = true);
 
   void PrintPropertyBool(const char* name, bool b);
   void PrintProperty(const char* name, intptr_t i);
   void PrintProperty(const char* name, double d);
   void PrintProperty(const char* name, const char* s);
+  void PrintfProperty(const char* name, const char* format, ...)
+      PRINTF_ATTRIBUTE(3, 4);
   void PrintProperty(const char* name, const Object& o, bool ref = true);
 
  private:
diff --git a/runtime/vm/json_test.cc b/runtime/vm/json_test.cc
index 8f3e40e..39a8eee 100644
--- a/runtime/vm/json_test.cc
+++ b/runtime/vm/json_test.cc
@@ -141,7 +141,7 @@
   EXPECT_STREQ("false", tb.buf());
 
   js.Clear();
-  js.PrintValue((intptr_t)4);
+  js.PrintValue(static_cast<intptr_t>(4));
   EXPECT_STREQ("4", tb.buf());
 
   js.Clear();
@@ -219,6 +219,26 @@
 }
 
 
+TEST_CASE(JSON_JSONStream_Printf) {
+  TextBuffer tb(256);
+  JSONStream js(&tb);
+  js.OpenArray();
+  js.PrintfValue("%d %s", 2, "hello");
+  js.CloseArray();
+  EXPECT_STREQ("[\"2 hello\"]", tb.buf());
+}
+
+
+TEST_CASE(JSON_JSONStream_ObjectPrintf) {
+  TextBuffer tb(256);
+  JSONStream js(&tb);
+  js.OpenObject();
+  js.PrintfProperty("key", "%d %s", 2, "hello");
+  js.CloseObject();
+  EXPECT_STREQ("{\"key\":\"2 hello\"}", tb.buf());
+}
+
+
 TEST_CASE(JSON_JSONStream_DartObject) {
   TextBuffer tb(256);
   JSONStream js(&tb);
diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc
index 44d0ea5..0223cb1 100644
--- a/runtime/vm/object.cc
+++ b/runtime/vm/object.cc
@@ -31,6 +31,7 @@
 #include "vm/intermediate_language.h"
 #include "vm/intrinsifier.h"
 #include "vm/longjump.h"
+#include "vm/object_id_ring.h"
 #include "vm/object_store.h"
 #include "vm/parser.h"
 #include "vm/runtime_entry.h"
@@ -2800,7 +2801,22 @@
 
 
 void Class::PrintToJSONStream(JSONStream* stream, bool ref) const {
+  const char* class_name = String::Handle(UserVisibleName()).ToCString();
+  ObjectIdRing* ring = Isolate::Current()->object_id_ring();
+  intptr_t id = ring->GetIdForObject(raw());
+  if (ref) {
+    stream->OpenObject();
+    stream->PrintProperty("type", "@Class");
+    stream->PrintProperty("id", id);
+    stream->PrintProperty("name", class_name);
+    stream->CloseObject();
+    return;
+  }
   stream->OpenObject();
+  stream->PrintProperty("type", "Class");
+  stream->PrintProperty("id", id);
+  stream->PrintProperty("name", class_name);
+  stream->PrintProperty("library", Object::Handle(library()));
   stream->CloseObject();
 }
 
@@ -4960,7 +4976,69 @@
 
 
 void Function::PrintToJSONStream(JSONStream* stream, bool ref) const {
+  const char* function_name =
+      String::Handle(QualifiedUserVisibleName()).ToCString();
+  ObjectIdRing* ring = Isolate::Current()->object_id_ring();
+  intptr_t id = ring->GetIdForObject(raw());
+  if (ref) {
+    stream->OpenObject();
+    stream->PrintProperty("type", "@Function");
+    stream->PrintProperty("id", id);
+    stream->PrintProperty("name", function_name);
+    stream->CloseObject();
+    return;
+  }
   stream->OpenObject();
+  stream->PrintProperty("type", "Function");
+  stream->PrintProperty("name", function_name);
+  stream->PrintProperty("id", id);
+  stream->PrintPropertyBool("is_static", is_static());
+  stream->PrintPropertyBool("is_const", is_const());
+  stream->PrintPropertyBool("is_optimizable", is_optimizable());
+  stream->PrintPropertyBool("is_inlinable", IsInlineable());
+  const char* kind_string = NULL;
+  switch (kind()) {
+      case RawFunction::kRegularFunction:
+        kind_string = "regular";
+        break;
+      case RawFunction::kGetterFunction:
+        kind_string = "getter";
+        break;
+      case RawFunction::kSetterFunction:
+        kind_string = "setter";
+        break;
+      case RawFunction::kImplicitGetter:
+        kind_string = "implicit getter";
+        break;
+      case RawFunction::kImplicitSetter:
+        kind_string = "implicit setter";
+        break;
+      case RawFunction::kMethodExtractor:
+        kind_string = "method extractor";
+        break;
+      case RawFunction::kNoSuchMethodDispatcher:
+        kind_string = "no such method";
+        break;
+      case RawFunction::kClosureFunction:
+        kind_string = "closure";
+        break;
+      case RawFunction::kConstructor:
+        kind_string = "constructor";
+        break;
+      case RawFunction::kImplicitStaticFinalGetter:
+        kind_string = "static final getter";
+        break;
+      default:
+        UNREACHABLE();
+  }
+  stream->PrintProperty("kind", kind_string);
+  stream->PrintProperty("unoptimized_code", Object::Handle(unoptimized_code()));
+  stream->PrintProperty("usage_counter", usage_counter());
+  stream->PrintProperty("optimized_call_site_count",
+                        optimized_call_site_count());
+  stream->PrintProperty("code", Object::Handle(CurrentCode()));
+  stream->PrintProperty("deoptimizations",
+                        static_cast<intptr_t>(deoptimization_counter()));
   stream->CloseObject();
 }
 
@@ -6334,6 +6412,10 @@
               token_pos);
 }
 
+void Library::AddLibraryMetadata(const Class& cls, intptr_t token_pos) const {
+  AddMetadata(cls, Symbols::TopLevel(), token_pos);
+}
+
 
 RawString* Library::MakeMetadataName(const Object& obj) const {
   if (obj.IsClass()) {
@@ -6342,6 +6424,8 @@
     return MakeFieldMetaName(Field::Cast(obj));
   } else if (obj.IsFunction()) {
     return MakeFunctionMetaName(Function::Cast(obj));
+  } else if (obj.IsLibrary()) {
+    return Symbols::TopLevel().raw();
   }
   UNIMPLEMENTED();
   return String::null();
@@ -6366,7 +6450,8 @@
 
 
 RawObject* Library::GetMetadata(const Object& obj) const {
-  if (!obj.IsClass() && !obj.IsField() && !obj.IsFunction()) {
+  if (!obj.IsClass() && !obj.IsField() && !obj.IsFunction() &&
+      !obj.IsLibrary()) {
     return Object::null();
   }
   const String& metaname = String::Handle(MakeMetadataName(obj));
@@ -7184,7 +7269,39 @@
 
 
 void Library::PrintToJSONStream(JSONStream* stream, bool ref) const {
+  const char* library_name = String::Handle(name()).ToCString();
+  const char* library_url = String::Handle(url()).ToCString();
+  ObjectIdRing* ring = Isolate::Current()->object_id_ring();
+  intptr_t id = ring->GetIdForObject(raw());
+  if (ref) {
+    // Print a reference
+    stream->OpenObject();
+    stream->PrintProperty("type", "@Library");
+    stream->PrintProperty("id", id);
+    stream->PrintProperty("name", library_name);
+    stream->CloseObject();
+    return;
+  }
   stream->OpenObject();
+  stream->PrintProperty("type", "Library");
+  stream->PrintProperty("id", id);
+  stream->PrintProperty("name", library_name);
+  stream->PrintProperty("url", library_url);
+  ClassDictionaryIterator class_iter(*this);
+  stream->OpenArray("classes");
+  Class& klass = Class::Handle();
+  while (class_iter.HasNext()) {
+    klass = class_iter.GetNextClass();
+    stream->PrintValue(klass);
+  }
+  stream->CloseArray();
+  stream->OpenArray("libraries");
+  Library& lib = Library::Handle();
+  for (intptr_t i = 0; i < num_imports(); i++) {
+    lib = ImportLibraryAt(i);
+    stream->PrintValue(lib);
+  }
+  stream->CloseArray();
   stream->CloseObject();
 }
 
@@ -8597,7 +8714,28 @@
 
 
 void Code::PrintToJSONStream(JSONStream* stream, bool ref) const {
+  ObjectIdRing* ring = Isolate::Current()->object_id_ring();
+  intptr_t id = ring->GetIdForObject(raw());
+  if (ref) {
+    stream->OpenObject();
+    stream->PrintProperty("type", "@Code");
+    stream->PrintProperty("id", id);
+    stream->CloseObject();
+    return;
+  }
   stream->OpenObject();
+  stream->PrintProperty("type", "Code");
+  stream->PrintProperty("id", id);
+  stream->PrintPropertyBool("is_optimized", is_optimized());
+  stream->PrintPropertyBool("is_alive", is_alive());
+  stream->PrintProperty("function", Object::Handle(function()));
+  stream->OpenArray("disassembly");
+  DisassembleToJSONStream formatter(stream);
+  const Instructions& instr = Instructions::Handle(instructions());
+  uword start = instr.EntryPoint();
+  Disassembler::Disassemble(start, start + instr.size(), &formatter,
+                            comments());
+  stream->CloseArray();
   stream->CloseObject();
 }
 
@@ -11269,7 +11407,7 @@
 
 
 // This is called from LiteralToken::New() in the parser, so we can't
-// raise an exception for 54-bit overflow here. Instead we do it in
+// raise an exception for javascript overflow here. Instead we do it in
 // Parser::CurrentIntegerLiteral(), which is the point in the parser where
 // integer literals escape, so we can call Parser::ErrorMsg().
 RawInteger* Integer::NewCanonical(const String& str) {
@@ -11289,13 +11427,10 @@
 }
 
 
-// dart2js represents integers as double precision floats. It does this using
-// a sign bit and 53 fraction bits. This gives us the range
-// -2^54 - 1 ... 2^54 - 1, i.e. the same as a 54-bit signed integer
-// without the most negative number. Thus, here we check if the value is
-// a 54-bit signed integer and not -2^54
-static bool Is54BitNoMinInt(int64_t value) {
-  return (Utils::IsInt(54, value)) && (value != (-0x1FFFFFFFFFFFFFLL - 1));
+// dart2js represents integers as double precision floats, which can represent
+// anything in the range -2^53 ... 2^53.
+static bool IsJavascriptInt(int64_t value) {
+  return ((-0x20000000000000LL <= value) && (value <= 0x20000000000000LL));
 }
 
 
@@ -11303,7 +11438,7 @@
   if ((value <= Smi::kMaxValue) && (value >= Smi::kMinValue)) {
     return Smi::New(value);
   }
-  if (FLAG_throw_on_javascript_int_overflow && !Is54BitNoMinInt(value)) {
+  if (FLAG_throw_on_javascript_int_overflow && !IsJavascriptInt(value)) {
     const Integer &i = Integer::Handle(Mint::New(value));
     ThrowJavascriptIntegerOverflow(i);
   }
@@ -11344,7 +11479,7 @@
 
 
 // Returns true if the signed Integer does not fit into a
-// Javascript (54-bit) integer.
+// Javascript integer.
 bool Integer::CheckJavascriptIntegerOverflow() const {
   // Always overflow if the value doesn't fit into an int64_t.
   int64_t value = 1ULL << 63;
@@ -11362,7 +11497,7 @@
       value = BigintOperations::ToInt64(big_value);
     }
   }
-  return !Is54BitNoMinInt(value);
+  return !IsJavascriptInt(value);
 }
 
 
diff --git a/runtime/vm/object.h b/runtime/vm/object.h
index 2e0d6c7..39142ab 100644
--- a/runtime/vm/object.h
+++ b/runtime/vm/object.h
@@ -2315,6 +2315,7 @@
   void AddClassMetadata(const Class& cls, intptr_t token_pos) const;
   void AddFieldMetadata(const Field& field, intptr_t token_pos) const;
   void AddFunctionMetadata(const Function& func, intptr_t token_pos) const;
+  void AddLibraryMetadata(const Class& cls, intptr_t token_pos) const;
   RawObject* GetMetadata(const Object& obj) const;
 
   // Library imports.
diff --git a/runtime/vm/parser.cc b/runtime/vm/parser.cc
index 61e184e..d5a8dde 100644
--- a/runtime/vm/parser.cc
+++ b/runtime/vm/parser.cc
@@ -4744,6 +4744,9 @@
       ErrorMsg("patch cannot override library name");
     }
     ParseLibraryName();
+    if (metadata_pos >= 0) {
+      library_.AddLibraryMetadata(current_class(), metadata_pos);
+    }
     metadata_pos = TokenPos();
     SkipMetadata();
   }
@@ -4808,6 +4811,7 @@
   toplevel_class.set_library(library_);
 
   if (is_library_source() || is_patch_source()) {
+    set_current_class(toplevel_class);
     ParseLibraryDefinition();
   } else if (is_part_source()) {
     ParsePartHeader();
diff --git a/runtime/vm/service.cc b/runtime/vm/service.cc
index 6a27c19..ffb08c0f 100644
--- a/runtime/vm/service.cc
+++ b/runtime/vm/service.cc
@@ -2,6 +2,8 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
+#include "vm/debugger.h"
+#include "vm/heap_histogram.h"
 #include "vm/isolate.h"
 #include "vm/message.h"
 #include "vm/object.h"
@@ -10,6 +12,16 @@
 
 namespace dart {
 
+typedef RawString* (*ServiceMessageHandler)(Isolate* isolate);
+
+struct ServiceMessageHandlerEntry {
+  const char* command;
+  ServiceMessageHandler handler;
+};
+
+static ServiceMessageHandler FindServiceMessageHandler(const char* command);
+
+
 static uint8_t* allocator(uint8_t* ptr, intptr_t old_size, intptr_t new_size) {
   void* new_ptr = realloc(reinterpret_cast<void*>(ptr), new_size);
   return reinterpret_cast<uint8_t*>(new_ptr);
@@ -26,28 +38,133 @@
 }
 
 
-static RawString* HandleIdMessage(Isolate* isolate, Dart_Port reply_port) {
+void Service::HandleServiceMessage(Isolate* isolate, Dart_Port reply_port,
+                                   const Instance& msg) {
+  ASSERT(isolate != NULL);
+  ASSERT(reply_port != ILLEGAL_PORT);
+  ASSERT(!msg.IsNull());
+  ASSERT(msg.IsGrowableObjectArray());
+
+  {
+    StackZone zone(isolate);
+    HANDLESCOPE(isolate);
+    const GrowableObjectArray& message = GrowableObjectArray::Cast(msg);
+    // Message is a list with three entries.
+    ASSERT(message.Length() == 3);
+
+    GrowableObjectArray& path = GrowableObjectArray::Handle();
+    GrowableObjectArray& option_keys = GrowableObjectArray::Handle();
+    GrowableObjectArray& option_values = GrowableObjectArray::Handle();
+    path ^= message.At(0);
+    option_keys ^= message.At(1);
+    option_values ^= message.At(2);
+
+    ASSERT(!path.IsNull());
+    ASSERT(!option_keys.IsNull());
+    ASSERT(!option_values.IsNull());
+    // Path always has at least one entry in it.
+    ASSERT(path.Length() > 0);
+    // Same number of option keys as values.
+    ASSERT(option_keys.Length() == option_values.Length());
+
+    String& pathSegment = String::Handle();
+    pathSegment ^= path.At(0);
+    ASSERT(!pathSegment.IsNull());
+
+    ServiceMessageHandler handler =
+        FindServiceMessageHandler(pathSegment.ToCString());
+    String& reply = String::Handle();
+    reply ^= handler(isolate);
+    ASSERT(!reply.IsNull());
+    PostReply(reply, reply_port);
+  }
+}
+
+
+static RawString* HandleName(Isolate* isolate) {
   TextBuffer buffer(256);
-  buffer.Printf("{ \"id\": \"%s\" }", isolate->name());
+  JSONStream js(&buffer);
+  js.OpenObject();
+  js.PrintProperty("type", "IsolateName");
+  js.PrintProperty("id", static_cast<intptr_t>(isolate->main_port()));
+  js.PrintProperty("name", isolate->name());
+  js.CloseObject();
   return String::New(buffer.buf());
 }
 
 
-void Service::HandleServiceMessage(Isolate* isolate, Dart_Port reply_port,
-                                   const Instance& message) {
-  ASSERT(isolate != NULL);
-  ASSERT(reply_port != ILLEGAL_PORT);
-  ASSERT(!message.IsNull());
-  ASSERT(message.IsString());
+RawString* HandleStackTrace(Isolate* isolate) {
+  TextBuffer buffer(256);
+  JSONStream js(&buffer);
+  DebuggerStackTrace* stack = isolate->debugger()->StackTrace();
+  js.OpenObject();
+  js.PrintProperty("type", "StackTrace");
+  js.OpenArray("members");
+  intptr_t n_frames = stack->Length();
+  String& url = String::Handle();
+  String& function = String::Handle();
+  for (int i = 0; i < n_frames; i++) {
+    ActivationFrame* frame = stack->ActivationFrameAt(i);
+    url ^= frame->SourceUrl();
+    function ^= frame->function().UserVisibleName();
+    js.OpenObject();
+    js.PrintProperty("name", function.ToCString());
+    js.PrintProperty("url", url.ToCString());
+    js.PrintProperty("line", frame->LineNumber());
+    js.PrintProperty("function", frame->function());
+    js.PrintProperty("code", frame->code());
+    js.CloseObject();
+  }
+  js.CloseArray();
+  js.CloseObject();
+  return String::New(buffer.buf());
+}
 
-  String& reply = String::Handle();
 
-  // For now, assume service message is always an id check.
-  reply = HandleIdMessage(isolate, reply_port);
+RawString* HandleObjectHistogram(Isolate* isolate) {
+  TextBuffer buffer(256);
+  JSONStream js(&buffer);
+  ObjectHistogram* histogram = Isolate::Current()->object_histogram();
+  if (histogram == NULL) {
+    js.OpenObject();
+    js.PrintProperty("type", "ObjectHistogram");
+    js.PrintProperty("error", "Run with --print_object_histogram");
+    js.CloseObject();
+    return String::New(buffer.buf());
+  }
+  histogram->PrintToJSONStream(&js);
+  return String::New(buffer.buf());
+}
 
-  ASSERT(!reply.IsNull());
 
-  PostReply(reply, reply_port);
+static ServiceMessageHandlerEntry __message_handlers[] = {
+  { "name", HandleName },
+  { "stacktrace", HandleStackTrace },
+  { "objecthistogram", HandleObjectHistogram},
+};
+
+
+static RawString* HandleFallthrough(Isolate* isolate) {
+  TextBuffer buffer(256);
+  JSONStream js(&buffer);
+  js.OpenObject();
+  js.PrintProperty("type", "error");
+  js.PrintProperty("text", "request not supported.");
+  js.CloseObject();
+  return String::New(buffer.buf());
+}
+
+
+static ServiceMessageHandler FindServiceMessageHandler(const char* command) {
+  intptr_t num_message_handlers = sizeof(__message_handlers) /
+                                  sizeof(__message_handlers[0]);
+  for (intptr_t i = 0; i < num_message_handlers; i++) {
+    const ServiceMessageHandlerEntry& entry = __message_handlers[i];
+    if (!strcmp(command, entry.command)) {
+      return entry.handler;
+    }
+  }
+  return HandleFallthrough;
 }
 
 }  // namespace dart
diff --git a/runtime/vm/simulator_mips.cc b/runtime/vm/simulator_mips.cc
index c30e25e..9d33b46 100644
--- a/runtime/vm/simulator_mips.cc
+++ b/runtime/vm/simulator_mips.cc
@@ -1022,7 +1022,8 @@
         SimulatorRuntimeCall target =
             reinterpret_cast<SimulatorRuntimeCall>(external);
         target(arguments);
-        set_register(V0, icount_);  // Zap result register from void function.
+        set_register(V0, icount_);  // Zap result registers from void function.
+        set_register(V1, icount_);
       } else if (redirection->call_kind() == kLeafRuntimeCall) {
         int32_t a0 = get_register(A0);
         int32_t a1 = get_register(A1);
@@ -1032,6 +1033,7 @@
             reinterpret_cast<SimulatorLeafRuntimeCall>(external);
         a0 = target(a0, a1, a2, a3);
         set_register(V0, a0);  // Set returned result from function.
+        set_register(V1, icount_);  // Zap second result register.
       } else if (redirection->call_kind() == kLeafFloatRuntimeCall) {
         ASSERT((0 <= redirection->argument_count()) &&
                (redirection->argument_count() <= 2));
@@ -1051,6 +1053,7 @@
             reinterpret_cast<SimulatorNativeCall>(external);
         target(arguments);
         set_register(V0, icount_);  // Zap result register from void function.
+        set_register(V1, icount_);
       }
       set_top_exit_frame_info(0);
 
diff --git a/sdk/lib/_internal/dartdoc/dartdoc.status b/sdk/lib/_internal/dartdoc/dartdoc.status
index 8b45e64..7e11ab4 100644
--- a/sdk/lib/_internal/dartdoc/dartdoc.status
+++ b/sdk/lib/_internal/dartdoc/dartdoc.status
@@ -7,7 +7,7 @@
 test/dartdoc_search_test: Pass, Skip
 
 # Dartdoc only runs on the VM, so just rule out all compilers.
-[ $compiler == dart2js || $compiler == dart2dart || $compiler == dartc ]
+[ $compiler == dart2js || $compiler == dart2dart ]
 *: Skip
 
 # Dartdoc only runs on the standalone VM, not in dartium.
diff --git a/sdk/lib/html/dart2js/html_dart2js.dart b/sdk/lib/html/dart2js/html_dart2js.dart
index 74a14e5..76a9830 100644
--- a/sdk/lib/html/dart2js/html_dart2js.dart
+++ b/sdk/lib/html/dart2js/html_dart2js.dart
@@ -28982,6 +28982,12 @@
   }
 
   /**
+   * Get the straight line (Euclidean) distance between the origin (0, 0) and
+   * this point.
+   */
+  num get magnitude => sqrt(x * x + y * y);
+
+  /**
    * Returns the distance between two points.
    */
   double distanceTo(Point other) {
diff --git a/sdk/lib/html/dartium/html_dartium.dart b/sdk/lib/html/dartium/html_dartium.dart
index 555a0d0..3b3637e 100644
--- a/sdk/lib/html/dartium/html_dartium.dart
+++ b/sdk/lib/html/dartium/html_dartium.dart
@@ -30691,6 +30691,12 @@
   }
 
   /**
+   * Get the straight line (Euclidean) distance between the origin (0, 0) and
+   * this point.
+   */
+  num get magnitude => sqrt(x * x + y * y);
+
+  /**
    * Returns the distance between two points.
    */
   double distanceTo(Point other) {
@@ -32031,6 +32037,8 @@
   // TODO(jacobr): we need a failsafe way to determine that a Node is really a
   // DOM node rather than just a class that extends Node.
   static bool isNode(obj) => obj is Node;
+
+  static bool isNoSuchMethodError(obj) => obj is NoSuchMethodError;
 }
 
 class _NPObject extends NativeFieldWrapperClass1 {
diff --git a/sdk/lib/io/http.dart b/sdk/lib/io/http.dart
index 755c96c..4b490c2 100644
--- a/sdk/lib/io/http.dart
+++ b/sdk/lib/io/http.dart
@@ -845,6 +845,21 @@
   List<Cookie> get cookies;
 
   /**
+   * Respond with a redirect to [location].
+   *
+   * The URI in [location] should be absolute, but there are no checks
+   * to enforce that.
+   *
+   * By default the HTTP status code `HttpStatus.MOVED_TEMPORARILY`
+   * (`302`) is used for the redirect, but an alternative one can be
+   * specified using the [status] argument.
+   *
+   * This method will also call `close`, and the returned future is
+   * the furure returned by `close`.
+   */
+  Future redirect(Uri location, {int status: HttpStatus.MOVED_TEMPORARILY});
+
+  /**
    * Detaches the underlying socket from the HTTP server. When the
    * socket is detached the HTTP server will no longer perform any
    * operations on it.
diff --git a/sdk/lib/io/http_impl.dart b/sdk/lib/io/http_impl.dart
index 3af4000..ca097c9 100644
--- a/sdk/lib/io/http_impl.dart
+++ b/sdk/lib/io/http_impl.dart
@@ -708,6 +708,13 @@
     _reasonPhrase = reasonPhrase;
   }
 
+  Future redirect(Uri location, {int status: HttpStatus.MOVED_TEMPORARILY}) {
+    if (_headersWritten) throw new StateError("Header already sent");
+    statusCode = status;
+    headers.set("Location", location.toString());
+    return close();
+  }
+
   Future<Socket> detachSocket() {
     if (_headersWritten) throw new StateError("Headers already sent");
     deadline = null;  // Be sure to stop any deadline.
diff --git a/sdk/lib/svg/dartium/svg_dartium.dart b/sdk/lib/svg/dartium/svg_dartium.dart
index 35fa28a..a4bea12 100644
--- a/sdk/lib/svg/dartium/svg_dartium.dart
+++ b/sdk/lib/svg/dartium/svg_dartium.dart
@@ -3435,7 +3435,7 @@
   Length operator[](int index) {
     if (index < 0 || index >= length)
       throw new RangeError.range(index, 0, length);
-    return this.getItem(index)(index);
+    return getItem(index);
   }
 
   void operator[]=(int index, Length value) {
@@ -4024,7 +4024,7 @@
   Number operator[](int index) {
     if (index < 0 || index >= length)
       throw new RangeError.range(index, 0, length);
-    return this.getItem(index)(index);
+    return getItem(index);
   }
 
   void operator[]=(int index, Number value) {
@@ -5094,7 +5094,7 @@
   PathSeg operator[](int index) {
     if (index < 0 || index >= length)
       throw new RangeError.range(index, 0, length);
-    return this.getItem(index)(index);
+    return getItem(index);
   }
 
   void operator[]=(int index, PathSeg value) {
@@ -6002,7 +6002,7 @@
   String operator[](int index) {
     if (index < 0 || index >= length)
       throw new RangeError.range(index, 0, length);
-    return this.getItem(index)(index);
+    return getItem(index);
   }
 
   void operator[]=(int index, String value) {
@@ -7139,7 +7139,7 @@
   Transform operator[](int index) {
     if (index < 0 || index >= length)
       throw new RangeError.range(index, 0, length);
-    return this.getItem(index)(index);
+    return getItem(index);
   }
 
   void operator[]=(int index, Transform value) {
diff --git a/tests/co19/co19-analyzer.status b/tests/co19/co19-analyzer.status
index aaea30a..78dc78a 100644
--- a/tests/co19/co19-analyzer.status
+++ b/tests/co19/co19-analyzer.status
@@ -430,3 +430,25 @@
 Language/11_Expressions/11_Instance_Creation_A03_t01: fail, OK
 Language/11_Expressions/11_Instance_Creation_A04_t01: fail, OK
 Language/11_Expressions/11_Instance_Creation_A04_t02: fail, OK
+
+# co19 issue #481
+Language/13_Libraries_and_Scripts/1_Imports_A03_t02: fail, OK
+Language/13_Libraries_and_Scripts/1_Imports_A03_t05: fail, OK
+Language/13_Libraries_and_Scripts/1_Imports_A03_t08: fail, OK
+Language/13_Libraries_and_Scripts/1_Imports_A03_t09: fail, OK
+Language/13_Libraries_and_Scripts/1_Imports_A03_t10: fail, OK
+Language/13_Libraries_and_Scripts/1_Imports_A03_t22: fail, OK
+Language/13_Libraries_and_Scripts/1_Imports_A03_t25: fail, OK
+Language/13_Libraries_and_Scripts/1_Imports_A03_t29: fail, OK
+Language/13_Libraries_and_Scripts/1_Imports_A03_t28: fail, OK
+Language/13_Libraries_and_Scripts/1_Imports_A03_t30: fail, OK
+Language/13_Libraries_and_Scripts/1_Imports_A03_t42: fail, OK
+Language/13_Libraries_and_Scripts/1_Imports_A03_t45: fail, OK
+Language/13_Libraries_and_Scripts/1_Imports_A03_t48: fail, OK
+Language/13_Libraries_and_Scripts/1_Imports_A03_t49: fail, OK
+Language/13_Libraries_and_Scripts/1_Imports_A03_t50: fail, OK
+Language/13_Libraries_and_Scripts/1_Imports_A03_t62: fail, OK
+Language/13_Libraries_and_Scripts/1_Imports_A03_t65: fail, OK
+Language/13_Libraries_and_Scripts/1_Imports_A03_t68: fail, OK
+Language/13_Libraries_and_Scripts/1_Imports_A03_t69: fail, OK
+Language/13_Libraries_and_Scripts/1_Imports_A03_t70: fail, OK
diff --git a/tests/co19/co19-runtime.status b/tests/co19/co19-runtime.status
index 7311058..822b076 100644
--- a/tests/co19/co19-runtime.status
+++ b/tests/co19/co19-runtime.status
@@ -517,26 +517,11 @@
 [ $compiler == none && $runtime == vm && $arch != x64 ]
 LibTest/core/int/operator_left_shift_A01_t02: Fail # co19 issue 129
 
-
-[ $compiler == none && $runtime == vm && $arch == arm && $mode == debug ]
-LibTest/core/List/sort_A01_t05: Crash # Too far relative jump.
-LibTest/core/List/sort_A01_t06: Crash # Too far relative jump.
-
 [ $compiler == none && $runtime == vm && $arch == simarm ]
 LibTest/math/cos_A01_t01: Pass, Fail # Fail on Mac
 
-[ $compiler == none && $runtime == vm && $arch == simarm && $mode == debug ]
-LibTest/core/List/sort_A01_t05: Crash # Too far relative jump.
-LibTest/core/List/sort_A01_t06: Crash # Too far relative jump.
-
-
 [ $compiler == none && $runtime == vm && $arch == mips ]
 *: Skip
 
 [ $compiler == none && $runtime == vm && $arch == simmips ]
 LibTest/math/cos_A01_t01: Pass, Fail # Fail on Mac
-
-[ $compiler == none && $runtime == vm && $arch == simmips && $mode == debug ]
-LibTest/core/List/sort_A01_t04: Crash # Too far relative jump.
-LibTest/core/List/sort_A01_t05: Crash
-LibTest/core/List/sort_A01_t06: Crash
diff --git a/tests/compiler/dart2js_foreign/dart2js_foreign.status b/tests/compiler/dart2js_foreign/dart2js_foreign.status
index 953a89f..7945115 100644
--- a/tests/compiler/dart2js_foreign/dart2js_foreign.status
+++ b/tests/compiler/dart2js_foreign/dart2js_foreign.status
@@ -60,5 +60,5 @@
 native_class_with_dart_methods_test: Fail # TODO(ahe): Convert to metadata syntax.
 native_to_string_test: Fail # TODO(ahe): Convert to metadata syntax.
 
-[ $compiler == dartc || $browser ]
+[ $browser ]
 *: Skip
diff --git a/tests/compiler/dart2js_native/dart2js_native.status b/tests/compiler/dart2js_native/dart2js_native.status
index f2e923f..cb7557d 100644
--- a/tests/compiler/dart2js_native/dart2js_native.status
+++ b/tests/compiler/dart2js_native/dart2js_native.status
@@ -2,7 +2,7 @@
 # for details. All rights reserved. Use of this source code is governed by a
 # BSD-style license that can be found in the LICENSE file.
 
-[ $compiler == dartc || $browser ]
+[ $browser ]
 *: Skip
 
 [ $compiler == dart2js ]
diff --git a/tests/corelib/hash_map2_test.dart b/tests/corelib/hash_map2_test.dart
index a43afd2..cc4ed3e 100644
--- a/tests/corelib/hash_map2_test.dart
+++ b/tests/corelib/hash_map2_test.dart
@@ -1,7 +1,6 @@
 // Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
-// VMOptions=--use-far-branches
 
 // Tests of hash map behavior, with focus in iteration and concurrent
 // modification errors.
diff --git a/tests/corelib/list_test.dart b/tests/corelib/list_test.dart
index 97552a6..8883e49 100644
--- a/tests/corelib/list_test.dart
+++ b/tests/corelib/list_test.dart
@@ -1,7 +1,6 @@
 // Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
-// VMOptions=--use-far-branches
 
 import "dart:collection";
 import "dart:typed_data";
diff --git a/tests/html/point_test.dart b/tests/html/point_test.dart
index 7a4fdbd..ef1fe5a 100644
--- a/tests/html/point_test.dart
+++ b/tests/html/point_test.dart
@@ -112,4 +112,14 @@
     var c = new Point(1, 0);
     expect(a.hashCode == c.hashCode, isFalse);
   });
+
+  test('magnitute', () {
+    var a = new Point(5, 10);
+    var b = new Point(0, 0);
+    expect(a.magnitude, a.distanceTo(b));
+    expect(b.magnitude, 0);
+
+    var c = new Point(-5, -10);
+    expect(c.magnitude, a.distanceTo(b));
+  });
 }
diff --git a/tests/language/arithmetic_test.dart b/tests/language/arithmetic_test.dart
index 00f6eb1..effcee9 100644
--- a/tests/language/arithmetic_test.dart
+++ b/tests/language/arithmetic_test.dart
@@ -2,7 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 // Dart test program to test arithmetic operations.
-// VMOptions=--optimization-counter-threshold=10 --no-use-osr --use-far-branches
+// VMOptions=--optimization-counter-threshold=10 --no-use-osr
 
 library arithmetic_test;
 import "package:expect/expect.dart";
diff --git a/tests/language/language_analyzer.status b/tests/language/language_analyzer.status
index e977432..3f4a04f 100644
--- a/tests/language/language_analyzer.status
+++ b/tests/language/language_analyzer.status
@@ -87,7 +87,17 @@
 static_field_test/02: fail
 static_field_test/03: fail
 
-library_ambiguous_test/04: Fail # TBF: Issue 12106
+# TBF
+method_override2_test/00: fail # issue 11497
+method_override2_test/01: fail # issue 11497
+method_override2_test/02: fail # issue 11497
+method_override2_test/03: fail # issue 11497
+method_override3_test/00: fail # issue 11497
+method_override3_test/01: fail # issue 11497
+method_override3_test/02: fail # issue 11497
+method_override4_test: fail # issue 11497
+method_override5_test: fail # issue 11497
+method_override6_test: fail # issue 11497
 
 
 
@@ -154,18 +164,6 @@
 # Test issue 11564, named parameter starts with '_'
 named_parameters_with_object_property_names_test: fail
 
-# TBF
-method_override2_test/00: fail # issue 11497
-method_override2_test/01: fail # issue 11497
-method_override2_test/02: fail # issue 11497
-method_override2_test/03: fail # issue 11497
-method_override3_test/00: fail # issue 11497
-method_override3_test/01: fail # issue 11497
-method_override3_test/02: fail # issue 11497
-method_override4_test: fail # issue 11497
-method_override5_test: fail # issue 11497
-method_override6_test: fail # issue 11497
-
 # test issue 11575, classes with abstrac members are not marked as abstract
 abstract_factory_constructor_test/none: fail
 abstract_syntax_test/none: fail
@@ -320,6 +318,14 @@
 # test issue 12184, It is static warning, not error, to assign to a constant variable.
 static_final_field2_negative_test: fail
 
+# test issue 12191, ambuguous import is always warning now
+prefix3_negative_test: fail
+library_ambiguous_test/00: fail
+library_ambiguous_test/01: fail
+library_ambiguous_test/02: fail
+library_ambiguous_test/03: fail
+
+
 [ $compiler == dartanalyzer && $checked ]
 factory1_test/00: fail
 factory1_test/01: fail
diff --git a/tests/language/large_implicit_getter_test.dart b/tests/language/large_implicit_getter_test.dart
index b7293b2..8dac849 100644
--- a/tests/language/large_implicit_getter_test.dart
+++ b/tests/language/large_implicit_getter_test.dart
@@ -2,7 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 // Dart test program for testing compilation of large implicit getters.
-// VMOptions=--optimization-counter-threshold=10 --use-far-branches
+// VMOptions=--optimization-counter-threshold=10
 
 List<List> panels = [
 [6853.940039224797,6050.837897021371]
diff --git a/tests/lib/lib.status b/tests/lib/lib.status
index 0690589..b321b7a 100644
--- a/tests/lib/lib.status
+++ b/tests/lib/lib.status
@@ -90,7 +90,6 @@
 
 [ $runtime == vm || ($compiler == none && $runtime == drt) ]
 async/run_async3_test: Fail # _enqueueImmediate runs after Timer. http://dartbug.com/9001.
-mirrors/library_metadata_test: Fail # http://dartbug.com/10906
 mirrors/parameter_test: Fail # http://dartbug.com/11567
 mirrors/operator_test: Fail # http://dartbug.com/11944
 mirrors/null_test: Fail # Issue 12128
diff --git a/tests/lib/typed_data/float32x4_shuffle_test.dart b/tests/lib/typed_data/float32x4_shuffle_test.dart
index 21044bf..a863f12 100644
--- a/tests/lib/typed_data/float32x4_shuffle_test.dart
+++ b/tests/lib/typed_data/float32x4_shuffle_test.dart
@@ -1,7 +1,7 @@
 // Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
-// VMOptions=--optimization-counter-threshold=10 --use-far-branches
+// VMOptions=--optimization-counter-threshold=10
 
 // Library tag to be able to run in html test framework.
 library float32x4_shuffle_test;
diff --git a/tests/standalone/io/http_redirect_test.dart b/tests/standalone/io/http_redirect_test.dart
index d0b78a0..346c154 100644
--- a/tests/standalone/io/http_redirect_test.dart
+++ b/tests/standalone/io/http_redirect_test.dart
@@ -32,10 +32,8 @@
       addRequestHandler(
          "/$number",
          (HttpRequest request, HttpResponse response) {
-         response.headers.set(HttpHeaders.LOCATION,
-                              "http://127.0.0.1:${server.port}/${number + 1}");
-         response.statusCode = statusCode;
-         response.close();
+           response.redirect(
+               Uri.parse("http://127.0.0.1:${server.port}/${number + 1}"));
        });
     }
 
@@ -43,10 +41,9 @@
     addRequestHandler(
        "/redirect",
        (HttpRequest request, HttpResponse response) {
-         response.headers.set(HttpHeaders.LOCATION,
-                              "http://127.0.0.1:${server.port}/location");
-         response.statusCode = HttpStatus.MOVED_PERMANENTLY;
-         response.close();
+         response.redirect(
+             Uri.parse("http://127.0.0.1:${server.port}/location"),
+             status: HttpStatus.MOVED_PERMANENTLY);
        }
     );
     addRequestHandler(
@@ -83,6 +80,13 @@
     );
 
     addRequestHandler(
+       "/some/relativeToAbsolute",
+       (HttpRequest request, HttpResponse response) {
+         response.redirect(Uri.parse("xxx"), status: HttpStatus.SEE_OTHER);
+       }
+    );
+
+    addRequestHandler(
        "/redirectUrl2",
        (HttpRequest request, HttpResponse response) {
          response.headers.set(HttpHeaders.LOCATION, "location");
@@ -456,6 +460,34 @@
   testPath("/redirectUrl5");
 }
 
+void testRedirectRelativeToAbsolute() {
+  setupServer().then((server) {
+    HttpClient client = new HttpClient();
+
+    int redirectCount = 0;
+    handleResponse(HttpClientResponse response) {
+      response.listen(
+          (_) => Expect.fail("Response data not expected"),
+          onDone: () {
+            Expect.equals(HttpStatus.SEE_OTHER, response.statusCode);
+            Expect.equals("xxx",
+                          response.headers["Location"][0]);
+            Expect.isTrue(response.isRedirect);
+            server.close();
+            client.close();
+          });
+    }
+    client.getUrl(
+        Uri.parse("http://127.0.0.1:${server.port}/some/relativeToAbsolute"))
+      .then((HttpClientRequest request) {
+        request.followRedirects = false;
+        return request.close();
+      })
+      .then(handleResponse);
+  });
+}
+
+
 main() {
   testManualRedirect();
   testManualRedirectWithHeaders();
@@ -467,4 +499,5 @@
   testRedirectLoop();
   testRedirectClosingConnection();
   testRedirectRelativeUrl();
+  testRedirectRelativeToAbsolute();
 }
diff --git a/tests/standalone/io/status_file_parser_test.dart b/tests/standalone/io/status_file_parser_test.dart
index 0369d49..d9c2f68 100644
--- a/tests/standalone/io/status_file_parser_test.dart
+++ b/tests/standalone/io/status_file_parser_test.dart
@@ -10,9 +10,6 @@
 
 
 void main() {
-  TestReadStatusFile("client/tests/dartc/dartc.status");
-  TestReadStatusFile("compiler/tests/dartc/dartc.status");
-  TestReadStatusFile("frog/tests/frog/frog.status");
   TestReadStatusFile("runtime/tests/vm/vm.status");
   TestReadStatusFile("samples/tests/samples/samples.status");
   TestReadStatusFile("tests/co19/co19-compiler.status");
diff --git a/tests/standalone/javascript_int_overflow_literal_test.dart b/tests/standalone/javascript_int_overflow_literal_test.dart
index 36c7b5b..2d45ef0 100644
--- a/tests/standalone/javascript_int_overflow_literal_test.dart
+++ b/tests/standalone/javascript_int_overflow_literal_test.dart
@@ -8,11 +8,11 @@
 import "package:expect/expect.dart";
 
 int literals() {
-  var okay_literal = 0x1FFFFFFFFFFFFF;
-  var too_big_literal = 0x20000000000000;  /// 01: compile-time error
+  var okay_literal = 0x20000000000000;
+  var too_big_literal = 0x20000000000001;  /// 01: compile-time error
   return okay_literal;
 }
 
 main() {
-  Expect.equals(0x1FFFFFFFFFFFFF, literals());
+  Expect.equals(0x20000000000000, literals());
 }
diff --git a/tests/standalone/javascript_int_overflow_test.dart b/tests/standalone/javascript_int_overflow_test.dart
index 6e1eb9b..6e38da6 100644
--- a/tests/standalone/javascript_int_overflow_test.dart
+++ b/tests/standalone/javascript_int_overflow_test.dart
@@ -29,12 +29,12 @@
 
 
 int max_add_throws() {
-  return 0x1FFFFFFFFFFFFF + 1;
+  return 0x20000000000000 + 1;
 }
 
 
 int min_sub_throws() {
-  return -0x1FFFFFFFFFFFFF - 1;
+  return -0x20000000000000 - 1;
 }
 
 
@@ -45,12 +45,12 @@
 
 
 int max_literal() {
-  return 0x1FFFFFFFFFFFFF;
+  return 0x20000000000000;
 }
 
 
 int min_literal() {
-  var min_literal = -0x1FFFFFFFFFFFFF;
+  var min_literal = -0x20000000000000;
   return min_literal;
 }
 
@@ -60,21 +60,21 @@
     e is Error && "$e".startsWith("Javascript Integer Overflow:");
 
 main() {
-  Expect.equals(0x1FFFFFFFFFFFFF, max_literal());
-  Expect.equals(-0x1FFFFFFFFFFFFF, min_literal());
+  Expect.equals(0x20000000000000, max_literal());
+  Expect.equals(-0x20000000000000, min_literal());
 
   // Run the tests once before optimizations.
-  dti_arg = 1.9e16;
+  dti_arg = 1.9e17;
   Expect.throws(double_to_int, isJavascriptIntError);
 
-  ia_arg1 = (1 << 52);
-  ia_arg2 = (1 << 52);
+  ia_arg1 = (1 << 53);
+  ia_arg2 = (1 << 53);
   Expect.throws(integer_add, isJavascriptIntError);
 
-  n_arg = -0x1FFFFFFFFFFFFF;
-  Expect.equals(0x1FFFFFFFFFFFFF, negate());
+  n_arg = -0x20000000000000;
+  Expect.equals(0x20000000000000, negate());
 
-  is_arg = (1 << 52);
+  is_arg = (1 << 53);
   Expect.throws(integer_shift, isJavascriptIntError);
 
   Expect.throws(max_add_throws, isJavascriptIntError);
@@ -101,17 +101,17 @@
   }
 
    // The optimized functions should now deoptimize and throw the error.
-  dti_arg = 1.9e16;
+  dti_arg = 1.9e17;
   Expect.throws(double_to_int, isJavascriptIntError);
 
-  ia_arg1 = (1 << 52);
-  ia_arg2 = (1 << 52);
+  ia_arg1 = (1 << 53);
+  ia_arg2 = (1 << 53);
   Expect.throws(integer_add, isJavascriptIntError);
 
-  n_arg = -0x1FFFFFFFFFFFFF;
-  Expect.equals(0x1FFFFFFFFFFFFF, negate());
+  n_arg = -0x20000000000000;
+  Expect.equals(0x20000000000000, negate());
 
-  is_arg = (1 << 52);
+  is_arg = (1 << 53);
   Expect.throws(integer_shift, isJavascriptIntError);
 
   Expect.throws(max_add_throws, isJavascriptIntError);
diff --git a/tests/standalone/vmservice/isolate_list_test.dart b/tests/standalone/vmservice/isolate_list_test.dart
index 2e68ced..7d7f2e0 100644
--- a/tests/standalone/vmservice/isolate_list_test.dart
+++ b/tests/standalone/vmservice/isolate_list_test.dart
@@ -1,12 +1,6 @@
 // Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
-// VMOptions=--short_socket_read
-// VMOptions=--short_socket_write
-// VMOptions=--short_socket_read --short_socket_write
-//
-// Test:
-//   *) Connect to VM Service and obtain list of running isolates.
 
 library isolate_list_test;
 
diff --git a/tests/standalone/vmservice/isolate_stacktrace_command_script.dart b/tests/standalone/vmservice/isolate_stacktrace_command_script.dart
new file mode 100644
index 0000000..a573126
--- /dev/null
+++ b/tests/standalone/vmservice/isolate_stacktrace_command_script.dart
@@ -0,0 +1,36 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library isolate_stacktrace_command_script;
+
+import 'dart:io';
+import 'dart:isolate';
+
+void a() {
+  int x = 0;
+  while (true) {
+    x &= x;
+  }
+}
+
+void b() {
+  a();
+}
+
+class C {
+  c() {
+    b();
+  }
+}
+
+void myIsolateName() {
+  new C().c();
+}
+
+main() {
+  spawnFunction(myIsolateName);
+  print(''); // Print blank line to signal that we are ready.
+  // Wait until signaled from spawning test.
+  stdin.first.then((_) => exit(0));
+}
diff --git a/tests/standalone/vmservice/isolate_stacktrace_command_test.dart b/tests/standalone/vmservice/isolate_stacktrace_command_test.dart
new file mode 100644
index 0000000..4b4ce79
--- /dev/null
+++ b/tests/standalone/vmservice/isolate_stacktrace_command_test.dart
@@ -0,0 +1,47 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library isolate_stacktrace_command_test;
+
+import 'test_helper.dart';
+import 'package:expect/expect.dart';
+
+class StacktraceTest extends VmServiceRequestHelper {
+  StacktraceTest(port, id) :
+      super('http://127.0.0.1:$port/isolates/$id/stacktrace');
+
+  onRequestCompleted(Map reply) {
+    Expect.equals('StackTrace', reply['type'], 'Not a StackTrace message.');
+    Expect.equals(4, reply['members'].length, 'Stacktrace is wrong length.');
+    Expect.equals('a', reply['members'][0]['name']);
+    Expect.equals('b', reply['members'][1]['name']);
+    Expect.equals('c', reply['members'][2]['name']);
+    Expect.equals('myIsolateName', reply['members'][3]['name']);
+  }
+}
+
+class IsolateListTest extends VmServiceRequestHelper {
+  IsolateListTest(port) : super('http://127.0.0.1:$port/isolates');
+
+  int _isolateId;
+  onRequestCompleted(Map reply) {
+    IsolateListTester tester = new IsolateListTester(reply);
+    tester.checkIsolateCount(2);
+    _isolateId = tester.checkIsolateNameContains('myIsolateName');
+  }
+}
+
+
+main() {
+  var process = new TestLauncher('isolate_stacktrace_command_script.dart');
+  process.launch().then((port) {
+    var test = new IsolateListTest(port);
+    test.makeRequest().then((_) {
+      var stacktraceTest = new StacktraceTest(port, test._isolateId);
+      stacktraceTest.makeRequest().then((_) {
+        process.requestExit();
+      });
+    });
+  });
+}
diff --git a/tests/standalone/vmservice/multiple_isolate_list_test.dart b/tests/standalone/vmservice/multiple_isolate_list_test.dart
index c3e9235..792ab3f 100644
--- a/tests/standalone/vmservice/multiple_isolate_list_test.dart
+++ b/tests/standalone/vmservice/multiple_isolate_list_test.dart
@@ -1,12 +1,6 @@
 // Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
-// VMOptions=--short_socket_read
-// VMOptions=--short_socket_write
-// VMOptions=--short_socket_read --short_socket_write
-//
-// Test:
-//   *) Connect to VM Service and obtain list of running isolates.
 
 library multiple_isolate_list_test;
 
diff --git a/tests/standalone/vmservice/test_helper.dart b/tests/standalone/vmservice/test_helper.dart
index 52d1983..7e95539 100644
--- a/tests/standalone/vmservice/test_helper.dart
+++ b/tests/standalone/vmservice/test_helper.dart
@@ -87,6 +87,7 @@
     String dartExecutable = Platform.executable;
     return Process.start(dartExecutable,
                          ['--enable-vm-service:0', scriptPath]).then((p) {
+
       Completer completer = new Completer();
       process = p;
       var portNumber;
@@ -108,17 +109,21 @@
           // Stop repeat completions.
           first = false;
         }
+        print(line);
       });
       process.stderr.transform(new StringDecoder())
                     .transform(new LineTransformer()).listen((line) {
+        print(line);
       });
-      process.exitCode.then((_) { });
+      process.exitCode.then((code) {
+        Expect.equals(0, code, 'Launched dart executable exited with error.');
+      });
       return completer.future;
     });
   }
 
   void requestExit() {
-    process.stdin.add([32]);
+    process.stdin.add([32, 13, 10]);
   }
 }
 
@@ -144,14 +149,17 @@
     Expect.isTrue(exists, 'No isolate with id: $id');
   }
 
-  void checkIsolateNameContains(String name) {
+  int checkIsolateNameContains(String name) {
     var exists = false;
+    int id;
     isolateList['members'].forEach((isolate) {
       if (isolate['name'].contains(name)) {
         exists = true;
+        id = isolate['id'];
       }
     });
     Expect.isTrue(exists, 'No isolate with name: $name');
+    return id;
   }
 
   void checkIsolateNamePrefix(int id, String name) {
diff --git a/tests/standalone/vmservice/unknown_command_script.dart b/tests/standalone/vmservice/unknown_command_script.dart
new file mode 100644
index 0000000..7751c89
--- /dev/null
+++ b/tests/standalone/vmservice/unknown_command_script.dart
@@ -0,0 +1,14 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library unknown_command_script;
+
+import 'dart:io';
+
+main() {
+  print(''); // Print blank line to signal that we are ready.
+
+  // Wait until signaled from spawning test.
+  stdin.first.then((_) => exit(0));
+}
diff --git a/tests/standalone/vmservice/unknown_command_test.dart b/tests/standalone/vmservice/unknown_command_test.dart
new file mode 100644
index 0000000..2ab54f8
--- /dev/null
+++ b/tests/standalone/vmservice/unknown_command_test.dart
@@ -0,0 +1,26 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library unknown_command_test;
+
+import 'test_helper.dart';
+import 'package:expect/expect.dart';
+
+class UnknownCommandTest extends VmServiceRequestHelper {
+  UnknownCommandTest(port) : super('http://127.0.0.1:$port/badcommand');
+
+  onRequestCompleted(Map reply) {
+    Expect.equals('error', reply['type']);
+  }
+}
+
+main() {
+  var process = new TestLauncher('unknown_command_script.dart');
+  process.launch().then((port) {
+    var test = new UnknownCommandTest(port);
+    test.makeRequest().then((_) {
+      process.requestExit();
+    });
+  });
+}
diff --git a/tests/standalone/vmservice/unknown_isolate_command_script.dart b/tests/standalone/vmservice/unknown_isolate_command_script.dart
new file mode 100644
index 0000000..e5870d3
--- /dev/null
+++ b/tests/standalone/vmservice/unknown_isolate_command_script.dart
@@ -0,0 +1,14 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library unknown_isolate_command_script;
+
+import 'dart:io';
+
+main() {
+  print(''); // Print blank line to signal that we are ready.
+
+  // Wait until signaled from spawning test.
+  stdin.first.then((_) => exit(0));
+}
diff --git a/tests/standalone/vmservice/unknown_isolate_command_test.dart b/tests/standalone/vmservice/unknown_isolate_command_test.dart
new file mode 100644
index 0000000..b6abf0b
--- /dev/null
+++ b/tests/standalone/vmservice/unknown_isolate_command_test.dart
@@ -0,0 +1,43 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library unknown_isolate_command_test;
+
+import 'test_helper.dart';
+import 'package:expect/expect.dart';
+
+class UnknownRequestTest extends VmServiceRequestHelper {
+  UnknownRequestTest(port, id) :
+      super('http://127.0.0.1:$port/isolates/$id/badrequest');
+
+  onRequestCompleted(Map reply) {
+    Expect.equals('error', reply['type']);
+  }
+}
+
+class IsolateListTest extends VmServiceRequestHelper {
+  IsolateListTest(port) : super('http://127.0.0.1:$port/isolates');
+
+  int _isolateId;
+  onRequestCompleted(Map reply) {
+    IsolateListTester tester = new IsolateListTester(reply);
+    tester.checkIsolateCount(1);
+    tester.checkIsolateNameContains('unknown_isolate_command_script.dart');
+    _isolateId = reply['members'][0]['id'];
+  }
+}
+
+
+main() {
+  var process = new TestLauncher('unknown_isolate_command_script.dart');
+  process.launch().then((port) {
+    var test = new IsolateListTest(port);
+    test.makeRequest().then((_) {
+      var unknownRequestTest = new UnknownRequestTest(port, test._isolateId);
+      unknownRequestTest.makeRequest().then((_) {
+        process.requestExit();
+      });
+    });
+  });
+}
diff --git a/tools/VERSION b/tools/VERSION
index 5c1426a..8a63454 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -1,4 +1,4 @@
 MAJOR 0
 MINOR 6
-BUILD 14
+BUILD 15
 PATCH 0
diff --git a/tools/bots/bot.py b/tools/bots/bot.py
index 92fec5c..993ff4f 100644
--- a/tools/bots/bot.py
+++ b/tools/bots/bot.py
@@ -25,7 +25,7 @@
   """
   Encapsulation of build information.
 
-  - compiler: None, 'dart2dart', 'dart2js' or 'dartc'.
+  - compiler: None, 'dart2dart' or 'dart2js'
   - runtime: 'd8', 'ie', 'ff', 'safari', 'chrome', 'opera', or None.
   - mode: 'debug' or 'release'.
   - system: 'linux', 'mac', or 'win7'.
diff --git a/compiler/scripts/dart_analyzer.sh b/tools/compiler_scripts/dart_analyzer.sh
old mode 100755
new mode 100644
similarity index 100%
rename from compiler/scripts/dart_analyzer.sh
rename to tools/compiler_scripts/dart_analyzer.sh
diff --git a/tools/compiler_scripts/generate_my_projects.py b/tools/compiler_scripts/generate_my_projects.py
new file mode 100644
index 0000000..cc41bf3
--- /dev/null
+++ b/tools/compiler_scripts/generate_my_projects.py
@@ -0,0 +1,52 @@
+#!/usr/bin/env python
+# Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+# for details. All rights reserved. Use of this source code is governed by a
+# BSD-style license that can be found in the LICENSE file.
+
+import os
+import sys
+
+
+def Main():
+  def normjoin(*args):
+    return os.path.normpath(os.path.join(*args))
+
+  dart_dir = normjoin(__file__, '..', '..', '..')
+  compiler_scripts = normjoin(dart_dir, 'tools', 'compiler_scripts')
+  editor = normjoin(dart_dir, 'editor')
+
+  locations = {
+    'compiler_scripts': compiler_scripts,
+    'editor': editor,
+  }
+
+  generate_source_list_calls = [
+    # The paths are relative to dart/editor/
+    {
+        "name" : "plugin_engine_java",
+        "output" : "%(editor)s/plugin_engine_sources" % locations,
+        "path" : "tools/plugins/com.google.dart.engine",
+    },
+    {
+        "name" : "plugin_command_analyze_java",
+        "output" : "%(editor)s/plugin_command_analyze_sources" % locations,
+        "path" : "tools/plugins/com.google.dart.command.analyze",
+    },
+  ]
+
+  for call_options in generate_source_list_calls:
+    command = (("python %(compiler_scripts)s/generate_source_list.py "
+                % locations) +
+               ("%(name)s %(output)s %(path)s" % call_options))
+    exit_code = os.system(command)
+    if exit_code:
+      return exit_code
+
+  if '--no-gyp' in sys.argv:
+    print '--no-gyp is deprecated.'
+
+  return 0
+
+
+if __name__ == '__main__':
+  sys.exit(Main())
diff --git a/compiler/generate_source_list.py b/tools/compiler_scripts/generate_source_list.py
similarity index 100%
rename from compiler/generate_source_list.py
rename to tools/compiler_scripts/generate_source_list.py
diff --git a/tools/dartc b/tools/dartc
deleted file mode 100644
index 19cc6bd..0000000
--- a/tools/dartc
+++ /dev/null
@@ -1,20 +0,0 @@
-#!/usr/bin/env python
-#
-# Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-# for details. All rights reserved. Use of this source code is governed by a
-# BSD-style license that can be found in the LICENSE file.
-
-import os
-import subprocess
-import sys
-
-import utils
-
-# Figure out the full path to the real dashc from the cwd.
-scriptPath = os.path.dirname(__file__)
-buildRoot = utils.GetBuildRoot(utils.GuessOS())
-dashcPath = os.path.join(scriptPath, "../compiler", buildRoot,
-    "Debug/ant-out/dist/bin/dashc")
-
-args = [dashcPath] + sys.argv[1:]
-sys.exit(subprocess.call(args))
diff --git a/tools/dom/docs/docs.status b/tools/dom/docs/docs.status
index 43d96f1..7cd95de 100644
--- a/tools/dom/docs/docs.status
+++ b/tools/dom/docs/docs.status
@@ -3,5 +3,5 @@
 # BSD-style license that can be found in the LICENSE file.
 
 # docs.dart is a tool that only runs on the VM
-[ $compiler == dart2js || $compiler == dart2dart || $compiler == dartc || $runtime == drt || $runtime == dartium ]
+[ $compiler == dart2js || $compiler == dart2dart || $runtime == drt || $runtime == dartium ]
 *: Skip
diff --git a/tools/dom/dom.py b/tools/dom/dom.py
index 54844a6..4e3240a 100755
--- a/tools/dom/dom.py
+++ b/tools/dom/dom.py
@@ -58,17 +58,6 @@
 def dart2js():
   compile_dart2js(argv.pop(0), True)
 
-def dartc():
-  return call([
-    os.path.join('tools', 'test.py'),
-    '-m',
-    'release',
-    '-c',
-    'dartc',
-    '-r',
-    'none'
-  ])
-
 def docs():
   return call([
     os.path.join(dart_out_dir, 'dart-sdk', 'bin', 'dart'),
@@ -176,7 +165,6 @@
   'analyze': [analyze, 'Run the dart analyzer'],
   'build': [build, 'Build dart in release mode'],
   'dart2js': [dart2js, 'Run dart2js on the .dart file specified'],
-  'dartc': [dartc, 'Runs dartc in release mode'],
   'docs': [docs, 'Generates docs.json'],
   'gen': [gen, 'Re-generate DOM generated files (run go.sh)'],
   'size_check': [size_check, 'Check the size of dart2js compiled Swarm'],
diff --git a/tools/dom/src/Point.dart b/tools/dom/src/Point.dart
index 366cae0..c5c1df8 100644
--- a/tools/dom/src/Point.dart
+++ b/tools/dom/src/Point.dart
@@ -35,6 +35,12 @@
   }
 
   /**
+   * Get the straight line (Euclidean) distance between the origin (0, 0) and
+   * this point.
+   */
+  num get magnitude => sqrt(x * x + y * y);
+
+  /**
    * Returns the distance between two points.
    */
   double distanceTo(Point other) {
diff --git a/tools/dom/src/native_DOMImplementation.dart b/tools/dom/src/native_DOMImplementation.dart
index eae77bd..ad04f3f 100644
--- a/tools/dom/src/native_DOMImplementation.dart
+++ b/tools/dom/src/native_DOMImplementation.dart
@@ -189,6 +189,8 @@
 
   static String addTrailingDot(String str) => '${str}.';
 
+  static bool isNoSuchMethodError(obj) => obj is NoSuchMethodError;
+
   // TODO(jacobr): we need a failsafe way to determine that a Node is really a
   // DOM node rather than just a class that extends Node.
   static bool isNode(obj) => obj is Node;
diff --git a/tools/test.dart b/tools/test.dart
index 787a1db..cd43215 100755
--- a/tools/test.dart
+++ b/tools/test.dart
@@ -36,7 +36,6 @@
 import "testing/dart/test_suite.dart";
 import "testing/dart/utils.dart";
 
-import "../compiler/tests/dartc/test_config.dart";
 import "../runtime/tests/vm/test_config.dart";
 import "../samples/tests/dartc/test_config.dart";
 import "../tests/co19/test_config.dart";
@@ -182,13 +181,6 @@
         // in [TEST_SUITE_DIRECTORIES]).
         testSuites.add(new VMTestSuite(conf));
       } else if (conf['analyzer']) {
-        if (key == 'dartc' && conf['compiler'] == 'dartc') {
-          testSuites.add(new JUnitDartcTestSuite(conf));
-        }
-        // TODO(devoncarew): get these running with the new analyzer
-        if (key == 'dartc' && conf['compiler'] == 'dartc') {
-          testSuites.add(new SamplesDartcTestSuite(conf));
-        }
         if (key == 'analyze_library') {
           testSuites.add(new AnalyzeLibraryTestSuite(conf));
         }
diff --git a/tools/testing/dart/co19_test.dart b/tools/testing/dart/co19_test.dart
index 9b38c59..547e4d0 100644
--- a/tools/testing/dart/co19_test.dart
+++ b/tools/testing/dart/co19_test.dart
@@ -30,7 +30,7 @@
 const List<List<String>> COMMAND_LINES = const <List<String>>[
     const <String>['-mrelease,debug', '-rvm', '-cnone'],
     const <String>['-mrelease,debug', '-rvm', '-cnone', '--checked'],
-    const <String>['-mrelease', '-rnone', '-cdartc'],
+    const <String>['-mrelease', '-rnone', '-cdartanalyzer'],
     const <String>['-mrelease', '-rvm', '-cdart2dart'],
     const <String>['-mrelease', '-rd8,jsshell', '-cdart2js', '--use-sdk'],
     const <String>['-mrelease', '-rd8', '-cdart2js', '--use-sdk', '--checked']];
diff --git a/tools/testing/dart/test_options.dart b/tools/testing/dart/test_options.dart
index cfb1c17..37a0411 100644
--- a/tools/testing/dart/test_options.dart
+++ b/tools/testing/dart/test_options.dart
@@ -10,7 +10,7 @@
 import "test_suite.dart";
 
 List<String> defaultTestSelectors =
-    const ['dartc', 'samples', 'standalone', 'corelib', 'co19', 'language',
+    const ['samples', 'standalone', 'corelib', 'co19', 'language',
            'isolate', 'vm', 'html', 'json', 'benchmark_smoke',
            'utils', 'lib', 'pkg', 'analyze_library', 'analyze_tests'];
 
@@ -77,14 +77,11 @@
          safari, ie9, ie10, firefox, opera, chromeOnAndroid,
          none (compile only)),
 
-   dartc: Perform static analysis on Dart code by running dartc.
-          (only valid with the following runtimes: none),
-
    dartanalyzer: Perform static analysis on Dart code by running the analyzer on Java.
    dart2analyzer: Perform static analysis on Dart code by running the analyzer on Dart.
           (only valid with the following runtimes: none)''',
               ['-c', '--compiler'],
-              ['none', 'dart2dart', 'dart2js', 'dartc', 'dartanalyzer', 'dart2analyzer'],
+              ['none', 'dart2dart', 'dart2js', 'dartanalyzer', 'dart2analyzer'],
               'none'),
           // TODO(antonm): fix the option drt.
           new _TestOptionSpecification(
@@ -104,8 +101,8 @@
     [ff | chrome | safari | ie9 | ie10 | opera | chromeOnAndroid]:
         Run JavaScript in the specified browser.
 
-    none: No runtime, compile only (for example, used for dartc static analysis
-          tests).''',
+    none: No runtime, compile only (for example, used for dartanalyzer static
+          analysis tests).''',
               ['-r', '--runtime'],
               ['vm', 'd8', 'jsshell', 'drt', 'dartium', 'ff', 'firefox',
                'chrome', 'safari', 'ie9', 'ie10', 'opera', 'chromeOnAndroid',
@@ -535,7 +532,6 @@
                                'ff', 'chrome', 'safari', 'ie9', 'ie10',
                                'opera', 'chromeOnAndroid'];
         break;
-      case 'dartc':
       case 'dartanalyzer':
       case 'dart2analyzer':
         validRuntimes = const ['none'];
@@ -685,7 +681,6 @@
     if (configuration['timeout'] == -1) {
       var timeout = 60;
       switch (configuration['compiler']) {
-        case 'dartc':
         case 'dartanalyzer':
         case 'dart2analyzer':
           timeout *= 4;
diff --git a/tools/testing/dart/test_suite.dart b/tools/testing/dart/test_suite.dart
index e4dfd50..5130abe 100644
--- a/tools/testing/dart/test_suite.dart
+++ b/tools/testing/dart/test_suite.dart
@@ -138,7 +138,6 @@
     }
     var name;
     switch (configuration['compiler']) {
-      case 'dartc':
       case 'dartanalyzer':
       case 'dart2analyzer':
         name = executablePath;
@@ -179,8 +178,6 @@
           return '$buildDir/dart-sdk/bin/dart$suffix';
         }
         return '$buildDir/dart$suffix';
-      case 'dartc':
-        return '$buildDir/analyzer/bin/dart_analyzer$suffix';
       case 'dartanalyzer':
         return 'sdk/bin/dartanalyzer_developer$suffix';
       case 'dart2analyzer':
@@ -807,7 +804,6 @@
       return commands;
 
     case 'none':
-    case 'dartc':
     case 'dartanalyzer':
     case 'dart2analyzer':
       var displayName = (configuration['compiler'] == 'none'
@@ -1193,7 +1189,6 @@
       case 'dart2js':
       case 'dartanalyzer':
       case 'dart2analyzer':
-      case 'dartc':
         return 'text/javascript';
       default:
         print('Non-web runtime, so no scriptType for: '
@@ -1872,7 +1867,7 @@
       const ['d8', 'jsshell'].contains(runtime);
 
   static bool isCommandLineAnalyzer(String compiler) =>
-      compiler == 'dartc' || compiler == 'dartanalyzer' || compiler == 'dart2analyzer';
+      compiler == 'dartanalyzer' || compiler == 'dart2analyzer';
 
   static String buildDir(Map configuration) {
     // FIXME(kustermann,ricow): Our code assumes that the returned 'buildDir'
