Version 1.8.0-dev.3.0

svn merge -r 41388:41500 https://dart.googlecode.com/svn/branches/bleeding_edge trunk

git-svn-id: http://dart.googlecode.com/svn/trunk@41515 260f80e4-7a28-3924-810f-c04153c831b5
diff --git a/pkg/analysis_server/doc/api.html b/pkg/analysis_server/doc/api.html
index 4b0c556..d029594 100644
--- a/pkg/analysis_server/doc/api.html
+++ b/pkg/analysis_server/doc/api.html
@@ -2106,7 +2106,29 @@
           in a completion suggestion.
         </p>
         
-      <dl><dt class="value">ARGUMENT_LIST</dt><dt class="value">CLASS</dt><dt class="value">CLASS_ALIAS</dt><dt class="value">CONSTRUCTOR</dt><dt class="value">FIELD</dt><dt class="value">FUNCTION</dt><dt class="value">FUNCTION_TYPE_ALIAS</dt><dt class="value">GETTER</dt><dt class="value">IMPORT</dt><dt class="value">KEYWORD</dt><dt class="value">LABEL</dt><dt class="value">LIBRARY_PREFIX</dt><dt class="value">LOCAL_VARIABLE</dt><dt class="value">METHOD</dt><dt class="value">METHOD_NAME</dt><dt class="value">NAMED_ARGUMENT</dt><dt class="value">OPTIONAL_ARGUMENT</dt><dt class="value">PARAMETER</dt><dt class="value">SETTER</dt><dt class="value">TOP_LEVEL_VARIABLE</dt><dt class="value">TYPE_PARAMETER</dt></dl></dd><dt class="typeDefinition"><a name="type_Element">Element: object</a></dt><dd>
+      <dl><dt class="value">ARGUMENT_LIST</dt><dt class="value">IMPORT</dt><dt class="value">IDENTIFIER</dt><dd>
+            
+            <p>
+              The element identifier should be inserted at the completion location.
+              For example "someMethod" in import 'myLib.dart' show someMethod; .
+              For suggestions of this kind, the element attribute is defined 
+              and the completion field is the element's identifier.
+            </p>
+          </dd><dt class="value">INVOCATION</dt><dd>
+            
+            <p>
+              The element is being invoked at the completion location.
+              For example, "someMethod" in x.someMethod(); .
+              For suggestions of this kind, the element attribute is defined 
+              and the completion field is the element's identifier.
+            </p>
+          </dd><dt class="value">KEYWORD</dt><dd>
+            
+            <p>
+              A keyword is being suggested.
+              For suggestions of this kind, the completion is the keyword.
+            </p>
+          </dd><dt class="value">NAMED_ARGUMENT</dt><dt class="value">OPTIONAL_ARGUMENT</dt><dt class="value">PARAMETER</dt></dl></dd><dt class="typeDefinition"><a name="type_Element">Element: object</a></dt><dd>
         <p>
           Information about an element (something that can be declared
           in code).
diff --git a/pkg/analysis_server/lib/src/analysis_logger.dart b/pkg/analysis_server/lib/src/analysis_logger.dart
index 8700cf3..477fb37 100644
--- a/pkg/analysis_server/lib/src/analysis_logger.dart
+++ b/pkg/analysis_server/lib/src/analysis_logger.dart
@@ -6,6 +6,7 @@
 
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:logging/logging.dart' as logging;
+import 'package:analyzer/src/generated/java_engine.dart';
 
 /**
  * Instances of the class [AnalysisLogger] translate from the analysis engine's
@@ -18,22 +19,30 @@
   final logging.Logger baseLogger = new logging.Logger('analysis.server');
 
   @override
-  void logError(String message) {
-    baseLogger.severe(message);
+  void logError(String message, [CaughtException exception]) {
+    if (exception == null) {
+      baseLogger.severe(message);
+    } else {
+      baseLogger.severe(message, exception.exception, exception.stackTrace);
+    }
   }
 
   @override
-  void logError2(String message, Exception exception) {
+  void logError2(String message, Object exception) {
     baseLogger.severe(message, exception);
   }
 
   @override
-  void logInformation(String message) {
-    baseLogger.info(message);
+  void logInformation(String message, [CaughtException exception]) {
+    if (exception == null) {
+      baseLogger.info(message);
+    } else {
+      baseLogger.info(message, exception.exception, exception.stackTrace);
+    }
   }
 
   @override
-  void logInformation2(String message, Exception exception) {
+  void logInformation2(String message, Object exception) {
     baseLogger.info(message, exception);
   }
 }
diff --git a/pkg/analysis_server/lib/src/analysis_server.dart b/pkg/analysis_server/lib/src/analysis_server.dart
index 2ad03fd..7abc951 100644
--- a/pkg/analysis_server/lib/src/analysis_server.dart
+++ b/pkg/analysis_server/lib/src/analysis_server.dart
@@ -435,8 +435,9 @@
           channel.sendResponse(exception.response);
           return;
         } catch (exception, stackTrace) {
-          RequestError error =
-              new RequestError(RequestErrorCode.SERVER_ERROR, exception);
+          RequestError error = new RequestError(
+              RequestErrorCode.SERVER_ERROR,
+              exception.toString());
           if (stackTrace != null) {
             error.stackTrace = stackTrace.toString();
           }
diff --git a/pkg/analysis_server/lib/src/channel/byte_stream_channel.dart b/pkg/analysis_server/lib/src/channel/byte_stream_channel.dart
index cc0274d..730f4ec 100644
--- a/pkg/analysis_server/lib/src/channel/byte_stream_channel.dart
+++ b/pkg/analysis_server/lib/src/channel/byte_stream_channel.dart
@@ -80,9 +80,11 @@
 
   @override
   void close() {
-    if (!_closed.isCompleted) {
-      _closed.complete();
-    }
+    output.flush().then((_) {
+      if (!_closed.isCompleted) {
+        _closed.complete();
+      }
+    });
   }
 
   @override
diff --git a/pkg/analysis_server/lib/src/computer/computer_navigation.dart b/pkg/analysis_server/lib/src/computer/computer_navigation.dart
index a21ec59..faf949d 100644
--- a/pkg/analysis_server/lib/src/computer/computer_navigation.dart
+++ b/pkg/analysis_server/lib/src/computer/computer_navigation.dart
@@ -163,29 +163,25 @@
     Element element = node.staticElement;
     ConstructorName constructorName = node.constructorName;
     if (element != null && constructorName != null) {
-      ClassElement classElement = element.enclosingElement;
+      // if a synthetic constructor, navigate to the class
       if (element.isSynthetic) {
+        ClassElement classElement = element.enclosingElement;
         element = classElement;
-        computer._addRegion_nodeStart_nodeStart(
-            node,
-            node.argumentList,
+      }
+      // "new ", excluding last character
+      computer._addRegion_nodeStart_nodeStart(
+          node,
+          constructorName.type,
+          element,
+          excludeLastChar: true);
+      // "ClassName<TypeA, TypeB>"
+      _safelyVisit(constructorName.type);
+      // optional ".name"
+      if (constructorName.period != null) {
+        computer._addRegion_tokenStart_nodeEnd(
+            constructorName.period,
+            constructorName,
             element);
-      } else {
-        // "new ", excluding last character
-        computer._addRegion_nodeStart_nodeStart(
-            node,
-            constructorName.type,
-            element,
-            excludeLastChar: true);
-        // "ClassName"
-        computer._addRegionForNode(constructorName.type, classElement);
-        // optional ".name"
-        if (constructorName.period != null) {
-          computer._addRegion_tokenStart_nodeEnd(
-              constructorName.period,
-              constructorName,
-              element);
-        }
       }
     }
     _safelyVisit(node.argumentList);
diff --git a/pkg/analysis_server/lib/src/context_manager.dart b/pkg/analysis_server/lib/src/context_manager.dart
index 2447fcd..6f815d1 100644
--- a/pkg/analysis_server/lib/src/context_manager.dart
+++ b/pkg/analysis_server/lib/src/context_manager.dart
@@ -239,20 +239,23 @@
     List<Resource> children = folder.getChildren();
     for (Resource child in children) {
       String path = child.path;
-      // ignore if wasn't previously excluded
-      bool wasExcluded =
-          _isExcludedBy(oldExcludedPaths, path) &&
-          !_isExcludedBy(excludedPaths, path);
-      if (!wasExcluded) {
-        continue;
-      }
       // add files, recurse into folders
       if (child is File) {
-        if (_shouldFileBeAnalyzed(child)) {
-          Source source = child.createSource();
-          changeSet.addedSource(source);
-          info.sources[path] = source;
+        // ignore if should not be analyzed at all
+        if (!_shouldFileBeAnalyzed(child)) {
+          continue;
         }
+        // ignore if was not excluded
+        bool wasExcluded =
+            _isExcludedBy(oldExcludedPaths, path) &&
+            !_isExcludedBy(excludedPaths, path);
+        if (!wasExcluded) {
+          continue;
+        }
+        // do add the file
+        Source source = child.createSource();
+        changeSet.addedSource(source);
+        info.sources[path] = source;
       } else if (child is Folder) {
         if (child.shortName == PACKAGES_NAME) {
           continue;
diff --git a/pkg/analysis_server/lib/src/generated_protocol.dart b/pkg/analysis_server/lib/src/generated_protocol.dart
index ccc138d..87020a8 100644
--- a/pkg/analysis_server/lib/src/generated_protocol.dart
+++ b/pkg/analysis_server/lib/src/generated_protocol.dart
@@ -5561,71 +5561,48 @@
  *
  * enum {
  *   ARGUMENT_LIST
- *   CLASS
- *   CLASS_ALIAS
- *   CONSTRUCTOR
- *   FIELD
- *   FUNCTION
- *   FUNCTION_TYPE_ALIAS
- *   GETTER
  *   IMPORT
+ *   IDENTIFIER
+ *   INVOCATION
  *   KEYWORD
- *   LABEL
- *   LIBRARY_PREFIX
- *   LOCAL_VARIABLE
- *   METHOD
- *   METHOD_NAME
  *   NAMED_ARGUMENT
  *   OPTIONAL_ARGUMENT
  *   PARAMETER
- *   SETTER
- *   TOP_LEVEL_VARIABLE
- *   TYPE_PARAMETER
  * }
  */
 class CompletionSuggestionKind implements Enum {
   static const ARGUMENT_LIST = const CompletionSuggestionKind._("ARGUMENT_LIST");
 
-  static const CLASS = const CompletionSuggestionKind._("CLASS");
-
-  static const CLASS_ALIAS = const CompletionSuggestionKind._("CLASS_ALIAS");
-
-  static const CONSTRUCTOR = const CompletionSuggestionKind._("CONSTRUCTOR");
-
-  static const FIELD = const CompletionSuggestionKind._("FIELD");
-
-  static const FUNCTION = const CompletionSuggestionKind._("FUNCTION");
-
-  static const FUNCTION_TYPE_ALIAS = const CompletionSuggestionKind._("FUNCTION_TYPE_ALIAS");
-
-  static const GETTER = const CompletionSuggestionKind._("GETTER");
-
   static const IMPORT = const CompletionSuggestionKind._("IMPORT");
 
+  /**
+   * The element identifier should be inserted at the completion location. For
+   * example "someMethod" in import 'myLib.dart' show someMethod; . For
+   * suggestions of this kind, the element attribute is defined and the
+   * completion field is the element's identifier.
+   */
+  static const IDENTIFIER = const CompletionSuggestionKind._("IDENTIFIER");
+
+  /**
+   * The element is being invoked at the completion location. For example,
+   * "someMethod" in x.someMethod(); . For suggestions of this kind, the
+   * element attribute is defined and the completion field is the element's
+   * identifier.
+   */
+  static const INVOCATION = const CompletionSuggestionKind._("INVOCATION");
+
+  /**
+   * A keyword is being suggested. For suggestions of this kind, the completion
+   * is the keyword.
+   */
   static const KEYWORD = const CompletionSuggestionKind._("KEYWORD");
 
-  static const LABEL = const CompletionSuggestionKind._("LABEL");
-
-  static const LIBRARY_PREFIX = const CompletionSuggestionKind._("LIBRARY_PREFIX");
-
-  static const LOCAL_VARIABLE = const CompletionSuggestionKind._("LOCAL_VARIABLE");
-
-  static const METHOD = const CompletionSuggestionKind._("METHOD");
-
-  static const METHOD_NAME = const CompletionSuggestionKind._("METHOD_NAME");
-
   static const NAMED_ARGUMENT = const CompletionSuggestionKind._("NAMED_ARGUMENT");
 
   static const OPTIONAL_ARGUMENT = const CompletionSuggestionKind._("OPTIONAL_ARGUMENT");
 
   static const PARAMETER = const CompletionSuggestionKind._("PARAMETER");
 
-  static const SETTER = const CompletionSuggestionKind._("SETTER");
-
-  static const TOP_LEVEL_VARIABLE = const CompletionSuggestionKind._("TOP_LEVEL_VARIABLE");
-
-  static const TYPE_PARAMETER = const CompletionSuggestionKind._("TYPE_PARAMETER");
-
   final String name;
 
   const CompletionSuggestionKind._(this.name);
@@ -5634,46 +5611,20 @@
     switch (name) {
       case "ARGUMENT_LIST":
         return ARGUMENT_LIST;
-      case "CLASS":
-        return CLASS;
-      case "CLASS_ALIAS":
-        return CLASS_ALIAS;
-      case "CONSTRUCTOR":
-        return CONSTRUCTOR;
-      case "FIELD":
-        return FIELD;
-      case "FUNCTION":
-        return FUNCTION;
-      case "FUNCTION_TYPE_ALIAS":
-        return FUNCTION_TYPE_ALIAS;
-      case "GETTER":
-        return GETTER;
       case "IMPORT":
         return IMPORT;
+      case "IDENTIFIER":
+        return IDENTIFIER;
+      case "INVOCATION":
+        return INVOCATION;
       case "KEYWORD":
         return KEYWORD;
-      case "LABEL":
-        return LABEL;
-      case "LIBRARY_PREFIX":
-        return LIBRARY_PREFIX;
-      case "LOCAL_VARIABLE":
-        return LOCAL_VARIABLE;
-      case "METHOD":
-        return METHOD;
-      case "METHOD_NAME":
-        return METHOD_NAME;
       case "NAMED_ARGUMENT":
         return NAMED_ARGUMENT;
       case "OPTIONAL_ARGUMENT":
         return OPTIONAL_ARGUMENT;
       case "PARAMETER":
         return PARAMETER;
-      case "SETTER":
-        return SETTER;
-      case "TOP_LEVEL_VARIABLE":
-        return TOP_LEVEL_VARIABLE;
-      case "TYPE_PARAMETER":
-        return TYPE_PARAMETER;
     }
     throw new Exception('Illegal enum value: $name');
   }
diff --git a/pkg/analysis_server/lib/src/get_handler.dart b/pkg/analysis_server/lib/src/get_handler.dart
index 91fe13b..f9b26b1 100644
--- a/pkg/analysis_server/lib/src/get_handler.dart
+++ b/pkg/analysis_server/lib/src/get_handler.dart
@@ -6,11 +6,15 @@
 
 import 'dart:convert';
 import 'dart:io';
+import 'dart:math';
 
+import 'package:analysis_server/src/analysis_server.dart';
 import 'package:analysis_server/src/socket_server.dart';
 import 'package:analyzer/file_system/file_system.dart';
+import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/java_engine.dart';
+import 'analysis_server.dart';
 
 /**
  * Instances of the class [GetHandler] handle GET requests.
@@ -22,6 +26,30 @@
   static const String STATUS_PATH = '/status';
 
   /**
+   * The path used to request the list of source files in a certain cache
+   * state.
+   */
+  static const String CACHE_STATE_PATH = '/cache_state';
+
+  /**
+   * Query parameter used to represent the cache state to search for, when
+   * accessing [CACHE_STATE_PATH].
+   */
+  static const String STATE_QUERY_PARAM = 'state';
+
+  /**
+   * Query parameter used to represent the context to search for, when
+   * accessing [CACHE_STATE_PATH].
+   */
+  static const String CONTEXT_QUERY_PARAM = 'context';
+
+  /**
+   * Query parameter used to represent the descriptor to search for, when
+   * accessing [CACHE_STATE_PATH].
+   */
+  static const String DESCRIPTOR_QUERY_PARAM = 'descriptor';
+
+  /**
    * The socket server whose status is to be reported on.
    */
   SocketServer _server;
@@ -43,12 +71,100 @@
     String path = request.uri.path;
     if (path == STATUS_PATH) {
       _returnServerStatus(request);
+    } else if (path == CACHE_STATE_PATH) {
+      _returnCacheState(request);
     } else {
       _returnUnknownRequest(request);
     }
   }
 
   /**
+   * Create a link to [path] with query parameters [params], with inner HTML
+   * [innerHtml].
+   */
+  String _makeLink(String path, Map<String, String> params, String innerHtml) {
+    Uri uri = new Uri(path: path, queryParameters: params);
+    return '<a href="${HTML_ESCAPE.convert(uri.toString())}">$innerHtml</a>';
+  }
+
+  /**
+   * Return a response indicating the set of source files in a certain cache
+   * state.
+   */
+  void _returnCacheState(HttpRequest request) {
+    // Figure out what CacheState is being searched for.
+    String stateQueryParam = request.uri.queryParameters[STATE_QUERY_PARAM];
+    if (stateQueryParam == null) {
+      return _returnFailure(request,
+          'Query parameter $STATE_QUERY_PARAM required');
+    }
+    CacheState stateFilter = null;
+    for (CacheState value in CacheState.values) {
+      if (value.toString() == stateQueryParam) {
+        stateFilter = value;
+      }
+    }
+    if (stateFilter == null) {
+      return _returnFailure(request,
+          'Query parameter $STATE_QUERY_PARAM is invalid');
+    }
+
+    // Figure out which context is being searched for.
+    String contextFilter = request.uri.queryParameters[CONTEXT_QUERY_PARAM];
+    if (contextFilter == null) {
+      return _returnFailure(request,
+          'Query parameter $CONTEXT_QUERY_PARAM required');
+    }
+
+    // Figure out which descriptor is being searched for.
+    String descriptorFilter =
+        request.uri.queryParameters[DESCRIPTOR_QUERY_PARAM];
+    if (descriptorFilter == null) {
+      return _returnFailure(request,
+          'Query parameter $DESCRIPTOR_QUERY_PARAM required');
+    }
+
+    AnalysisServer analysisServer = _server.analysisServer;
+    if (analysisServer == null) {
+      return _returnFailure(request, 'Analysis server not running');
+    }
+    HttpResponse response = request.response;
+    response.statusCode = HttpStatus.OK;
+    response.headers.add(HttpHeaders.CONTENT_TYPE, "text/html");
+    response.write('<html>');
+    response.write('<head>');
+    response.write('<title>Dart Analysis Server - Search result</title>');
+    response.write('</head>');
+    response.write('<body>');
+    response.write('<h1>');
+    response.write('Files with state ${HTML_ESCAPE.convert(stateQueryParam)}');
+    response.write(' for descriptor ${HTML_ESCAPE.convert(descriptorFilter)}');
+    response.write(' in context ${HTML_ESCAPE.convert(contextFilter)}');
+    response.write('</h1>');
+    response.write('<ul>');
+    int count = 0;
+    analysisServer.folderMap.forEach((Folder folder,
+                                      AnalysisContextImpl context) {
+      if (folder.path != contextFilter) {
+        return;
+      }
+      context.visitCacheItems((Source source, SourceEntry dartEntry,
+                               DataDescriptor rowDesc, CacheState state) {
+        if (state != stateFilter || rowDesc.toString() != descriptorFilter) {
+          return;
+        }
+        response.write('<li>${HTML_ESCAPE.convert(source.fullName)}</li>');
+        count++;
+      });
+    });
+    response.write('</ul>');
+    response.write('<p>$count files found</p>');
+    response.write('</body>');
+    response.write('</html>');
+    response.close();
+  }
+
+  /**
    * Return a response indicating the status of the analysis server.
    */
   void _returnServerStatus(HttpRequest request) {
@@ -58,62 +174,70 @@
     response.write('<html>');
     response.write('<head>');
     response.write('<title>Dart Analysis Server - Status</title>');
+    response.write('<style>');
+    response.write('td.right {text-align: right;}');
+    response.write('</style>');
     response.write('</head>');
     response.write('<body>');
     response.write('<h1>Analysis Server</h1>');
-    if (_server.analysisServer == null) {
+    AnalysisServer analysisServer = _server.analysisServer;
+    if (analysisServer == null) {
       response.write('<p>Not running</p>');
     } else {
-      response.write('<p>Running</p>');
+      if (analysisServer.statusAnalyzing) {
+        response.write('<p>Running (analyzing)</p>');
+      } else {
+        response.write('<p>Running (not analyzing)</p>');
+      }
       response.write('<h1>Analysis Contexts</h1>');
       response.write('<h2>Summary</h2>');
       response.write('<table>');
-      _writeRow(
-          response,
-          ['Context', 'ERROR', 'FLUSHED', 'IN_PROCESS', 'INVALID', 'VALID'],
-          true);
-      _server.analysisServer.folderMap.forEach((Folder folder, AnalysisContextImpl context) {
+      List headerRowText = ['Context'];
+      headerRowText.addAll(CacheState.values);
+      _writeRow(response, headerRowText, header: true);
+      Map<Folder, AnalysisContext> folderMap = analysisServer.folderMap;
+      List<Folder> folders = folderMap.keys.toList();
+      folders.sort((Folder first, Folder second)
+          => first.shortName.compareTo(second.shortName));
+      folders.forEach((Folder folder) {
+        AnalysisContextImpl context = folderMap[folder];
         String key = folder.shortName;
         AnalysisContextStatistics statistics = context.statistics;
-        int errorCount = 0;
-        int flushedCount = 0;
-        int inProcessCount = 0;
-        int invalidCount = 0;
-        int validCount = 0;
+        Map<CacheState, int> totals = <CacheState, int>{};
+        for (CacheState state in CacheState.values) {
+          totals[state] = 0;
+        }
         statistics.cacheRows.forEach((AnalysisContextStatistics_CacheRow row) {
-          errorCount += row.errorCount;
-          flushedCount += row.flushedCount;
-          inProcessCount += row.inProcessCount;
-          invalidCount += row.invalidCount;
-          validCount += row.validCount;
+          for (CacheState state in CacheState.values) {
+            totals[state] += row.getCount(state);
+          }
         });
-        _writeRow(response, [
-            '<a href="#context_${HTML_ESCAPE.convert(key)}">$key</a>',
-            errorCount,
-            flushedCount,
-            inProcessCount,
-            invalidCount,
-            validCount]);
+        List rowText = ['<a href="#context_${HTML_ESCAPE.convert(key)}">$key</a>'];
+        for (CacheState state in CacheState.values) {
+          rowText.add(totals[state]);
+        }
+        _writeRow(response, rowText, classes: [null, "right"]);
       });
       response.write('</table>');
-      _server.analysisServer.folderMap.forEach((Folder folder, AnalysisContextImpl context) {
+      folders.forEach((Folder folder) {
+        AnalysisContextImpl context = folderMap[folder];
         String key = folder.shortName;
         response.write('<h2><a name="context_${HTML_ESCAPE.convert(key)}">Analysis Context: $key</a></h2>');
         AnalysisContextStatistics statistics = context.statistics;
         response.write('<table>');
-        _writeRow(
-            response,
-            ['Item', 'ERROR', 'FLUSHED', 'IN_PROCESS', 'INVALID', 'VALID'],
-            true);
+        _writeRow(response, headerRowText, header: true);
         statistics.cacheRows.forEach((AnalysisContextStatistics_CacheRow row) {
-          _writeRow(
-              response,
-              [row.name,
-               row.errorCount,
-               row.flushedCount,
-               row.inProcessCount,
-               row.invalidCount,
-               row.validCount]);
+          List rowText = [row.name];
+          for (CacheState state in CacheState.values) {
+            String text = row.getCount(state).toString();
+            Map<String, String> params = <String, String>{
+              STATE_QUERY_PARAM: state.toString(),
+              CONTEXT_QUERY_PARAM: folder.path,
+              DESCRIPTOR_QUERY_PARAM: row.name
+            };
+            rowText.add(_makeLink(CACHE_STATE_PATH, params, text));
+          }
+          _writeRow(response, rowText, classes: [null, "right"]);
         });
         response.write('</table>');
         List<CaughtException> exceptions = statistics.exceptions;
@@ -146,26 +270,51 @@
     response.close();
   }
 
+  void _returnFailure(HttpRequest request, String message) {
+    HttpResponse response = request.response;
+    response.statusCode = HttpStatus.OK;
+    response.headers.add(HttpHeaders.CONTENT_TYPE, "text/html");
+    response.write('<html>');
+    response.write('<head>');
+    response.write('<title>Dart Analysis Server - Failure</title>');
+    response.write('</head>');
+    response.write('<body>');
+    response.write(HTML_ESCAPE.convert(message));
+    response.write('</body>');
+    response.write('</html>');
+    response.close();
+  }
+
   /**
    * Write a single row within a table to the given [response] object. The row
    * will have one cell for each of the [columns], and will be a header row if
    * [header] is `true`.
    */
-  void _writeRow(HttpResponse response, List<Object> columns, [bool header = false]) {
+  void _writeRow(HttpResponse response, List<Object> columns,
+        {bool header : false, List<String> classes}) {
     response.write('<tr>');
-    columns.forEach((Object value) {
-      if (header) {
-        response.write('<th>');
-      } else {
-        response.write('<td>');
+    int count = columns.length;
+    int maxClassIndex = classes == null ? 0 : classes.length - 1;
+    for (int i = 0; i < count; i++) {
+      String classAttribute = '';
+      if (classes != null) {
+        String className = classes[min(i, maxClassIndex)];
+        if (className != null) {
+          classAttribute = ' class="$className"';
+        }
       }
-      response.write(value);
+      if (header) {
+        response.write('<th$classAttribute>');
+      } else {
+        response.write('<td$classAttribute>');
+      }
+      response.write(columns[i]);
       if (header) {
         response.write('</th>');
       } else {
         response.write('</td>');
       }
-    });
+    };
     response.write('</tr>');
   }
 }
\ No newline at end of file
diff --git a/pkg/analysis_server/lib/src/protocol_server.dart b/pkg/analysis_server/lib/src/protocol_server.dart
index c97e96c..971e527 100644
--- a/pkg/analysis_server/lib/src/protocol_server.dart
+++ b/pkg/analysis_server/lib/src/protocol_server.dart
@@ -89,61 +89,6 @@
 
 
 /**
- * Construct from an analyzer engine element kind.
- */
-CompletionSuggestionKind
-    newCompletionSuggestionKind_fromElementKind(engine.ElementKind kind) {
-  //    ElementKind.ANGULAR_FORMATTER,
-  //    ElementKind.ANGULAR_COMPONENT,
-  //    ElementKind.ANGULAR_CONTROLLER,
-  //    ElementKind.ANGULAR_DIRECTIVE,
-  //    ElementKind.ANGULAR_PROPERTY,
-  //    ElementKind.ANGULAR_SCOPE_PROPERTY,
-  //    ElementKind.ANGULAR_SELECTOR,
-  //    ElementKind.ANGULAR_VIEW,
-  if (kind == engine.ElementKind.CLASS) return CompletionSuggestionKind.CLASS;
-  //    ElementKind.COMPILATION_UNIT,
-  if (kind ==
-      engine.ElementKind.CONSTRUCTOR) return CompletionSuggestionKind.CONSTRUCTOR;
-  //    ElementKind.DYNAMIC,
-  //    ElementKind.EMBEDDED_HTML_SCRIPT,
-  //    ElementKind.ERROR,
-  //    ElementKind.EXPORT,
-  //    ElementKind.EXTERNAL_HTML_SCRIPT,
-  if (kind == engine.ElementKind.FIELD) return CompletionSuggestionKind.FIELD;
-  if (kind ==
-      engine.ElementKind.FUNCTION) return CompletionSuggestionKind.FUNCTION;
-  if (kind ==
-      engine.ElementKind.FUNCTION_TYPE_ALIAS) return
-          CompletionSuggestionKind.FUNCTION_TYPE_ALIAS;
-  if (kind == engine.ElementKind.GETTER) return CompletionSuggestionKind.GETTER;
-  //    ElementKind.HTML,
-  if (kind == engine.ElementKind.IMPORT) return CompletionSuggestionKind.IMPORT;
-  //    ElementKind.LABEL,
-  //    ElementKind.LIBRARY,
-  if (kind ==
-      engine.ElementKind.LOCAL_VARIABLE) return
-          CompletionSuggestionKind.LOCAL_VARIABLE;
-  if (kind == engine.ElementKind.METHOD) return CompletionSuggestionKind.METHOD;
-  //    ElementKind.NAME,
-  if (kind ==
-      engine.ElementKind.PARAMETER) return CompletionSuggestionKind.PARAMETER;
-  //    ElementKind.POLYMER_ATTRIBUTE,
-  //    ElementKind.POLYMER_TAG_DART,
-  //    ElementKind.POLYMER_TAG_HTML,
-  //    ElementKind.PREFIX,
-  if (kind == engine.ElementKind.SETTER) return CompletionSuggestionKind.SETTER;
-  if (kind ==
-      engine.ElementKind.TOP_LEVEL_VARIABLE) return
-          CompletionSuggestionKind.TOP_LEVEL_VARIABLE;
-  //    ElementKind.TYPE_PARAMETER,
-  //    ElementKind.UNIVERSE
-  throw new ArgumentError('Unknown CompletionSuggestionKind for: $kind');
-}
-
-
-
-/**
  * Construct based on a value from the analyzer engine.
  */
 ElementKind newElementKind_fromEngine(engine.ElementKind kind) {
diff --git a/pkg/analysis_server/lib/src/services/completion/combinator_computer.dart b/pkg/analysis_server/lib/src/services/completion/combinator_computer.dart
new file mode 100644
index 0000000..d2ae886
--- /dev/null
+++ b/pkg/analysis_server/lib/src/services/completion/combinator_computer.dart
@@ -0,0 +1,70 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for 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 services.completion.computer.dart.combinator;
+
+import 'dart:async';
+
+import 'package:analysis_server/src/protocol_server.dart' hide Element,
+    ElementKind;
+import 'package:analysis_server/src/services/completion/dart_completion_manager.dart';
+import 'package:analysis_server/src/services/completion/suggestion_builder.dart';
+import 'package:analyzer/src/generated/ast.dart';
+import 'package:analyzer/src/generated/element.dart';
+
+/**
+ * A computer for calculating `completion.getSuggestions` request results
+ * for the import combinators show and hide.
+ */
+
+class CombinatorComputer extends DartCompletionComputer {
+
+  @override
+  bool computeFast(DartCompletionRequest request) {
+    return false;
+  }
+
+  @override
+  Future<bool> computeFull(DartCompletionRequest request) {
+    return request.node.accept(new _CombinatorAstVisitor(request));
+  }
+}
+
+/**
+ * A visitor for determining which imported classes and top level variables
+ * should be suggested and building those suggestions.
+ */
+class _CombinatorAstVisitor extends GeneralizingAstVisitor<Future<bool>> {
+  final DartCompletionRequest request;
+
+  _CombinatorAstVisitor(this.request);
+
+  @override
+  Future<bool> visitCombinator(Combinator node) {
+    return _addCombinatorSuggestions(node);
+  }
+
+  @override
+  Future<bool> visitNode(AstNode node) {
+    return new Future.value(false);
+  }
+
+  @override
+  Future<bool> visitSimpleIdentifier(SimpleIdentifier node) {
+    return node.parent.accept(this);
+  }
+
+  Future _addCombinatorSuggestions(Combinator node) {
+    var directive = node.getAncestor((parent) => parent is NamespaceDirective);
+    if (directive is NamespaceDirective) {
+      LibraryElement library = directive.uriElement;
+      LibraryElementSuggestionBuilder.suggestionsFor(
+          request,
+          CompletionSuggestionKind.IDENTIFIER,
+          library);
+      return new Future.value(true);
+    }
+    return new Future.value(false);
+  }
+}
\ No newline at end of file
diff --git a/pkg/analysis_server/lib/src/services/completion/dart_completion_manager.dart b/pkg/analysis_server/lib/src/services/completion/dart_completion_manager.dart
index e96fccb..d30a83a 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart_completion_manager.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart_completion_manager.dart
@@ -7,6 +7,7 @@
 import 'dart:async';
 
 import 'package:analysis_server/src/protocol.dart';
+import 'package:analysis_server/src/services/completion/combinator_computer.dart';
 import 'package:analysis_server/src/services/completion/completion_manager.dart';
 import 'package:analysis_server/src/services/completion/imported_computer.dart';
 import 'package:analysis_server/src/services/completion/invocation_computer.dart';
@@ -93,7 +94,7 @@
       int count = computers.length;
       computers.forEach((c) {
         c.computeFull(request).then((bool changed) {
-          var last = --count == 0;
+          bool last = --count == 0;
           if (changed || last) {
             sendResults(last);
           }
@@ -110,6 +111,7 @@
       computers = [
           new KeywordComputer(),
           new LocalComputer(),
+          new CombinatorComputer(),
           new ImportedComputer(),
           new InvocationComputer()];
     }
diff --git a/pkg/analysis_server/lib/src/services/completion/imported_computer.dart b/pkg/analysis_server/lib/src/services/completion/imported_computer.dart
index 2cfbc81..73f972b 100644
--- a/pkg/analysis_server/lib/src/services/completion/imported_computer.dart
+++ b/pkg/analysis_server/lib/src/services/completion/imported_computer.dart
@@ -39,7 +39,7 @@
 }
 
 /**
- * A visitor for determining which imported class and top level variable
+ * A visitor for determining which imported classes and top level variables
  * should be suggested and building those suggestions.
  */
 class _ImportedVisitor extends GeneralizingAstVisitor<Future<bool>> {
@@ -79,11 +79,6 @@
   }
 
   @override
-  Future<bool> visitCombinator(Combinator node) {
-    return _addCombinatorSuggestions(node);
-  }
-
-  @override
   Future<bool> visitExpression(Expression node) {
     return _addImportedElementSuggestions(node, excludeVoidReturn: true);
   }
@@ -100,9 +95,21 @@
   }
 
   @override
+  Future<bool> visitFormalParameterList(FormalParameterList node) {
+    Token leftParen = node.leftParenthesis;
+    if (leftParen != null && request.offset > leftParen.offset) {
+      Token rightParen = node.rightParenthesis;
+      if (rightParen == null || request.offset <= rightParen.offset) {
+        return _addImportedElementSuggestions(node);
+      }
+    }
+    return new Future.value(false);
+  }
+
+  @override
   Future<bool> visitForStatement(ForStatement node) {
-    Token leftParenthesis = node.leftParenthesis;
-    if (leftParenthesis != null && request.offset >= leftParenthesis.end) {
+    Token leftParen = node.leftParenthesis;
+    if (leftParen != null && request.offset >= leftParen.end) {
       return _addImportedElementSuggestions(node);
     }
     return new Future.value(false);
@@ -190,17 +197,6 @@
     return new Future.value(false);
   }
 
-  Future _addCombinatorSuggestions(Combinator node) {
-    var directive = node.getAncestor((parent) => parent is NamespaceDirective);
-    if (directive is NamespaceDirective) {
-      LibraryElement library = directive.uriElement;
-      LibraryElementSuggestionBuilder.suggestionsFor(request, library);
-      return new Future.value(true);
-    }
-
-    return new Future.value(false);
-  }
-
   void _addElementSuggestion(Element element, bool typesOnly,
       bool excludeVoidReturn, CompletionRelevance relevance) {
 
@@ -219,13 +215,10 @@
       return;
     }
 
-    CompletionSuggestionKind kind =
-        newCompletionSuggestionKind_fromElementKind(element.kind);
-
     String completion = element.displayName;
     CompletionSuggestion suggestion = new CompletionSuggestion(
-        kind,
-        relevance,
+        CompletionSuggestionKind.INVOCATION,
+        element.isDeprecated ? CompletionRelevance.LOW : relevance,
         completion,
         completion.length,
         0,
@@ -381,7 +374,7 @@
     String completion = importElem.prefix.displayName;
     if (completion != null && completion.length > 0) {
       CompletionSuggestion suggestion = new CompletionSuggestion(
-          CompletionSuggestionKind.LIBRARY_PREFIX,
+          CompletionSuggestionKind.INVOCATION,
           CompletionRelevance.DEFAULT,
           completion,
           completion.length,
diff --git a/pkg/analysis_server/lib/src/services/completion/invocation_computer.dart b/pkg/analysis_server/lib/src/services/completion/invocation_computer.dart
index 3669bd4..9b91205 100644
--- a/pkg/analysis_server/lib/src/services/completion/invocation_computer.dart
+++ b/pkg/analysis_server/lib/src/services/completion/invocation_computer.dart
@@ -12,6 +12,8 @@
 import 'package:analyzer/src/generated/element.dart';
 import 'package:analyzer/src/generated/scanner.dart';
 
+import '../../protocol_server.dart' show CompletionSuggestionKind;
+
 /**
  * A computer for calculating invocation / access suggestions
  * `completion.getSuggestions` request results.
@@ -140,7 +142,10 @@
     if (element != null) {
       InterfaceType type = element.type;
       if (type != null) {
-        ClassElementSuggestionBuilder.staticSuggestionsFor(request, type.element);
+        ClassElementSuggestionBuilder.suggestionsFor(
+            request,
+            type.element,
+            staticOnly: true);
       }
     }
     return new Future.value(false);
@@ -163,7 +168,10 @@
           if (directive.prefix.name == element.name) {
             // Suggest elements from the imported library
             LibraryElement library = directive.uriElement;
-            LibraryElementSuggestionBuilder.suggestionsFor(request, library);
+            LibraryElementSuggestionBuilder.suggestionsFor(
+                request,
+                CompletionSuggestionKind.INVOCATION,
+                library);
             modified = true;
           }
         }
diff --git a/pkg/analysis_server/lib/src/services/completion/local_computer.dart b/pkg/analysis_server/lib/src/services/completion/local_computer.dart
index 8e0ba88..82d34ff 100644
--- a/pkg/analysis_server/lib/src/services/completion/local_computer.dart
+++ b/pkg/analysis_server/lib/src/services/completion/local_computer.dart
@@ -133,11 +133,9 @@
       } else if (declaration is TopLevelVariableDeclaration) {
         _addTopLevelVarSuggestions(declaration.variables);
       } else if (declaration is ClassTypeAlias) {
-        CompletionSuggestion suggestion = _addSuggestion(
-            declaration.name,
-            CompletionSuggestionKind.CLASS_ALIAS,
-            null,
-            null);
+        bool isDeprecated = _isDeprecated(declaration);
+        CompletionSuggestion suggestion =
+            _addSuggestion(declaration.name, null, null, isDeprecated);
         if (suggestion != null) {
           suggestion.element = _createElement(
               protocol.ElementKind.CLASS_TYPE_ALIAS,
@@ -145,22 +143,21 @@
               null,
               NO_RETURN_TYPE,
               true,
-              _isDeprecated(declaration.metadata));
+              isDeprecated);
         }
       } else if (declaration is FunctionTypeAlias) {
-        CompletionSuggestion suggestion = _addSuggestion(
-            declaration.name,
-            CompletionSuggestionKind.FUNCTION_TYPE_ALIAS,
-            declaration.returnType,
-            null);
+        bool isDeprecated = _isDeprecated(declaration);
+        CompletionSuggestion suggestion =
+            _addSuggestion(declaration.name, declaration.returnType, null, isDeprecated);
         if (suggestion != null) {
+          // TODO (danrubel) determine parameters and return type
           suggestion.element = _createElement(
               protocol.ElementKind.FUNCTION_TYPE_ALIAS,
               declaration.name,
-              null, // TODO (danrubel) determine parameters
-              NO_RETURN_TYPE, // TODO (danrubel) determine return type
+              null,
+              NO_RETURN_TYPE,
               true,
-              _isDeprecated(declaration.metadata));
+              isDeprecated);
         }
       }
     });
@@ -308,8 +305,9 @@
   }
 
   void _addClassSuggestion(ClassDeclaration declaration) {
+    bool isDeprecated = _isDeprecated(declaration);
     CompletionSuggestion suggestion =
-        _addSuggestion(declaration.name, CompletionSuggestionKind.CLASS, null, null);
+        _addSuggestion(declaration.name, null, null, isDeprecated);
     if (suggestion != null) {
       suggestion.element = _createElement(
           protocol.ElementKind.CLASS,
@@ -317,7 +315,7 @@
           null,
           NO_RETURN_TYPE,
           declaration.isAbstract,
-          _isDeprecated(declaration.metadata));
+          isDeprecated);
     }
   }
 
@@ -325,13 +323,14 @@
     if (typesOnly) {
       return;
     }
-    bool isDeprecated = _isDeprecated(fieldDecl.metadata);
+    bool isDeprecated = _isDeprecated(fieldDecl);
     fieldDecl.fields.variables.forEach((VariableDeclaration varDecl) {
+      bool isSingleFieldDeprecated = isDeprecated || _isDeprecated(varDecl);
       CompletionSuggestion suggestion = _addSuggestion(
           varDecl.name,
-          CompletionSuggestionKind.GETTER,
           fieldDecl.fields.type,
-          node);
+          node,
+          isSingleFieldDeprecated);
       if (suggestion != null) {
         suggestion.element = _createElement(
             protocol.ElementKind.GETTER,
@@ -339,7 +338,7 @@
             '()',
             fieldDecl.fields.type,
             false,
-            isDeprecated || _isDeprecated(varDecl.metadata));
+            isSingleFieldDeprecated);
       }
     });
   }
@@ -351,11 +350,9 @@
     if (excludeVoidReturn && _isVoid(declaration.returnType)) {
       return;
     }
-    CompletionSuggestion suggestion = _addSuggestion(
-        declaration.name,
-        CompletionSuggestionKind.FUNCTION,
-        declaration.returnType,
-        null);
+    bool isDeprecated = _isDeprecated(declaration);
+    CompletionSuggestion suggestion =
+        _addSuggestion(declaration.name, declaration.returnType, null, isDeprecated);
     if (suggestion != null) {
       suggestion.element = _createElement(
           protocol.ElementKind.FUNCTION,
@@ -363,7 +360,7 @@
           declaration.functionExpression.parameters.toSource(),
           declaration.returnType,
           false,
-          _isDeprecated(declaration.metadata));
+          isDeprecated);
     }
   }
 
@@ -372,7 +369,7 @@
       return;
     }
     CompletionSuggestion suggestion =
-        _addSuggestion(id, CompletionSuggestionKind.LOCAL_VARIABLE, returnType, null);
+        _addSuggestion(id, returnType, null, false);
     if (suggestion != null) {
       suggestion.element = _createElement(
           protocol.ElementKind.LOCAL_VARIABLE,
@@ -389,29 +386,26 @@
       return;
     }
     protocol.ElementKind kind;
-    CompletionSuggestionKind csKind;
     String parameters;
     if (classMbr.isGetter) {
       kind = protocol.ElementKind.GETTER;
-      csKind = CompletionSuggestionKind.GETTER;
       parameters = '()';
     } else if (classMbr.isSetter) {
       if (excludeVoidReturn) {
         return;
       }
       kind = protocol.ElementKind.SETTER;
-      csKind = CompletionSuggestionKind.SETTER;
       parameters = '(${classMbr.returnType.toSource()} value)';
     } else {
       if (excludeVoidReturn && _isVoid(classMbr.returnType)) {
         return;
       }
       kind = protocol.ElementKind.METHOD;
-      csKind = CompletionSuggestionKind.METHOD;
       parameters = classMbr.parameters.toSource();
     }
+    bool isDeprecated = _isDeprecated(classMbr);
     CompletionSuggestion suggestion =
-        _addSuggestion(classMbr.name, csKind, classMbr.returnType, node);
+        _addSuggestion(classMbr.name, classMbr.returnType, node, isDeprecated);
     if (suggestion != null) {
       suggestion.element = _createElement(
           kind,
@@ -419,7 +413,7 @@
           parameters,
           classMbr.returnType,
           classMbr.isAbstract,
-          _isDeprecated(classMbr.metadata));
+          isDeprecated);
     }
   }
 
@@ -453,7 +447,7 @@
       return;
     }
     CompletionSuggestion suggestion =
-        _addSuggestion(identifier, CompletionSuggestionKind.PARAMETER, type, null);
+        _addSuggestion(identifier, type, null, false);
     if (suggestion != null) {
       suggestion.element = _createElement(
           protocol.ElementKind.PARAMETER,
@@ -465,14 +459,14 @@
     }
   }
 
-  CompletionSuggestion _addSuggestion(SimpleIdentifier id,
-      CompletionSuggestionKind kind, TypeName typeName, ClassDeclaration classDecl) {
+  CompletionSuggestion _addSuggestion(SimpleIdentifier id, TypeName typeName,
+      ClassDeclaration classDecl, bool isDeprecated) {
     if (id != null) {
       String completion = id.name;
       if (completion != null && completion.length > 0 && completion != '_') {
         CompletionSuggestion suggestion = new CompletionSuggestion(
-            kind,
-            CompletionRelevance.DEFAULT,
+            CompletionSuggestionKind.INVOCATION,
+            isDeprecated ? CompletionRelevance.LOW : CompletionRelevance.DEFAULT,
             completion,
             completion.length,
             0,
@@ -508,13 +502,11 @@
       return;
     }
     if (varList != null) {
-      bool isDeprecated = _isDeprecated(varList.metadata);
+      bool isDeprecated = _isDeprecated(varList);
       varList.variables.forEach((VariableDeclaration varDecl) {
-        CompletionSuggestion suggestion = _addSuggestion(
-            varDecl.name,
-            CompletionSuggestionKind.TOP_LEVEL_VARIABLE,
-            varList.type,
-            null);
+        bool isSingleVarDeprecated = isDeprecated || _isDeprecated(varDecl);
+        CompletionSuggestion suggestion =
+            _addSuggestion(varDecl.name, varList.type, null, isSingleVarDeprecated);
         if (suggestion != null) {
           suggestion.element = _createElement(
               protocol.ElementKind.TOP_LEVEL_VARIABLE,
@@ -522,7 +514,7 @@
               null,
               varList.type,
               false,
-              isDeprecated || _isDeprecated(varDecl.metadata));
+              isSingleVarDeprecated);
         }
       });
     }
@@ -542,8 +534,8 @@
    * Create a new protocol Element for inclusion in a completion suggestion.
    */
   protocol.Element _createElement(protocol.ElementKind kind,
-      SimpleIdentifier id, String parameters, TypeName returnType,
-      bool isAbstract, bool isDeprecated) {
+      SimpleIdentifier id, String parameters, TypeName returnType, bool isAbstract,
+      bool isDeprecated) {
     String name = id.name;
     int flags = protocol.Element.makeFlags(
         isAbstract: isAbstract,
@@ -557,13 +549,21 @@
         returnType: _nameForType(returnType));
   }
 
+
   /**
    * Return `true` if the @deprecated annotation is present
    */
-  bool _isDeprecated(NodeList<Annotation> metadata) =>
-      metadata != null &&
-          metadata.any(
-              (Annotation a) => a.name is SimpleIdentifier && a.name.name == 'deprecated');
+  bool _isDeprecated(AnnotatedNode node) {
+    if (node != null) {
+      NodeList<Annotation> metadata = node.metadata;
+      if (metadata != null) {
+        return metadata.any((Annotation a) {
+          return a.name is SimpleIdentifier && a.name.name == 'deprecated';
+        });
+      }
+    }
+    return false;
+  }
 
   bool _isVoid(TypeName returnType) {
     if (returnType != null) {
diff --git a/pkg/analysis_server/lib/src/services/completion/suggestion_builder.dart b/pkg/analysis_server/lib/src/services/completion/suggestion_builder.dart
index 391ac2a..d98c968 100644
--- a/pkg/analysis_server/lib/src/services/completion/suggestion_builder.dart
+++ b/pkg/analysis_server/lib/src/services/completion/suggestion_builder.dart
@@ -96,9 +96,8 @@
 class ClassElementSuggestionBuilder extends _AbstractSuggestionBuilder {
   final bool staticOnly;
 
-  ClassElementSuggestionBuilder(DartCompletionRequest request, {bool staticOnly:
-      false})
-      : super(request),
+  ClassElementSuggestionBuilder(DartCompletionRequest request, bool staticOnly)
+      : super(request, CompletionSuggestionKind.INVOCATION),
         this.staticOnly = staticOnly;
 
   @override
@@ -119,11 +118,7 @@
     if (staticOnly && !element.isStatic) {
       return;
     }
-    _addElementSuggestion(
-        element,
-        CompletionSuggestionKind.GETTER,
-        element.type,
-        element.enclosingElement);
+    _addElementSuggestion(element, element.type, element.enclosingElement);
   }
 
   @override
@@ -136,7 +131,6 @@
     }
     _addElementSuggestion(
         element,
-        CompletionSuggestionKind.METHOD,
         element.returnType,
         element.enclosingElement);
   }
@@ -149,13 +143,11 @@
     if (element.isGetter) {
       _addElementSuggestion(
           element,
-          CompletionSuggestionKind.GETTER,
           element.returnType,
           element.enclosingElement);
     } else if (element.isSetter) {
       _addElementSuggestion(
           element,
-          CompletionSuggestionKind.SETTER,
           element.returnType,
           element.enclosingElement);
     }
@@ -164,20 +156,13 @@
   /**
    * Add suggestions for the visible members in the given class
    */
-  static void suggestionsFor(DartCompletionRequest request, Element element) {
+  static void suggestionsFor(DartCompletionRequest request, Element element,
+      {bool staticOnly: false}) {
     if (element is ClassElement) {
-      return element.accept(new ClassElementSuggestionBuilder(request));
+      return element.accept(
+          new ClassElementSuggestionBuilder(request, staticOnly));
     }
   }
-
-  /**
-   * Add suggestions for the visible static members in the given class
-   */
-  static void staticSuggestionsFor(DartCompletionRequest request,
-      ClassElement element) {
-    return element.accept(
-        new ClassElementSuggestionBuilder(request, staticOnly: true));
-  }
 }
 
 /**
@@ -187,12 +172,13 @@
  */
 class LibraryElementSuggestionBuilder extends _AbstractSuggestionBuilder {
 
-  LibraryElementSuggestionBuilder(DartCompletionRequest request)
-      : super(request);
+  LibraryElementSuggestionBuilder(DartCompletionRequest request,
+      CompletionSuggestionKind kind)
+      : super(request, kind);
 
   @override
   visitClassElement(ClassElement element) {
-    _addElementSuggestion(element, CompletionSuggestionKind.CLASS, null, null);
+    _addElementSuggestion(element, null, null);
   }
 
   @override
@@ -207,38 +193,26 @@
 
   @override
   visitFunctionElement(FunctionElement element) {
-    _addElementSuggestion(
-        element,
-        CompletionSuggestionKind.FUNCTION,
-        element.returnType,
-        null);
+    _addElementSuggestion(element, element.returnType, null);
   }
 
   @override
   visitFunctionTypeAliasElement(FunctionTypeAliasElement element) {
-    _addElementSuggestion(
-        element,
-        CompletionSuggestionKind.FUNCTION_TYPE_ALIAS,
-        element.returnType,
-        null);
+    _addElementSuggestion(element, element.returnType, null);
   }
 
   @override
   visitTopLevelVariableElement(TopLevelVariableElement element) {
-    _addElementSuggestion(
-        element,
-        CompletionSuggestionKind.TOP_LEVEL_VARIABLE,
-        element.type,
-        null);
+    _addElementSuggestion(element, element.type, null);
   }
 
   /**
    * Add suggestions for the visible members in the given library
    */
   static void suggestionsFor(DartCompletionRequest request,
-      LibraryElement library) {
+      CompletionSuggestionKind kind, LibraryElement library) {
     if (library != null) {
-      library.visitChildren(new LibraryElementSuggestionBuilder(request));
+      library.visitChildren(new LibraryElementSuggestionBuilder(request, kind));
     }
   }
 }
@@ -251,7 +225,7 @@
 class NamedConstructorSuggestionBuilder extends _AbstractSuggestionBuilder {
 
   NamedConstructorSuggestionBuilder(DartCompletionRequest request)
-      : super(request);
+      : super(request, CompletionSuggestionKind.INVOCATION);
 
   @override
   visitClassElement(ClassElement element) {
@@ -262,7 +236,6 @@
   visitConstructorElement(ConstructorElement element) {
     _addElementSuggestion(
         element,
-        CompletionSuggestionKind.CONSTRUCTOR,
         element.returnType,
         element.enclosingElement);
   }
@@ -287,12 +260,13 @@
  */
 class _AbstractSuggestionBuilder extends GeneralizingElementVisitor {
   final DartCompletionRequest request;
+  final CompletionSuggestionKind kind;
   final Set<String> _completions = new Set<String>();
 
-  _AbstractSuggestionBuilder(this.request);
+  _AbstractSuggestionBuilder(this.request, this.kind);
 
-  void _addElementSuggestion(Element element, CompletionSuggestionKind kind,
-      DartType type, ClassElement enclosingElement) {
+  void _addElementSuggestion(Element element, DartType type,
+      ClassElement enclosingElement) {
     if (element.isSynthetic) {
       return;
     }
@@ -309,13 +283,14 @@
         !_completions.add(completion)) {
       return;
     }
+    bool isDeprecated = element.isDeprecated;
     CompletionSuggestion suggestion = new CompletionSuggestion(
         kind,
-        CompletionRelevance.DEFAULT,
+        isDeprecated ? CompletionRelevance.LOW : CompletionRelevance.DEFAULT,
         completion,
         completion.length,
         0,
-        element.isDeprecated,
+        isDeprecated,
         false);
     suggestion.element = protocol.newElement_fromEngine(element);
     if (suggestion.element != null) {
diff --git a/pkg/analysis_server/lib/src/services/correction/assist_internal.dart b/pkg/analysis_server/lib/src/services/correction/assist_internal.dart
index 964c87b..4358dd3 100644
--- a/pkg/analysis_server/lib/src/services/correction/assist_internal.dart
+++ b/pkg/analysis_server/lib/src/services/correction/assist_internal.dart
@@ -73,7 +73,8 @@
     node =
         new NodeLocator.con2(selectionOffset, selectionEnd).searchWithin(unit);
     // try to add proposals
-    _addProposal_addTypeAnnotation();
+    _addProposal_addTypeAnnotation_DeclaredIdentifier();
+    _addProposal_addTypeAnnotation_VariableDeclaration();
     _addProposal_assignToLocalVariable();
     _addProposal_convertToBlockFunctionBody();
     _addProposal_convertToExpressionFunctionBody();
@@ -166,7 +167,54 @@
     edits.add(edit);
   }
 
-  void _addProposal_addTypeAnnotation() {
+  void _addProposal_addTypeAnnotation_DeclaredIdentifier() {
+    DeclaredIdentifier declaredIdentifier =
+        node.getAncestor((n) => n is DeclaredIdentifier);
+    if (declaredIdentifier == null) {
+      ForEachStatement forEach = node.getAncestor((n) => n is ForEachStatement);
+      int offset = node.offset;
+      if (forEach != null &&
+          forEach.iterable != null &&
+          offset < forEach.iterable.offset) {
+        declaredIdentifier = forEach.loopVariable;
+      }
+    }
+    if (declaredIdentifier == null) {
+      _coverageMarker();
+      return;
+    }
+    // may be has type annotation already
+    if (declaredIdentifier.type != null) {
+      _coverageMarker();
+      return;
+    }
+    // prepare type source
+    String typeSource;
+    DartType type = declaredIdentifier.identifier.bestType;
+    if (type is InterfaceType || type is FunctionType) {
+      typeSource = utils.getTypeSource(type);
+    } else {
+      _coverageMarker();
+      return;
+    }
+    // add edit
+    Token keyword = declaredIdentifier.keyword;
+    if (keyword is KeywordToken && keyword.keyword == Keyword.VAR) {
+      SourceRange range = rangeToken(keyword);
+      _addReplaceEdit(range, typeSource);
+    } else {
+      _addInsertEdit(declaredIdentifier.identifier.offset, '$typeSource ');
+    }
+    // add proposal
+    _addAssist(AssistKind.ADD_TYPE_ANNOTATION, []);
+  }
+
+  void _addProposal_addTypeAnnotation_VariableDeclaration() {
+    AstNode node = this.node;
+    // check if "var v = 42;^"
+    if (node is VariableDeclarationStatement) {
+      node = (node as VariableDeclarationStatement).variables;
+    }
     // prepare VariableDeclarationList
     VariableDeclarationList declarationList =
         node.getAncestor((node) => node is VariableDeclarationList);
@@ -1081,12 +1129,10 @@
       return;
     }
     // returns
-    if (thenStatement is ReturnStatement || elseStatement is ReturnStatement) {
-      ReturnStatement thenReturn = thenStatement as ReturnStatement;
-      ReturnStatement elseReturn = elseStatement as ReturnStatement;
+    if (thenStatement is ReturnStatement && elseStatement is ReturnStatement) {
       String conditionSrc = _getNodeText(ifStatement.condition);
-      String theSrc = _getNodeText(thenReturn.expression);
-      String elseSrc = _getNodeText(elseReturn.expression);
+      String theSrc = _getNodeText(thenStatement.expression);
+      String elseSrc = _getNodeText(elseStatement.expression);
       _addReplaceEdit(
           rangeNode(ifStatement),
           'return $conditionSrc ? $theSrc : $elseSrc;');
diff --git a/pkg/analysis_server/lib/src/services/correction/name_suggestion.dart b/pkg/analysis_server/lib/src/services/correction/name_suggestion.dart
index 9ce5a4c..e3b36cf 100644
--- a/pkg/analysis_server/lib/src/services/correction/name_suggestion.dart
+++ b/pkg/analysis_server/lib/src/services/correction/name_suggestion.dart
@@ -52,41 +52,6 @@
 }
 
 /**
- * Returns possible names for a [String] variable with [text] value.
- */
-List<String> getVariableNameSuggestionsForText(String text,
-    Set<String> excluded) {
-  // filter out everything except of letters and white spaces
-  {
-    StringBuffer sb = new StringBuffer();
-    for (int i = 0; i < text.length; i++) {
-      int c = text.codeUnitAt(i);
-      if (isLetter(c) || isWhitespace(c)) {
-        sb.writeCharCode(c);
-      }
-    }
-    text = sb.toString();
-  }
-  // make single camel-case text
-  {
-    List<String> words = text.split(' ');
-    StringBuffer sb = new StringBuffer();
-    for (int i = 0; i < words.length; i++) {
-      String word = words[i];
-      if (i > 0) {
-        word = capitalize(word);
-      }
-      sb.write(word);
-    }
-    text = sb.toString();
-  }
-  // split camel-case into separate suggested names
-  Set<String> res = new Set();
-  _addAll(excluded, res, _getCamelWordCombinations(text));
-  return new List.from(res);
-}
-
-/**
  * Returns possible names for a variable with the given expected type and
  * expression assigned.
  */
@@ -125,6 +90,41 @@
 }
 
 /**
+ * Returns possible names for a [String] variable with [text] value.
+ */
+List<String> getVariableNameSuggestionsForText(String text,
+    Set<String> excluded) {
+  // filter out everything except of letters and white spaces
+  {
+    StringBuffer sb = new StringBuffer();
+    for (int i = 0; i < text.length; i++) {
+      int c = text.codeUnitAt(i);
+      if (isLetter(c) || isWhitespace(c)) {
+        sb.writeCharCode(c);
+      }
+    }
+    text = sb.toString();
+  }
+  // make single camel-case text
+  {
+    List<String> words = text.split(' ');
+    StringBuffer sb = new StringBuffer();
+    for (int i = 0; i < words.length; i++) {
+      String word = words[i];
+      if (i > 0) {
+        word = capitalize(word);
+      }
+      sb.write(word);
+    }
+    text = sb.toString();
+  }
+  // split camel-case into separate suggested names
+  Set<String> res = new Set();
+  _addAll(excluded, res, _getCamelWordCombinations(text));
+  return new List.from(res);
+}
+
+/**
  * Adds [toAdd] items which are not excluded.
  */
 void _addAll(Set<String> excluded, Set<String> result, Iterable<String> toAdd) {
@@ -175,6 +175,9 @@
   } else if (expression is PrefixedIdentifier) {
     PrefixedIdentifier node = expression;
     return node.identifier.name;
+  } else if (expression is PropertyAccess) {
+    PropertyAccess node = expression;
+    return node.propertyName.name;
   } else if (expression is MethodInvocation) {
     name = expression.methodName.name;
   } else if (expression is InstanceCreationExpression) {
diff --git a/pkg/analysis_server/lib/src/services/generated/completion.dart b/pkg/analysis_server/lib/src/services/generated/completion.dart.unused
similarity index 100%
rename from pkg/analysis_server/lib/src/services/generated/completion.dart
rename to pkg/analysis_server/lib/src/services/generated/completion.dart.unused
diff --git a/pkg/analysis_server/lib/src/services/index/store/split_store.dart b/pkg/analysis_server/lib/src/services/index/store/split_store.dart
index 1db798d..6f2e190 100644
--- a/pkg/analysis_server/lib/src/services/index/store/split_store.dart
+++ b/pkg/analysis_server/lib/src/services/index/store/split_store.dart
@@ -82,10 +82,10 @@
       }
       _DataInputStream stream = new _DataInputStream(bytes);
       return _readNode(stream);
-    }).catchError((e, stackTrace) {
-      _logger.logError2(
+    }).catchError((exception, stackTrace) {
+      _logger.logError(
           'Exception during reading index file ${name}',
-          new CaughtException(e, stackTrace));
+          new CaughtException(exception, stackTrace));
     });
   }
 
@@ -108,10 +108,10 @@
       _writeNode(node, stream);
       var bytes = stream.getBytes();
       return _fileManager.write(name, bytes);
-    }).catchError((e, stackTrace) {
-      _logger.logError2(
+    }).catchError((exception, stackTrace) {
+      _logger.logError(
           'Exception during reading index file ${name}',
-          new CaughtException(e, stackTrace));
+          new CaughtException(exception, stackTrace));
     });
   }
 
diff --git a/pkg/analysis_server/lib/src/services/refactoring/inline_local.dart b/pkg/analysis_server/lib/src/services/refactoring/inline_local.dart
index 4f79dc7..fdee721 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/inline_local.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/inline_local.dart
@@ -137,7 +137,6 @@
     // prepare initializer
     Expression initializer = _variableNode.initializer;
     String initializerCode = utils.getNodeText(initializer);
-    int initializerPrecedence = getExpressionPrecedence(initializer);
     // replace references
     for (SearchMatch reference in _references) {
       SourceRange range = reference.sourceRange;
@@ -171,7 +170,7 @@
         } else {
           codeForReference = initializerCode;
         }
-      } else if (initializerPrecedence < getExpressionParentPrecedence(node)) {
+      } else if (_shouldUseParenthesis(initializer, node)) {
         codeForReference = '($initializerCode)';
       } else {
         codeForReference = initializerCode;
@@ -195,4 +194,25 @@
     return targetType == TokenType.STRING_INTERPOLATION_IDENTIFIER &&
         expression is! SimpleIdentifier;
   }
+
+  static bool _shouldUseParenthesis(Expression init, AstNode node) {
+    // check precedence
+    int initPrecedence = getExpressionPrecedence(init);
+    if (initPrecedence < getExpressionParentPrecedence(node)) {
+      return true;
+    }
+    // special case for '-'
+    AstNode parent = node.parent;
+    if (init is PrefixExpression && parent is PrefixExpression) {
+      if (parent.operator.type == TokenType.MINUS) {
+        TokenType initializerOperator = init.operator.type;
+        if (initializerOperator == TokenType.MINUS ||
+            initializerOperator == TokenType.MINUS_MINUS) {
+          return true;
+        }
+      }
+    }
+    // no () is needed
+    return false;
+  }
 }
diff --git a/pkg/analysis_server/lib/src/services/refactoring/inline_method.dart b/pkg/analysis_server/lib/src/services/refactoring/inline_method.dart
index c6c680e..96dbb03 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/inline_method.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/inline_method.dart
@@ -19,6 +19,7 @@
 import 'package:analyzer/src/generated/ast.dart';
 import 'package:analyzer/src/generated/element.dart';
 import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/src/generated/utilities_dart.dart';
 
 
 /**
@@ -46,8 +47,9 @@
  * Returns the source which should replace given invocation with given
  * arguments.
  */
-String _getMethodSourceForInvocation(_SourcePart part, CorrectionUtils utils,
-    AstNode contextNode, Expression targetExpression, List<Expression> arguments) {
+String _getMethodSourceForInvocation(RefactoringStatus status, _SourcePart part,
+    CorrectionUtils utils, AstNode contextNode, Expression targetExpression,
+    List<Expression> arguments) {
   // prepare edits to replace parameters with arguments
   List<SourceEdit> edits = <SourceEdit>[];
   part._parameters.forEach(
@@ -63,15 +65,34 @@
     if (argument is NamedExpression) {
       argument = (argument as NamedExpression).expression;
     }
-    int argumentPrecedence = getExpressionPrecedence(argument);
-    String argumentSource = utils.getNodeText(argument);
+    // prepare argument properties
+    int argumentPrecedence;
+    String argumentSource;
+    if (argument != null) {
+      argumentPrecedence = getExpressionPrecedence(argument);
+      argumentSource = utils.getNodeText(argument);
+    } else {
+      // report about a missing required parameter
+      if (parameter.parameterKind == ParameterKind.REQUIRED) {
+        status.addError(
+            'No argument for the parameter "${parameter.name}".',
+            newLocation_fromNode(contextNode));
+        return;
+      }
+      // an optional parameter
+      argumentPrecedence = -1000;
+      argumentSource = parameter.defaultValueCode;
+      if (argumentSource == null) {
+        argumentSource = 'null';
+      }
+    }
     // replace all occurrences of this parameter
     for (_ParameterOccurrence occurrence in occurrences) {
       SourceRange range = occurrence.range;
       // prepare argument source to apply at this occurrence
       String occurrenceArgumentSource;
       if (argumentPrecedence < occurrence.parentPrecedence) {
-        occurrenceArgumentSource = "(${argumentSource})";
+        occurrenceArgumentSource = "($argumentSource)";
       } else {
         occurrenceArgumentSource = argumentSource;
       }
@@ -488,6 +509,7 @@
       if (ref._methodStatementsPart != null) {
         // prepare statements source for invocation
         String source = _getMethodSourceForInvocation(
+            status,
             ref._methodStatementsPart,
             _refUtils,
             usage,
@@ -506,6 +528,7 @@
       if (ref._methodExpressionPart != null) {
         // prepare expression source for invocation
         String source = _getMethodSourceForInvocation(
+            status,
             ref._methodExpressionPart,
             _refUtils,
             usage,
diff --git a/pkg/analysis_server/pubspec.yaml b/pkg/analysis_server/pubspec.yaml
index 1fd1a09..b1a0d38 100644
--- a/pkg/analysis_server/pubspec.yaml
+++ b/pkg/analysis_server/pubspec.yaml
@@ -7,7 +7,7 @@
   sdk: '>=1.0.0 <2.0.0'
 dependencies:
   analyzer: 0.23.0-dev.13
-  args: any
+  args: '>=0.12.1 <0.13.0'
   logging: any
   path: any
   watcher: any
diff --git a/pkg/analysis_server/test/analysis/notification_navigation_test.dart b/pkg/analysis_server/test/analysis/notification_navigation_test.dart
index 42c2d5a..fc40264 100644
--- a/pkg/analysis_server/test/analysis/notification_navigation_test.dart
+++ b/pkg/analysis_server/test/analysis/notification_navigation_test.dart
@@ -318,8 +318,35 @@
 }
 ''');
     return prepareNavigation().then((_) {
-      findRegion(findOffset('new A'), 'new A'.length, true);
-      assertHasTarget('A {');
+      {
+        findRegion(findOffset('new A'), 'new'.length, true);
+        assertHasTarget('A {');
+      }
+      {
+        findRegion(findOffset('A()'), 'A'.length, true);
+        assertHasTarget('A {');
+      }
+    });
+  }
+
+  test_instanceCreation_implicit_withTypeArgument() {
+    addTestFile('''
+class A {}
+class B<T> {
+}
+main() {
+  new B<A>();
+}
+''');
+    return prepareNavigation().then((_) {
+      {
+        findRegion(findOffset('new B'), 'new'.length, true);
+        assertHasTarget('B<T> {');
+      }
+      {
+        findRegion(findOffset('A>();'), 'A'.length, true);
+        assertHasTarget('A {');
+      }
     });
   }
 
@@ -348,6 +375,36 @@
     });
   }
 
+  test_instanceCreation_named_withTypeArgument() {
+    addTestFile('''
+class A {}
+class B<T> {
+  A.named() {}
+}
+main() {
+  new B<A>.named();
+}
+''');
+    return prepareNavigation().then((_) {
+      {
+        findRegion(findOffset('new '), 'new'.length, true);
+        assertHasTarget('named() {}');
+      }
+      {
+        findRegion(findOffset('B<A>.named();'), 'B'.length, true);
+        assertHasTarget('B<T> {');
+      }
+      {
+        findRegion(findOffset('.named();'), '.named'.length, true);
+        assertHasTarget('named() {}');
+      }
+      {
+        findRegion(findOffset('A>.named();'), 'A'.length, true);
+        assertHasTarget('A {');
+      }
+    });
+  }
+
   test_instanceCreation_unnamed() {
     addTestFile('''
 class A {
@@ -369,6 +426,32 @@
     });
   }
 
+  test_instanceCreation_unnamed_withTypeArgument() {
+    addTestFile('''
+class A {}
+class B<T> {
+  B() {}
+}
+main() {
+  new B<A>();
+}
+''');
+    return prepareNavigation().then((_) {
+      {
+        findRegion(findOffset('new '), 'new'.length, true);
+        assertHasTarget('B() {}', 0);
+      }
+      {
+        findRegion(findOffset('B<A>();'), 'B'.length, true);
+        assertHasTarget('B<T> {');
+      }
+      {
+        findRegion(findOffset('A>();'), 'A'.length, true);
+        assertHasTarget('A {');
+      }
+    });
+  }
+
   test_multiplyDefinedElement() {
     addFile('$projectPath/bin/libA.dart', 'library A; int TEST = 1;');
     addFile('$projectPath/bin/libB.dart', 'library B; int TEST = 2;');
diff --git a/pkg/analysis_server/test/context_manager_test.dart b/pkg/analysis_server/test/context_manager_test.dart
index 161c060..0fb2192 100644
--- a/pkg/analysis_server/test/context_manager_test.dart
+++ b/pkg/analysis_server/test/context_manager_test.dart
@@ -323,6 +323,24 @@
     manager.assertContextFiles(project, [file1, file2]);
   }
 
+  void test_setRoots_exclude_sameRoot_removeExcludedFile_inFolder() {
+    // prepare paths
+    String project = '/project';
+    String file1 = '$project/bin/file1.dart';
+    String file2 = '$project/bin/file2.dart';
+    // create files
+    resourceProvider.newFile(file1, '// 1');
+    resourceProvider.newFile(file2, '// 2');
+    // set roots
+    manager.setRoots(<String>[project], <String>[file2], <String, String>{});
+    manager.assertContextPaths([project]);
+    manager.assertContextFiles(project, [file1]);
+    // stop excluding "2"
+    manager.setRoots(<String>[project], <String>[], <String, String>{});
+    manager.assertContextPaths([project]);
+    manager.assertContextFiles(project, [file1, file2]);
+  }
+
   void test_setRoots_exclude_sameRoot_removeExcludedFolder() {
     // prepare paths
     String project = '/project';
diff --git a/pkg/analysis_server/test/domain_completion_test.dart b/pkg/analysis_server/test/domain_completion_test.dart
index 7413542..8eb8136 100644
--- a/pkg/analysis_server/test/domain_completion_test.dart
+++ b/pkg/analysis_server/test/domain_completion_test.dart
@@ -139,8 +139,8 @@
     return getSuggestions().then((_) {
       expect(replacementOffset, equals(completionOffset));
       expect(replacementLength, equals(0));
-      assertHasResult(CompletionSuggestionKind.CLASS, 'Object');
-      assertHasResult(CompletionSuggestionKind.CLASS, 'HtmlElement');
+      assertHasResult(CompletionSuggestionKind.INVOCATION, 'Object');
+      assertHasResult(CompletionSuggestionKind.INVOCATION, 'HtmlElement');
       assertNoResult('test');
     });
   }
@@ -153,8 +153,8 @@
     return getSuggestions().then((_) {
       expect(replacementOffset, equals(completionOffset));
       expect(replacementLength, equals(0));
-      assertHasResult(CompletionSuggestionKind.CLASS, 'Object');
-      assertHasResult(CompletionSuggestionKind.LIBRARY_PREFIX, 'foo');
+      assertHasResult(CompletionSuggestionKind.INVOCATION, 'Object');
+      assertHasResult(CompletionSuggestionKind.INVOCATION, 'foo');
       assertNoResult('HtmlElement');
       assertNoResult('test');
     });
@@ -181,10 +181,10 @@
     return getSuggestions().then((_) {
       expect(replacementOffset, equals(completionOffset));
       expect(replacementLength, equals(0));
-      assertHasResult(CompletionSuggestionKind.CLASS, 'A');
-      assertHasResult(CompletionSuggestionKind.GETTER, 'a');
-      assertHasResult(CompletionSuggestionKind.LOCAL_VARIABLE, 'b');
-      assertHasResult(CompletionSuggestionKind.METHOD, 'x');
+      assertHasResult(CompletionSuggestionKind.INVOCATION, 'A');
+      assertHasResult(CompletionSuggestionKind.INVOCATION, 'a');
+      assertHasResult(CompletionSuggestionKind.INVOCATION, 'b');
+      assertHasResult(CompletionSuggestionKind.INVOCATION, 'x');
     });
   }
 
@@ -193,7 +193,7 @@
     return getSuggestions().then((_) {
       expect(replacementOffset, equals(completionOffset));
       expect(replacementLength, equals(0));
-      assertHasResult(CompletionSuggestionKind.METHOD, 'b');
+      assertHasResult(CompletionSuggestionKind.INVOCATION, 'b');
     });
   }
 
@@ -206,8 +206,8 @@
     return getSuggestions().then((_) {
       expect(replacementOffset, equals(completionOffset - 3));
       expect(replacementLength, equals(4));
-      assertHasResult(CompletionSuggestionKind.CLASS, 'Object');
-      assertHasResult(CompletionSuggestionKind.TOP_LEVEL_VARIABLE, 'test');
+      assertHasResult(CompletionSuggestionKind.INVOCATION, 'Object');
+      assertHasResult(CompletionSuggestionKind.INVOCATION, 'test');
       assertNoResult('HtmlElement');
     });
   }
diff --git a/pkg/analysis_server/test/integration/protocol_matchers.dart b/pkg/analysis_server/test/integration/protocol_matchers.dart
index 691cc81..88483a2 100644
--- a/pkg/analysis_server/test/integration/protocol_matchers.dart
+++ b/pkg/analysis_server/test/integration/protocol_matchers.dart
@@ -1036,50 +1036,24 @@
  *
  * enum {
  *   ARGUMENT_LIST
- *   CLASS
- *   CLASS_ALIAS
- *   CONSTRUCTOR
- *   FIELD
- *   FUNCTION
- *   FUNCTION_TYPE_ALIAS
- *   GETTER
  *   IMPORT
+ *   IDENTIFIER
+ *   INVOCATION
  *   KEYWORD
- *   LABEL
- *   LIBRARY_PREFIX
- *   LOCAL_VARIABLE
- *   METHOD
- *   METHOD_NAME
  *   NAMED_ARGUMENT
  *   OPTIONAL_ARGUMENT
  *   PARAMETER
- *   SETTER
- *   TOP_LEVEL_VARIABLE
- *   TYPE_PARAMETER
  * }
  */
 final Matcher isCompletionSuggestionKind = new MatchesEnum("CompletionSuggestionKind", [
   "ARGUMENT_LIST",
-  "CLASS",
-  "CLASS_ALIAS",
-  "CONSTRUCTOR",
-  "FIELD",
-  "FUNCTION",
-  "FUNCTION_TYPE_ALIAS",
-  "GETTER",
   "IMPORT",
+  "IDENTIFIER",
+  "INVOCATION",
   "KEYWORD",
-  "LABEL",
-  "LIBRARY_PREFIX",
-  "LOCAL_VARIABLE",
-  "METHOD",
-  "METHOD_NAME",
   "NAMED_ARGUMENT",
   "OPTIONAL_ARGUMENT",
-  "PARAMETER",
-  "SETTER",
-  "TOP_LEVEL_VARIABLE",
-  "TYPE_PARAMETER"
+  "PARAMETER"
 ]);
 
 /**
diff --git a/pkg/analysis_server/test/mock_sdk.dart b/pkg/analysis_server/test/mock_sdk.dart
index c87ef8d..8673177 100644
--- a/pkg/analysis_server/test/mock_sdk.dart
+++ b/pkg/analysis_server/test/mock_sdk.dart
@@ -60,11 +60,22 @@
 }
 const Object deprecated = const Deprecated("next release");
 
-abstract class List<E> extends Object {
+class Iterator<E> {
+  bool moveNext();
+  E get current;
+}
+
+abstract class Iterable<E> {
+  Iterator<E> get iterator;
+}
+
+abstract class List<E> implements Iterable<E> {
   void add(E value);
   E operator [](int index);
   void operator []=(int index, E value);
+  Iterator<E> get iterator => null;
 }
+
 class Map<K, V> extends Object {}
 
 external bool identical(Object a, Object b);
diff --git a/pkg/analysis_server/test/services/completion/combinator_computer_test.dart b/pkg/analysis_server/test/services/completion/combinator_computer_test.dart
new file mode 100644
index 0000000..af4fc0f
--- /dev/null
+++ b/pkg/analysis_server/test/services/completion/combinator_computer_test.dart
@@ -0,0 +1,155 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for 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 test.services.completion.dart.combinator;
+
+import 'package:analysis_server/src/protocol.dart';
+import 'package:analysis_server/src/services/completion/combinator_computer.dart';
+import 'package:unittest/unittest.dart';
+
+import '../../reflective_tests.dart';
+import 'completion_test_util.dart';
+
+main() {
+  groupSep = ' | ';
+  runReflectiveTests(CombinatorComputerTest);
+}
+
+@ReflectiveTestCase()
+class CombinatorComputerTest extends AbstractCompletionTest {
+
+  @override
+  void setUp() {
+    super.setUp();
+    computer = new CombinatorComputer();
+  }
+
+  test_Block_inherited_local() {
+    // Block  BlockFunctionBody  MethodDeclaration  ClassDeclaration
+    addTestSource('''
+      class F { var f1; f2() { } }
+      class E extends F { var e1; e2() { } }
+      class I { int i1; i2() { } }
+      class M { var m1; int m2() { } }
+      class A extends E implements I with M {a() {^}}''');
+    computeFast();
+    return computeFull(true).then((_) {
+      assertNoSuggestions();
+    });
+  }
+
+  test_Combinator_hide() {
+    // SimpleIdentifier  HideCombinator  ImportDirective
+    addSource('/testAB.dart', '''
+      library libAB;
+      part '/partAB.dart';
+      class A { }
+      class B { }''');
+    addSource('/partAB.dart', '''
+      part of libAB;
+      var T1;
+      PB F1() => new PB();
+      class PB { }''');
+    addSource('/testCD.dart', '''
+      class C { }
+      class D { }''');
+    addTestSource('''
+      import "/testAB.dart" hide ^;
+      import "/testCD.dart";
+      class X {}''');
+    computeFast();
+    return computeFull(true).then((_) {
+      assertSuggestClass(
+          'A',
+          CompletionRelevance.DEFAULT,
+          CompletionSuggestionKind.IDENTIFIER);
+      assertSuggestClass(
+          'B',
+          CompletionRelevance.DEFAULT,
+          CompletionSuggestionKind.IDENTIFIER);
+      assertSuggestClass(
+          'PB',
+          CompletionRelevance.DEFAULT,
+          CompletionSuggestionKind.IDENTIFIER);
+      assertSuggestTopLevelVar(
+          'T1',
+          null,
+          CompletionRelevance.DEFAULT,
+          CompletionSuggestionKind.IDENTIFIER);
+      assertSuggestFunction(
+          'F1',
+          'PB',
+          false,
+          CompletionRelevance.DEFAULT,
+          CompletionSuggestionKind.IDENTIFIER);
+      assertNotSuggested('C');
+      assertNotSuggested('D');
+      assertNotSuggested('X');
+      assertNotSuggested('Object');
+    });
+  }
+
+  test_Combinator_show() {
+    // SimpleIdentifier  HideCombinator  ImportDirective
+    addSource('/testAB.dart', '''
+      library libAB;
+      part '/partAB.dart';
+      class A { }
+      class B { }''');
+    addSource('/partAB.dart', '''
+      part of libAB;
+      var T1;
+      PB F1() => new PB();
+      typedef PB2 F2(int blat);
+      class Clz = Object with Object;
+      class PB { }''');
+    addSource('/testCD.dart', '''
+      class C { }
+      class D { }''');
+    addTestSource('''
+      import "/testAB.dart" show ^;
+      import "/testCD.dart";
+      class X {}''');
+    computeFast();
+    return computeFull(true).then((_) {
+      assertSuggestClass(
+          'A',
+          CompletionRelevance.DEFAULT,
+          CompletionSuggestionKind.IDENTIFIER);
+      assertSuggestClass(
+          'B',
+          CompletionRelevance.DEFAULT,
+          CompletionSuggestionKind.IDENTIFIER);
+      assertSuggestClass(
+          'PB',
+          CompletionRelevance.DEFAULT,
+          CompletionSuggestionKind.IDENTIFIER);
+      assertSuggestTopLevelVar(
+          'T1',
+          null,
+          CompletionRelevance.DEFAULT,
+          CompletionSuggestionKind.IDENTIFIER);
+      assertSuggestFunction(
+          'F1',
+          'PB',
+          false,
+          CompletionRelevance.DEFAULT,
+          CompletionSuggestionKind.IDENTIFIER);
+      assertSuggestClass(
+          'Clz',
+          CompletionRelevance.DEFAULT,
+          CompletionSuggestionKind.IDENTIFIER);
+      assertSuggestFunctionTypeAlias(
+          'F2',
+          null,
+          false,
+          CompletionRelevance.DEFAULT,
+          CompletionSuggestionKind.IDENTIFIER);
+      assertNotSuggested('C');
+      assertNotSuggested('D');
+      assertNotSuggested('X');
+      assertNotSuggested('Object');
+    });
+  }
+}
diff --git a/pkg/analysis_server/test/services/completion/completion_computer_test.dart b/pkg/analysis_server/test/services/completion/completion_computer_test.dart
index 30b0afc..4448236 100644
--- a/pkg/analysis_server/test/services/completion/completion_computer_test.dart
+++ b/pkg/analysis_server/test/services/completion/completion_computer_test.dart
@@ -8,17 +8,18 @@
 
 import 'package:analysis_server/src/protocol.dart';
 import 'package:analysis_server/src/services/completion/completion_manager.dart';
+import 'package:analysis_server/src/services/completion/dart_completion_manager.dart';
 import 'package:analysis_server/src/services/index/index.dart';
 import 'package:analysis_server/src/services/index/local_memory_index.dart';
 import 'package:analysis_server/src/services/search/search_engine.dart';
-import 'package:analysis_server/src/services/completion/dart_completion_manager.dart';
 import 'package:analysis_server/src/services/search/search_engine_internal.dart';
-import '../../abstract_single_unit.dart';
-import '../../reflective_tests.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/source.dart';
 import 'package:unittest/unittest.dart';
 
+import '../../abstract_single_unit.dart';
+import '../../reflective_tests.dart';
+
 main() {
   groupSep = ' | ';
   runReflectiveTests(DartCompletionManagerTest);
@@ -63,7 +64,7 @@
     source = addSource('/does/not/exist.dart', '');
     manager = new DartCompletionManager(context, searchEngine, source, 0);
     suggestion1 = new CompletionSuggestion(
-        CompletionSuggestionKind.CLASS,
+        CompletionSuggestionKind.INVOCATION,
         CompletionRelevance.DEFAULT,
         "suggestion1",
         1,
@@ -71,7 +72,7 @@
         false,
         false);
     suggestion2 = new CompletionSuggestion(
-        CompletionSuggestionKind.CLASS,
+        CompletionSuggestionKind.IDENTIFIER,
         CompletionRelevance.DEFAULT,
         "suggestion2",
         2,
diff --git a/pkg/analysis_server/test/services/completion/completion_test_util.dart b/pkg/analysis_server/test/services/completion/completion_test_util.dart
index 54929ec..941b3b7 100644
--- a/pkg/analysis_server/test/services/completion/completion_test_util.dart
+++ b/pkg/analysis_server/test/services/completion/completion_test_util.dart
@@ -8,7 +8,7 @@
 
 import 'package:analysis_server/src/protocol.dart' as protocol show Element,
     ElementKind;
-import 'package:analysis_server/src/protocol.dart' hide Element;
+import 'package:analysis_server/src/protocol.dart' hide Element, ElementKind;
 import 'package:analysis_server/src/services/completion/dart_completion_manager.dart';
 import 'package:analysis_server/src/services/completion/imported_computer.dart';
 import 'package:analysis_server/src/services/completion/invocation_computer.dart';
@@ -72,26 +72,35 @@
     return null;
   }
 
-  CompletionSuggestion assertSuggest(CompletionSuggestionKind kind,
-      String completion, [CompletionRelevance relevance = CompletionRelevance.DEFAULT,
-      bool isDeprecated = false, bool isPotential = false]) {
+  CompletionSuggestion assertSuggest(String completion,
+      {CompletionSuggestionKind csKind: CompletionSuggestionKind.INVOCATION,
+      CompletionRelevance relevance: CompletionRelevance.DEFAULT,
+      protocol.ElementKind elemKind: null, bool isDeprecated: false, bool isPotential:
+      false}) {
     CompletionSuggestion cs;
     request.suggestions.forEach((s) {
-      if (s.completion == completion && s.kind == kind) {
-        if (cs == null) {
-          cs = s;
-        } else {
-          _failedCompletion(
-              'expected exactly one $completion',
-              request.suggestions.where((s) => s.completion == completion));
+      if (s.completion == completion && s.kind == csKind) {
+        protocol.Element element = s.element;
+        if (elemKind == null || (element != null && elemKind == element.kind)) {
+          if (cs == null) {
+            cs = s;
+          } else {
+            _failedCompletion(
+                'expected exactly one $completion',
+                request.suggestions.where((s) => s.completion == completion));
+          }
         }
       }
     });
     if (cs == null) {
-      _failedCompletion('expected $completion $kind', request.suggestions);
+      _failedCompletion('expected $completion $csKind', request.suggestions);
     }
-    expect(cs.kind, equals(kind));
-    expect(cs.relevance, equals(relevance));
+    expect(cs.kind, equals(csKind));
+    if (isDeprecated) {
+      expect(cs.relevance, equals(CompletionRelevance.LOW));
+    } else {
+      expect(cs.relevance, equals(relevance));
+    }
     expect(cs.selectionOffset, equals(completion.length));
     expect(cs.selectionLength, equals(0));
     expect(cs.isDeprecated, equals(isDeprecated));
@@ -100,9 +109,10 @@
   }
 
   CompletionSuggestion assertSuggestClass(String name,
-      [CompletionRelevance relevance = CompletionRelevance.DEFAULT]) {
+      [CompletionRelevance relevance = CompletionRelevance.DEFAULT,
+      CompletionSuggestionKind kind = CompletionSuggestionKind.INVOCATION]) {
     CompletionSuggestion cs =
-        assertSuggest(CompletionSuggestionKind.CLASS, name, relevance);
+        assertSuggest(name, csKind: kind, relevance: relevance);
     protocol.Element element = cs.element;
     expect(element, isNotNull);
     expect(element.kind, equals(protocol.ElementKind.CLASS));
@@ -113,9 +123,10 @@
   }
 
   CompletionSuggestion assertSuggestClassTypeAlias(String name,
-      [CompletionRelevance relevance = CompletionRelevance.DEFAULT]) {
+      [CompletionRelevance relevance = CompletionRelevance.DEFAULT,
+      CompletionSuggestionKind kind = CompletionSuggestionKind.INVOCATION]) {
     CompletionSuggestion cs =
-        assertSuggest(CompletionSuggestionKind.CLASS_ALIAS, name, relevance);
+        assertSuggest(name, csKind: kind, relevance: relevance);
     protocol.Element element = cs.element;
     expect(element, isNotNull);
     expect(element.kind, equals(protocol.ElementKind.CLASS_TYPE_ALIAS));
@@ -126,13 +137,13 @@
   }
 
   CompletionSuggestion assertSuggestFunction(String name, String returnType,
-      bool isDeprecated, [CompletionRelevance relevance =
-      CompletionRelevance.DEFAULT]) {
+      bool isDeprecated, [CompletionRelevance relevance = CompletionRelevance.DEFAULT,
+      CompletionSuggestionKind kind = CompletionSuggestionKind.INVOCATION]) {
     CompletionSuggestion cs = assertSuggest(
-        CompletionSuggestionKind.FUNCTION,
         name,
-        relevance,
-        isDeprecated);
+        csKind: kind,
+        relevance: relevance,
+        isDeprecated: isDeprecated);
     expect(cs.returnType, equals(returnType));
     protocol.Element element = cs.element;
     expect(element, isNotNull);
@@ -151,12 +162,13 @@
 
   CompletionSuggestion assertSuggestFunctionTypeAlias(String name,
       String returnType, bool isDeprecated, [CompletionRelevance relevance =
-      CompletionRelevance.DEFAULT]) {
+      CompletionRelevance.DEFAULT, CompletionSuggestionKind kind =
+      CompletionSuggestionKind.INVOCATION]) {
     CompletionSuggestion cs = assertSuggest(
-        CompletionSuggestionKind.FUNCTION_TYPE_ALIAS,
         name,
-        relevance,
-        isDeprecated);
+        csKind: kind,
+        relevance: relevance,
+        isDeprecated: isDeprecated);
     expect(cs.returnType, equals(returnType));
     protocol.Element element = cs.element;
     expect(element, isNotNull);
@@ -176,9 +188,15 @@
   }
 
   CompletionSuggestion assertSuggestGetter(String name, String returnType,
-      [CompletionRelevance relevance = CompletionRelevance.DEFAULT]) {
-    CompletionSuggestion cs =
-        assertSuggest(CompletionSuggestionKind.GETTER, name, relevance);
+      {CompletionRelevance relevance: CompletionRelevance.DEFAULT,
+      CompletionSuggestionKind kind: CompletionSuggestionKind.INVOCATION,
+      bool isDeprecated: false}) {
+    CompletionSuggestion cs = assertSuggest(
+        name,
+        csKind: kind,
+        relevance: relevance,
+        elemKind: protocol.ElementKind.GETTER,
+        isDeprecated: isDeprecated);
     expect(cs.returnType, equals(returnType));
     protocol.Element element = cs.element;
     expect(element, isNotNull);
@@ -194,11 +212,12 @@
   }
 
   CompletionSuggestion assertSuggestLibraryPrefix(String prefix,
-      [CompletionRelevance relevance = CompletionRelevance.DEFAULT]) {
+      [CompletionRelevance relevance = CompletionRelevance.DEFAULT,
+      CompletionSuggestionKind kind = CompletionSuggestionKind.INVOCATION]) {
     // Library prefix should only be suggested by ImportedComputer
     if (computer is ImportedComputer) {
       CompletionSuggestion cs =
-          assertSuggest(CompletionSuggestionKind.LIBRARY_PREFIX, prefix, relevance);
+          assertSuggest(prefix, csKind: kind, relevance: relevance);
       protocol.Element element = cs.element;
       expect(element, isNotNull);
       expect(element.kind, equals(protocol.ElementKind.LIBRARY));
@@ -211,12 +230,12 @@
   }
 
   CompletionSuggestion assertSuggestLocalVariable(String name,
-      String returnType, [CompletionRelevance relevance =
-      CompletionRelevance.DEFAULT]) {
+      String returnType, [CompletionRelevance relevance = CompletionRelevance.DEFAULT,
+      CompletionSuggestionKind kind = CompletionSuggestionKind.INVOCATION]) {
     // Local variables should only be suggested by LocalComputer
     if (computer is LocalComputer) {
       CompletionSuggestion cs =
-          assertSuggest(CompletionSuggestionKind.LOCAL_VARIABLE, name, relevance);
+          assertSuggest(name, csKind: kind, relevance: relevance);
       expect(cs.returnType, equals(returnType));
       protocol.Element element = cs.element;
       expect(element, isNotNull);
@@ -233,10 +252,10 @@
   }
 
   CompletionSuggestion assertSuggestMethod(String name, String declaringType,
-      String returnType, [CompletionRelevance relevance =
-      CompletionRelevance.DEFAULT]) {
+      String returnType, [CompletionRelevance relevance = CompletionRelevance.DEFAULT,
+      CompletionSuggestionKind kind = CompletionSuggestionKind.INVOCATION]) {
     CompletionSuggestion cs =
-        assertSuggest(CompletionSuggestionKind.METHOD, name, relevance);
+        assertSuggest(name, csKind: kind, relevance: relevance);
     expect(cs.declaringType, equals(declaringType));
     expect(cs.returnType, equals(returnType));
     protocol.Element element = cs.element;
@@ -254,11 +273,11 @@
   }
 
   CompletionSuggestion assertSuggestNamedConstructor(String name,
-      String returnType, [CompletionRelevance relevance =
-      CompletionRelevance.DEFAULT]) {
+      String returnType, [CompletionRelevance relevance = CompletionRelevance.DEFAULT,
+      CompletionSuggestionKind kind = CompletionSuggestionKind.INVOCATION]) {
     if (computer is InvocationComputer) {
       CompletionSuggestion cs =
-          assertSuggest(CompletionSuggestionKind.CONSTRUCTOR, name, relevance);
+          assertSuggest(name, csKind: kind, relevance: relevance);
       protocol.Element element = cs.element;
       expect(element, isNotNull);
       expect(element.kind, equals(protocol.ElementKind.CONSTRUCTOR));
@@ -275,11 +294,12 @@
   }
 
   CompletionSuggestion assertSuggestParameter(String name, String returnType,
-      [CompletionRelevance relevance = CompletionRelevance.DEFAULT]) {
+      [CompletionRelevance relevance = CompletionRelevance.DEFAULT,
+      CompletionSuggestionKind kind = CompletionSuggestionKind.INVOCATION]) {
     // Parameters should only be suggested by LocalComputer
     if (computer is LocalComputer) {
       CompletionSuggestion cs =
-          assertSuggest(CompletionSuggestionKind.PARAMETER, name, relevance);
+          assertSuggest(name, csKind: kind, relevance: relevance);
       expect(cs.returnType, equals(returnType));
       protocol.Element element = cs.element;
       expect(element, isNotNull);
@@ -296,9 +316,13 @@
   }
 
   CompletionSuggestion assertSuggestSetter(String name,
-      [CompletionRelevance relevance = CompletionRelevance.DEFAULT]) {
-    CompletionSuggestion cs =
-        assertSuggest(CompletionSuggestionKind.SETTER, name, relevance);
+      [CompletionRelevance relevance = CompletionRelevance.DEFAULT,
+      CompletionSuggestionKind kind = CompletionSuggestionKind.INVOCATION]) {
+    CompletionSuggestion cs = assertSuggest(
+        name,
+        csKind: kind,
+        relevance: relevance,
+        elemKind: protocol.ElementKind.SETTER);
     protocol.Element element = cs.element;
     expect(element, isNotNull);
     expect(element.kind, equals(protocol.ElementKind.SETTER));
@@ -310,9 +334,10 @@
   }
 
   CompletionSuggestion assertSuggestTopLevelVar(String name, String returnType,
-      [CompletionRelevance relevance = CompletionRelevance.DEFAULT]) {
+      [CompletionRelevance relevance = CompletionRelevance.DEFAULT,
+      CompletionSuggestionKind kind = CompletionSuggestionKind.INVOCATION]) {
     CompletionSuggestion cs =
-        assertSuggest(CompletionSuggestionKind.TOP_LEVEL_VARIABLE, name, relevance);
+        assertSuggest(name, csKind: kind, relevance: relevance);
     expect(cs.returnType, equals(returnType));
     protocol.Element element = cs.element;
     expect(element, isNotNull);
@@ -447,9 +472,10 @@
   }
 
   CompletionSuggestion assertSuggestImportedClass(String name,
-      [CompletionRelevance relevance = CompletionRelevance.DEFAULT]) {
+      [CompletionRelevance relevance = CompletionRelevance.DEFAULT,
+      CompletionSuggestionKind kind = CompletionSuggestionKind.INVOCATION]) {
     if (computer is ImportedComputer) {
-      return assertSuggestClass(name, relevance);
+      return assertSuggestClass(name, relevance, kind);
     } else {
       return assertNotSuggested(name);
     }
@@ -457,9 +483,15 @@
 
   CompletionSuggestion assertSuggestImportedFunction(String name,
       String returnType, [bool isDeprecated = false, CompletionRelevance relevance =
-      CompletionRelevance.DEFAULT]) {
+      CompletionRelevance.DEFAULT, CompletionSuggestionKind kind =
+      CompletionSuggestionKind.INVOCATION]) {
     if (computer is ImportedComputer) {
-      return assertSuggestFunction(name, returnType, isDeprecated, relevance);
+      return assertSuggestFunction(
+          name,
+          returnType,
+          isDeprecated,
+          relevance,
+          kind);
     } else {
       return assertNotSuggested(name);
     }
@@ -467,13 +499,15 @@
 
   CompletionSuggestion assertSuggestImportedFunctionTypeAlias(String name,
       String returnType, [bool isDeprecated = false, CompletionRelevance relevance =
-      CompletionRelevance.DEFAULT]) {
+      CompletionRelevance.DEFAULT, CompletionSuggestionKind kind =
+      CompletionSuggestionKind.INVOCATION]) {
     if (computer is ImportedComputer) {
       return assertSuggestFunctionTypeAlias(
           name,
           returnType,
           isDeprecated,
-          relevance);
+          relevance,
+          kind);
     } else {
       return assertNotSuggested(name);
     }
@@ -483,7 +517,7 @@
       String returnType, [CompletionRelevance relevance =
       CompletionRelevance.DEFAULT]) {
     if (computer is ImportedComputer) {
-      return assertSuggestGetter(name, returnType, relevance);
+      return assertSuggestGetter(name, returnType, relevance: relevance);
     } else {
       return assertNotSuggested(name);
     }
@@ -500,10 +534,10 @@
   }
 
   CompletionSuggestion assertSuggestImportedTopLevelVar(String name,
-      String returnType, [CompletionRelevance relevance =
-      CompletionRelevance.DEFAULT]) {
+      String returnType, [CompletionRelevance relevance = CompletionRelevance.DEFAULT,
+      CompletionSuggestionKind kind = CompletionSuggestionKind.INVOCATION]) {
     if (computer is ImportedComputer) {
-      return assertSuggestTopLevelVar(name, returnType, relevance);
+      return assertSuggestTopLevelVar(name, returnType, relevance, kind);
     } else {
       return assertNotSuggested(name);
     }
@@ -519,10 +553,14 @@
   }
 
   CompletionSuggestion assertSuggestInvocationGetter(String name,
-      String returnType, [CompletionRelevance relevance =
-      CompletionRelevance.DEFAULT]) {
+      String returnType, {CompletionRelevance relevance: CompletionRelevance.DEFAULT,
+      bool isDeprecated: false}) {
     if (computer is InvocationComputer) {
-      return assertSuggestGetter(name, returnType, relevance);
+      return assertSuggestGetter(
+          name,
+          returnType,
+          relevance: relevance,
+          isDeprecated: isDeprecated);
     } else {
       return assertNotSuggested(name);
     }
@@ -602,7 +640,7 @@
   CompletionSuggestion assertSuggestLocalGetter(String name, String returnType,
       [CompletionRelevance relevance = CompletionRelevance.DEFAULT]) {
     if (computer is LocalComputer) {
-      return assertSuggestGetter(name, returnType, relevance);
+      return assertSuggestGetter(name, returnType, relevance: relevance);
     } else {
       return assertNotSuggested(name);
     }
@@ -632,14 +670,41 @@
     // ArgumentList  MethodInvocation  ExpressionStatement  Block
     addSource('/libA.dart', '''
       library A;
+      bool hasLength(int expected) { }
+      void baz() { }''');
+    addTestSource('''
+      import '/libA.dart'
+      class B { }
+      String bar() => true;
+      void main() {expect(^)}''');
+    computeFast();
+    return computeFull(true).then((_) {
+      assertSuggestLocalFunction('bar', 'String');
+      assertSuggestImportedFunction('hasLength', 'bool');
+      assertSuggestImportedFunction('identical', 'bool');
+      assertSuggestLocalClass('B');
+      assertSuggestImportedClass('Object');
+      assertNotSuggested('main');
+      assertNotSuggested('baz');
+      assertNotSuggested('print');
+    });
+  }
+
+  test_ArgumentList_namedParam() {
+    // SimpleIdentifier  NamedExpression  ArgumentList  MethodInvocation
+    // ExpressionStatement
+    addSource('/libA.dart', '''
+      library A;
       bool hasLength(int expected) { }''');
     addTestSource('''
       import '/libA.dart'
-      main() {expect(^)}''');
+      String bar() => true;
+      void main() {expect(foo: ^)}''');
     computeFast();
     return computeFull(true).then((_) {
-      assertSuggestLocalFunction('main', null);
+      assertSuggestLocalFunction('bar', 'String');
       assertSuggestImportedFunction('hasLength', 'bool');
+      assertNotSuggested('main');
     });
   }
 
@@ -765,7 +830,7 @@
       assertSuggestImportedClass('C');
       // hidden element suggested as low relevance
       assertSuggestImportedClass('D', CompletionRelevance.LOW);
-      assertSuggestImportedFunction('D1', null, true);
+      assertSuggestImportedFunction('D1', null, true, CompletionRelevance.LOW);
       assertSuggestLocalFunction('D2', 'Z');
       assertSuggestImportedClass('EE');
       // hidden element suggested as low relevance
@@ -885,6 +950,28 @@
     });
   }
 
+  test_CascadeExpression_selector2_withTrailingReturn() {
+    // PropertyAccess  CascadeExpression  ExpressionStatement  Block
+    addSource('/testB.dart', '''
+      class B { }''');
+    addTestSource('''
+      import "/testB.dart";
+      class A {var b; X _c;}
+      class X{}
+      main() {A a; a..^ return}''');
+    computeFast();
+    return computeFull(true).then((_) {
+      assertSuggestInvocationGetter('b', null);
+      assertSuggestInvocationGetter('_c', 'X');
+      assertNotSuggested('Object');
+      assertNotSuggested('A');
+      assertNotSuggested('B');
+      assertNotSuggested('X');
+      assertNotSuggested('z');
+      assertNotSuggested('==');
+    });
+  }
+
   test_CascadeExpression_target() {
     // SimpleIdentifier  CascadeExpression  ExpressionStatement
     addTestSource('''
@@ -939,7 +1026,8 @@
       A T;''');
     computeFast();
     return computeFull(true).then((_) {
-      CompletionSuggestion suggestionA = assertSuggestLocalClass('A');
+      CompletionSuggestion suggestionA =
+          assertSuggestLocalClass('A', CompletionRelevance.LOW);
       if (suggestionA != null) {
         expect(suggestionA.element.isDeprecated, isTrue);
         expect(suggestionA.element.isPrivate, isFalse);
@@ -980,15 +1068,7 @@
       class X {}''');
     computeFast();
     return computeFull(true).then((_) {
-      assertSuggestImportedClass('A');
-      assertSuggestImportedClass('B');
-      assertSuggestImportedClass('PB');
-      assertSuggestImportedTopLevelVar('T1', null);
-      assertSuggestImportedFunction('F1', 'PB');
-      assertNotSuggested('C');
-      assertNotSuggested('D');
-      assertNotSuggested('X');
-      assertNotSuggested('Object');
+      assertNoSuggestions();
     });
   }
 
@@ -1015,17 +1095,7 @@
       class X {}''');
     computeFast();
     return computeFull(true).then((_) {
-      assertSuggestImportedClass('A');
-      assertSuggestImportedClass('B');
-      assertSuggestImportedClass('PB');
-      assertSuggestImportedTopLevelVar('T1', null);
-      assertSuggestImportedFunction('F1', 'PB');
-      assertSuggestImportedClass('Clz');
-      assertSuggestImportedFunctionTypeAlias('F2', null);
-      assertNotSuggested('C');
-      assertNotSuggested('D');
-      assertNotSuggested('X');
-      assertNotSuggested('Object');
+      assertNoSuggestions();
     });
   }
 
@@ -1157,6 +1227,23 @@
     });
   }
 
+  test_FormalParameterList() {
+    // FormalParameterList MethodDeclaration
+    addTestSource('''
+      foo() { }
+      void bar() { }
+      class A {a(^) { }}''');
+    computeFast();
+    return computeFull(true).then((_) {
+      assertSuggestLocalFunction('foo', null);
+      assertSuggestLocalMethod('a', 'A', null);
+      assertSuggestLocalClass('A');
+      assertSuggestImportedClass('String');
+      assertSuggestImportedFunction('identical', 'bool');
+      assertNotSuggested('bar');
+    });
+  }
+
   test_ForStatement_body() {
     // Block  ForStatement
     addTestSource('main(args) {for (int i; i < 10; ++i) {^}}');
@@ -1394,7 +1481,8 @@
         expect(methodA.element.isDeprecated, isFalse);
         expect(methodA.element.isPrivate, isFalse);
       }
-      CompletionSuggestion getterF = assertSuggestLocalGetter('f', 'X');
+      CompletionSuggestion getterF =
+          assertSuggestLocalGetter('f', 'X', CompletionRelevance.LOW);
       if (getterF != null) {
         expect(getterF.element.isDeprecated, isTrue);
         expect(getterF.element.isPrivate, isFalse);
@@ -1417,7 +1505,8 @@
         expect(methodA.element.isDeprecated, isFalse);
         expect(methodA.element.isPrivate, isTrue);
       }
-      CompletionSuggestion getterF = assertSuggestLocalGetter('f', 'X');
+      CompletionSuggestion getterF =
+          assertSuggestLocalGetter('f', 'X', CompletionRelevance.LOW);
       if (getterF != null) {
         expect(getterF.element.isDeprecated, isTrue);
         expect(getterF.element.isPrivate, isFalse);
@@ -1436,7 +1525,8 @@
     addTestSource('class A {@deprecated Z a(X x, _, b, {y: boo}) {^}}');
     computeFast();
     return computeFull(true).then((_) {
-      CompletionSuggestion methodA = assertSuggestLocalMethod('a', 'A', 'Z');
+      CompletionSuggestion methodA =
+          assertSuggestLocalMethod('a', 'A', 'Z', CompletionRelevance.LOW);
       if (methodA != null) {
         expect(methodA.element.isDeprecated, isTrue);
         expect(methodA.element.isPrivate, isFalse);
@@ -1550,7 +1640,7 @@
       class I {X get f => new A();get _g => new A();}
       class A implements I {
         static const int sc = 12;
-        var b; X _c;
+        @deprecated var b; X _c;
         X get d => new A();get _e => new A();
         set s1(I x) {} set _s2(I x) {}
         m(X x) {} I _n(X x) {}}
@@ -1561,7 +1651,7 @@
     computeFast();
     return computeFull(true).then((_) {
       assertSuggestInvocationGetter('sc', 'int');
-      assertSuggestInvocationGetter('b', null);
+      assertSuggestInvocationGetter('b', null, isDeprecated: true);
       assertNotSuggested('_c');
       assertSuggestInvocationGetter('d', 'X');
       assertNotSuggested('_e');
diff --git a/pkg/analysis_server/test/services/completion/test_all.dart b/pkg/analysis_server/test/services/completion/test_all.dart
index 1aeba0d..7efd76a 100644
--- a/pkg/analysis_server/test/services/completion/test_all.dart
+++ b/pkg/analysis_server/test/services/completion/test_all.dart
@@ -6,6 +6,7 @@
 
 import 'package:unittest/unittest.dart';
 
+import 'combinator_computer_test.dart' as combinator_test;
 import 'completion_computer_test.dart' as completion_computer_test;
 import 'completion_manager_test.dart' as completion_manager_test;
 import 'imported_computer_test.dart' as imported_test;
@@ -17,6 +18,7 @@
 main() {
   groupSep = ' | ';
   group('completion', () {
+    combinator_test.main();
     completion_computer_test.main();
     completion_manager_test.main();
     imported_test.main();
diff --git a/pkg/analysis_server/test/services/correction/assist_test.dart b/pkg/analysis_server/test/services/correction/assist_test.dart
index 06e6509..65c8cd1 100644
--- a/pkg/analysis_server/test/services/correction/assist_test.dart
+++ b/pkg/analysis_server/test/services/correction/assist_test.dart
@@ -133,6 +133,76 @@
 ''');
   }
 
+  void test_addTypeAnnotation_declaredIdentifier_BAD_hasTypeAnnotation() {
+    _indexTestUnit('''
+main(List<String> items) {
+  for (String item in items) {
+  }
+}
+''');
+    assertNoAssistAt('item in', AssistKind.ADD_TYPE_ANNOTATION);
+  }
+
+  void test_addTypeAnnotation_declaredIdentifier_BAD_inForEachBody() {
+    _indexTestUnit('''
+main(List<String> items) {
+  for (var item in items) {
+    42;
+  }
+}
+''');
+    assertNoAssistAt('42;', AssistKind.ADD_TYPE_ANNOTATION);
+  }
+
+  void test_addTypeAnnotation_declaredIdentifier_BAD_unknownType() {
+    verifyNoTestUnitErrors = false;
+    _indexTestUnit('''
+main() {
+  for (var item in unknownList) {
+  }
+}
+''');
+    assertNoAssistAt('item in', AssistKind.ADD_TYPE_ANNOTATION);
+  }
+
+  void test_addTypeAnnotation_declaredIdentifier_OK() {
+    _indexTestUnit('''
+main(List<String> items) {
+  for (var item in items) {
+  }
+}
+''');
+    // on identifier
+    assertHasAssistAt('item in', AssistKind.ADD_TYPE_ANNOTATION, '''
+main(List<String> items) {
+  for (String item in items) {
+  }
+}
+''');
+    // on "for"
+    assertHasAssistAt('for (', AssistKind.ADD_TYPE_ANNOTATION, '''
+main(List<String> items) {
+  for (String item in items) {
+  }
+}
+''');
+  }
+
+  void test_addTypeAnnotation_declaredIdentifier_OK_final() {
+    _indexTestUnit('''
+main(List<String> items) {
+  for (final item in items) {
+  }
+}
+''');
+    assertHasAssistAt('item in', AssistKind.ADD_TYPE_ANNOTATION, '''
+main(List<String> items) {
+  for (final String item in items) {
+  }
+}
+''');
+  }
+
   void test_addTypeAnnotation_local_OK_Function() {
     _indexTestUnit('''
 main() {
@@ -211,6 +281,19 @@
 ''');
   }
 
+  void test_addTypeAnnotation_local_OK_onVariableDeclarationStatement() {
+    _indexTestUnit('''
+main() {
+  var v = 123; // marker
+}
+''');
+    assertHasAssistAt(' // marker', AssistKind.ADD_TYPE_ANNOTATION, '''
+main() {
+  int v = 123; // marker
+}
+''');
+  }
+
   void test_addTypeAnnotation_local_wrong_hasTypeAnnotation() {
     _indexTestUnit('''
 main() {
@@ -1897,6 +1980,19 @@
 ''');
   }
 
+  void test_replaceIfElseWithConditional_wrong_expressionVsReturn() {
+    _indexTestUnit('''
+main() {
+  if (true) {
+    print(42);
+  } else {
+    return;
+  }
+}
+''');
+    assertNoAssistAt('else', AssistKind.REPLACE_IF_ELSE_WITH_CONDITIONAL);
+  }
+
   void test_replaceIfElseWithConditional_wrong_notIfStatement() {
     _indexTestUnit('''
 main() {
diff --git a/pkg/analysis_server/test/services/correction/name_suggestion_test.dart b/pkg/analysis_server/test/services/correction/name_suggestion_test.dart
index 9ef37c3..c1b2273 100644
--- a/pkg/analysis_server/test/services/correction/name_suggestion_test.dart
+++ b/pkg/analysis_server/test/services/correction/name_suggestion_test.dart
@@ -5,12 +5,13 @@
 library test.services.correction.name_suggestion;
 
 import 'package:analysis_server/src/services/correction/name_suggestion.dart';
-import '../../abstract_single_unit.dart';
-import '../../reflective_tests.dart';
 import 'package:analyzer/src/generated/ast.dart';
 import 'package:analyzer/src/generated/element.dart';
 import 'package:unittest/unittest.dart';
 
+import '../../abstract_single_unit.dart';
+import '../../reflective_tests.dart';
+
 
 main() {
   groupSep = ' | ';
@@ -45,31 +46,13 @@
     DartType expectedType = (findElement('node') as LocalVariableElement).type;
     Expression assignedExpression =
         findNodeAtString('null;', (node) => node is NullLiteral);
-    List<String> suggestions =
-        getVariableNameSuggestionsForExpression(
-            expectedType,
-            assignedExpression,
-            excluded);
+    List<String> suggestions = getVariableNameSuggestionsForExpression(
+        expectedType,
+        assignedExpression,
+        excluded);
     expect(suggestions, unorderedEquals(['treeNode', 'node']));
   }
 
-  void test_forExpression_expectedType_String() {
-    resolveTestUnit('''
-main() {
-  String res = 'abc';
-}
-''');
-    DartType expectedType = (findElement('res') as LocalVariableElement).type;
-    Expression assignedExpression = findNodeAtString("'abc';");
-    // first choice for "String" is "s"
-    expect(
-        getVariableNameSuggestionsForExpression(
-            expectedType,
-            assignedExpression,
-            new Set.from([])),
-        unorderedEquals(['s']));
-  }
-
   void test_forExpression_expectedType_double() {
     resolveTestUnit('''
 main() {
@@ -118,6 +101,23 @@
         unorderedEquals(['k']));
   }
 
+  void test_forExpression_expectedType_String() {
+    resolveTestUnit('''
+main() {
+  String res = 'abc';
+}
+''');
+    DartType expectedType = (findElement('res') as LocalVariableElement).type;
+    Expression assignedExpression = findNodeAtString("'abc';");
+    // first choice for "String" is "s"
+    expect(
+        getVariableNameSuggestionsForExpression(
+            expectedType,
+            assignedExpression,
+            new Set.from([])),
+        unorderedEquals(['s']));
+  }
+
   void test_forExpression_instanceCreation() {
     verifyNoTestUnitErrors = false;
     resolveTestUnit('''
@@ -268,6 +268,21 @@
         unorderedEquals([]));
   }
 
+  void test_forExpression_prefixedIdentifier() {
+    resolveTestUnit('''
+main(p) {
+  var res = p.sortedNodes;
+}
+''');
+    var excluded = new Set.from([]);
+    expect(
+        getVariableNameSuggestionsForExpression(
+            null,
+            findNodeAtString('p.sorted', (node) => node is PrefixedIdentifier),
+            excluded),
+        unorderedEquals(['sortedNodes', 'nodes']));
+  }
+
   void test_forExpression_privateName() {
     resolveTestUnit('''
 main(p) {
@@ -293,15 +308,14 @@
   void test_forExpression_propertyAccess() {
     resolveTestUnit('''
 main(p) {
-  var res = p.sortedNodes;
+  var res = p.q.sortedNodes;
 }
 ''');
     var excluded = new Set.from([]);
+    PropertyAccess expression =
+        findNodeAtString('p.q.sorted', (node) => node is PropertyAccess);
     expect(
-        getVariableNameSuggestionsForExpression(
-            null,
-            findNodeAtString('p.sorted', (node) => node is PrefixedIdentifier),
-            excluded),
+        getVariableNameSuggestionsForExpression(null, expression, excluded),
         unorderedEquals(['sortedNodes', 'nodes']));
   }
 
diff --git a/pkg/analysis_server/test/services/index/store/split_store_test.dart b/pkg/analysis_server/test/services/index/store/split_store_test.dart
index 452fae9..35372e0 100644
--- a/pkg/analysis_server/test/services/index/store/split_store_test.dart
+++ b/pkg/analysis_server/test/services/index/store/split_store_test.dart
@@ -132,7 +132,7 @@
       // no IndexNode
       expect(node, isNull);
       // failed
-      verify(logger.logError2(anyObject, anyObject)).once();
+      verify(logger.logError(anyObject, anyObject)).once();
     });
   }
 
@@ -145,7 +145,7 @@
     return nodeManager.getNode(name).then((IndexNode node) {
       expect(node, isNull);
       // failed
-      verify(logger.logError2(anyString, anyObject)).once();
+      verify(logger.logError(anyString, anyObject)).once();
     });
   }
 
@@ -236,7 +236,7 @@
     // try to put
     return nodeManager.putNode(name, node).then((_) {
       // failed
-      verify(logger.logError2(anyString, anyObject)).once();
+      verify(logger.logError(anyString, anyObject)).once();
     });
   }
 
diff --git a/pkg/analysis_server/test/services/refactoring/inline_local_test.dart b/pkg/analysis_server/test/services/refactoring/inline_local_test.dart
index 17e0b73..bbed045 100644
--- a/pkg/analysis_server/test/services/refactoring/inline_local_test.dart
+++ b/pkg/analysis_server/test/services/refactoring/inline_local_test.dart
@@ -24,6 +24,102 @@
 class InlineLocalTest extends RefactoringTest {
   InlineLocalRefactoringImpl refactoring;
 
+  test_access() {
+    indexTestUnit('''
+main() {
+  int test = 1 + 2;
+  print(test);
+  print(test);
+}
+''');
+    _createRefactoring('test =');
+    expect(refactoring.refactoringName, 'Inline Local Variable');
+    // check initial conditions and access
+    return refactoring.checkInitialConditions().then((_) {
+      expect(refactoring.variableName, 'test');
+      expect(refactoring.referenceCount, 2);
+    });
+  }
+
+  test_bad_selectionMethod() {
+    indexTestUnit(r'''
+main() {
+}
+''');
+    _createRefactoring('main() {');
+    return refactoring.checkInitialConditions().then((status) {
+      _assert_fatalError_selection(status);
+    });
+  }
+
+  test_bad_selectionParameter() {
+    indexTestUnit(r'''
+main(int test) {
+}
+''');
+    _createRefactoring('test) {');
+    return refactoring.checkInitialConditions().then((status) {
+      _assert_fatalError_selection(status);
+    });
+  }
+
+  test_bad_selectionVariable_hasAssignments_1() {
+    indexTestUnit(r'''
+main() {
+  int test = 0;
+  test = 1;
+}
+''');
+    _createRefactoring('test = 0');
+    return refactoring.checkInitialConditions().then((status) {
+      assertRefactoringStatus(
+          status,
+          RefactoringProblemSeverity.FATAL,
+          expectedContextSearch: 'test = 1');
+    });
+  }
+
+  test_bad_selectionVariable_hasAssignments_2() {
+    indexTestUnit(r'''
+main() {
+  int test = 0;
+  test += 1;
+}
+''');
+    _createRefactoring('test = 0');
+    return refactoring.checkInitialConditions().then((status) {
+      assertRefactoringStatus(
+          status,
+          RefactoringProblemSeverity.FATAL,
+          expectedContextSearch: 'test += 1');
+    });
+  }
+
+  test_bad_selectionVariable_notInBlock() {
+    indexTestUnit(r'''
+main() {
+  if (true)
+    int test = 0;
+}
+''');
+    _createRefactoring('test = 0');
+    return refactoring.checkInitialConditions().then((status) {
+      assertRefactoringStatus(status, RefactoringProblemSeverity.FATAL);
+    });
+  }
+
+  test_bad_selectionVariable_notInitialized() {
+    indexTestUnit(r'''
+main() {
+  int test;
+}
+''');
+    _createRefactoring('test;');
+    return refactoring.checkInitialConditions().then((status) {
+      assertRefactoringStatus(status, RefactoringProblemSeverity.FATAL);
+    });
+  }
+
   test_OK_cascade_intoCascade() {
     indexTestUnit(r'''
 class A {
@@ -118,24 +214,6 @@
 ''');
   }
 
-  test_OK_intoStringInterpolation_stringInterpolation() {
-    indexTestUnit(r'''
-main() {
-  String a = 'aaa';
-  String b = '$a bbb';
-  String c = '$b ccc';
-}
-''');
-    _createRefactoring('b =');
-    // validate change
-    return assertSuccessfulRefactoring(r'''
-main() {
-  String a = 'aaa';
-  String c = '$a bbb ccc';
-}
-''');
-  }
-
   test_OK_intoStringInterpolation_string_differentQuotes() {
     indexTestUnit(r'''
 main() {
@@ -298,6 +376,24 @@
 ''');
   }
 
+  test_OK_intoStringInterpolation_stringInterpolation() {
+    indexTestUnit(r'''
+main() {
+  String a = 'aaa';
+  String b = '$a bbb';
+  String c = '$b ccc';
+}
+''');
+    _createRefactoring('b =');
+    // validate change
+    return assertSuccessfulRefactoring(r'''
+main() {
+  String a = 'aaa';
+  String c = '$a bbb ccc';
+}
+''');
+  }
+
   /**
    * <p>
    * https://code.google.com/p/dart/issues/detail?id=18587
@@ -368,6 +464,24 @@
 ''');
   }
 
+  test_OK_parenthesis_decrement_intoNegate() {
+    indexTestUnit('''
+main() {
+  var a = 1;
+  var test = --a;
+  var b = -test;
+}
+''');
+    _createRefactoring('test =');
+    // validate change
+    return assertSuccessfulRefactoring('''
+main() {
+  var a = 1;
+  var b = -(--a);
+}
+''');
+  }
+
   test_OK_parenthesis_instanceCreation_intoList() {
     indexTestUnit('''
 class A {}
@@ -386,6 +500,24 @@
 ''');
   }
 
+  test_OK_parenthesis_negate_intoNegate() {
+    indexTestUnit('''
+main() {
+  var a = 1;
+  var test = -a;
+  var b = -test;
+}
+''');
+    _createRefactoring('test =');
+    // validate change
+    return assertSuccessfulRefactoring('''
+main() {
+  var a = 1;
+  var b = -(-a);
+}
+''');
+  }
+
   test_OK_parenthesis_plus_intoMultiply() {
     indexTestUnit('''
 main() {
@@ -420,102 +552,6 @@
 ''');
   }
 
-  test_access() {
-    indexTestUnit('''
-main() {
-  int test = 1 + 2;
-  print(test);
-  print(test);
-}
-''');
-    _createRefactoring('test =');
-    expect(refactoring.refactoringName, 'Inline Local Variable');
-    // check initial conditions and access
-    return refactoring.checkInitialConditions().then((_) {
-      expect(refactoring.variableName, 'test');
-      expect(refactoring.referenceCount, 2);
-    });
-  }
-
-  test_bad_selectionMethod() {
-    indexTestUnit(r'''
-main() {
-}
-''');
-    _createRefactoring('main() {');
-    return refactoring.checkInitialConditions().then((status) {
-      _assert_fatalError_selection(status);
-    });
-  }
-
-  test_bad_selectionParameter() {
-    indexTestUnit(r'''
-main(int test) {
-}
-''');
-    _createRefactoring('test) {');
-    return refactoring.checkInitialConditions().then((status) {
-      _assert_fatalError_selection(status);
-    });
-  }
-
-  test_bad_selectionVariable_hasAssignments_1() {
-    indexTestUnit(r'''
-main() {
-  int test = 0;
-  test = 1;
-}
-''');
-    _createRefactoring('test = 0');
-    return refactoring.checkInitialConditions().then((status) {
-      assertRefactoringStatus(
-          status,
-          RefactoringProblemSeverity.FATAL,
-          expectedContextSearch: 'test = 1');
-    });
-  }
-
-  test_bad_selectionVariable_hasAssignments_2() {
-    indexTestUnit(r'''
-main() {
-  int test = 0;
-  test += 1;
-}
-''');
-    _createRefactoring('test = 0');
-    return refactoring.checkInitialConditions().then((status) {
-      assertRefactoringStatus(
-          status,
-          RefactoringProblemSeverity.FATAL,
-          expectedContextSearch: 'test += 1');
-    });
-  }
-
-  test_bad_selectionVariable_notInBlock() {
-    indexTestUnit(r'''
-main() {
-  if (true)
-    int test = 0;
-}
-''');
-    _createRefactoring('test = 0');
-    return refactoring.checkInitialConditions().then((status) {
-      assertRefactoringStatus(status, RefactoringProblemSeverity.FATAL);
-    });
-  }
-
-  test_bad_selectionVariable_notInitialized() {
-    indexTestUnit(r'''
-main() {
-  int test;
-}
-''');
-    _createRefactoring('test;');
-    return refactoring.checkInitialConditions().then((status) {
-      assertRefactoringStatus(status, RefactoringProblemSeverity.FATAL);
-    });
-  }
-
   void _assert_fatalError_selection(RefactoringStatus status) {
     expect(refactoring.variableName, isNull);
     expect(refactoring.referenceCount, 0);
diff --git a/pkg/analysis_server/test/services/refactoring/inline_method_test.dart b/pkg/analysis_server/test/services/refactoring/inline_method_test.dart
index d665de6..5a87e76 100644
--- a/pkg/analysis_server/test/services/refactoring/inline_method_test.dart
+++ b/pkg/analysis_server/test/services/refactoring/inline_method_test.dart
@@ -998,6 +998,85 @@
 ''');
   }
 
+  test_noArgument_named_hasDefault() {
+    verifyNoTestUnitErrors = false;
+    indexTestUnit(r'''
+test({a: 42}) {
+  print(a);
+}
+main() {
+  test();
+}
+''');
+    _createRefactoring('test(');
+    // validate change
+    return _assertSuccessfulRefactoring(r'''
+main() {
+  print(42);
+}
+''');
+  }
+
+  test_noArgument_positional_hasDefault() {
+    verifyNoTestUnitErrors = false;
+    indexTestUnit(r'''
+test([a = 42]) {
+  print(a);
+}
+main() {
+  test();
+}
+''');
+    _createRefactoring('test(');
+    // validate change
+    return _assertSuccessfulRefactoring(r'''
+main() {
+  print(42);
+}
+''');
+  }
+
+  test_noArgument_positional_noDefault() {
+    verifyNoTestUnitErrors = false;
+    indexTestUnit(r'''
+test([a]) {
+  print(a);
+}
+main() {
+  test();
+}
+''');
+    _createRefactoring('test(');
+    // validate change
+    return _assertSuccessfulRefactoring(r'''
+main() {
+  print(null);
+}
+''');
+  }
+
+  test_noArgument_required() {
+    verifyNoTestUnitErrors = false;
+    indexTestUnit(r'''
+test(a) {
+  print(a);
+}
+main() {
+  test();
+}
+''');
+    _createRefactoring('test();');
+    // error
+    return refactoring.checkAllConditions().then((status) {
+      var location = new SourceRange(findOffset('test();'), 'test()'.length);
+      assertRefactoringStatus(
+          status,
+          RefactoringProblemSeverity.ERROR,
+          expectedMessage: 'No argument for the parameter "a".',
+          expectedContextRange: location);
+    });
+  }
+
   test_reference_expressionBody() {
     indexTestUnit(r'''
 String message() => 'Hello, World!';
diff --git a/pkg/analysis_server/test/services/refactoring/rename_unit_member_test.dart b/pkg/analysis_server/test/services/refactoring/rename_unit_member_test.dart
index 84a34fe..f78c21a 100644
--- a/pkg/analysis_server/test/services/refactoring/rename_unit_member_test.dart
+++ b/pkg/analysis_server/test/services/refactoring/rename_unit_member_test.dart
@@ -173,9 +173,6 @@
   }
 
   test_checkFinalConditions_shadowsInSubClass_notImportedLib() {
-    indexTestUnit('''
-class Test {}
-''');
     indexUnit('/lib.dart', '''
 library my.lib;
 class A {
@@ -187,6 +184,9 @@
   }",
 }
 ''');
+    indexTestUnit('''
+class Test {}
+''');
     createRenameRefactoringAtString('Test {}');
     // check status
     refactoring.newName = 'NewName';
diff --git a/pkg/analysis_server/tool/spec/spec_input.html b/pkg/analysis_server/tool/spec/spec_input.html
index da50b3c..70ee2b2 100644
--- a/pkg/analysis_server/tool/spec/spec_input.html
+++ b/pkg/analysis_server/tool/spec/spec_input.html
@@ -1879,26 +1879,35 @@
         </p>
         <enum>
           <value><code>ARGUMENT_LIST</code></value>
-          <value><code>CLASS</code></value>
-          <value><code>CLASS_ALIAS</code></value>
-          <value><code>CONSTRUCTOR</code></value>
-          <value><code>FIELD</code></value>
-          <value><code>FUNCTION</code></value>
-          <value><code>FUNCTION_TYPE_ALIAS</code></value>
-          <value><code>GETTER</code></value>
           <value><code>IMPORT</code></value>
-          <value><code>KEYWORD</code></value>
-          <value><code>LABEL</code></value>
-          <value><code>LIBRARY_PREFIX</code></value>
-          <value><code>LOCAL_VARIABLE</code></value>
-          <value><code>METHOD</code></value>
-          <value><code>METHOD_NAME</code></value>
+          <value>
+            <code>IDENTIFIER</code>
+            <p>
+              The element identifier should be inserted at the completion location.
+              For example "someMethod" in import 'myLib.dart' show someMethod; .
+              For suggestions of this kind, the element attribute is defined 
+              and the completion field is the element's identifier.
+            </p>
+          </value>
+          <value>
+            <code>INVOCATION</code>
+            <p>
+              The element is being invoked at the completion location.
+              For example, "someMethod" in x.someMethod(); .
+              For suggestions of this kind, the element attribute is defined 
+              and the completion field is the element's identifier.
+            </p>
+          </value>
+          <value>
+            <code>KEYWORD</code>
+            <p>
+              A keyword is being suggested.
+              For suggestions of this kind, the completion is the keyword.
+            </p>
+          </value>
           <value><code>NAMED_ARGUMENT</code></value>
           <value><code>OPTIONAL_ARGUMENT</code></value>
           <value><code>PARAMETER</code></value>
-          <value><code>SETTER</code></value>
-          <value><code>TOP_LEVEL_VARIABLE</code></value>
-          <value><code>TYPE_PARAMETER</code></value>
         </enum>
       </type>
       <type name="Element">
diff --git a/pkg/analyzer/bin/coverage.dart b/pkg/analyzer/bin/coverage.dart
index 30efc6c..32194c6 100644
--- a/pkg/analyzer/bin/coverage.dart
+++ b/pkg/analyzer/bin/coverage.dart
@@ -78,7 +78,7 @@
 
 
 printUsage([var description = 'Code coverage tool for Dart.']) {
-  var usage = _argParser.getUsage();
+  var usage = _argParser.usage;
   print('$description\n');
   print('Usage: coverage [options] <script>\n');
   print('$usage\n');
diff --git a/pkg/analyzer/bin/formatter.dart b/pkg/analyzer/bin/formatter.dart
index c4c689e..28436f6 100755
--- a/pkg/analyzer/bin/formatter.dart
+++ b/pkg/analyzer/bin/formatter.dart
@@ -227,7 +227,7 @@
         ..write('\n\n')
         ..write('Usage: $BINARY_NAME [flags] [path...]\n\n')
         ..write('Supported flags are:\n')
-        ..write('${argParser.getUsage()}\n\n');
+        ..write('${argParser.usage}\n\n');
   _log(buffer.toString());
 }
 
diff --git a/pkg/analyzer/lib/options.dart b/pkg/analyzer/lib/options.dart
index f6e51e7..0e31c41 100644
--- a/pkg/analyzer/lib/options.dart
+++ b/pkg/analyzer/lib/options.dart
@@ -276,9 +276,9 @@
   /**
    * Generates a string displaying usage information for the defined options.
    *
-   * See [ArgParser.getUsage()].
+   * See [ArgParser.usage].
    */
-  String getUsage() => _parser.getUsage();
+  String getUsage() => _parser.usage;
 
   /**
    * Parses [args], a list of command-line arguments, matches them against the
diff --git a/pkg/analyzer/lib/src/analyzer_impl.dart b/pkg/analyzer/lib/src/analyzer_impl.dart
index 4de0a6a1..25bac6e 100644
--- a/pkg/analyzer/lib/src/analyzer_impl.dart
+++ b/pkg/analyzer/lib/src/analyzer_impl.dart
@@ -24,6 +24,7 @@
 import 'package:analyzer/source/package_map_resolver.dart';
 import 'package:analyzer/source/package_map_provider.dart';
 import 'package:analyzer/source/pub_package_map_provider.dart';
+import 'package:analyzer/src/generated/java_engine.dart';
 
 /**
  * The maximum number of sources for which AST structures should be kept in the cache.
@@ -67,7 +68,8 @@
   final HashMap<Source, AnalysisErrorInfo> sourceErrorsMap =
       new HashMap<Source, AnalysisErrorInfo>();
 
-  AnalyzerImpl(this.sourcePath, this.options, this.startTime) {
+  AnalyzerImpl(String sourcePath, this.options, this.startTime)
+      : sourcePath = _normalizeSourcePath(sourcePath) {
     if (sdk == null) {
       sdk = new DirectoryBasedDartSdk(new JavaFile(options.dartSdkPath));
     }
@@ -111,6 +113,13 @@
     prepareAnalysisContext(sourceFile, librarySource);
   }
 
+  /**
+   * Convert [sourcePath] into an absolute path.
+   */
+  static String _normalizeSourcePath(String sourcePath) {
+    return new File(sourcePath).absolute.path;
+  }
+
   /// The sync version of analysis.
   ErrorSeverity _analyzeSync(int printMode) {
     // don't try to analyze parts
@@ -411,24 +420,30 @@
   StdLogger(this.log);
 
   @override
-  void logError(String message) {
+  void logError(String message, [CaughtException exception]) {
     stderr.writeln(message);
-  }
-
-  @override
-  void logError2(String message, Exception exception) {
-    stderr.writeln(message);
-  }
-
-  @override
-  void logInformation(String message) {
-    if (log) {
-      stdout.writeln(message);
+    if (exception != null) {
+      stderr.writeln(exception);
     }
   }
 
   @override
-  void logInformation2(String message, Exception exception) {
+  void logError2(String message, Object exception) {
+    stderr.writeln(message);
+  }
+
+  @override
+  void logInformation(String message, [CaughtException exception]) {
+    if (log) {
+      stdout.writeln(message);
+      if (exception != null) {
+        stderr.writeln(exception);
+      }
+    }
+  }
+
+  @override
+  void logInformation2(String message, Object exception) {
     if (log) {
       stdout.writeln(message);
     }
diff --git a/pkg/analyzer/lib/src/generated/ast.dart b/pkg/analyzer/lib/src/generated/ast.dart
index f5506fb..ddc9a1b 100644
--- a/pkg/analyzer/lib/src/generated/ast.dart
+++ b/pkg/analyzer/lib/src/generated/ast.dart
@@ -801,7 +801,9 @@
       } else {
         message = "The right-hand size is null";
       }
-      AnalysisEngine.instance.logger.logError2(message, new JavaException(message));
+      AnalysisEngine.instance.logger.logError(
+          message,
+          new CaughtException(new AnalysisException(message), null));
     }
     this._leftHandSide = becomeParentOf(leftHandSide);
     this._rightHandSide = becomeParentOf(rightHandSide);
@@ -1390,7 +1392,7 @@
           cloneToken(node.leftParenthesis),
           cloneNode(node.identifier),
           cloneToken(node.inKeyword),
-          cloneNode(node.iterator),
+          cloneNode(node.iterable),
           cloneToken(node.rightParenthesis),
           cloneNode(node.body));
     }
@@ -1400,7 +1402,7 @@
         cloneToken(node.leftParenthesis),
         cloneNode(loopVariable),
         cloneToken(node.inKeyword),
-        cloneNode(node.iterator),
+        cloneNode(node.iterable),
         cloneToken(node.rightParenthesis),
         cloneNode(node.body));
   }
@@ -2157,7 +2159,7 @@
   @override
   bool visitForEachStatement(ForEachStatement node) {
     ForEachStatement other = this._other as ForEachStatement;
-    return isEqualTokens(node.forKeyword, other.forKeyword) && isEqualTokens(node.leftParenthesis, other.leftParenthesis) && isEqualNodes(node.loopVariable, other.loopVariable) && isEqualTokens(node.inKeyword, other.inKeyword) && isEqualNodes(node.iterator, other.iterator) && isEqualTokens(node.rightParenthesis, other.rightParenthesis) && isEqualNodes(node.body, other.body);
+    return isEqualTokens(node.forKeyword, other.forKeyword) && isEqualTokens(node.leftParenthesis, other.leftParenthesis) && isEqualNodes(node.loopVariable, other.loopVariable) && isEqualTokens(node.inKeyword, other.inKeyword) && isEqualNodes(node.iterable, other.iterable) && isEqualTokens(node.rightParenthesis, other.rightParenthesis) && isEqualNodes(node.body, other.body);
   }
 
   @override
@@ -7518,7 +7520,7 @@
   /**
    * The expression evaluated to produce the iterator.
    */
-  Expression _iterator;
+  Expression _iterable;
 
   /**
    * The right parenthesis.
@@ -7543,7 +7545,7 @@
    */
   ForEachStatement.con1(this.awaitKeyword, this.forKeyword, this.leftParenthesis, DeclaredIdentifier loopVariable, this.inKeyword, Expression iterator, this.rightParenthesis, Statement body) {
     this._loopVariable = becomeParentOf(loopVariable);
-    this._iterator = becomeParentOf(iterator);
+    this._iterable = becomeParentOf(iterator);
     this._body = becomeParentOf(body);
   }
 
@@ -7560,7 +7562,7 @@
    */
   ForEachStatement.con2(this.awaitKeyword, this.forKeyword, this.leftParenthesis, SimpleIdentifier identifier, this.inKeyword, Expression iterator, this.rightParenthesis, Statement body) {
     this._identifier = becomeParentOf(identifier);
-    this._iterator = becomeParentOf(iterator);
+    this._iterable = becomeParentOf(iterator);
     this._body = becomeParentOf(body);
   }
 
@@ -7592,7 +7594,7 @@
    *
    * @return the expression evaluated to produce the iterator
    */
-  Expression get iterator => _iterator;
+  Expression get iterable => _iterable;
 
   /**
    * Return the declaration of the loop variable, or `null` if the loop variable is a simple
@@ -7625,8 +7627,8 @@
    *
    * @param expression the expression evaluated to produce the iterator
    */
-  void set iterator(Expression expression) {
-    _iterator = becomeParentOf(expression);
+  void set iterable(Expression expression) {
+    _iterable = becomeParentOf(expression);
   }
 
   /**
@@ -7642,7 +7644,7 @@
   void visitChildren(AstVisitor visitor) {
     safelyVisitChild(_loopVariable, visitor);
     safelyVisitChild(_identifier, visitor);
-    safelyVisitChild(_iterator, visitor);
+    safelyVisitChild(_iterable, visitor);
     safelyVisitChild(_body, visitor);
   }
 }
@@ -9879,9 +9881,9 @@
   ForEachStatement visitForEachStatement(ForEachStatement node) {
     DeclaredIdentifier loopVariable = node.loopVariable;
     if (loopVariable == null) {
-      return new ForEachStatement.con2(_mapToken(node.awaitKeyword), _mapToken(node.forKeyword), _mapToken(node.leftParenthesis), _cloneNode(node.identifier), _mapToken(node.inKeyword), _cloneNode(node.iterator), _mapToken(node.rightParenthesis), _cloneNode(node.body));
+      return new ForEachStatement.con2(_mapToken(node.awaitKeyword), _mapToken(node.forKeyword), _mapToken(node.leftParenthesis), _cloneNode(node.identifier), _mapToken(node.inKeyword), _cloneNode(node.iterable), _mapToken(node.rightParenthesis), _cloneNode(node.body));
     }
-    return new ForEachStatement.con1(_mapToken(node.awaitKeyword), _mapToken(node.forKeyword), _mapToken(node.leftParenthesis), _cloneNode(loopVariable), _mapToken(node.inKeyword), _cloneNode(node.iterator), _mapToken(node.rightParenthesis), _cloneNode(node.body));
+    return new ForEachStatement.con1(_mapToken(node.awaitKeyword), _mapToken(node.forKeyword), _mapToken(node.leftParenthesis), _cloneNode(loopVariable), _mapToken(node.inKeyword), _cloneNode(node.iterable), _mapToken(node.rightParenthesis), _cloneNode(node.body));
   }
 
   @override
@@ -12443,8 +12445,10 @@
       node.accept(this);
     } on NodeLocator_NodeFoundException catch (exception) {
       // A node with the right source position was found.
-    } catch (exception) {
-      AnalysisEngine.instance.logger.logInformation2("Unable to locate element at offset ($_startOffset - $_endOffset)", exception);
+    } catch (exception, stackTrace) {
+      AnalysisEngine.instance.logger.logInformation(
+          "Unable to locate element at offset ($_startOffset - $_endOffset)",
+          new CaughtException(exception, stackTrace));
       return null;
     }
     return _foundNode;
@@ -12463,10 +12467,12 @@
     try {
       node.visitChildren(this);
     } on NodeLocator_NodeFoundException catch (exception) {
-      throw exception;
-    } catch (exception) {
+      rethrow;
+    } catch (exception, stackTrace) {
       // Ignore the exception and proceed in order to visit the rest of the structure.
-      AnalysisEngine.instance.logger.logInformation2("Exception caught while traversing an AST structure.", exception);
+      AnalysisEngine.instance.logger.logInformation(
+          "Exception caught while traversing an AST structure.",
+          new CaughtException(exception, stackTrace));
     }
     if (start <= _startOffset && _endOffset <= end) {
       _foundNode = node;
@@ -12939,8 +12945,8 @@
     } else if (identical(node.identifier, _oldNode)) {
       node.identifier = _newNode as SimpleIdentifier;
       return true;
-    } else if (identical(node.iterator, _oldNode)) {
-      node.iterator = _newNode as Expression;
+    } else if (identical(node.iterable, _oldNode)) {
+      node.iterable = _newNode as Expression;
       return true;
     } else if (identical(node.body, _oldNode)) {
       node.body = _newNode as Statement;
@@ -16348,6 +16354,12 @@
         return false;
       }
     }
+    if (parent is ForEachStatement) {
+      ForEachStatement stmt = parent as ForEachStatement;
+      if (identical(stmt.identifier, target)) {
+        return false;
+      }
+    }
     return true;
   }
 
@@ -16387,6 +16399,8 @@
       return true;
     } else if (parent is AssignmentExpression) {
       return identical((parent as AssignmentExpression).leftHandSide, target);
+    } else if (parent is ForEachStatement) {
+      return identical((parent as ForEachStatement).identifier, target);
     }
     return false;
   }
@@ -16452,7 +16466,9 @@
    */
   Element _returnOrReportElement(AstNode parent, bool isValid, Element element) {
     if (!isValid) {
-      AnalysisEngine.instance.logger.logInformation2("Internal error: attempting to set the name of a ${parent.runtimeType} to a ${element.runtimeType}", new JavaException());
+      AnalysisEngine.instance.logger.logInformation(
+          "Internal error: attempting to set the name of a ${parent.runtimeType} to a ${element.runtimeType}",
+          new CaughtException(new AnalysisException(), null));
       return null;
     }
     return element;
@@ -17765,7 +17781,7 @@
       _visitNode(loopVariable);
     }
     _writer.print(" in ");
-    _visitNode(node.iterator);
+    _visitNode(node.iterable);
     _writer.print(") ");
     _visitNode(node.body);
     return null;
diff --git a/pkg/analyzer/lib/src/generated/constant.dart b/pkg/analyzer/lib/src/generated/constant.dart
index ee68be8..21f12f6 100644
--- a/pkg/analyzer/lib/src/generated/constant.dart
+++ b/pkg/analyzer/lib/src/generated/constant.dart
@@ -74,6 +74,11 @@
   @override
   BoolState equalEqual(InstanceState rightOperand) {
     assertBoolNumStringOrNull(rightOperand);
+    return isIdentical(rightOperand);
+  }
+
+  @override
+  BoolState isIdentical(InstanceState rightOperand) {
     if (value == null) {
       return UNKNOWN_VALUE;
     }
@@ -1253,7 +1258,8 @@
             if (library.isDartCore) {
               DartObjectImpl leftArgument = arguments[0].accept(this);
               DartObjectImpl rightArgument = arguments[1].accept(this);
-              return _dartObjectComputer.equalEqual(node, leftArgument, rightArgument);
+              return _dartObjectComputer.isIdentical(node, leftArgument,
+                  rightArgument);
             }
           }
         }
@@ -1727,6 +1733,18 @@
     return null;
   }
 
+  DartObjectImpl isIdentical(Expression node, DartObjectImpl leftOperand,
+                             DartObjectImpl rightOperand) {
+    if (leftOperand != null && rightOperand != null) {
+      try {
+        return leftOperand.isIdentical(_typeProvider, rightOperand);
+      } on EvaluationException catch (exception) {
+        _errorReporter.reportErrorForNode(exception.errorCode, node, []);
+      }
+    }
+    return null;
+  }
+
   DartObjectImpl lessThan(BinaryExpression node, DartObjectImpl leftOperand, DartObjectImpl rightOperand) {
     if (leftOperand != null && rightOperand != null) {
       try {
@@ -2119,6 +2137,21 @@
   DartObjectImpl integerDivide(TypeProvider typeProvider, DartObjectImpl rightOperand) => new DartObjectImpl(typeProvider.intType, _state.integerDivide(rightOperand._state));
 
   /**
+   * Return the result of invoking the identical function on this object with
+   * the given argument.
+   *
+   * @param typeProvider the type provider used to find known types
+   * @param rightOperand the right-hand operand of the operation
+   * @return the result of invoking the identical function on this object with
+   *         the given argument
+   */
+  DartObjectImpl isIdentical(TypeProvider typeProvider,
+                             DartObjectImpl rightOperand) {
+    return new DartObjectImpl(typeProvider.boolType,
+        _state.isIdentical(rightOperand._state));
+  }
+
+  /**
    * Return `true` if this object represents an object whose type is 'bool'.
    *
    * @return `true` if this object represents a boolean value
@@ -2517,6 +2550,11 @@
   @override
   BoolState equalEqual(InstanceState rightOperand) {
     assertBoolNumStringOrNull(rightOperand);
+    return isIdentical(rightOperand);
+  }
+
+  @override
+  BoolState isIdentical(InstanceState rightOperand) {
     if (value == null) {
       return BoolState.UNKNOWN_VALUE;
     }
@@ -2824,6 +2862,11 @@
   }
 
   @override
+  BoolState isIdentical(InstanceState rightOperand) {
+    return BoolState.UNKNOWN_VALUE;
+  }
+
+  @override
   String get typeName => "dynamic";
 
   @override
@@ -3080,6 +3123,11 @@
 
   @override
   BoolState equalEqual(InstanceState rightOperand) {
+    return isIdentical(rightOperand);
+  }
+
+  @override
+  BoolState isIdentical(InstanceState rightOperand) {
     if (_element == null) {
       return BoolState.UNKNOWN_VALUE;
     }
@@ -3138,6 +3186,11 @@
   @override
   BoolState equalEqual(InstanceState rightOperand) {
     assertBoolNumStringOrNull(rightOperand);
+    return isIdentical(rightOperand);
+  }
+
+  @override
+  BoolState isIdentical(InstanceState rightOperand) {
     if (rightOperand is DynamicState) {
       return BoolState.UNKNOWN_VALUE;
     }
@@ -3376,6 +3429,16 @@
   }
 
   /**
+   * Return the result of invoking the identical function on this object with
+   * the given argument.
+   *
+   * @param rightOperand the right-hand operand of the operation
+   * @return the result of invoking the identical function on this object with
+   *         the given argument
+   */
+  BoolState isIdentical(InstanceState rightOperand);
+
+  /**
    * Return `true` if this object represents an object whose type is 'bool'.
    *
    * @return `true` if this object represents a boolean value
@@ -3760,6 +3823,11 @@
   @override
   BoolState equalEqual(InstanceState rightOperand) {
     assertBoolNumStringOrNull(rightOperand);
+    return isIdentical(rightOperand);
+  }
+
+  @override
+  BoolState isIdentical(InstanceState rightOperand) {
     if (value == null) {
       return BoolState.UNKNOWN_VALUE;
     }
@@ -4080,6 +4148,11 @@
   @override
   BoolState equalEqual(InstanceState rightOperand) {
     assertBoolNumStringOrNull(rightOperand);
+    return isIdentical(rightOperand);
+  }
+
+  @override
+  BoolState isIdentical(InstanceState rightOperand) {
     if (rightOperand is DynamicState) {
       return BoolState.UNKNOWN_VALUE;
     }
@@ -4168,6 +4241,11 @@
   @override
   BoolState equalEqual(InstanceState rightOperand) {
     assertBoolNumStringOrNull(rightOperand);
+    return isIdentical(rightOperand);
+  }
+
+  @override
+  BoolState isIdentical(InstanceState rightOperand) {
     if (rightOperand is DynamicState) {
       return BoolState.UNKNOWN_VALUE;
     }
@@ -4252,6 +4330,11 @@
   @override
   BoolState equalEqual(InstanceState rightOperand) {
     assertBoolNumStringOrNull(rightOperand);
+    return isIdentical(rightOperand);
+  }
+
+  @override
+  BoolState isIdentical(InstanceState rightOperand) {
     if (rightOperand is DynamicState) {
       return BoolState.UNKNOWN_VALUE;
     }
@@ -4314,6 +4397,11 @@
   }
 
   @override
+  BoolState isIdentical(InstanceState rightOperand) {
+    return BoolState.UNKNOWN_VALUE;
+  }
+
+  @override
   bool operator ==(Object object) => object is NumState;
 
   @override
@@ -4539,6 +4627,11 @@
   @override
   BoolState equalEqual(InstanceState rightOperand) {
     assertBoolNumStringOrNull(rightOperand);
+    return isIdentical(rightOperand);
+  }
+
+  @override
+  BoolState isIdentical(InstanceState rightOperand) {
     if (value == null) {
       return BoolState.UNKNOWN_VALUE;
     }
@@ -4612,6 +4705,11 @@
   @override
   BoolState equalEqual(InstanceState rightOperand) {
     assertBoolNumStringOrNull(rightOperand);
+    return isIdentical(rightOperand);
+  }
+
+  @override
+  BoolState isIdentical(InstanceState rightOperand) {
     if (value == null) {
       return BoolState.UNKNOWN_VALUE;
     }
@@ -4673,6 +4771,11 @@
   @override
   BoolState equalEqual(InstanceState rightOperand) {
     assertBoolNumStringOrNull(rightOperand);
+    return isIdentical(rightOperand);
+  }
+
+  @override
+  BoolState isIdentical(InstanceState rightOperand) {
     if (_element == null) {
       return BoolState.UNKNOWN_VALUE;
     }
diff --git a/pkg/analyzer/lib/src/generated/element.dart b/pkg/analyzer/lib/src/generated/element.dart
index 91d8575..6025f07 100644
--- a/pkg/analyzer/lib/src/generated/element.dart
+++ b/pkg/analyzer/lib/src/generated/element.dart
@@ -8166,7 +8166,9 @@
       InterfaceType futureType = futureElement.type;
       return futureType.substitute4(<DartType> [DynamicTypeImpl.instance]);
     } on AnalysisException catch (exception, stackTrace) {
-      AnalysisEngine.instance.logger.logError2("Could not build the element model for dart:async", new CaughtException(exception, stackTrace));
+      AnalysisEngine.instance.logger.logError(
+          "Could not build the element model for dart:async",
+          new CaughtException(exception, stackTrace));
       return VoidTypeImpl.instance;
     }
   }
@@ -10034,6 +10036,11 @@
     List<DartType> argumentTypes = definingType.typeArguments;
     if (baseAccessor != null && argumentTypes.length != 0) {
       FunctionType baseType = baseAccessor.type;
+      if (baseType == null) {
+        AnalysisEngine.instance.logger.logInformation(
+            'Type of $baseAccessor is null in PropertyAccessorMember._isChangedByTypeSubstitution');
+        return false;
+      }
       List<DartType> parameterTypes = definingType.element.type.typeArguments;
       FunctionType substitutedType = baseType.substitute2(argumentTypes, parameterTypes);
       if (baseType != substitutedType) {
@@ -10677,16 +10684,31 @@
 }
 
 /**
- * The abstract class `TypeImpl` implements the behavior common to objects representing the
- * declared type of elements in the element model.
+ * The abstract class `TypeImpl` implements the behavior common to objects
+ * representing the declared type of elements in the element model.
  */
 abstract class TypeImpl implements DartType {
-  static bool equalArrays(List<DartType> typeArgs1, List<DartType> typeArgs2, Set<ElementPair> visitedElementPairs) {
-    if (typeArgs1.length != typeArgs2.length) {
+  /**
+   * Return `true` if corresponding elements of the [first] and [second] lists
+   * of type arguments are all equal. Use the set of [visitedElementPairs] to
+   * prevent infinite loops when the types are recursively defined.
+   */
+  static bool equalArrays(List<DartType> first, List<DartType> second,
+      Set<ElementPair> visitedElementPairs) {
+    if (first.length != second.length) {
       return false;
     }
-    for (int i = 0; i < typeArgs1.length; i++) {
-      if (!(typeArgs1[i] as TypeImpl).internalEquals(typeArgs2[i], visitedElementPairs)) {
+    for (int i = 0; i < first.length; i++) {
+      if (first[i] == null) {
+        AnalysisEngine.instance.logger.logInformation(
+            'Found null type argument in TypeImpl.equalArrays');
+        return second[i] == null;
+      } else if (second[i] == null) {
+        AnalysisEngine.instance.logger.logInformation(
+            'Found null type argument in TypeImpl.equalArrays');
+        return false;
+      }
+      if (!(first[i] as TypeImpl).internalEquals(second[i], visitedElementPairs)) {
         return false;
       }
     }
diff --git a/pkg/analyzer/lib/src/generated/element_resolver.dart b/pkg/analyzer/lib/src/generated/element_resolver.dart
new file mode 100644
index 0000000..04d3684
--- /dev/null
+++ b/pkg/analyzer/lib/src/generated/element_resolver.dart
@@ -0,0 +1,2637 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for 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 engine.resolver.element_resolver;
+
+import 'dart:collection';
+
+import 'error.dart';
+import 'scanner.dart' as sc;
+import 'utilities_dart.dart';
+import 'ast.dart';
+import 'element.dart';
+import 'engine.dart';
+import 'resolver.dart';
+
+/**
+ * Instances of the class `ElementResolver` are used by instances of [ResolverVisitor]
+ * to resolve references within the AST structure to the elements being referenced. The requirements
+ * for the element resolver are:
+ * <ol>
+ * * Every [SimpleIdentifier] should be resolved to the element to which it refers.
+ * Specifically:
+ * * An identifier within the declaration of that name should resolve to the element being
+ * declared.
+ * * An identifier denoting a prefix should resolve to the element representing the import that
+ * defines the prefix (an [ImportElement]).
+ * * An identifier denoting a variable should resolve to the element representing the variable (a
+ * [VariableElement]).
+ * * An identifier denoting a parameter should resolve to the element representing the parameter
+ * (a [ParameterElement]).
+ * * An identifier denoting a field should resolve to the element representing the getter or
+ * setter being invoked (a [PropertyAccessorElement]).
+ * * An identifier denoting the name of a method or function being invoked should resolve to the
+ * element representing the method or function (a [ExecutableElement]).
+ * * An identifier denoting a label should resolve to the element representing the label (a
+ * [LabelElement]).
+ * The identifiers within directives are exceptions to this rule and are covered below.
+ * * Every node containing a token representing an operator that can be overridden (
+ * [BinaryExpression], [PrefixExpression], [PostfixExpression]) should resolve to
+ * the element representing the method invoked by that operator (a [MethodElement]).
+ * * Every [FunctionExpressionInvocation] should resolve to the element representing the
+ * function being invoked (a [FunctionElement]). This will be the same element as that to
+ * which the name is resolved if the function has a name, but is provided for those cases where an
+ * unnamed function is being invoked.
+ * * Every [LibraryDirective] and [PartOfDirective] should resolve to the element
+ * representing the library being specified by the directive (a [LibraryElement]) unless, in
+ * the case of a part-of directive, the specified library does not exist.
+ * * Every [ImportDirective] and [ExportDirective] should resolve to the element
+ * representing the library being specified by the directive unless the specified library does not
+ * exist (an [ImportElement] or [ExportElement]).
+ * * The identifier representing the prefix in an [ImportDirective] should resolve to the
+ * element representing the prefix (a [PrefixElement]).
+ * * The identifiers in the hide and show combinators in [ImportDirective]s and
+ * [ExportDirective]s should resolve to the elements that are being hidden or shown,
+ * respectively, unless those names are not defined in the specified library (or the specified
+ * library does not exist).
+ * * Every [PartDirective] should resolve to the element representing the compilation unit
+ * being specified by the string unless the specified compilation unit does not exist (a
+ * [CompilationUnitElement]).
+ * </ol>
+ * Note that AST nodes that would represent elements that are not defined are not resolved to
+ * anything. This includes such things as references to undeclared variables (which is an error) and
+ * names in hide and show combinators that are not defined in the imported library (which is not an
+ * error).
+ */
+class ElementResolver extends SimpleAstVisitor<Object> {
+  /**
+   * Checks whether the given expression is a reference to a class. If it is then the
+   * [ClassElement] is returned, otherwise `null` is returned.
+   *
+   * @param expression the expression to evaluate
+   * @return the element representing the class
+   */
+  static ClassElementImpl getTypeReference(Expression expression) {
+    if (expression is Identifier) {
+      Element staticElement = expression.staticElement;
+      if (staticElement is ClassElementImpl) {
+        return staticElement;
+      }
+    }
+    return null;
+  }
+
+  /**
+   * Helper function for `maybeMergeExecutableElements` that does the actual merging.
+   *
+   * @param elementArrayToMerge non-empty array of elements to merge.
+   * @return
+   */
+  static ExecutableElement _computeMergedExecutableElement(List<ExecutableElement> elementArrayToMerge) {
+    // Flatten methods structurally. Based on
+    // [InheritanceManager.computeMergedExecutableElement] and
+    // [InheritanceManager.createSyntheticExecutableElement].
+    //
+    // However, the approach we take here is much simpler, but expected to work
+    // well in the common case. It degrades gracefully in the uncommon case,
+    // by computing the type [dynamic] for the method, preventing any
+    // hints from being generated (TODO: not done yet).
+    //
+    // The approach is: we require that each [ExecutableElement] has the
+    // same shape: the same number of required, optional positional, and optional named
+    // parameters, in the same positions, and with the named parameters in the
+    // same order. We compute a type by unioning pointwise.
+    ExecutableElement e_0 = elementArrayToMerge[0];
+    List<ParameterElement> ps_0 = e_0.parameters;
+    List<ParameterElementImpl> ps_out = new List<ParameterElementImpl>(ps_0.length);
+    for (int j = 0; j < ps_out.length; j++) {
+      ps_out[j] = new ParameterElementImpl(ps_0[j].name, 0);
+      ps_out[j].synthetic = true;
+      ps_out[j].type = ps_0[j].type;
+      ps_out[j].parameterKind = ps_0[j].parameterKind;
+    }
+    DartType r_out = e_0.returnType;
+    for (int i = 1; i < elementArrayToMerge.length; i++) {
+      ExecutableElement e_i = elementArrayToMerge[i];
+      r_out = UnionTypeImpl.union([r_out, e_i.returnType]);
+      List<ParameterElement> ps_i = e_i.parameters;
+      // Each function must have the same number of params.
+      if (ps_0.length != ps_i.length) {
+        return null;
+        // TODO (collinsn): return an element representing [dynamic] here instead.
+      } else {
+        // Each function must have the same kind of params, with the same names,
+        // in the same order.
+        for (int j = 0; j < ps_i.length; j++) {
+          if (ps_0[j].parameterKind != ps_i[j].parameterKind || !identical(ps_0[j].name, ps_i[j].name)) {
+            return null;
+          } else {
+            // The output parameter type is the union of the input parameter types.
+            ps_out[j].type = UnionTypeImpl.union([ps_out[j].type, ps_i[j].type]);
+          }
+        }
+      }
+    }
+    // TODO (collinsn): this code should work for functions and methods,
+    // so we may want [FunctionElementImpl]
+    // instead here in some cases? And then there are constructors and property accessors.
+    // Maybe the answer is to create a new subclass of [ExecutableElementImpl] which
+    // is used for merged executable elements, in analogy with [MultiplyInheritedMethodElementImpl]
+    // and [MultiplyInheritedPropertyAcessorElementImpl].
+    ExecutableElementImpl e_out = new MethodElementImpl(e_0.name, 0);
+    e_out.synthetic = true;
+    e_out.returnType = r_out;
+    e_out.parameters = ps_out;
+    e_out.type = new FunctionTypeImpl.con1(e_out);
+    // Get NPE in [toString()] w/o this.
+    e_out.enclosingElement = e_0.enclosingElement;
+    return e_out;
+  }
+
+  /**
+   * Return `true` if the given identifier is the return type of a constructor declaration.
+   *
+   * @return `true` if the given identifier is the return type of a constructor declaration.
+   */
+  static bool _isConstructorReturnType(SimpleIdentifier identifier) {
+    AstNode parent = identifier.parent;
+    if (parent is ConstructorDeclaration) {
+      return identical(parent.returnType, identifier);
+    }
+    return false;
+  }
+
+  /**
+   * Return `true` if the given identifier is the return type of a factory constructor.
+   *
+   * @return `true` if the given identifier is the return type of a factory constructor
+   *         declaration.
+   */
+  static bool _isFactoryConstructorReturnType(SimpleIdentifier node) {
+    AstNode parent = node.parent;
+    if (parent is ConstructorDeclaration) {
+      ConstructorDeclaration constructor = parent;
+      return identical(constructor.returnType, node) && constructor.factoryKeyword != null;
+    }
+    return false;
+  }
+
+  /**
+   * Return `true` if the given 'super' expression is used in a valid context.
+   *
+   * @param node the 'super' expression to analyze
+   * @return `true` if the 'super' expression is in a valid context
+   */
+  static bool _isSuperInValidContext(SuperExpression node) {
+    for (AstNode n = node; n != null; n = n.parent) {
+      if (n is CompilationUnit) {
+        return false;
+      }
+      if (n is ConstructorDeclaration) {
+        ConstructorDeclaration constructor = n as ConstructorDeclaration;
+        return constructor.factoryKeyword == null;
+      }
+      if (n is ConstructorFieldInitializer) {
+        return false;
+      }
+      if (n is MethodDeclaration) {
+        MethodDeclaration method = n as MethodDeclaration;
+        return !method.isStatic;
+      }
+    }
+    return false;
+  }
+
+  /**
+   * Return a method representing the merge of the given elements. The type of the merged element is
+   * the component-wise union of the types of the given elements. If not all input elements have the
+   * same shape then [null] is returned.
+   *
+   * @param elements the `ExecutableElement`s to merge
+   * @return an `ExecutableElement` representing the merge of `elements`
+   */
+  static ExecutableElement _maybeMergeExecutableElements(Set<ExecutableElement> elements) {
+    List<ExecutableElement> elementArrayToMerge = new List.from(elements);
+    if (elementArrayToMerge.length == 0) {
+      return null;
+    } else if (elementArrayToMerge.length == 1) {
+      // If all methods are equal, don't bother building a new one.
+      return elementArrayToMerge[0];
+    } else {
+      return _computeMergedExecutableElement(elementArrayToMerge);
+    }
+  }
+
+  /**
+   * The resolver driving this participant.
+   */
+  final ResolverVisitor _resolver;
+
+  /**
+   * The element for the library containing the compilation unit being visited.
+   */
+  LibraryElement _definingLibrary;
+
+  /**
+   * A flag indicating whether we should generate hints.
+   */
+  bool _enableHints = false;
+
+  /**
+   * The type representing the type 'dynamic'.
+   */
+  DartType _dynamicType;
+
+  /**
+   * The type representing the type 'type'.
+   */
+  DartType _typeType;
+
+  /**
+   * A utility class for the resolver to answer the question of "what are my subtypes?".
+   */
+  SubtypeManager _subtypeManager;
+
+  /**
+   * The object keeping track of which elements have had their types promoted.
+   */
+  TypePromotionManager _promoteManager;
+
+  /**
+   * Initialize a newly created visitor to resolve the nodes in a compilation unit.
+   *
+   * @param resolver the resolver driving this participant
+   */
+  ElementResolver(this._resolver) {
+    this._definingLibrary = _resolver.definingLibrary;
+    AnalysisOptions options = _definingLibrary.context.analysisOptions;
+    _enableHints = options.hint;
+    _dynamicType = _resolver.typeProvider.dynamicType;
+    _typeType = _resolver.typeProvider.typeType;
+    _subtypeManager = new SubtypeManager();
+    _promoteManager = _resolver.promoteManager;
+  }
+
+  @override
+  Object visitAssignmentExpression(AssignmentExpression node) {
+    sc.Token operator = node.operator;
+    sc.TokenType operatorType = operator.type;
+    if (operatorType != sc.TokenType.EQ) {
+      operatorType = _operatorFromCompoundAssignment(operatorType);
+      Expression leftHandSide = node.leftHandSide;
+      if (leftHandSide != null) {
+        String methodName = operatorType.lexeme;
+        DartType staticType = _getStaticType(leftHandSide);
+        MethodElement staticMethod = _lookUpMethod(leftHandSide, staticType, methodName);
+        node.staticElement = staticMethod;
+        DartType propagatedType = _getPropagatedType(leftHandSide);
+        MethodElement propagatedMethod = _lookUpMethod(leftHandSide, propagatedType, methodName);
+        node.propagatedElement = propagatedMethod;
+        if (_shouldReportMissingMember(staticType, staticMethod)) {
+          _recordUndefinedToken(staticType.element, StaticTypeWarningCode.UNDEFINED_METHOD, operator, [methodName, staticType.displayName]);
+        } else if (_enableHints && _shouldReportMissingMember(propagatedType, propagatedMethod) && !_memberFoundInSubclass(propagatedType.element, methodName, true, false)) {
+          _recordUndefinedToken(propagatedType.element, HintCode.UNDEFINED_METHOD, operator, [methodName, propagatedType.displayName]);
+        }
+      }
+    }
+    return null;
+  }
+
+  @override
+  Object visitBinaryExpression(BinaryExpression node) {
+    sc.Token operator = node.operator;
+    if (operator.isUserDefinableOperator) {
+      Expression leftOperand = node.leftOperand;
+      if (leftOperand != null) {
+        String methodName = operator.lexeme;
+        DartType staticType = _getStaticType(leftOperand);
+        MethodElement staticMethod = _lookUpMethod(leftOperand, staticType, methodName);
+        node.staticElement = staticMethod;
+        DartType propagatedType = _getPropagatedType(leftOperand);
+        MethodElement propagatedMethod = _lookUpMethod(leftOperand, propagatedType, methodName);
+        node.propagatedElement = propagatedMethod;
+        if (_shouldReportMissingMember(staticType, staticMethod)) {
+          _recordUndefinedToken(staticType.element, StaticTypeWarningCode.UNDEFINED_OPERATOR, operator, [methodName, staticType.displayName]);
+        } else if (_enableHints && _shouldReportMissingMember(propagatedType, propagatedMethod) && !_memberFoundInSubclass(propagatedType.element, methodName, true, false)) {
+          _recordUndefinedToken(propagatedType.element, HintCode.UNDEFINED_OPERATOR, operator, [methodName, propagatedType.displayName]);
+        }
+      }
+    }
+    return null;
+  }
+
+  @override
+  Object visitBreakStatement(BreakStatement node) {
+    _lookupLabel(node, node.label);
+    return null;
+  }
+
+  @override
+  Object visitClassDeclaration(ClassDeclaration node) {
+    _setMetadata(node.element, node);
+    return null;
+  }
+
+  @override
+  Object visitClassTypeAlias(ClassTypeAlias node) {
+    _setMetadata(node.element, node);
+    return null;
+  }
+
+  @override
+  Object visitCommentReference(CommentReference node) {
+    Identifier identifier = node.identifier;
+    if (identifier is SimpleIdentifier) {
+      SimpleIdentifier simpleIdentifier = identifier;
+      Element element = _resolveSimpleIdentifier(simpleIdentifier);
+      if (element == null) {
+        //
+        // This might be a reference to an imported name that is missing the prefix.
+        //
+        element = _findImportWithoutPrefix(simpleIdentifier);
+        if (element is MultiplyDefinedElement) {
+          // TODO(brianwilkerson) Report this error?
+          element = null;
+        }
+      }
+      if (element == null) {
+        // TODO(brianwilkerson) Report this error?
+        //        resolver.reportError(
+        //            StaticWarningCode.UNDEFINED_IDENTIFIER,
+        //            simpleIdentifier,
+        //            simpleIdentifier.getName());
+      } else {
+        if (element.library == null || element.library != _definingLibrary) {
+          // TODO(brianwilkerson) Report this error?
+        }
+        simpleIdentifier.staticElement = element;
+        if (node.newKeyword != null) {
+          if (element is ClassElement) {
+            ConstructorElement constructor = (element as ClassElement).unnamedConstructor;
+            if (constructor == null) {
+              // TODO(brianwilkerson) Report this error.
+            } else {
+              simpleIdentifier.staticElement = constructor;
+            }
+          } else {
+            // TODO(brianwilkerson) Report this error.
+          }
+        }
+      }
+    } else if (identifier is PrefixedIdentifier) {
+      PrefixedIdentifier prefixedIdentifier = identifier;
+      SimpleIdentifier prefix = prefixedIdentifier.prefix;
+      SimpleIdentifier name = prefixedIdentifier.identifier;
+      Element element = _resolveSimpleIdentifier(prefix);
+      if (element == null) {
+        //        resolver.reportError(StaticWarningCode.UNDEFINED_IDENTIFIER, prefix, prefix.getName());
+      } else {
+        if (element is PrefixElement) {
+          prefix.staticElement = element;
+          // TODO(brianwilkerson) Report this error?
+          element = _resolver.nameScope.lookup(identifier, _definingLibrary);
+          name.staticElement = element;
+          return null;
+        }
+        LibraryElement library = element.library;
+        if (library == null) {
+          // TODO(brianwilkerson) We need to understand how the library could ever be null.
+          AnalysisEngine.instance.logger.logError("Found element with null library: ${element.name}");
+        } else if (library != _definingLibrary) {
+          // TODO(brianwilkerson) Report this error.
+        }
+        name.staticElement = element;
+        if (node.newKeyword == null) {
+          if (element is ClassElement) {
+            Element memberElement = _lookupGetterOrMethod((element as ClassElement).type, name.name);
+            if (memberElement == null) {
+              memberElement = (element as ClassElement).getNamedConstructor(name.name);
+              if (memberElement == null) {
+                memberElement = _lookUpSetter(prefix, (element as ClassElement).type, name.name);
+              }
+            }
+            if (memberElement == null) {
+              //              reportGetterOrSetterNotFound(prefixedIdentifier, name, element.getDisplayName());
+            } else {
+              name.staticElement = memberElement;
+            }
+          } else {
+            // TODO(brianwilkerson) Report this error.
+          }
+        } else {
+          if (element is ClassElement) {
+            ConstructorElement constructor = (element as ClassElement).getNamedConstructor(name.name);
+            if (constructor == null) {
+              // TODO(brianwilkerson) Report this error.
+            } else {
+              name.staticElement = constructor;
+            }
+          } else {
+            // TODO(brianwilkerson) Report this error.
+          }
+        }
+      }
+    }
+    return null;
+  }
+
+  @override
+  Object visitConstructorDeclaration(ConstructorDeclaration node) {
+    super.visitConstructorDeclaration(node);
+    ConstructorElement element = node.element;
+    if (element is ConstructorElementImpl) {
+      ConstructorElementImpl constructorElement = element;
+      ConstructorName redirectedNode = node.redirectedConstructor;
+      if (redirectedNode != null) {
+        // set redirected factory constructor
+        ConstructorElement redirectedElement = redirectedNode.staticElement;
+        constructorElement.redirectedConstructor = redirectedElement;
+      } else {
+        // set redirected generative constructor
+        for (ConstructorInitializer initializer in node.initializers) {
+          if (initializer is RedirectingConstructorInvocation) {
+            ConstructorElement redirectedElement = initializer.staticElement;
+            constructorElement.redirectedConstructor = redirectedElement;
+          }
+        }
+      }
+      _setMetadata(constructorElement, node);
+    }
+    return null;
+  }
+
+  @override
+  Object visitConstructorFieldInitializer(ConstructorFieldInitializer node) {
+    SimpleIdentifier fieldName = node.fieldName;
+    ClassElement enclosingClass = _resolver.enclosingClass;
+    FieldElement fieldElement = enclosingClass.getField(fieldName.name);
+    fieldName.staticElement = fieldElement;
+    return null;
+  }
+
+  @override
+  Object visitConstructorName(ConstructorName node) {
+    DartType type = node.type.type;
+    if (type != null && type.isDynamic) {
+      return null;
+    } else if (type is! InterfaceType) {
+      // TODO(brianwilkerson) Report these errors.
+      //      ASTNode parent = node.getParent();
+      //      if (parent instanceof InstanceCreationExpression) {
+      //        if (((InstanceCreationExpression) parent).isConst()) {
+      //          // CompileTimeErrorCode.CONST_WITH_NON_TYPE
+      //        } else {
+      //          // StaticWarningCode.NEW_WITH_NON_TYPE
+      //        }
+      //      } else {
+      //        // This is part of a redirecting factory constructor; not sure which error code to use
+      //      }
+      return null;
+    }
+    // look up ConstructorElement
+    ConstructorElement constructor;
+    SimpleIdentifier name = node.name;
+    InterfaceType interfaceType = type as InterfaceType;
+    if (name == null) {
+      constructor = interfaceType.lookUpConstructor(null, _definingLibrary);
+    } else {
+      constructor = interfaceType.lookUpConstructor(name.name, _definingLibrary);
+      name.staticElement = constructor;
+    }
+    node.staticElement = constructor;
+    return null;
+  }
+
+  @override
+  Object visitContinueStatement(ContinueStatement node) {
+    _lookupLabel(node, node.label);
+    return null;
+  }
+
+  @override
+  Object visitDeclaredIdentifier(DeclaredIdentifier node) {
+    _setMetadata(node.element, node);
+    return null;
+  }
+
+  @override
+  Object visitExportDirective(ExportDirective node) {
+    ExportElement exportElement = node.element;
+    if (exportElement != null) {
+      // The element is null when the URI is invalid
+      // TODO(brianwilkerson) Figure out whether the element can ever be something other than an
+      // ExportElement
+      _resolveCombinators(exportElement.exportedLibrary, node.combinators);
+      _setMetadata(exportElement, node);
+    }
+    return null;
+  }
+
+  @override
+  Object visitFieldFormalParameter(FieldFormalParameter node) {
+    _setMetadataForParameter(node.element, node);
+    return super.visitFieldFormalParameter(node);
+  }
+
+  @override
+  Object visitFunctionDeclaration(FunctionDeclaration node) {
+    _setMetadata(node.element, node);
+    return null;
+  }
+
+  @override
+  Object visitFunctionExpressionInvocation(FunctionExpressionInvocation node) {
+    // TODO(brianwilkerson) Can we ever resolve the function being invoked?
+    Expression expression = node.function;
+    if (expression is FunctionExpression) {
+      FunctionExpression functionExpression = expression;
+      ExecutableElement functionElement = functionExpression.element;
+      ArgumentList argumentList = node.argumentList;
+      List<ParameterElement> parameters = _resolveArgumentsToFunction(false, argumentList, functionElement);
+      if (parameters != null) {
+        argumentList.correspondingStaticParameters = parameters;
+      }
+    }
+    return null;
+  }
+
+  @override
+  Object visitFunctionTypeAlias(FunctionTypeAlias node) {
+    _setMetadata(node.element, node);
+    return null;
+  }
+
+  @override
+  Object visitFunctionTypedFormalParameter(FunctionTypedFormalParameter node) {
+    _setMetadataForParameter(node.element, node);
+    return null;
+  }
+
+  @override
+  Object visitImportDirective(ImportDirective node) {
+    SimpleIdentifier prefixNode = node.prefix;
+    if (prefixNode != null) {
+      String prefixName = prefixNode.name;
+      for (PrefixElement prefixElement in _definingLibrary.prefixes) {
+        if (prefixElement.displayName == prefixName) {
+          prefixNode.staticElement = prefixElement;
+          break;
+        }
+      }
+    }
+    ImportElement importElement = node.element;
+    if (importElement != null) {
+      // The element is null when the URI is invalid
+      LibraryElement library = importElement.importedLibrary;
+      if (library != null) {
+        _resolveCombinators(library, node.combinators);
+      }
+      _setMetadata(importElement, node);
+    }
+    return null;
+  }
+
+  @override
+  Object visitIndexExpression(IndexExpression node) {
+    Expression target = node.realTarget;
+    DartType staticType = _getStaticType(target);
+    DartType propagatedType = _getPropagatedType(target);
+    String getterMethodName = sc.TokenType.INDEX.lexeme;
+    String setterMethodName = sc.TokenType.INDEX_EQ.lexeme;
+    bool isInGetterContext = node.inGetterContext();
+    bool isInSetterContext = node.inSetterContext();
+    if (isInGetterContext && isInSetterContext) {
+      // lookup setter
+      MethodElement setterStaticMethod = _lookUpMethod(target, staticType, setterMethodName);
+      MethodElement setterPropagatedMethod = _lookUpMethod(target, propagatedType, setterMethodName);
+      // set setter element
+      node.staticElement = setterStaticMethod;
+      node.propagatedElement = setterPropagatedMethod;
+      // generate undefined method warning
+      _checkForUndefinedIndexOperator(node, target, getterMethodName, setterStaticMethod, setterPropagatedMethod, staticType, propagatedType);
+      // lookup getter method
+      MethodElement getterStaticMethod = _lookUpMethod(target, staticType, getterMethodName);
+      MethodElement getterPropagatedMethod = _lookUpMethod(target, propagatedType, getterMethodName);
+      // set getter element
+      AuxiliaryElements auxiliaryElements = new AuxiliaryElements(getterStaticMethod, getterPropagatedMethod);
+      node.auxiliaryElements = auxiliaryElements;
+      // generate undefined method warning
+      _checkForUndefinedIndexOperator(node, target, getterMethodName, getterStaticMethod, getterPropagatedMethod, staticType, propagatedType);
+    } else if (isInGetterContext) {
+      // lookup getter method
+      MethodElement staticMethod = _lookUpMethod(target, staticType, getterMethodName);
+      MethodElement propagatedMethod = _lookUpMethod(target, propagatedType, getterMethodName);
+      // set getter element
+      node.staticElement = staticMethod;
+      node.propagatedElement = propagatedMethod;
+      // generate undefined method warning
+      _checkForUndefinedIndexOperator(node, target, getterMethodName, staticMethod, propagatedMethod, staticType, propagatedType);
+    } else if (isInSetterContext) {
+      // lookup setter method
+      MethodElement staticMethod = _lookUpMethod(target, staticType, setterMethodName);
+      MethodElement propagatedMethod = _lookUpMethod(target, propagatedType, setterMethodName);
+      // set setter element
+      node.staticElement = staticMethod;
+      node.propagatedElement = propagatedMethod;
+      // generate undefined method warning
+      _checkForUndefinedIndexOperator(node, target, setterMethodName, staticMethod, propagatedMethod, staticType, propagatedType);
+    }
+    return null;
+  }
+
+  @override
+  Object visitInstanceCreationExpression(InstanceCreationExpression node) {
+    ConstructorElement invokedConstructor = node.constructorName.staticElement;
+    node.staticElement = invokedConstructor;
+    ArgumentList argumentList = node.argumentList;
+    List<ParameterElement> parameters = _resolveArgumentsToFunction(node.isConst, argumentList, invokedConstructor);
+    if (parameters != null) {
+      argumentList.correspondingStaticParameters = parameters;
+    }
+    return null;
+  }
+
+  @override
+  Object visitLibraryDirective(LibraryDirective node) {
+    _setMetadata(node.element, node);
+    return null;
+  }
+
+  @override
+  Object visitMethodDeclaration(MethodDeclaration node) {
+    _setMetadata(node.element, node);
+    return null;
+  }
+
+  @override
+  Object visitMethodInvocation(MethodInvocation node) {
+    SimpleIdentifier methodName = node.methodName;
+    //
+    // Synthetic identifiers have been already reported during parsing.
+    //
+    if (methodName.isSynthetic) {
+      return null;
+    }
+    //
+    // We have a method invocation of one of two forms: 'e.m(a1, ..., an)' or 'm(a1, ..., an)'. The
+    // first step is to figure out which executable is being invoked, using both the static and the
+    // propagated type information.
+    //
+    Expression target = node.realTarget;
+    if (target is SuperExpression && !_isSuperInValidContext(target)) {
+      return null;
+    }
+    Element staticElement;
+    Element propagatedElement;
+    DartType staticType = null;
+    DartType propagatedType = null;
+    if (target == null) {
+      staticElement = _resolveInvokedElement(methodName);
+      propagatedElement = null;
+    } else if (methodName.name == FunctionElement.LOAD_LIBRARY_NAME && _isDeferredPrefix(target)) {
+      LibraryElement importedLibrary = _getImportedLibrary(target);
+      methodName.staticElement = importedLibrary.loadLibraryFunction;
+      return null;
+    } else {
+      staticType = _getStaticType(target);
+      propagatedType = _getPropagatedType(target);
+      //
+      // If this method invocation is of the form 'C.m' where 'C' is a class, then we don't call
+      // resolveInvokedElement(..) which walks up the class hierarchy, instead we just look for the
+      // member in the type only.
+      //
+      ClassElementImpl typeReference = getTypeReference(target);
+      if (typeReference != null) {
+        staticElement = propagatedElement = _resolveElement(typeReference, methodName);
+      } else {
+        staticElement = _resolveInvokedElementWithTarget(target, staticType, methodName);
+        propagatedElement = _resolveInvokedElementWithTarget(target, propagatedType, methodName);
+      }
+    }
+    staticElement = _convertSetterToGetter(staticElement);
+    propagatedElement = _convertSetterToGetter(propagatedElement);
+    //
+    // Record the results.
+    //
+    methodName.staticElement = staticElement;
+    methodName.propagatedElement = propagatedElement;
+    ArgumentList argumentList = node.argumentList;
+    if (staticElement != null) {
+      List<ParameterElement> parameters = _computeCorrespondingParameters(argumentList, staticElement);
+      if (parameters != null) {
+        argumentList.correspondingStaticParameters = parameters;
+      }
+    }
+    if (propagatedElement != null) {
+      List<ParameterElement> parameters = _computeCorrespondingParameters(argumentList, propagatedElement);
+      if (parameters != null) {
+        argumentList.correspondingPropagatedParameters = parameters;
+      }
+    }
+    //
+    // Then check for error conditions.
+    //
+    ErrorCode errorCode = _checkForInvocationError(target, true, staticElement);
+    bool generatedWithTypePropagation = false;
+    if (_enableHints && errorCode == null && staticElement == null) {
+      // The method lookup may have failed because there were multiple
+      // incompatible choices. In this case we don't want to generate a hint.
+      if (propagatedElement == null && propagatedType is UnionType) {
+        // TODO(collinsn): an improvement here is to make the propagated type of the method call
+        // the union of the propagated types of all possible calls.
+        if (_lookupMethods(target, propagatedType as UnionType, methodName.name).length > 1) {
+          return null;
+        }
+      }
+      errorCode = _checkForInvocationError(target, false, propagatedElement);
+      if (identical(errorCode, StaticTypeWarningCode.UNDEFINED_METHOD)) {
+        ClassElement classElementContext = null;
+        if (target == null) {
+          classElementContext = _resolver.enclosingClass;
+        } else {
+          DartType type = target.bestType;
+          if (type != null) {
+            if (type.element is ClassElement) {
+              classElementContext = type.element as ClassElement;
+            }
+          }
+        }
+        if (classElementContext != null) {
+          _subtypeManager.ensureLibraryVisited(_definingLibrary);
+          HashSet<ClassElement> subtypeElements = _subtypeManager.computeAllSubtypes(classElementContext);
+          for (ClassElement subtypeElement in subtypeElements) {
+            if (subtypeElement.getMethod(methodName.name) != null) {
+              errorCode = null;
+            }
+          }
+        }
+      }
+      generatedWithTypePropagation = true;
+    }
+    if (errorCode == null) {
+      return null;
+    }
+    if (identical(errorCode, StaticTypeWarningCode.INVOCATION_OF_NON_FUNCTION)) {
+      _resolver.reportErrorForNode(StaticTypeWarningCode.INVOCATION_OF_NON_FUNCTION, methodName, [methodName.name]);
+    } else if (identical(errorCode, StaticTypeWarningCode.UNDEFINED_FUNCTION)) {
+      _resolver.reportErrorForNode(StaticTypeWarningCode.UNDEFINED_FUNCTION, methodName, [methodName.name]);
+    } else if (identical(errorCode, StaticTypeWarningCode.UNDEFINED_METHOD)) {
+      String targetTypeName;
+      if (target == null) {
+        ClassElement enclosingClass = _resolver.enclosingClass;
+        targetTypeName = enclosingClass.displayName;
+        ErrorCode proxyErrorCode = (generatedWithTypePropagation ? HintCode.UNDEFINED_METHOD : StaticTypeWarningCode.UNDEFINED_METHOD);
+        _recordUndefinedNode(_resolver.enclosingClass, proxyErrorCode, methodName, [methodName.name, targetTypeName]);
+      } else {
+        // ignore Function "call"
+        // (if we are about to create a hint using type propagation, then we can use type
+        // propagation here as well)
+        DartType targetType = null;
+        if (!generatedWithTypePropagation) {
+          targetType = _getStaticType(target);
+        } else {
+          // choose the best type
+          targetType = _getPropagatedType(target);
+          if (targetType == null) {
+            targetType = _getStaticType(target);
+          }
+        }
+        if (targetType != null && targetType.isDartCoreFunction && methodName.name == FunctionElement.CALL_METHOD_NAME) {
+          // TODO(brianwilkerson) Can we ever resolve the function being invoked?
+          //resolveArgumentsToParameters(node.getArgumentList(), invokedFunction);
+          return null;
+        }
+        targetTypeName = targetType == null ? null : targetType.displayName;
+        ErrorCode proxyErrorCode = (generatedWithTypePropagation ? HintCode.UNDEFINED_METHOD : StaticTypeWarningCode.UNDEFINED_METHOD);
+        _recordUndefinedNode(targetType.element, proxyErrorCode, methodName, [methodName.name, targetTypeName]);
+      }
+    } else if (identical(errorCode, StaticTypeWarningCode.UNDEFINED_SUPER_METHOD)) {
+      // Generate the type name.
+      // The error code will never be generated via type propagation
+      DartType targetType = _getStaticType(target);
+      if (targetType is InterfaceType && !targetType.isObject) {
+        targetType = (targetType as InterfaceType).superclass;
+      }
+      String targetTypeName = targetType == null ? null : targetType.name;
+      _resolver.reportErrorForNode(StaticTypeWarningCode.UNDEFINED_SUPER_METHOD, methodName, [methodName.name, targetTypeName]);
+    }
+    return null;
+  }
+
+  @override
+  Object visitPartDirective(PartDirective node) {
+    _setMetadata(node.element, node);
+    return null;
+  }
+
+  @override
+  Object visitPartOfDirective(PartOfDirective node) {
+    _setMetadata(node.element, node);
+    return null;
+  }
+
+  @override
+  Object visitPostfixExpression(PostfixExpression node) {
+    Expression operand = node.operand;
+    String methodName = _getPostfixOperator(node);
+    DartType staticType = _getStaticType(operand);
+    MethodElement staticMethod = _lookUpMethod(operand, staticType, methodName);
+    node.staticElement = staticMethod;
+    DartType propagatedType = _getPropagatedType(operand);
+    MethodElement propagatedMethod = _lookUpMethod(operand, propagatedType, methodName);
+    node.propagatedElement = propagatedMethod;
+    if (_shouldReportMissingMember(staticType, staticMethod)) {
+      _recordUndefinedToken(staticType.element, StaticTypeWarningCode.UNDEFINED_OPERATOR, node.operator, [methodName, staticType.displayName]);
+    } else if (_enableHints && _shouldReportMissingMember(propagatedType, propagatedMethod) && !_memberFoundInSubclass(propagatedType.element, methodName, true, false)) {
+      _recordUndefinedToken(propagatedType.element, HintCode.UNDEFINED_OPERATOR, node.operator, [methodName, propagatedType.displayName]);
+    }
+    return null;
+  }
+
+  @override
+  Object visitPrefixedIdentifier(PrefixedIdentifier node) {
+    SimpleIdentifier prefix = node.prefix;
+    SimpleIdentifier identifier = node.identifier;
+    //
+    // First, check the "lib.loadLibrary" case
+    //
+    if (identifier.name == FunctionElement.LOAD_LIBRARY_NAME && _isDeferredPrefix(prefix)) {
+      LibraryElement importedLibrary = _getImportedLibrary(prefix);
+      identifier.staticElement = importedLibrary.loadLibraryFunction;
+      return null;
+    }
+    //
+    // Check to see whether the prefix is really a prefix.
+    //
+    Element prefixElement = prefix.staticElement;
+    if (prefixElement is PrefixElement) {
+      Element element = _resolver.nameScope.lookup(node, _definingLibrary);
+      if (element == null && identifier.inSetterContext()) {
+        element = _resolver.nameScope.lookup(new ElementResolver_SyntheticIdentifier("${node.name}="), _definingLibrary);
+      }
+      if (element == null) {
+        if (identifier.inSetterContext()) {
+          _resolver.reportErrorForNode(StaticWarningCode.UNDEFINED_SETTER, identifier, [identifier.name, prefixElement.name]);
+        } else if (node.parent is Annotation) {
+          Annotation annotation = node.parent as Annotation;
+          _resolver.reportErrorForNode(CompileTimeErrorCode.INVALID_ANNOTATION, annotation, []);
+          return null;
+        } else {
+          _resolver.reportErrorForNode(StaticWarningCode.UNDEFINED_GETTER, identifier, [identifier.name, prefixElement.name]);
+        }
+        return null;
+      }
+      if (element is PropertyAccessorElement && identifier.inSetterContext()) {
+        PropertyInducingElement variable = (element as PropertyAccessorElement).variable;
+        if (variable != null) {
+          PropertyAccessorElement setter = variable.setter;
+          if (setter != null) {
+            element = setter;
+          }
+        }
+      }
+      // TODO(brianwilkerson) The prefix needs to be resolved to the element for the import that
+      // defines the prefix, not the prefix's element.
+      identifier.staticElement = element;
+      // Validate annotation element.
+      if (node.parent is Annotation) {
+        Annotation annotation = node.parent as Annotation;
+        _resolveAnnotationElement(annotation);
+        return null;
+      }
+      return null;
+    }
+    // May be annotation, resolve invocation of "const" constructor.
+    if (node.parent is Annotation) {
+      Annotation annotation = node.parent as Annotation;
+      _resolveAnnotationElement(annotation);
+    }
+    //
+    // Otherwise, the prefix is really an expression that happens to be a simple identifier and this
+    // is really equivalent to a property access node.
+    //
+    _resolvePropertyAccess(prefix, identifier);
+    return null;
+  }
+
+  @override
+  Object visitPrefixExpression(PrefixExpression node) {
+    sc.Token operator = node.operator;
+    sc.TokenType operatorType = operator.type;
+    if (operatorType.isUserDefinableOperator || operatorType == sc.TokenType.PLUS_PLUS || operatorType == sc.TokenType.MINUS_MINUS) {
+      Expression operand = node.operand;
+      String methodName = _getPrefixOperator(node);
+      DartType staticType = _getStaticType(operand);
+      MethodElement staticMethod = _lookUpMethod(operand, staticType, methodName);
+      node.staticElement = staticMethod;
+      DartType propagatedType = _getPropagatedType(operand);
+      MethodElement propagatedMethod = _lookUpMethod(operand, propagatedType, methodName);
+      node.propagatedElement = propagatedMethod;
+      if (_shouldReportMissingMember(staticType, staticMethod)) {
+        _recordUndefinedToken(staticType.element, StaticTypeWarningCode.UNDEFINED_OPERATOR, operator, [methodName, staticType.displayName]);
+      } else if (_enableHints && _shouldReportMissingMember(propagatedType, propagatedMethod) && !_memberFoundInSubclass(propagatedType.element, methodName, true, false)) {
+        _recordUndefinedToken(propagatedType.element, HintCode.UNDEFINED_OPERATOR, operator, [methodName, propagatedType.displayName]);
+      }
+    }
+    return null;
+  }
+
+  @override
+  Object visitPropertyAccess(PropertyAccess node) {
+    Expression target = node.realTarget;
+    if (target is SuperExpression && !_isSuperInValidContext(target)) {
+      return null;
+    }
+    SimpleIdentifier propertyName = node.propertyName;
+    _resolvePropertyAccess(target, propertyName);
+    return null;
+  }
+
+  @override
+  Object visitRedirectingConstructorInvocation(RedirectingConstructorInvocation node) {
+    ClassElement enclosingClass = _resolver.enclosingClass;
+    if (enclosingClass == null) {
+      // TODO(brianwilkerson) Report this error.
+      return null;
+    }
+    SimpleIdentifier name = node.constructorName;
+    ConstructorElement element;
+    if (name == null) {
+      element = enclosingClass.unnamedConstructor;
+    } else {
+      element = enclosingClass.getNamedConstructor(name.name);
+    }
+    if (element == null) {
+      // TODO(brianwilkerson) Report this error and decide what element to associate with the node.
+      return null;
+    }
+    if (name != null) {
+      name.staticElement = element;
+    }
+    node.staticElement = element;
+    ArgumentList argumentList = node.argumentList;
+    List<ParameterElement> parameters = _resolveArgumentsToFunction(false, argumentList, element);
+    if (parameters != null) {
+      argumentList.correspondingStaticParameters = parameters;
+    }
+    return null;
+  }
+
+  @override
+  Object visitSimpleFormalParameter(SimpleFormalParameter node) {
+    _setMetadataForParameter(node.element, node);
+    return null;
+  }
+
+  @override
+  Object visitSimpleIdentifier(SimpleIdentifier node) {
+    //
+    // Synthetic identifiers have been already reported during parsing.
+    //
+    if (node.isSynthetic) {
+      return null;
+    }
+    //
+    // We ignore identifiers that have already been resolved, such as identifiers representing the
+    // name in a declaration.
+    //
+    if (node.staticElement != null) {
+      return null;
+    }
+    //
+    // The name dynamic denotes a Type object even though dynamic is not a class.
+    //
+    if (node.name == _dynamicType.name) {
+      node.staticElement = _dynamicType.element;
+      node.staticType = _typeType;
+      return null;
+    }
+    //
+    // Otherwise, the node should be resolved.
+    //
+    Element element = _resolveSimpleIdentifier(node);
+    ClassElement enclosingClass = _resolver.enclosingClass;
+    if (_isFactoryConstructorReturnType(node) && !identical(element, enclosingClass)) {
+      _resolver.reportErrorForNode(CompileTimeErrorCode.INVALID_FACTORY_NAME_NOT_A_CLASS, node, []);
+    } else if (_isConstructorReturnType(node) && !identical(element, enclosingClass)) {
+      _resolver.reportErrorForNode(CompileTimeErrorCode.INVALID_CONSTRUCTOR_NAME, node, []);
+      element = null;
+    } else if (element == null || (element is PrefixElement && !_isValidAsPrefix(node))) {
+      // TODO(brianwilkerson) Recover from this error.
+      if (_isConstructorReturnType(node)) {
+        _resolver.reportErrorForNode(CompileTimeErrorCode.INVALID_CONSTRUCTOR_NAME, node, []);
+      } else if (node.parent is Annotation) {
+        Annotation annotation = node.parent as Annotation;
+        _resolver.reportErrorForNode(CompileTimeErrorCode.INVALID_ANNOTATION, annotation, []);
+      } else {
+        _recordUndefinedNode(_resolver.enclosingClass, StaticWarningCode.UNDEFINED_IDENTIFIER, node, [node.name]);
+      }
+    }
+    node.staticElement = element;
+    if (node.inSetterContext() && node.inGetterContext() && enclosingClass != null) {
+      InterfaceType enclosingType = enclosingClass.type;
+      AuxiliaryElements auxiliaryElements = new AuxiliaryElements(_lookUpGetter(null, enclosingType, node.name), null);
+      node.auxiliaryElements = auxiliaryElements;
+    }
+    //
+    // Validate annotation element.
+    //
+    if (node.parent is Annotation) {
+      Annotation annotation = node.parent as Annotation;
+      _resolveAnnotationElement(annotation);
+    }
+    return null;
+  }
+
+  @override
+  Object visitSuperConstructorInvocation(SuperConstructorInvocation node) {
+    ClassElement enclosingClass = _resolver.enclosingClass;
+    if (enclosingClass == null) {
+      // TODO(brianwilkerson) Report this error.
+      return null;
+    }
+    InterfaceType superType = enclosingClass.supertype;
+    if (superType == null) {
+      // TODO(brianwilkerson) Report this error.
+      return null;
+    }
+    SimpleIdentifier name = node.constructorName;
+    String superName = name != null ? name.name : null;
+    ConstructorElement element = superType.lookUpConstructor(superName, _definingLibrary);
+    if (element == null) {
+      if (name != null) {
+        _resolver.reportErrorForNode(CompileTimeErrorCode.UNDEFINED_CONSTRUCTOR_IN_INITIALIZER, node, [superType.displayName, name]);
+      } else {
+        _resolver.reportErrorForNode(CompileTimeErrorCode.UNDEFINED_CONSTRUCTOR_IN_INITIALIZER_DEFAULT, node, [superType.displayName]);
+      }
+      return null;
+    } else {
+      if (element.isFactory) {
+        _resolver.reportErrorForNode(CompileTimeErrorCode.NON_GENERATIVE_CONSTRUCTOR, node, [element]);
+      }
+    }
+    if (name != null) {
+      name.staticElement = element;
+    }
+    node.staticElement = element;
+    ArgumentList argumentList = node.argumentList;
+    List<ParameterElement> parameters = _resolveArgumentsToFunction(isInConstConstructor, argumentList, element);
+    if (parameters != null) {
+      argumentList.correspondingStaticParameters = parameters;
+    }
+    return null;
+  }
+
+  @override
+  Object visitSuperExpression(SuperExpression node) {
+    if (!_isSuperInValidContext(node)) {
+      _resolver.reportErrorForNode(CompileTimeErrorCode.SUPER_IN_INVALID_CONTEXT, node, []);
+    }
+    return super.visitSuperExpression(node);
+  }
+
+  @override
+  Object visitTypeParameter(TypeParameter node) {
+    _setMetadata(node.element, node);
+    return null;
+  }
+
+  @override
+  Object visitVariableDeclaration(VariableDeclaration node) {
+    _setMetadata(node.element, node);
+    return null;
+  }
+
+  /**
+   * Generate annotation elements for each of the annotations in the given node list and add them to
+   * the given list of elements.
+   *
+   * @param annotationList the list of elements to which new elements are to be added
+   * @param annotations the AST nodes used to generate new elements
+   */
+  void _addAnnotations(List<ElementAnnotationImpl> annotationList, NodeList<Annotation> annotations) {
+    int annotationCount = annotations.length;
+    for (int i = 0; i < annotationCount; i++) {
+      Annotation annotation = annotations[i];
+      Element resolvedElement = annotation.element;
+      if (resolvedElement != null) {
+        ElementAnnotationImpl elementAnnotation = new ElementAnnotationImpl(resolvedElement);
+        annotation.elementAnnotation = elementAnnotation;
+        annotationList.add(elementAnnotation);
+      }
+    }
+  }
+
+  /**
+   * Given that we have found code to invoke the given element, return the error code that should be
+   * reported, or `null` if no error should be reported.
+   *
+   * @param target the target of the invocation, or `null` if there was no target
+   * @param useStaticContext
+   * @param element the element to be invoked
+   * @return the error code that should be reported
+   */
+  ErrorCode _checkForInvocationError(Expression target, bool useStaticContext, Element element) {
+    // Prefix is not declared, instead "prefix.id" are declared.
+    if (element is PrefixElement) {
+      element = null;
+    }
+    if (element is PropertyAccessorElement) {
+      //
+      // This is really a function expression invocation.
+      //
+      // TODO(brianwilkerson) Consider the possibility of re-writing the AST.
+      FunctionType getterType = element.type;
+      if (getterType != null) {
+        DartType returnType = getterType.returnType;
+        if (!_isExecutableType(returnType)) {
+          return StaticTypeWarningCode.INVOCATION_OF_NON_FUNCTION;
+        }
+      }
+    } else if (element is ExecutableElement) {
+      return null;
+    } else if (element is MultiplyDefinedElement) {
+      // The error has already been reported
+      return null;
+    } else if (element == null && target is SuperExpression) {
+      // TODO(jwren) We should split the UNDEFINED_METHOD into two error codes, this one, and
+      // a code that describes the situation where the method was found, but it was not
+      // accessible from the current library.
+      return StaticTypeWarningCode.UNDEFINED_SUPER_METHOD;
+    } else {
+      //
+      // This is really a function expression invocation.
+      //
+      // TODO(brianwilkerson) Consider the possibility of re-writing the AST.
+      if (element is PropertyInducingElement) {
+        PropertyAccessorElement getter = element.getter;
+        FunctionType getterType = getter.type;
+        if (getterType != null) {
+          DartType returnType = getterType.returnType;
+          if (!_isExecutableType(returnType)) {
+            return StaticTypeWarningCode.INVOCATION_OF_NON_FUNCTION;
+          }
+        }
+      } else if (element is VariableElement) {
+        DartType variableType = element.type;
+        if (!_isExecutableType(variableType)) {
+          return StaticTypeWarningCode.INVOCATION_OF_NON_FUNCTION;
+        }
+      } else {
+        if (target == null) {
+          ClassElement enclosingClass = _resolver.enclosingClass;
+          if (enclosingClass == null) {
+            return StaticTypeWarningCode.UNDEFINED_FUNCTION;
+          } else if (element == null) {
+            // Proxy-conditional warning, based on state of resolver.getEnclosingClass()
+            return StaticTypeWarningCode.UNDEFINED_METHOD;
+          } else {
+            return StaticTypeWarningCode.INVOCATION_OF_NON_FUNCTION;
+          }
+        } else {
+          DartType targetType;
+          if (useStaticContext) {
+            targetType = _getStaticType(target);
+          } else {
+            // Compute and use the propagated type, if it is null, then it may be the case that
+            // static type is some type, in which the static type should be used.
+            targetType = target.bestType;
+          }
+          if (targetType == null) {
+            return StaticTypeWarningCode.UNDEFINED_FUNCTION;
+          } else if (!targetType.isDynamic && !targetType.isBottom) {
+            // Proxy-conditional warning, based on state of targetType.getElement()
+            return StaticTypeWarningCode.UNDEFINED_METHOD;
+          }
+        }
+      }
+    }
+    return null;
+  }
+
+  /**
+   * Check that the for some index expression that the method element was resolved, otherwise a
+   * [StaticWarningCode#UNDEFINED_OPERATOR] is generated.
+   *
+   * @param node the index expression to resolve
+   * @param target the target of the expression
+   * @param methodName the name of the operator associated with the context of using of the given
+   *          index expression
+   * @return `true` if and only if an error code is generated on the passed node
+   */
+  bool _checkForUndefinedIndexOperator(IndexExpression node, Expression target, String methodName, MethodElement staticMethod, MethodElement propagatedMethod, DartType staticType, DartType propagatedType) {
+    bool shouldReportMissingMember_static = _shouldReportMissingMember(staticType, staticMethod);
+    bool shouldReportMissingMember_propagated = !shouldReportMissingMember_static && _enableHints && _shouldReportMissingMember(propagatedType, propagatedMethod) && !_memberFoundInSubclass(propagatedType.element, methodName, true, false);
+    if (shouldReportMissingMember_static || shouldReportMissingMember_propagated) {
+      sc.Token leftBracket = node.leftBracket;
+      sc.Token rightBracket = node.rightBracket;
+      ErrorCode errorCode = (shouldReportMissingMember_static ? StaticTypeWarningCode.UNDEFINED_OPERATOR : HintCode.UNDEFINED_OPERATOR);
+      if (leftBracket == null || rightBracket == null) {
+        _recordUndefinedNode(shouldReportMissingMember_static ? staticType.element : propagatedType.element, errorCode, node, [
+            methodName,
+            shouldReportMissingMember_static ? staticType.displayName : propagatedType.displayName]);
+      } else {
+        int offset = leftBracket.offset;
+        int length = rightBracket.offset - offset + 1;
+        _recordUndefinedOffset(shouldReportMissingMember_static ? staticType.element : propagatedType.element, errorCode, offset, length, [
+            methodName,
+            shouldReportMissingMember_static ? staticType.displayName : propagatedType.displayName]);
+      }
+      return true;
+    }
+    return false;
+  }
+
+  /**
+   * Given a list of arguments and the element that will be invoked using those argument, compute
+   * the list of parameters that correspond to the list of arguments. Return the parameters that
+   * correspond to the arguments, or `null` if no correspondence could be computed.
+   *
+   * @param argumentList the list of arguments being passed to the element
+   * @param executableElement the element that will be invoked with the arguments
+   * @return the parameters that correspond to the arguments
+   */
+  List<ParameterElement> _computeCorrespondingParameters(ArgumentList argumentList, Element element) {
+    if (element is PropertyAccessorElement) {
+      //
+      // This is an invocation of the call method defined on the value returned by the getter.
+      //
+      FunctionType getterType = element.type;
+      if (getterType != null) {
+        DartType getterReturnType = getterType.returnType;
+        if (getterReturnType is InterfaceType) {
+          MethodElement callMethod = getterReturnType.lookUpMethod(FunctionElement.CALL_METHOD_NAME, _definingLibrary);
+          if (callMethod != null) {
+            return _resolveArgumentsToFunction(false, argumentList, callMethod);
+          }
+        } else if (getterReturnType is FunctionType) {
+          List<ParameterElement> parameters = getterReturnType.parameters;
+          return _resolveArgumentsToParameters(false, argumentList, parameters);
+        }
+      }
+    } else if (element is ExecutableElement) {
+      return _resolveArgumentsToFunction(false, argumentList, element);
+    } else if (element is VariableElement) {
+      VariableElement variable = element;
+      DartType type = _promoteManager.getStaticType(variable);
+      if (type is FunctionType) {
+        FunctionType functionType = type;
+        List<ParameterElement> parameters = functionType.parameters;
+        return _resolveArgumentsToParameters(false, argumentList, parameters);
+      } else if (type is InterfaceType) {
+        // "call" invocation
+        MethodElement callMethod = type.lookUpMethod(FunctionElement.CALL_METHOD_NAME, _definingLibrary);
+        if (callMethod != null) {
+          List<ParameterElement> parameters = callMethod.parameters;
+          return _resolveArgumentsToParameters(false, argumentList, parameters);
+        }
+      }
+    }
+    return null;
+  }
+
+  /**
+   * If the given element is a setter, return the getter associated with it. Otherwise, return the
+   * element unchanged.
+   *
+   * @param element the element to be normalized
+   * @return a non-setter element derived from the given element
+   */
+  Element _convertSetterToGetter(Element element) {
+    // TODO(brianwilkerson) Determine whether and why the element could ever be a setter.
+    if (element is PropertyAccessorElement) {
+      return element.variable.getter;
+    }
+    return element;
+  }
+
+  /**
+   * Return `true` if the given element is not a proxy.
+   *
+   * @param element the enclosing element. If null, `true` will be returned.
+   * @return `false` iff the passed [Element] is a [ClassElement] that is a proxy
+   *         or inherits proxy
+   * @see ClassElement#isOrInheritsProxy()
+   */
+  bool _doesntHaveProxy(Element element) => !(element is ClassElement && element.isOrInheritsProxy);
+
+  /**
+   * Look for any declarations of the given identifier that are imported using a prefix. Return the
+   * element that was found, or `null` if the name is not imported using a prefix.
+   *
+   * @param identifier the identifier that might have been imported using a prefix
+   * @return the element that was found
+   */
+  Element _findImportWithoutPrefix(SimpleIdentifier identifier) {
+    Element element = null;
+    Scope nameScope = _resolver.nameScope;
+    for (ImportElement importElement in _definingLibrary.imports) {
+      PrefixElement prefixElement = importElement.prefix;
+      if (prefixElement != null) {
+        Identifier prefixedIdentifier = new ElementResolver_SyntheticIdentifier("${prefixElement.name}.${identifier.name}");
+        Element importedElement = nameScope.lookup(prefixedIdentifier, _definingLibrary);
+        if (importedElement != null) {
+          if (element == null) {
+            element = importedElement;
+          } else {
+            element = MultiplyDefinedElementImpl.fromElements(_definingLibrary.context, element, importedElement);
+          }
+        }
+      }
+    }
+    return element;
+  }
+
+  /**
+   * Assuming that the given expression is a prefix for a deferred import, return the library that
+   * is being imported.
+   *
+   * @param expression the expression representing the deferred import's prefix
+   * @return the library that is being imported by the import associated with the prefix
+   */
+  LibraryElement _getImportedLibrary(Expression expression) {
+    PrefixElement prefixElement = (expression as SimpleIdentifier).staticElement as PrefixElement;
+    List<ImportElement> imports = prefixElement.enclosingElement.getImportsWithPrefix(prefixElement);
+    return imports[0].importedLibrary;
+  }
+
+  /**
+   * Return the name of the method invoked by the given postfix expression.
+   *
+   * @param node the postfix expression being invoked
+   * @return the name of the method invoked by the expression
+   */
+  String _getPostfixOperator(PostfixExpression node) => (node.operator.type == sc.TokenType.PLUS_PLUS) ? sc.TokenType.PLUS.lexeme : sc.TokenType.MINUS.lexeme;
+
+  /**
+   * Return the name of the method invoked by the given postfix expression.
+   *
+   * @param node the postfix expression being invoked
+   * @return the name of the method invoked by the expression
+   */
+  String _getPrefixOperator(PrefixExpression node) {
+    sc.Token operator = node.operator;
+    sc.TokenType operatorType = operator.type;
+    if (operatorType == sc.TokenType.PLUS_PLUS) {
+      return sc.TokenType.PLUS.lexeme;
+    } else if (operatorType == sc.TokenType.MINUS_MINUS) {
+      return sc.TokenType.MINUS.lexeme;
+    } else if (operatorType == sc.TokenType.MINUS) {
+      return "unary-";
+    } else {
+      return operator.lexeme;
+    }
+  }
+
+  /**
+   * Return the propagated type of the given expression that is to be used for type analysis.
+   *
+   * @param expression the expression whose type is to be returned
+   * @return the type of the given expression
+   */
+  DartType _getPropagatedType(Expression expression) {
+    DartType propagatedType = _resolveTypeParameter(expression.propagatedType);
+    if (propagatedType is FunctionType) {
+      //
+      // All function types are subtypes of 'Function', which is itself a subclass of 'Object'.
+      //
+      propagatedType = _resolver.typeProvider.functionType;
+    }
+    return propagatedType;
+  }
+
+  /**
+   * Return the static type of the given expression that is to be used for type analysis.
+   *
+   * @param expression the expression whose type is to be returned
+   * @return the type of the given expression
+   */
+  DartType _getStaticType(Expression expression) {
+    if (expression is NullLiteral) {
+      return _resolver.typeProvider.bottomType;
+    }
+    DartType staticType = _resolveTypeParameter(expression.staticType);
+    if (staticType is FunctionType) {
+      //
+      // All function types are subtypes of 'Function', which is itself a subclass of 'Object'.
+      //
+      staticType = _resolver.typeProvider.functionType;
+    }
+    return staticType;
+  }
+
+  /**
+   * Return `true` if the given expression is a prefix for a deferred import.
+   *
+   * @param expression the expression being tested
+   * @return `true` if the given expression is a prefix for a deferred import
+   */
+  bool _isDeferredPrefix(Expression expression) {
+    if (expression is! SimpleIdentifier) {
+      return false;
+    }
+    Element element = (expression as SimpleIdentifier).staticElement;
+    if (element is! PrefixElement) {
+      return false;
+    }
+    PrefixElement prefixElement = element as PrefixElement;
+    List<ImportElement> imports = prefixElement.enclosingElement.getImportsWithPrefix(prefixElement);
+    if (imports.length != 1) {
+      return false;
+    }
+    return imports[0].isDeferred;
+  }
+
+  /**
+   * Return `true` if the given type represents an object that could be invoked using the call
+   * operator '()'.
+   *
+   * @param type the type being tested
+   * @return `true` if the given type represents an object that could be invoked
+   */
+  bool _isExecutableType(DartType type) {
+    if (type.isDynamic || (type is FunctionType) || type.isDartCoreFunction || type.isObject) {
+      return true;
+    } else if (type is InterfaceType) {
+      ClassElement classElement = type.element;
+      // 16078 from Gilad: If the type is a Functor with the @proxy annotation, treat it as an
+      // executable type.
+      // example code: NonErrorResolverTest.test_invocationOfNonFunction_proxyOnFunctionClass()
+      if (classElement.isProxy && type.isSubtypeOf(_resolver.typeProvider.functionType)) {
+        return true;
+      }
+      MethodElement methodElement = classElement.lookUpMethod(FunctionElement.CALL_METHOD_NAME, _definingLibrary);
+      return methodElement != null;
+    }
+    return false;
+  }
+
+  /**
+   * @return `true` iff current enclosing function is constant constructor declaration.
+   */
+  bool get isInConstConstructor {
+    ExecutableElement function = _resolver.enclosingFunction;
+    if (function is ConstructorElement) {
+      return function.isConst;
+    }
+    return false;
+  }
+
+  /**
+   * Return `true` if the given element is a static element.
+   *
+   * @param element the element being tested
+   * @return `true` if the given element is a static element
+   */
+  bool _isStatic(Element element) {
+    if (element is ExecutableElement) {
+      return element.isStatic;
+    } else if (element is PropertyInducingElement) {
+      return element.isStatic;
+    }
+    return false;
+  }
+
+  /**
+   * Return `true` if the given node can validly be resolved to a prefix:
+   * * it is the prefix in an import directive, or
+   * * it is the prefix in a prefixed identifier.
+   *
+   * @param node the node being tested
+   * @return `true` if the given node is the prefix in an import directive
+   */
+  bool _isValidAsPrefix(SimpleIdentifier node) {
+    AstNode parent = node.parent;
+    if (parent is ImportDirective) {
+      return identical(parent.prefix, node);
+    } else if (parent is PrefixedIdentifier) {
+      return true;
+    } else if (parent is MethodInvocation) {
+      return identical(parent.target, node);
+    }
+    return false;
+  }
+
+  /**
+   * Look up the getter with the given name in the given type. Return the element representing the
+   * getter that was found, or `null` if there is no getter with the given name.
+   *
+   * @param target the target of the invocation, or `null` if there is no target
+   * @param type the type in which the getter is defined
+   * @param getterName the name of the getter being looked up
+   * @return the element representing the getter that was found
+   */
+  PropertyAccessorElement _lookUpGetter(Expression target, DartType type, String getterName) {
+    type = _resolveTypeParameter(type);
+    if (type is InterfaceType) {
+      InterfaceType interfaceType = type;
+      PropertyAccessorElement accessor;
+      if (target is SuperExpression) {
+        accessor = interfaceType.lookUpGetterInSuperclass(getterName, _definingLibrary);
+      } else {
+        accessor = interfaceType.lookUpGetter(getterName, _definingLibrary);
+      }
+      if (accessor != null) {
+        return accessor;
+      }
+      return _lookUpGetterInInterfaces(interfaceType, false, getterName, new HashSet<ClassElement>());
+    }
+    return null;
+  }
+
+  /**
+   * Look up the getter with the given name in the interfaces implemented by the given type, either
+   * directly or indirectly. Return the element representing the getter that was found, or
+   * `null` if there is no getter with the given name.
+   *
+   * @param targetType the type in which the getter might be defined
+   * @param includeTargetType `true` if the search should include the target type
+   * @param getterName the name of the getter being looked up
+   * @param visitedInterfaces a set containing all of the interfaces that have been examined, used
+   *          to prevent infinite recursion and to optimize the search
+   * @return the element representing the getter that was found
+   */
+  PropertyAccessorElement _lookUpGetterInInterfaces(InterfaceType targetType, bool includeTargetType, String getterName, HashSet<ClassElement> visitedInterfaces) {
+    // TODO(brianwilkerson) This isn't correct. Section 8.1.1 of the specification (titled
+    // "Inheritance and Overriding" under "Interfaces") describes a much more complex scheme for
+    // finding the inherited member. We need to follow that scheme. The code below should cover the
+    // 80% case.
+    ClassElement targetClass = targetType.element;
+    if (visitedInterfaces.contains(targetClass)) {
+      return null;
+    }
+    visitedInterfaces.add(targetClass);
+    if (includeTargetType) {
+      PropertyAccessorElement getter = targetType.getGetter(getterName);
+      if (getter != null && getter.isAccessibleIn(_definingLibrary)) {
+        return getter;
+      }
+    }
+    for (InterfaceType interfaceType in targetType.interfaces) {
+      PropertyAccessorElement getter = _lookUpGetterInInterfaces(interfaceType, true, getterName, visitedInterfaces);
+      if (getter != null) {
+        return getter;
+      }
+    }
+    for (InterfaceType mixinType in targetType.mixins) {
+      PropertyAccessorElement getter = _lookUpGetterInInterfaces(mixinType, true, getterName, visitedInterfaces);
+      if (getter != null) {
+        return getter;
+      }
+    }
+    InterfaceType superclass = targetType.superclass;
+    if (superclass == null) {
+      return null;
+    }
+    return _lookUpGetterInInterfaces(superclass, true, getterName, visitedInterfaces);
+  }
+
+  /**
+   * Look up the method or getter with the given name in the given type. Return the element
+   * representing the method or getter that was found, or `null` if there is no method or
+   * getter with the given name.
+   *
+   * @param type the type in which the method or getter is defined
+   * @param memberName the name of the method or getter being looked up
+   * @return the element representing the method or getter that was found
+   */
+  ExecutableElement _lookupGetterOrMethod(DartType type, String memberName) {
+    type = _resolveTypeParameter(type);
+    if (type is InterfaceType) {
+      InterfaceType interfaceType = type;
+      ExecutableElement member = interfaceType.lookUpMethod(memberName, _definingLibrary);
+      if (member != null) {
+        return member;
+      }
+      member = interfaceType.lookUpGetter(memberName, _definingLibrary);
+      if (member != null) {
+        return member;
+      }
+      return _lookUpGetterOrMethodInInterfaces(interfaceType, false, memberName, new HashSet<ClassElement>());
+    }
+    return null;
+  }
+
+  /**
+   * Look up the method or getter with the given name in the interfaces implemented by the given
+   * type, either directly or indirectly. Return the element representing the method or getter that
+   * was found, or `null` if there is no method or getter with the given name.
+   *
+   * @param targetType the type in which the method or getter might be defined
+   * @param includeTargetType `true` if the search should include the target type
+   * @param memberName the name of the method or getter being looked up
+   * @param visitedInterfaces a set containing all of the interfaces that have been examined, used
+   *          to prevent infinite recursion and to optimize the search
+   * @return the element representing the method or getter that was found
+   */
+  ExecutableElement _lookUpGetterOrMethodInInterfaces(InterfaceType targetType, bool includeTargetType, String memberName, HashSet<ClassElement> visitedInterfaces) {
+    // TODO(brianwilkerson) This isn't correct. Section 8.1.1 of the specification (titled
+    // "Inheritance and Overriding" under "Interfaces") describes a much more complex scheme for
+    // finding the inherited member. We need to follow that scheme. The code below should cover the
+    // 80% case.
+    ClassElement targetClass = targetType.element;
+    if (visitedInterfaces.contains(targetClass)) {
+      return null;
+    }
+    visitedInterfaces.add(targetClass);
+    if (includeTargetType) {
+      ExecutableElement member = targetType.getMethod(memberName);
+      if (member != null) {
+        return member;
+      }
+      member = targetType.getGetter(memberName);
+      if (member != null) {
+        return member;
+      }
+    }
+    for (InterfaceType interfaceType in targetType.interfaces) {
+      ExecutableElement member = _lookUpGetterOrMethodInInterfaces(interfaceType, true, memberName, visitedInterfaces);
+      if (member != null) {
+        return member;
+      }
+    }
+    for (InterfaceType mixinType in targetType.mixins) {
+      ExecutableElement member = _lookUpGetterOrMethodInInterfaces(mixinType, true, memberName, visitedInterfaces);
+      if (member != null) {
+        return member;
+      }
+    }
+    InterfaceType superclass = targetType.superclass;
+    if (superclass == null) {
+      return null;
+    }
+    return _lookUpGetterOrMethodInInterfaces(superclass, true, memberName, visitedInterfaces);
+  }
+
+  /**
+   * Find the element corresponding to the given label node in the current label scope.
+   *
+   * @param parentNode the node containing the given label
+   * @param labelNode the node representing the label being looked up
+   * @return the element corresponding to the given label node in the current scope
+   */
+  LabelElementImpl _lookupLabel(AstNode parentNode, SimpleIdentifier labelNode) {
+    LabelScope labelScope = _resolver.labelScope;
+    LabelElementImpl labelElement = null;
+    if (labelNode == null) {
+      if (labelScope == null) {
+        // TODO(brianwilkerson) Do we need to report this error, or is this condition always caught in the parser?
+        // reportError(ResolverErrorCode.BREAK_OUTSIDE_LOOP);
+      } else {
+        labelElement = labelScope.lookup(LabelScope.EMPTY_LABEL) as LabelElementImpl;
+        if (labelElement == null) {
+          // TODO(brianwilkerson) Do we need to report this error, or is this condition always caught in the parser?
+          // reportError(ResolverErrorCode.BREAK_OUTSIDE_LOOP);
+        }
+        //
+        // The label element that was returned was a marker for look-up and isn't stored in the
+        // element model.
+        //
+        labelElement = null;
+      }
+    } else {
+      if (labelScope == null) {
+        _resolver.reportErrorForNode(CompileTimeErrorCode.LABEL_UNDEFINED, labelNode, [labelNode.name]);
+      } else {
+        labelElement = labelScope.lookup(labelNode.name) as LabelElementImpl;
+        if (labelElement == null) {
+          _resolver.reportErrorForNode(CompileTimeErrorCode.LABEL_UNDEFINED, labelNode, [labelNode.name]);
+        } else {
+          labelNode.staticElement = labelElement;
+        }
+      }
+    }
+    if (labelElement != null) {
+      ExecutableElement labelContainer = labelElement.getAncestor((element) => element is ExecutableElement);
+      if (!identical(labelContainer, _resolver.enclosingFunction)) {
+        _resolver.reportErrorForNode(CompileTimeErrorCode.LABEL_IN_OUTER_SCOPE, labelNode, [labelNode.name]);
+        labelElement = null;
+      }
+    }
+    return labelElement;
+  }
+
+  /**
+   * Look up the method with the given name in the given type. Return the element representing the
+   * method that was found, or `null` if there is no method with the given name.
+   *
+   * @param target the target of the invocation, or `null` if there is no target
+   * @param type the type in which the method is defined
+   * @param methodName the name of the method being looked up
+   * @return the element representing the method that was found
+   */
+  MethodElement _lookUpMethod(Expression target, DartType type, String methodName) {
+    type = _resolveTypeParameter(type);
+    if (type is InterfaceType) {
+      InterfaceType interfaceType = type;
+      MethodElement method;
+      if (target is SuperExpression) {
+        method = interfaceType.lookUpMethodInSuperclass(methodName, _definingLibrary);
+      } else {
+        method = interfaceType.lookUpMethod(methodName, _definingLibrary);
+      }
+      if (method != null) {
+        return method;
+      }
+      return _lookUpMethodInInterfaces(interfaceType, false, methodName, new HashSet<ClassElement>());
+    } else if (type is UnionType) {
+      // TODO (collinsn): I want [computeMergedExecutableElement] to be general
+      // and work with functions, methods, constructors, and property accessors. However,
+      // I won't be able to assume it returns [MethodElement] here then.
+      return _maybeMergeExecutableElements(_lookupMethods(target, type, methodName)) as MethodElement;
+    }
+    return null;
+  }
+
+  /**
+   * Look up the method with the given name in the interfaces implemented by the given type, either
+   * directly or indirectly. Return the element representing the method that was found, or
+   * `null` if there is no method with the given name.
+   *
+   * @param targetType the type in which the member might be defined
+   * @param includeTargetType `true` if the search should include the target type
+   * @param methodName the name of the method being looked up
+   * @param visitedInterfaces a set containing all of the interfaces that have been examined, used
+   *          to prevent infinite recursion and to optimize the search
+   * @return the element representing the method that was found
+   */
+  MethodElement _lookUpMethodInInterfaces(InterfaceType targetType, bool includeTargetType, String methodName, HashSet<ClassElement> visitedInterfaces) {
+    // TODO(brianwilkerson) This isn't correct. Section 8.1.1 of the specification (titled
+    // "Inheritance and Overriding" under "Interfaces") describes a much more complex scheme for
+    // finding the inherited member. We need to follow that scheme. The code below should cover the
+    // 80% case.
+    ClassElement targetClass = targetType.element;
+    if (visitedInterfaces.contains(targetClass)) {
+      return null;
+    }
+    visitedInterfaces.add(targetClass);
+    if (includeTargetType) {
+      MethodElement method = targetType.getMethod(methodName);
+      if (method != null && method.isAccessibleIn(_definingLibrary)) {
+        return method;
+      }
+    }
+    for (InterfaceType interfaceType in targetType.interfaces) {
+      MethodElement method = _lookUpMethodInInterfaces(interfaceType, true, methodName, visitedInterfaces);
+      if (method != null) {
+        return method;
+      }
+    }
+    for (InterfaceType mixinType in targetType.mixins) {
+      MethodElement method = _lookUpMethodInInterfaces(mixinType, true, methodName, visitedInterfaces);
+      if (method != null) {
+        return method;
+      }
+    }
+    InterfaceType superclass = targetType.superclass;
+    if (superclass == null) {
+      return null;
+    }
+    return _lookUpMethodInInterfaces(superclass, true, methodName, visitedInterfaces);
+  }
+
+  /**
+   * Look up all methods of a given name defined on a union type.
+   *
+   * @param target
+   * @param type
+   * @param methodName
+   * @return all methods named `methodName` defined on the union type `type`.
+   */
+  Set<ExecutableElement> _lookupMethods(Expression target, UnionType type, String methodName) {
+    Set<ExecutableElement> methods = new HashSet<ExecutableElement>();
+    bool allElementsHaveMethod = true;
+    for (DartType t in type.elements) {
+      MethodElement m = _lookUpMethod(target, t, methodName);
+      if (m != null) {
+        methods.add(m);
+      } else {
+        allElementsHaveMethod = false;
+      }
+    }
+    // For strict union types we require that all types in the union define the method.
+    if (AnalysisEngine.instance.strictUnionTypes) {
+      if (allElementsHaveMethod) {
+        return methods;
+      } else {
+        return new Set<ExecutableElement>();
+      }
+    } else {
+      return methods;
+    }
+  }
+
+  /**
+   * Look up the setter with the given name in the given type. Return the element representing the
+   * setter that was found, or `null` if there is no setter with the given name.
+   *
+   * @param target the target of the invocation, or `null` if there is no target
+   * @param type the type in which the setter is defined
+   * @param setterName the name of the setter being looked up
+   * @return the element representing the setter that was found
+   */
+  PropertyAccessorElement _lookUpSetter(Expression target, DartType type, String setterName) {
+    type = _resolveTypeParameter(type);
+    if (type is InterfaceType) {
+      InterfaceType interfaceType = type;
+      PropertyAccessorElement accessor;
+      if (target is SuperExpression) {
+        accessor = interfaceType.lookUpSetterInSuperclass(setterName, _definingLibrary);
+      } else {
+        accessor = interfaceType.lookUpSetter(setterName, _definingLibrary);
+      }
+      if (accessor != null) {
+        return accessor;
+      }
+      return _lookUpSetterInInterfaces(interfaceType, false, setterName, new HashSet<ClassElement>());
+    }
+    return null;
+  }
+
+  /**
+   * Look up the setter with the given name in the interfaces implemented by the given type, either
+   * directly or indirectly. Return the element representing the setter that was found, or
+   * `null` if there is no setter with the given name.
+   *
+   * @param targetType the type in which the setter might be defined
+   * @param includeTargetType `true` if the search should include the target type
+   * @param setterName the name of the setter being looked up
+   * @param visitedInterfaces a set containing all of the interfaces that have been examined, used
+   *          to prevent infinite recursion and to optimize the search
+   * @return the element representing the setter that was found
+   */
+  PropertyAccessorElement _lookUpSetterInInterfaces(InterfaceType targetType, bool includeTargetType, String setterName, HashSet<ClassElement> visitedInterfaces) {
+    // TODO(brianwilkerson) This isn't correct. Section 8.1.1 of the specification (titled
+    // "Inheritance and Overriding" under "Interfaces") describes a much more complex scheme for
+    // finding the inherited member. We need to follow that scheme. The code below should cover the
+    // 80% case.
+    ClassElement targetClass = targetType.element;
+    if (visitedInterfaces.contains(targetClass)) {
+      return null;
+    }
+    visitedInterfaces.add(targetClass);
+    if (includeTargetType) {
+      PropertyAccessorElement setter = targetType.getSetter(setterName);
+      if (setter != null && setter.isAccessibleIn(_definingLibrary)) {
+        return setter;
+      }
+    }
+    for (InterfaceType interfaceType in targetType.interfaces) {
+      PropertyAccessorElement setter = _lookUpSetterInInterfaces(interfaceType, true, setterName, visitedInterfaces);
+      if (setter != null) {
+        return setter;
+      }
+    }
+    for (InterfaceType mixinType in targetType.mixins) {
+      PropertyAccessorElement setter = _lookUpSetterInInterfaces(mixinType, true, setterName, visitedInterfaces);
+      if (setter != null) {
+        return setter;
+      }
+    }
+    InterfaceType superclass = targetType.superclass;
+    if (superclass == null) {
+      return null;
+    }
+    return _lookUpSetterInInterfaces(superclass, true, setterName, visitedInterfaces);
+  }
+
+  /**
+   * Given some class element, this method uses [subtypeManager] to find the set of all
+   * subtypes; the subtypes are then searched for a member (method, getter, or setter), that matches
+   * a passed
+   *
+   * @param element the class element to search the subtypes of, if a non-ClassElement element is
+   *          passed, then `false` is returned
+   * @param memberName the member name to search for
+   * @param asMethod `true` if the methods should be searched for in the subtypes
+   * @param asAccessor `true` if the accessors (getters and setters) should be searched for in
+   *          the subtypes
+   * @return `true` if and only if the passed memberName was found in a subtype
+   */
+  bool _memberFoundInSubclass(Element element, String memberName, bool asMethod, bool asAccessor) {
+    if (element is ClassElement) {
+      _subtypeManager.ensureLibraryVisited(_definingLibrary);
+      HashSet<ClassElement> subtypeElements = _subtypeManager.computeAllSubtypes(element);
+      for (ClassElement subtypeElement in subtypeElements) {
+        if (asMethod && subtypeElement.getMethod(memberName) != null) {
+          return true;
+        } else if (asAccessor && (subtypeElement.getGetter(memberName) != null || subtypeElement.getSetter(memberName) != null)) {
+          return true;
+        }
+      }
+    }
+    return false;
+  }
+
+  /**
+   * Return the binary operator that is invoked by the given compound assignment operator.
+   *
+   * @param operator the assignment operator being mapped
+   * @return the binary operator that invoked by the given assignment operator
+   */
+  sc.TokenType _operatorFromCompoundAssignment(sc.TokenType operator) {
+    while (true) {
+      if (operator == sc.TokenType.AMPERSAND_EQ) {
+        return sc.TokenType.AMPERSAND;
+      } else if (operator == sc.TokenType.BAR_EQ) {
+        return sc.TokenType.BAR;
+      } else if (operator == sc.TokenType.CARET_EQ) {
+        return sc.TokenType.CARET;
+      } else if (operator == sc.TokenType.GT_GT_EQ) {
+        return sc.TokenType.GT_GT;
+      } else if (operator == sc.TokenType.LT_LT_EQ) {
+        return sc.TokenType.LT_LT;
+      } else if (operator == sc.TokenType.MINUS_EQ) {
+        return sc.TokenType.MINUS;
+      } else if (operator == sc.TokenType.PERCENT_EQ) {
+        return sc.TokenType.PERCENT;
+      } else if (operator == sc.TokenType.PLUS_EQ) {
+        return sc.TokenType.PLUS;
+      } else if (operator == sc.TokenType.SLASH_EQ) {
+        return sc.TokenType.SLASH;
+      } else if (operator == sc.TokenType.STAR_EQ) {
+        return sc.TokenType.STAR;
+      } else if (operator == sc.TokenType.TILDE_SLASH_EQ) {
+        return sc.TokenType.TILDE_SLASH;
+      } else {
+        // Internal error: Unmapped assignment operator.
+        AnalysisEngine.instance.logger.logError("Failed to map ${operator.lexeme} to it's corresponding operator");
+        return operator;
+      }
+      break;
+    }
+  }
+
+  /**
+   * Record that the given node is undefined, causing an error to be reported if appropriate.
+   *
+   * @param declaringElement the element inside which no declaration was found. If this element is a
+   *          proxy, no error will be reported. If null, then an error will always be reported.
+   * @param errorCode the error code to report.
+   * @param node the node which is undefined.
+   * @param arguments arguments to the error message.
+   */
+  void _recordUndefinedNode(Element declaringElement, ErrorCode errorCode, AstNode node, List<Object> arguments) {
+    if (_doesntHaveProxy(declaringElement)) {
+      _resolver.reportErrorForNode(errorCode, node, arguments);
+    }
+  }
+
+  /**
+   * Record that the given offset/length is undefined, causing an error to be reported if
+   * appropriate.
+   *
+   * @param declaringElement the element inside which no declaration was found. If this element is a
+   *          proxy, no error will be reported. If null, then an error will always be reported.
+   * @param errorCode the error code to report.
+   * @param offset the offset to the text which is undefined.
+   * @param length the length of the text which is undefined.
+   * @param arguments arguments to the error message.
+   */
+  void _recordUndefinedOffset(Element declaringElement, ErrorCode errorCode, int offset, int length, List<Object> arguments) {
+    if (_doesntHaveProxy(declaringElement)) {
+      _resolver.reportErrorForOffset(errorCode, offset, length, arguments);
+    }
+  }
+
+  /**
+   * Record that the given token is undefined, causing an error to be reported if appropriate.
+   *
+   * @param declaringElement the element inside which no declaration was found. If this element is a
+   *          proxy, no error will be reported. If null, then an error will always be reported.
+   * @param errorCode the error code to report.
+   * @param token the token which is undefined.
+   * @param arguments arguments to the error message.
+   */
+  void _recordUndefinedToken(Element declaringElement, ErrorCode errorCode, sc.Token token, List<Object> arguments) {
+    if (_doesntHaveProxy(declaringElement)) {
+      _resolver.reportErrorForToken(errorCode, token, arguments);
+    }
+  }
+
+  void _resolveAnnotationConstructorInvocationArguments(Annotation annotation, ConstructorElement constructor) {
+    ArgumentList argumentList = annotation.arguments;
+    // error will be reported in ConstantVerifier
+    if (argumentList == null) {
+      return;
+    }
+    // resolve arguments to parameters
+    List<ParameterElement> parameters = _resolveArgumentsToFunction(true, argumentList, constructor);
+    if (parameters != null) {
+      argumentList.correspondingStaticParameters = parameters;
+    }
+  }
+
+  /**
+   * Continues resolution of the given [Annotation].
+   *
+   * @param annotation the [Annotation] to resolve
+   */
+  void _resolveAnnotationElement(Annotation annotation) {
+    SimpleIdentifier nameNode1;
+    SimpleIdentifier nameNode2;
+    {
+      Identifier annName = annotation.name;
+      if (annName is PrefixedIdentifier) {
+        PrefixedIdentifier prefixed = annName;
+        nameNode1 = prefixed.prefix;
+        nameNode2 = prefixed.identifier;
+      } else {
+        nameNode1 = annName as SimpleIdentifier;
+        nameNode2 = null;
+      }
+    }
+    SimpleIdentifier nameNode3 = annotation.constructorName;
+    ConstructorElement constructor = null;
+    //
+    // CONST or Class(args)
+    //
+    if (nameNode1 != null && nameNode2 == null && nameNode3 == null) {
+      Element element1 = nameNode1.staticElement;
+      // CONST
+      if (element1 is PropertyAccessorElement) {
+        _resolveAnnotationElementGetter(annotation, element1);
+        return;
+      }
+      // Class(args)
+      if (element1 is ClassElement) {
+        ClassElement classElement = element1;
+        constructor = new InterfaceTypeImpl.con1(classElement).lookUpConstructor(null, _definingLibrary);
+      }
+    }
+    //
+    // prefix.CONST or prefix.Class() or Class.CONST or Class.constructor(args)
+    //
+    if (nameNode1 != null && nameNode2 != null && nameNode3 == null) {
+      Element element1 = nameNode1.staticElement;
+      Element element2 = nameNode2.staticElement;
+      // Class.CONST - not resolved yet
+      if (element1 is ClassElement) {
+        ClassElement classElement = element1;
+        element2 = classElement.lookUpGetter(nameNode2.name, _definingLibrary);
+      }
+      // prefix.CONST or Class.CONST
+      if (element2 is PropertyAccessorElement) {
+        nameNode2.staticElement = element2;
+        annotation.element = element2;
+        _resolveAnnotationElementGetter(annotation, element2 as PropertyAccessorElement);
+        return;
+      }
+      // prefix.Class()
+      if (element2 is ClassElement) {
+        ClassElement classElement = element2 as ClassElement;
+        constructor = classElement.unnamedConstructor;
+      }
+      // Class.constructor(args)
+      if (element1 is ClassElement) {
+        ClassElement classElement = element1;
+        constructor = new InterfaceTypeImpl.con1(classElement).lookUpConstructor(nameNode2.name, _definingLibrary);
+        nameNode2.staticElement = constructor;
+      }
+    }
+    //
+    // prefix.Class.CONST or prefix.Class.constructor(args)
+    //
+    if (nameNode1 != null && nameNode2 != null && nameNode3 != null) {
+      Element element2 = nameNode2.staticElement;
+      // element2 should be ClassElement
+      if (element2 is ClassElement) {
+        ClassElement classElement = element2;
+        String name3 = nameNode3.name;
+        // prefix.Class.CONST
+        PropertyAccessorElement getter = classElement.lookUpGetter(name3, _definingLibrary);
+        if (getter != null) {
+          nameNode3.staticElement = getter;
+          annotation.element = element2;
+          _resolveAnnotationElementGetter(annotation, getter);
+          return;
+        }
+        // prefix.Class.constructor(args)
+        constructor = new InterfaceTypeImpl.con1(classElement).lookUpConstructor(name3, _definingLibrary);
+        nameNode3.staticElement = constructor;
+      }
+    }
+    // we need constructor
+    if (constructor == null) {
+      _resolver.reportErrorForNode(CompileTimeErrorCode.INVALID_ANNOTATION, annotation, []);
+      return;
+    }
+    // record element
+    annotation.element = constructor;
+    // resolve arguments
+    _resolveAnnotationConstructorInvocationArguments(annotation, constructor);
+  }
+
+  void _resolveAnnotationElementGetter(Annotation annotation, PropertyAccessorElement accessorElement) {
+    // accessor should be synthetic
+    if (!accessorElement.isSynthetic) {
+      _resolver.reportErrorForNode(CompileTimeErrorCode.INVALID_ANNOTATION, annotation, []);
+      return;
+    }
+    // variable should be constant
+    VariableElement variableElement = accessorElement.variable;
+    if (!variableElement.isConst) {
+      _resolver.reportErrorForNode(CompileTimeErrorCode.INVALID_ANNOTATION, annotation, []);
+    }
+    // OK
+    return;
+  }
+
+  /**
+   * Given a list of arguments and the element that will be invoked using those argument, compute
+   * the list of parameters that correspond to the list of arguments. Return the parameters that
+   * correspond to the arguments, or `null` if no correspondence could be computed.
+   *
+   * @param reportError if `true` then compile-time error should be reported; if `false`
+   *          then compile-time warning
+   * @param argumentList the list of arguments being passed to the element
+   * @param executableElement the element that will be invoked with the arguments
+   * @return the parameters that correspond to the arguments
+   */
+  List<ParameterElement> _resolveArgumentsToFunction(bool reportError, ArgumentList argumentList, ExecutableElement executableElement) {
+    if (executableElement == null) {
+      return null;
+    }
+    List<ParameterElement> parameters = executableElement.parameters;
+    return _resolveArgumentsToParameters(reportError, argumentList, parameters);
+  }
+
+  /**
+   * Given a list of arguments and the parameters related to the element that will be invoked using
+   * those argument, compute the list of parameters that correspond to the list of arguments. Return
+   * the parameters that correspond to the arguments.
+   *
+   * @param reportError if `true` then compile-time error should be reported; if `false`
+   *          then compile-time warning
+   * @param argumentList the list of arguments being passed to the element
+   * @param parameters the of the function that will be invoked with the arguments
+   * @return the parameters that correspond to the arguments
+   */
+  List<ParameterElement> _resolveArgumentsToParameters(bool reportError, ArgumentList argumentList, List<ParameterElement> parameters) {
+    List<ParameterElement> requiredParameters = new List<ParameterElement>();
+    List<ParameterElement> positionalParameters = new List<ParameterElement>();
+    HashMap<String, ParameterElement> namedParameters = new HashMap<String, ParameterElement>();
+    for (ParameterElement parameter in parameters) {
+      ParameterKind kind = parameter.parameterKind;
+      if (kind == ParameterKind.REQUIRED) {
+        requiredParameters.add(parameter);
+      } else if (kind == ParameterKind.POSITIONAL) {
+        positionalParameters.add(parameter);
+      } else {
+        namedParameters[parameter.name] = parameter;
+      }
+    }
+    List<ParameterElement> unnamedParameters = new List<ParameterElement>.from(requiredParameters);
+    unnamedParameters.addAll(positionalParameters);
+    int unnamedParameterCount = unnamedParameters.length;
+    int unnamedIndex = 0;
+    NodeList<Expression> arguments = argumentList.arguments;
+    int argumentCount = arguments.length;
+    List<ParameterElement> resolvedParameters = new List<ParameterElement>(argumentCount);
+    int positionalArgumentCount = 0;
+    HashSet<String> usedNames = new HashSet<String>();
+    bool noBlankArguments = true;
+    for (int i = 0; i < argumentCount; i++) {
+      Expression argument = arguments[i];
+      if (argument is NamedExpression) {
+        SimpleIdentifier nameNode = argument.name.label;
+        String name = nameNode.name;
+        ParameterElement element = namedParameters[name];
+        if (element == null) {
+          ErrorCode errorCode = (reportError ? CompileTimeErrorCode.UNDEFINED_NAMED_PARAMETER : StaticWarningCode.UNDEFINED_NAMED_PARAMETER);
+          _resolver.reportErrorForNode(errorCode, nameNode, [name]);
+        } else {
+          resolvedParameters[i] = element;
+          nameNode.staticElement = element;
+        }
+        if (!usedNames.add(name)) {
+          _resolver.reportErrorForNode(CompileTimeErrorCode.DUPLICATE_NAMED_ARGUMENT, nameNode, [name]);
+        }
+      } else {
+        if (argument is SimpleIdentifier && argument.name.isEmpty) {
+          noBlankArguments = false;
+        }
+        positionalArgumentCount++;
+        if (unnamedIndex < unnamedParameterCount) {
+          resolvedParameters[i] = unnamedParameters[unnamedIndex++];
+        }
+      }
+    }
+    if (positionalArgumentCount < requiredParameters.length && noBlankArguments) {
+      ErrorCode errorCode = (reportError ? CompileTimeErrorCode.NOT_ENOUGH_REQUIRED_ARGUMENTS : StaticWarningCode.NOT_ENOUGH_REQUIRED_ARGUMENTS);
+      _resolver.reportErrorForNode(errorCode, argumentList, [requiredParameters.length, positionalArgumentCount]);
+    } else if (positionalArgumentCount > unnamedParameterCount && noBlankArguments) {
+      ErrorCode errorCode = (reportError ? CompileTimeErrorCode.EXTRA_POSITIONAL_ARGUMENTS : StaticWarningCode.EXTRA_POSITIONAL_ARGUMENTS);
+      _resolver.reportErrorForNode(errorCode, argumentList, [unnamedParameterCount, positionalArgumentCount]);
+    }
+    return resolvedParameters;
+  }
+
+  /**
+   * Resolve the names in the given combinators in the scope of the given library.
+   *
+   * @param library the library that defines the names
+   * @param combinators the combinators containing the names to be resolved
+   */
+  void _resolveCombinators(LibraryElement library, NodeList<Combinator> combinators) {
+    if (library == null) {
+      //
+      // The library will be null if the directive containing the combinators has a URI that is not
+      // valid.
+      //
+      return;
+    }
+    Namespace namespace = new NamespaceBuilder().createExportNamespaceForLibrary(library);
+    for (Combinator combinator in combinators) {
+      NodeList<SimpleIdentifier> names;
+      if (combinator is HideCombinator) {
+        names = combinator.hiddenNames;
+      } else {
+        names = (combinator as ShowCombinator).shownNames;
+      }
+      for (SimpleIdentifier name in names) {
+        String nameStr = name.name;
+        Element element = namespace.get(nameStr);
+        if (element == null) {
+          element = namespace.get("$nameStr=");
+        }
+        if (element != null) {
+          // Ensure that the name always resolves to a top-level variable
+          // rather than a getter or setter
+          if (element is PropertyAccessorElement) {
+            element = (element as PropertyAccessorElement).variable;
+          }
+          name.staticElement = element;
+        }
+      }
+    }
+  }
+
+  /**
+   * Given an invocation of the form 'C.x()' where 'C' is a class, find and return the element 'x'
+   * in 'C'.
+   *
+   * @param classElement the class element
+   * @param nameNode the member name node
+   */
+  Element _resolveElement(ClassElementImpl classElement, SimpleIdentifier nameNode) {
+    String name = nameNode.name;
+    Element element = classElement.getMethod(name);
+    if (element == null && nameNode.inSetterContext()) {
+      element = classElement.getSetter(name);
+    }
+    if (element == null && nameNode.inGetterContext()) {
+      element = classElement.getGetter(name);
+    }
+    if (element != null && element.isAccessibleIn(_definingLibrary)) {
+      return element;
+    }
+    return null;
+  }
+
+  /**
+   * Given an invocation of the form 'm(a1, ..., an)', resolve 'm' to the element being invoked. If
+   * the returned element is a method, then the method will be invoked. If the returned element is a
+   * getter, the getter will be invoked without arguments and the result of that invocation will
+   * then be invoked with the arguments.
+   *
+   * @param methodName the name of the method being invoked ('m')
+   * @return the element being invoked
+   */
+  Element _resolveInvokedElement(SimpleIdentifier methodName) {
+    //
+    // Look first in the lexical scope.
+    //
+    Element element = _resolver.nameScope.lookup(methodName, _definingLibrary);
+    if (element == null) {
+      //
+      // If it isn't defined in the lexical scope, and the invocation is within a class, then look
+      // in the inheritance scope.
+      //
+      ClassElement enclosingClass = _resolver.enclosingClass;
+      if (enclosingClass != null) {
+        InterfaceType enclosingType = enclosingClass.type;
+        element = _lookUpMethod(null, enclosingType, methodName.name);
+        if (element == null) {
+          //
+          // If there's no method, then it's possible that 'm' is a getter that returns a function.
+          //
+          element = _lookUpGetter(null, enclosingType, methodName.name);
+        }
+      }
+    }
+    // TODO(brianwilkerson) Report this error.
+    return element;
+  }
+
+  /**
+   * Given an invocation of the form 'e.m(a1, ..., an)', resolve 'e.m' to the element being invoked.
+   * If the returned element is a method, then the method will be invoked. If the returned element
+   * is a getter, the getter will be invoked without arguments and the result of that invocation
+   * will then be invoked with the arguments.
+   *
+   * @param target the target of the invocation ('e')
+   * @param targetType the type of the target
+   * @param methodName the name of the method being invoked ('m')
+   * @return the element being invoked
+   */
+  Element _resolveInvokedElementWithTarget(Expression target, DartType targetType, SimpleIdentifier methodName) {
+    if (targetType is InterfaceType || targetType is UnionType) {
+      Element element = _lookUpMethod(target, targetType, methodName.name);
+      if (element == null) {
+        //
+        // If there's no method, then it's possible that 'm' is a getter that returns a function.
+        //
+        // TODO (collinsn): need to add union type support here too, in the style of [lookUpMethod].
+        element = _lookUpGetter(target, targetType, methodName.name);
+      }
+      return element;
+    } else if (target is SimpleIdentifier) {
+      Element targetElement = target.staticElement;
+      if (targetElement is PrefixElement) {
+        //
+        // Look to see whether the name of the method is really part of a prefixed identifier for an
+        // imported top-level function or top-level getter that returns a function.
+        //
+        String name = "${target.name}.$methodName";
+        Identifier functionName = new ElementResolver_SyntheticIdentifier(name);
+        Element element = _resolver.nameScope.lookup(functionName, _definingLibrary);
+        if (element != null) {
+          // TODO(brianwilkerson) This isn't a method invocation, it's a function invocation where
+          // the function name is a prefixed identifier. Consider re-writing the AST.
+          return element;
+        }
+      }
+    }
+    // TODO(brianwilkerson) Report this error.
+    return null;
+  }
+
+  /**
+   * Given that we are accessing a property of the given type with the given name, return the
+   * element that represents the property.
+   *
+   * @param target the target of the invocation ('e')
+   * @param targetType the type in which the search for the property should begin
+   * @param propertyName the name of the property being accessed
+   * @return the element that represents the property
+   */
+  ExecutableElement _resolveProperty(Expression target, DartType targetType, SimpleIdentifier propertyName) {
+    ExecutableElement memberElement = null;
+    if (propertyName.inSetterContext()) {
+      memberElement = _lookUpSetter(target, targetType, propertyName.name);
+    }
+    if (memberElement == null) {
+      memberElement = _lookUpGetter(target, targetType, propertyName.name);
+    }
+    if (memberElement == null) {
+      memberElement = _lookUpMethod(target, targetType, propertyName.name);
+    }
+    return memberElement;
+  }
+
+  void _resolvePropertyAccess(Expression target, SimpleIdentifier propertyName) {
+    DartType staticType = _getStaticType(target);
+    DartType propagatedType = _getPropagatedType(target);
+    Element staticElement = null;
+    Element propagatedElement = null;
+    //
+    // If this property access is of the form 'C.m' where 'C' is a class, then we don't call
+    // resolveProperty(..) which walks up the class hierarchy, instead we just look for the
+    // member in the type only.
+    //
+    ClassElementImpl typeReference = getTypeReference(target);
+    if (typeReference != null) {
+      // TODO(brianwilkerson) Why are we setting the propagated element here? It looks wrong.
+      staticElement = propagatedElement = _resolveElement(typeReference, propertyName);
+    } else {
+      staticElement = _resolveProperty(target, staticType, propertyName);
+      propagatedElement = _resolveProperty(target, propagatedType, propertyName);
+    }
+    // May be part of annotation, record property element only if exists.
+    // Error was already reported in validateAnnotationElement().
+    if (target.parent.parent is Annotation) {
+      if (staticElement != null) {
+        propertyName.staticElement = staticElement;
+      }
+      return;
+    }
+    propertyName.staticElement = staticElement;
+    propertyName.propagatedElement = propagatedElement;
+    bool shouldReportMissingMember_static = _shouldReportMissingMember(staticType, staticElement);
+    bool shouldReportMissingMember_propagated = !shouldReportMissingMember_static && _enableHints && _shouldReportMissingMember(propagatedType, propagatedElement) && !_memberFoundInSubclass(propagatedType.element, propertyName.name, false, true);
+    // TODO(collinsn): add support for errors on union types by extending
+    // [lookupGetter] and [lookupSetter] in analogy with the earlier [lookupMethod] extensions.
+    if (propagatedType is UnionType) {
+      shouldReportMissingMember_propagated = false;
+    }
+    if (shouldReportMissingMember_static || shouldReportMissingMember_propagated) {
+      Element staticOrPropagatedEnclosingElt = shouldReportMissingMember_static ? staticType.element : propagatedType.element;
+      bool isStaticProperty = _isStatic(staticOrPropagatedEnclosingElt);
+      String displayName = staticOrPropagatedEnclosingElt != null ? staticOrPropagatedEnclosingElt.displayName : propagatedType != null ? propagatedType.displayName : staticType.displayName;
+      // Special getter cases.
+      if (propertyName.inGetterContext()) {
+        if (!isStaticProperty && staticOrPropagatedEnclosingElt is ClassElement) {
+          ClassElement classElement = staticOrPropagatedEnclosingElt;
+          InterfaceType targetType = classElement.type;
+          if (targetType != null && targetType.isDartCoreFunction && propertyName.name == FunctionElement.CALL_METHOD_NAME) {
+            // TODO(brianwilkerson) Can we ever resolve the function being invoked?
+            //resolveArgumentsToParameters(node.getArgumentList(), invokedFunction);
+            return;
+          } else if (classElement.isEnum && propertyName.name == "_name") {
+            _resolver.reportErrorForNode(CompileTimeErrorCode.ACCESS_PRIVATE_ENUM_FIELD, propertyName, [propertyName.name]);
+            return;
+          }
+        }
+      }
+      Element declaringElement = staticType.isVoid ? null : staticOrPropagatedEnclosingElt;
+      if (propertyName.inSetterContext()) {
+        ErrorCode staticErrorCode = (isStaticProperty && !staticType.isVoid ? StaticWarningCode.UNDEFINED_SETTER : StaticTypeWarningCode.UNDEFINED_SETTER);
+        ErrorCode errorCode = shouldReportMissingMember_static ? staticErrorCode : HintCode.UNDEFINED_SETTER;
+        _recordUndefinedNode(declaringElement, errorCode, propertyName, [propertyName.name, displayName]);
+      } else if (propertyName.inGetterContext()) {
+        ErrorCode staticErrorCode = (isStaticProperty && !staticType.isVoid ? StaticWarningCode.UNDEFINED_GETTER : StaticTypeWarningCode.UNDEFINED_GETTER);
+        ErrorCode errorCode = shouldReportMissingMember_static ? staticErrorCode : HintCode.UNDEFINED_GETTER;
+        _recordUndefinedNode(declaringElement, errorCode, propertyName, [propertyName.name, displayName]);
+      } else {
+        _recordUndefinedNode(declaringElement, StaticWarningCode.UNDEFINED_IDENTIFIER, propertyName, [propertyName.name]);
+      }
+    }
+  }
+
+  /**
+   * Resolve the given simple identifier if possible. Return the element to which it could be
+   * resolved, or `null` if it could not be resolved. This does not record the results of the
+   * resolution.
+   *
+   * @param node the identifier to be resolved
+   * @return the element to which the identifier could be resolved
+   */
+  Element _resolveSimpleIdentifier(SimpleIdentifier node) {
+    Element element = _resolver.nameScope.lookup(node, _definingLibrary);
+    if (element is PropertyAccessorElement && node.inSetterContext()) {
+      PropertyInducingElement variable = (element as PropertyAccessorElement).variable;
+      if (variable != null) {
+        PropertyAccessorElement setter = variable.setter;
+        if (setter == null) {
+          //
+          // Check to see whether there might be a locally defined getter and an inherited setter.
+          //
+          ClassElement enclosingClass = _resolver.enclosingClass;
+          if (enclosingClass != null) {
+            setter = _lookUpSetter(null, enclosingClass.type, node.name);
+          }
+        }
+        if (setter != null) {
+          element = setter;
+        }
+      }
+    } else if (element == null && (node.inSetterContext() || node.parent is CommentReference)) {
+      element = _resolver.nameScope.lookup(new ElementResolver_SyntheticIdentifier("${node.name}="), _definingLibrary);
+    }
+    ClassElement enclosingClass = _resolver.enclosingClass;
+    if (element == null && enclosingClass != null) {
+      InterfaceType enclosingType = enclosingClass.type;
+      if (element == null && (node.inSetterContext() || node.parent is CommentReference)) {
+        element = _lookUpSetter(null, enclosingType, node.name);
+      }
+      if (element == null && node.inGetterContext()) {
+        element = _lookUpGetter(null, enclosingType, node.name);
+      }
+      if (element == null) {
+        element = _lookUpMethod(null, enclosingType, node.name);
+      }
+    }
+    return element;
+  }
+
+  /**
+   * If the given type is a type parameter, resolve it to the type that should be used when looking
+   * up members. Otherwise, return the original type.
+   *
+   * @param type the type that is to be resolved if it is a type parameter
+   * @return the type that should be used in place of the argument if it is a type parameter, or the
+   *         original argument if it isn't a type parameter
+   */
+  DartType _resolveTypeParameter(DartType type) {
+    if (type is TypeParameterType) {
+      DartType bound = type.element.bound;
+      if (bound == null) {
+        return _resolver.typeProvider.objectType;
+      }
+      return bound;
+    }
+    return type;
+  }
+
+  /**
+   * Given a node that can have annotations associated with it and the element to which that node
+   * has been resolved, create the annotations in the element model representing the annotations on
+   * the node.
+   *
+   * @param element the element to which the node has been resolved
+   * @param node the node that can have annotations associated with it
+   */
+  void _setMetadata(Element element, AnnotatedNode node) {
+    if (element is! ElementImpl) {
+      return;
+    }
+    List<ElementAnnotationImpl> annotationList = new List<ElementAnnotationImpl>();
+    _addAnnotations(annotationList, node.metadata);
+    if (node is VariableDeclaration && node.parent is VariableDeclarationList) {
+      VariableDeclarationList list = node.parent as VariableDeclarationList;
+      _addAnnotations(annotationList, list.metadata);
+      if (list.parent is FieldDeclaration) {
+        FieldDeclaration fieldDeclaration = list.parent as FieldDeclaration;
+        _addAnnotations(annotationList, fieldDeclaration.metadata);
+      } else if (list.parent is TopLevelVariableDeclaration) {
+        TopLevelVariableDeclaration variableDeclaration = list.parent as TopLevelVariableDeclaration;
+        _addAnnotations(annotationList, variableDeclaration.metadata);
+      }
+    }
+    if (!annotationList.isEmpty) {
+      (element as ElementImpl).metadata = annotationList;
+    }
+  }
+
+  /**
+   * Given a node that can have annotations associated with it and the element to which that node
+   * has been resolved, create the annotations in the element model representing the annotations on
+   * the node.
+   *
+   * @param element the element to which the node has been resolved
+   * @param node the node that can have annotations associated with it
+   */
+  void _setMetadataForParameter(Element element, NormalFormalParameter node) {
+    if (element is! ElementImpl) {
+      return;
+    }
+    List<ElementAnnotationImpl> annotationList = new List<ElementAnnotationImpl>();
+    _addAnnotations(annotationList, node.metadata);
+    if (!annotationList.isEmpty) {
+      (element as ElementImpl).metadata = annotationList;
+    }
+  }
+
+  /**
+   * Return `true` if we should report an error as a result of looking up a member in the
+   * given type and not finding any member.
+   *
+   * @param type the type in which we attempted to perform the look-up
+   * @param member the result of the look-up
+   * @return `true` if we should report an error
+   */
+  bool _shouldReportMissingMember(DartType type, Element member) {
+    if (member != null || type == null || type.isDynamic || type.isBottom) {
+      return false;
+    }
+    return true;
+  }
+}
+
+/**
+ * Instances of the class `SyntheticIdentifier` implement an identifier that can be used to
+ * look up names in the lexical scope when there is no identifier in the AST structure. There is
+ * no identifier in the AST when the parser could not distinguish between a method invocation and
+ * an invocation of a top-level function imported with a prefix.
+ */
+class ElementResolver_SyntheticIdentifier extends Identifier {
+  /**
+   * The name of the synthetic identifier.
+   */
+  final String name;
+
+  /**
+   * Initialize a newly created synthetic identifier to have the given name.
+   *
+   * @param name the name of the synthetic identifier
+   */
+  ElementResolver_SyntheticIdentifier(this.name);
+
+  @override
+  accept(AstVisitor visitor) => null;
+
+  @override
+  sc.Token get beginToken => null;
+
+  @override
+  Element get bestElement => null;
+
+  @override
+  sc.Token get endToken => null;
+
+  @override
+  int get precedence => 16;
+
+  @override
+  Element get propagatedElement => null;
+
+  @override
+  Element get staticElement => null;
+
+  @override
+  void visitChildren(AstVisitor visitor) {
+  }
+}
+
diff --git a/pkg/analyzer/lib/src/generated/engine.dart b/pkg/analyzer/lib/src/generated/engine.dart
index 4de74d4..3404ad8 100644
--- a/pkg/analyzer/lib/src/generated/engine.dart
+++ b/pkg/analyzer/lib/src/generated/engine.dart
@@ -18,6 +18,7 @@
 import 'utilities_general.dart';
 import 'instrumentation.dart';
 import 'error.dart';
+import 'error_verifier.dart';
 import 'source.dart';
 import 'scanner.dart';
 import 'ast.dart';
@@ -111,11 +112,13 @@
       }
     }
     //
-    // We should never get to this point because the last partition should always be a universal
-    // partition, except in the case of the SDK context, in which case the source should always be
-    // part of the SDK.
+    // We should never get to this point because the last partition should
+    // always be a universal partition, except in the case of the SDK context,
+    // in which case the source should always be part of the SDK.
     //
-    AnalysisEngine.instance.logger.logInformation2("Could not find context for ${source.fullName}", new JavaException());
+    AnalysisEngine.instance.logger.logInformation(
+        "Could not find context for ${source.fullName}",
+        new CaughtException(new AnalysisException(), null));
     return null;
   }
 
@@ -1158,8 +1161,10 @@
             }
           }
         }
-      } on ObsoleteSourceAnalysisException catch (exception) {
-        AnalysisEngine.instance.logger.logInformation2("Could not compute errors", exception);
+      } on ObsoleteSourceAnalysisException catch (exception, stackTrace) {
+        AnalysisEngine.instance.logger.logInformation(
+            "Could not compute errors",
+            new CaughtException(exception, stackTrace));
       }
       if (errors.isEmpty) {
         return AnalysisError.NO_ERRORS;
@@ -1169,8 +1174,10 @@
       HtmlEntry htmlEntry = sourceEntry;
       try {
         return _getHtmlResolutionData2(source, htmlEntry, HtmlEntry.RESOLUTION_ERRORS);
-      } on ObsoleteSourceAnalysisException catch (exception) {
-        AnalysisEngine.instance.logger.logInformation2("Could not compute errors", exception);
+      } on ObsoleteSourceAnalysisException catch (exception, stackTrace) {
+        AnalysisEngine.instance.logger.logInformation(
+            "Could not compute errors",
+            new CaughtException(exception, stackTrace));
       }
     }
     return AnalysisError.NO_ERRORS;
@@ -1212,8 +1219,10 @@
       } else if (sourceEntry is DartEntry) {
         return _getDartScanData2(source, SourceEntry.LINE_INFO, null);
       }
-    } on ObsoleteSourceAnalysisException catch (exception) {
-      AnalysisEngine.instance.logger.logInformation2("Could not compute ${SourceEntry.LINE_INFO}", exception);
+    } on ObsoleteSourceAnalysisException catch (exception, stackTrace) {
+      AnalysisEngine.instance.logger.logInformation(
+          "Could not compute ${SourceEntry.LINE_INFO}",
+          new CaughtException(exception, stackTrace));
     }
     return null;
   }
@@ -1529,7 +1538,11 @@
       NamespaceBuilder builder = new NamespaceBuilder();
       namespace = builder.createPublicNamespaceForLibrary(library);
       if (dartEntry == null) {
-        AnalysisEngine.instance.logger.logError2("Could not compute the public namespace for ${library.source.fullName}", new CaughtException(new AnalysisException("A Dart file became a non-Dart file: ${source.fullName}"), null));
+        AnalysisEngine.instance.logger.logError(
+            "Could not compute the public namespace for ${library.source.fullName}",
+            new CaughtException(
+                new AnalysisException("A Dart file became a non-Dart file: ${source.fullName}"),
+                null));
         return null;
       }
       if (identical(dartEntry.getValue(DartEntry.ELEMENT), library)) {
@@ -1613,55 +1626,95 @@
   }
 
   @override
-  AnalysisContextStatistics get statistics {
+  void visitCacheItems(void callback(Source source, SourceEntry dartEntry,
+                                     DataDescriptor rowDesc,
+                                     CacheState state)) {
+    void handleCacheItem(Source source, SourceEntry dartEntry,
+                         DataDescriptor descriptor) {
+      callback(source, dartEntry, descriptor, dartEntry.getState(descriptor));
+    }
+    void handleCacheItemInLibrary(DartEntry dartEntry, Source librarySource,
+                                  DataDescriptor descriptor) {
+      callback(librarySource, dartEntry, descriptor,
+          dartEntry.getStateInLibrary(descriptor, librarySource));
+    }
+
     bool hintsEnabled = _options.hint;
-    AnalysisContextStatisticsImpl statistics = new AnalysisContextStatisticsImpl();
     MapIterator<Source, SourceEntry> iterator = _cache.iterator();
     while (iterator.moveNext()) {
+      Source source = iterator.key;
       SourceEntry sourceEntry = iterator.value;
       if (sourceEntry is DartEntry) {
-        Source source = iterator.key;
         DartEntry dartEntry = sourceEntry;
         SourceKind kind = dartEntry.getValue(DartEntry.SOURCE_KIND);
         // get library independent values
-        statistics.putCacheItem(dartEntry, SourceEntry.LINE_INFO);
-        statistics.putCacheItem(dartEntry, DartEntry.PARSE_ERRORS);
-        statistics.putCacheItem(dartEntry, DartEntry.PARSED_UNIT);
-        statistics.putCacheItem(dartEntry, DartEntry.SOURCE_KIND);
+        handleCacheItem(source, dartEntry, SourceEntry.CONTENT);
+        handleCacheItem(source, dartEntry, SourceEntry.LINE_INFO);
+        // The list of containing libraries is always valid, so the state isn't
+        // interesting.
+//        handleCacheItem(source, dartEntry, DartEntry.CONTAINING_LIBRARIES);
+        handleCacheItem(source, dartEntry, DartEntry.PARSE_ERRORS);
+        handleCacheItem(source, dartEntry, DartEntry.PARSED_UNIT);
+        handleCacheItem(source, dartEntry, DartEntry.SCAN_ERRORS);
+        handleCacheItem(source, dartEntry, DartEntry.SOURCE_KIND);
+        handleCacheItem(source, dartEntry, DartEntry.TOKEN_STREAM);
         if (kind == SourceKind.LIBRARY) {
-          statistics.putCacheItem(dartEntry, DartEntry.ELEMENT);
-          statistics.putCacheItem(dartEntry, DartEntry.EXPORTED_LIBRARIES);
-          statistics.putCacheItem(dartEntry, DartEntry.IMPORTED_LIBRARIES);
-          statistics.putCacheItem(dartEntry, DartEntry.INCLUDED_PARTS);
-          statistics.putCacheItem(dartEntry, DartEntry.IS_CLIENT);
-          statistics.putCacheItem(dartEntry, DartEntry.IS_LAUNCHABLE);
-          // The public namespace isn't computed by performAnalysisTask() and therefore isn't
-          // interesting.
-          //statistics.putCacheItem(dartEntry, DartEntry.PUBLIC_NAMESPACE);
+          handleCacheItem(source, dartEntry, DartEntry.ELEMENT);
+          handleCacheItem(source, dartEntry, DartEntry.EXPORTED_LIBRARIES);
+          handleCacheItem(source, dartEntry, DartEntry.IMPORTED_LIBRARIES);
+          handleCacheItem(source, dartEntry, DartEntry.INCLUDED_PARTS);
+          handleCacheItem(source, dartEntry, DartEntry.IS_CLIENT);
+          handleCacheItem(source, dartEntry, DartEntry.IS_LAUNCHABLE);
+          // The public namespace isn't computed by performAnalysisTask()
+          // and therefore isn't interesting.
+          //handleCacheItem(key, dartEntry, DartEntry.PUBLIC_NAMESPACE);
         }
         // get library-specific values
         List<Source> librarySources = getLibrariesContaining(source);
         for (Source librarySource in librarySources) {
-          statistics.putCacheItemInLibrary(dartEntry, librarySource, DartEntry.RESOLUTION_ERRORS);
-          statistics.putCacheItemInLibrary(dartEntry, librarySource, DartEntry.RESOLVED_UNIT);
+          // These values are not currently being computed, so their state is
+          // not interesting.
+//          handleCacheItemInLibrary(dartEntry, librarySource, DartEntry.ANGULAR_ERRORS);
+//          handleCacheItemInLibrary(dartEntry, librarySource, DartEntry.BUILT_ELEMENT);
+//          handleCacheItemInLibrary(dartEntry, librarySource, DartEntry.BUILT_UNIT);
+          handleCacheItemInLibrary(dartEntry, librarySource, DartEntry.RESOLUTION_ERRORS);
+          handleCacheItemInLibrary(dartEntry, librarySource, DartEntry.RESOLVED_UNIT);
           if (_generateSdkErrors || !source.isInSystemLibrary) {
-            statistics.putCacheItemInLibrary(dartEntry, librarySource, DartEntry.VERIFICATION_ERRORS);
+            handleCacheItemInLibrary(dartEntry, librarySource, DartEntry.VERIFICATION_ERRORS);
             if (hintsEnabled) {
-              statistics.putCacheItemInLibrary(dartEntry, librarySource, DartEntry.HINTS);
+              handleCacheItemInLibrary(dartEntry, librarySource, DartEntry.HINTS);
             }
           }
         }
       } else if (sourceEntry is HtmlEntry) {
         HtmlEntry htmlEntry = sourceEntry;
-        statistics.putCacheItem(htmlEntry, SourceEntry.LINE_INFO);
-        statistics.putCacheItem(htmlEntry, HtmlEntry.PARSE_ERRORS);
-        statistics.putCacheItem(htmlEntry, HtmlEntry.PARSED_UNIT);
-        statistics.putCacheItem(htmlEntry, HtmlEntry.RESOLUTION_ERRORS);
-        statistics.putCacheItem(htmlEntry, HtmlEntry.RESOLVED_UNIT);
+        handleCacheItem(source, htmlEntry, SourceEntry.CONTENT);
+        handleCacheItem(source, htmlEntry, SourceEntry.LINE_INFO);
+        // These values are not currently being computed, so their state is
+        // not interesting.
+//        handleCacheItem(source, htmlEntry, HtmlEntry.ANGULAR_APPLICATION);
+//        handleCacheItem(source, htmlEntry, HtmlEntry.ANGULAR_COMPONENT);
+//        handleCacheItem(source, htmlEntry, HtmlEntry.ANGULAR_ENTRY);
+//        handleCacheItem(source, htmlEntry, HtmlEntry.ANGULAR_ERRORS);
+        handleCacheItem(source, htmlEntry, HtmlEntry.ELEMENT);
+        handleCacheItem(source, htmlEntry, HtmlEntry.PARSE_ERRORS);
+        handleCacheItem(source, htmlEntry, HtmlEntry.PARSED_UNIT);
+        // These values are not currently being computed, so their state is
+        // not interesting.
+//        handleCacheItem(source, htmlEntry, HtmlEntry.POLYMER_BUILD_ERRORS);
+//        handleCacheItem(source, htmlEntry, HtmlEntry.POLYMER_RESOLUTION_ERRORS);
+        handleCacheItem(source, htmlEntry, HtmlEntry.RESOLUTION_ERRORS);
+        handleCacheItem(source, htmlEntry, HtmlEntry.RESOLVED_UNIT);
         // We are not currently recording any hints related to HTML.
-        // statistics.putCacheItem(htmlEntry, HtmlEntry.HINTS);
+//        handleCacheItem(key, htmlEntry, HtmlEntry.HINTS);
       }
     }
+  }
+
+  @override
+  AnalysisContextStatistics get statistics {
+    AnalysisContextStatisticsImpl statistics = new AnalysisContextStatisticsImpl();
+    visitCacheItems(statistics._internalPutCacheItem);
     statistics.partitionData = _cache.partitionData;
     return statistics;
   }
@@ -1730,11 +1783,15 @@
     int performStart = JavaSystem.currentTimeMillis();
     try {
       task.perform(_resultRecorder);
-    } on ObsoleteSourceAnalysisException catch (exception) {
-      AnalysisEngine.instance.logger.logInformation2("Could not perform analysis task: $taskDescription", exception);
-    } on AnalysisException catch (exception) {
+    } on ObsoleteSourceAnalysisException catch (exception, stackTrace) {
+      AnalysisEngine.instance.logger.logInformation(
+          "Could not perform analysis task: $taskDescription",
+          new CaughtException(exception, stackTrace));
+    } on AnalysisException catch (exception, stackTrace) {
       if (exception.cause is! JavaIOException) {
-        AnalysisEngine.instance.logger.logError2("Internal error while performing the task: $task", exception);
+        AnalysisEngine.instance.logger.logError(
+            "Internal error while performing the task: $task",
+            new CaughtException(exception, stackTrace));
       }
     }
     int performEnd = JavaSystem.currentTimeMillis();
@@ -2511,8 +2568,10 @@
     }
     CompilationUnit unit = unitEntry.getValueInLibrary(DartEntry.RESOLVED_UNIT, librarySource);
     if (unit == null) {
-      CaughtException exception = new CaughtException(new AnalysisException("Entry has VALID state for RESOLVED_UNIT but null value for ${unitSource.fullName} in ${librarySource.fullName}"), null);
-      AnalysisEngine.instance.logger.logInformation2(exception.toString(), exception);
+      CaughtException exception = new CaughtException(
+          new AnalysisException("Entry has VALID state for RESOLVED_UNIT but null value for ${unitSource.fullName} in ${librarySource.fullName}"),
+          null);
+      AnalysisEngine.instance.logger.logInformation(exception.toString(), exception);
       unitEntry.recordResolutionError(exception);
       return new AnalysisContextImpl_TaskData(null, false);
     }
@@ -2679,7 +2738,9 @@
       return new AnalysisContextImpl_TaskData(new ResolveDartLibraryCycleTask(this, source, source, builder.librariesInCycle), false);
     } on AnalysisException catch (exception, stackTrace) {
       dartEntry.recordResolutionError(new CaughtException(exception, stackTrace));
-      AnalysisEngine.instance.logger.logError2("Internal error trying to create a ResolveDartLibraryTask", new CaughtException(exception, stackTrace));
+      AnalysisEngine.instance.logger.logError(
+          "Internal error trying to create a ResolveDartLibraryTask",
+          new CaughtException(exception, stackTrace));
     }
     return new AnalysisContextImpl_TaskData(null, false);
   }
@@ -2837,8 +2898,10 @@
     }
     try {
       return _getDartParseData(source, dartEntry, descriptor);
-    } on ObsoleteSourceAnalysisException catch (exception) {
-      AnalysisEngine.instance.logger.logInformation2("Could not compute $descriptor", exception);
+    } on ObsoleteSourceAnalysisException catch (exception, stackTrace) {
+      AnalysisEngine.instance.logger.logInformation(
+          "Could not compute $descriptor",
+          new CaughtException(exception, stackTrace));
       return defaultValue;
     }
   }
@@ -2891,8 +2954,10 @@
     }
     try {
       return _getDartResolutionData(unitSource, librarySource, dartEntry, descriptor);
-    } on ObsoleteSourceAnalysisException catch (exception) {
-      AnalysisEngine.instance.logger.logInformation2("Could not compute $descriptor", exception);
+    } on ObsoleteSourceAnalysisException catch (exception, stackTrace) {
+      AnalysisEngine.instance.logger.logInformation(
+          "Could not compute $descriptor",
+          new CaughtException(exception, stackTrace));
       return defaultValue;
     }
   }
@@ -2936,8 +3001,10 @@
     }
     try {
       return _getDartScanData(source, dartEntry, descriptor);
-    } on ObsoleteSourceAnalysisException catch (exception) {
-      AnalysisEngine.instance.logger.logInformation2("Could not compute $descriptor", exception);
+    } on ObsoleteSourceAnalysisException catch (exception, stackTrace) {
+      AnalysisEngine.instance.logger.logInformation(
+          "Could not compute $descriptor",
+          new CaughtException(exception, stackTrace));
       return defaultValue;
     }
   }
@@ -3010,8 +3077,10 @@
     }
     try {
       return _getHtmlResolutionData2(source, htmlEntry, descriptor);
-    } on ObsoleteSourceAnalysisException catch (exception) {
-      AnalysisEngine.instance.logger.logInformation2("Could not compute $descriptor", exception);
+    } on ObsoleteSourceAnalysisException catch (exception, stackTrace) {
+      AnalysisEngine.instance.logger.logInformation(
+          "Could not compute $descriptor",
+          new CaughtException(exception, stackTrace));
       return defaultValue;
     }
   }
@@ -3657,20 +3726,6 @@
   }
 
   /**
-   * Log the given debugging information.
-   *
-   * @param message the message to be added to the log
-   * @param exception the exception to be included in the log entry
-   */
-  void _logInformation2(String message, Exception exception) {
-    if (exception == null) {
-      AnalysisEngine.instance.logger.logInformation(message);
-    } else {
-      AnalysisEngine.instance.logger.logInformation2(message, exception);
-    }
-  }
-
-  /**
    * Notify all of the analysis listeners that a task is about to be performed.
    *
    * @param taskDescription a human readable description of the task that is about to be performed
@@ -5113,14 +5168,6 @@
   @override
   List<Source> get sources => _sources;
 
-  void putCacheItem(SourceEntry dartEntry, DataDescriptor descriptor) {
-    _internalPutCacheItem(dartEntry, descriptor, dartEntry.getState(descriptor));
-  }
-
-  void putCacheItemInLibrary(DartEntry dartEntry, Source librarySource, DataDescriptor descriptor) {
-    _internalPutCacheItem(dartEntry, descriptor, dartEntry.getStateInLibrary(descriptor, librarySource));
-  }
-
   /**
    * Set the partition data returned by this object to the given data.
    */
@@ -5128,7 +5175,8 @@
     _partitionData = data;
   }
 
-  void _internalPutCacheItem(SourceEntry dartEntry, DataDescriptor rowDesc, CacheState state) {
+  void _internalPutCacheItem(Source source, SourceEntry dartEntry,
+                             DataDescriptor rowDesc, CacheState state) {
     String rowName = rowDesc.toString();
     AnalysisContextStatisticsImpl_CacheRowImpl row = _dataMap[rowName] as AnalysisContextStatisticsImpl_CacheRowImpl;
     if (row == null) {
@@ -5148,15 +5196,7 @@
 class AnalysisContextStatisticsImpl_CacheRowImpl implements AnalysisContextStatistics_CacheRow {
   final String name;
 
-  int _errorCount = 0;
-
-  int _flushedCount = 0;
-
-  int _inProcessCount = 0;
-
-  int _invalidCount = 0;
-
-  int _validCount = 0;
+  Map<CacheState, int> _counts = <CacheState, int>{};
 
   AnalysisContextStatisticsImpl_CacheRowImpl(this.name);
 
@@ -5164,38 +5204,38 @@
   bool operator ==(Object obj) => obj is AnalysisContextStatisticsImpl_CacheRowImpl && obj.name == name;
 
   @override
-  int get errorCount => _errorCount;
+  int get errorCount => getCount(CacheState.ERROR);
 
   @override
-  int get flushedCount => _flushedCount;
+  int get flushedCount => getCount(CacheState.FLUSHED);
 
   @override
-  int get inProcessCount => _inProcessCount;
+  int get inProcessCount => getCount(CacheState.IN_PROCESS);
 
   @override
-  int get invalidCount => _invalidCount;
+  int get invalidCount => getCount(CacheState.INVALID);
 
   @override
-  int get validCount => _validCount;
+  int get validCount => getCount(CacheState.VALID);
 
   @override
   int get hashCode => name.hashCode;
 
+  @override
+  int getCount(CacheState state) {
+    int count = _counts[state];
+    if (count != null) {
+      return count;
+    } else {
+      return 0;
+    }
+  }
+
   void _incState(CacheState state) {
-    if (state == CacheState.ERROR) {
-      _errorCount++;
-    }
-    if (state == CacheState.FLUSHED) {
-      _flushedCount++;
-    }
-    if (state == CacheState.IN_PROCESS) {
-      _inProcessCount++;
-    }
-    if (state == CacheState.INVALID) {
-      _invalidCount++;
-    }
-    if (state == CacheState.VALID) {
-      _validCount++;
+    if (_counts[state] == null) {
+      _counts[state] = 1;
+    } else {
+      _counts[state]++;
     }
   }
 }
@@ -5213,6 +5253,18 @@
  */
 abstract class AnalysisContextStatistics_CacheRow {
   /**
+   * List of possible states which can be queried.
+   */
+  static const List<CacheState> STATES = const <CacheState>[
+      CacheState.ERROR, CacheState.FLUSHED, CacheState.IN_PROCESS,
+      CacheState.INVALID, CacheState.VALID];
+
+  /**
+   * Return the number of entries whose state is [state].
+   */
+  int getCount(CacheState state);
+
+  /**
    * Return the number of entries whose state is [CacheState.ERROR].
    */
   int get errorCount;
@@ -5936,7 +5988,9 @@
       _safelyPerform();
     } on AnalysisException catch (exception, stackTrace) {
       _thrownException = new CaughtException(exception, stackTrace);
-      AnalysisEngine.instance.logger.logInformation2("Task failed: $taskDescription", new CaughtException(exception, stackTrace));
+      AnalysisEngine.instance.logger.logInformation(
+          "Task failed: $taskDescription",
+          new CaughtException(exception, stackTrace));
     }
     return accept(visitor);
   }
@@ -7425,7 +7479,9 @@
     this._errors = errors;
     this._lineInfo = lineInfo;
     if (lineInfo == null) {
-      AnalysisEngine.instance.logger.logInformation2("No line info: $source", new JavaException());
+      AnalysisEngine.instance.logger.logInformation(
+          "No line info: $source",
+          new CaughtException(new AnalysisException(), null));
     }
   }
 
@@ -8023,10 +8079,10 @@
       if (state.getState(BUILT_UNIT) == CacheState.VALID) {
         // TODO(brianwilkerson) We're cloning the structure to remove any
         // previous resolution data, but I'm not sure that's necessary.
-        return state.getValue(BUILT_UNIT).accept(new AstCloner()) as CompilationUnit;
+        return state.getValue(BUILT_UNIT).accept(new AstCloner());
       }
       if (state.getState(RESOLVED_UNIT) == CacheState.VALID) {
-        return state.getValue(RESOLVED_UNIT).accept(new AstCloner()) as CompilationUnit;
+        return state.getValue(RESOLVED_UNIT).accept(new AstCloner());
       }
       state = state._nextState;
     }
@@ -8133,10 +8189,12 @@
       ResolutionState state = _resolutionState;
       while (state != null) {
         if (state.getState(BUILT_UNIT) == CacheState.VALID) {
-          setValue(PARSED_UNIT, state.getValue(BUILT_UNIT));
+          CompilationUnit unit = state.getValue(BUILT_UNIT);
+          setValue(PARSED_UNIT, unit.accept(new AstCloner()));
           break;
         } else if (state.getState(RESOLVED_UNIT) == CacheState.VALID) {
-          setValue(PARSED_UNIT, state.getValue(RESOLVED_UNIT));
+          CompilationUnit unit = state.getValue(RESOLVED_UNIT);
+          setValue(PARSED_UNIT, unit.accept(new AstCloner()));
           break;
         }
         state = state._nextState;
@@ -8519,7 +8577,8 @@
    * relative to a library.
    */
   bool _isValidLibraryDescriptor(DataDescriptor descriptor) {
-    return descriptor == BUILT_ELEMENT
+    return descriptor == ANGULAR_ERRORS
+        || descriptor == BUILT_ELEMENT
         || descriptor == BUILT_UNIT
         || descriptor == HINTS
         || descriptor == RESOLUTION_ERRORS
@@ -10209,6 +10268,13 @@
       instrumentation.log();
     }
   }
+
+  @override
+  void visitCacheItems(void callback(Source source, SourceEntry dartEntry,
+                                     DataDescriptor rowDesc,
+                                     CacheState state)) {
+    _basis.visitCacheItems(callback);
+  }
 }
 
 /**
@@ -10306,23 +10372,34 @@
    *          the elements representing the libraries
    */
   void recordLibraryElements(Map<Source, LibraryElement> elementMap);
+
+  /**
+   * Call the given callback function for eache cache item in the context.
+   */
+  void visitCacheItems(void callback(Source source, SourceEntry dartEntry,
+                                     DataDescriptor rowDesc,
+                                     CacheState state));
 }
 
 /**
- * The interface `Logger` defines the behavior of objects that can be used to receive
- * information about errors within the analysis engine. Implementations usually write this
- * information to a file, but can also record the information for later use (such as during testing)
- * or even ignore the information.
+ * A `Logger` is an object that can be used to receive information about errors
+ * within the analysis engine. Implementations usually write this information to
+ * a file, but can also record the information for later use (such as during
+ * testing) or even ignore the information.
  */
 abstract class Logger {
-  static final Logger NULL = new Logger_NullLogger();
+  /**
+   * A logger that ignores all logging.
+   */
+  static final Logger NULL = new NullLogger();
 
   /**
-   * Log the given message as an error.
-   *
-   * @param message an explanation of why the error occurred or what it means
+   * Log the given message as an error. The [message] is expected to be an
+   * explanation of why the error occurred or what it means. The [exception] is
+   * expected to be the reason for the error. At least one argument must be
+   * provided.
    */
-  void logError(String message);
+  void logError(String message, [CaughtException exception]);
 
   /**
    * Log the given exception as one representing an error.
@@ -10330,15 +10407,15 @@
    * @param message an explanation of why the error occurred or what it means
    * @param exception the exception being logged
    */
-  void logError2(String message, Exception exception);
+  @deprecated
+  void logError2(String message, Object exception);
 
   /**
-   * Log the given informational message.
-   *
-   * @param message an explanation of why the error occurred or what it means
-   * @param exception the exception being logged
+   * Log the given informational message. The [message] is expected to be an
+   * explanation of why the error occurred or what it means. The [exception] is
+   * expected to be the reason for the error.
    */
-  void logInformation(String message);
+  void logInformation(String message, [CaughtException exception]);
 
   /**
    * Log the given exception as one representing an informational message.
@@ -10346,27 +10423,28 @@
    * @param message an explanation of why the error occurred or what it means
    * @param exception the exception being logged
    */
-  void logInformation2(String message, Exception exception);
+  @deprecated
+  void logInformation2(String message, Object exception);
 }
 
 /**
- * Implementation of [Logger] that does nothing.
+ * An implementation of [Logger] that does nothing.
  */
-class Logger_NullLogger implements Logger {
+class NullLogger implements Logger {
   @override
-  void logError(String message) {
+  void logError(String message, [CaughtException exception]) {
   }
 
   @override
-  void logError2(String message, Exception exception) {
+  void logError2(String message, Object exception) {
   }
 
   @override
-  void logInformation(String message) {
+  void logInformation(String message, [CaughtException exception]) {
   }
 
   @override
-  void logInformation2(String message, Exception exception) {
+  void logInformation2(String message, Object exception) {
   }
 }
 
@@ -11769,10 +11847,17 @@
 }
 
 /**
- * Instances of the class `ResolutionEraser` remove any resolution information from an AST
+ * A `ResolutionEraser` removes any resolution information from an AST
  * structure when used to visit that structure.
  */
 class ResolutionEraser extends GeneralizingAstVisitor<Object> {
+  /**
+   * Remove any resolution information from the given AST structure.
+   */
+  static void erase(AstNode node) {
+    node.accept(new ResolutionEraser());
+  }
+
   @override
   Object visitAssignmentExpression(AssignmentExpression node) {
     node.staticElement = null;
@@ -11955,10 +12040,12 @@
   void invalidateAllResolutionInformation() {
     _nextState = null;
     _librarySource = null;
+    setState(DartEntry.BUILT_UNIT, CacheState.INVALID);
+    setState(DartEntry.BUILT_ELEMENT, CacheState.INVALID);
+    setState(DartEntry.HINTS, CacheState.INVALID);
     setState(DartEntry.RESOLVED_UNIT, CacheState.INVALID);
     setState(DartEntry.RESOLUTION_ERRORS, CacheState.INVALID);
     setState(DartEntry.VERIFICATION_ERRORS, CacheState.INVALID);
-    setState(DartEntry.HINTS, CacheState.INVALID);
   }
 
   /**
@@ -11988,6 +12075,7 @@
     setState(DartEntry.RESOLVED_UNIT, CacheState.ERROR);
     setState(DartEntry.RESOLUTION_ERRORS, CacheState.ERROR);
     recordVerificationError();
+    setState(DartEntry.ANGULAR_ERRORS, CacheState.ERROR);
   }
 
   /**
@@ -13010,8 +13098,8 @@
       result.state = state;
       if (state != CacheState.IN_PROCESS) {
         //
-        // If the state is in-process, we can leave the current value in the cache
-        // for any 'get' methods to access.
+        // If the state is in-process, we can leave the current value in the
+        // cache for any 'get' methods to access.
         //
         result.value = descriptor.defaultValue;
       }
diff --git a/pkg/analyzer/lib/src/generated/error_verifier.dart b/pkg/analyzer/lib/src/generated/error_verifier.dart
new file mode 100644
index 0000000..74542c1
--- /dev/null
+++ b/pkg/analyzer/lib/src/generated/error_verifier.dart
@@ -0,0 +1,5498 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for 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 engine.resolver.error_verifier;
+
+import 'dart:collection';
+import "dart:math" as math;
+
+import 'java_engine.dart';
+import 'error.dart';
+import 'scanner.dart' as sc;
+import 'utilities_dart.dart';
+import 'ast.dart';
+import 'parser.dart' show Parser, ParserErrorCode;
+import 'sdk.dart' show DartSdk, SdkLibrary;
+import 'element.dart';
+import 'constant.dart';
+import 'resolver.dart';
+import 'element_resolver.dart';
+
+/**
+ * Instances of the class `ErrorVerifier` traverse an AST structure looking for additional
+ * errors and warnings not covered by the parser and resolver.
+ */
+class ErrorVerifier extends RecursiveAstVisitor<Object> {
+  /**
+   * Return the static type of the given expression that is to be used for type analysis.
+   *
+   * @param expression the expression whose type is to be returned
+   * @return the static type of the given expression
+   */
+  static DartType getStaticType(Expression expression) {
+    DartType type = expression.staticType;
+    if (type == null) {
+      // TODO(brianwilkerson) This should never happen.
+      return DynamicTypeImpl.instance;
+    }
+    return type;
+  }
+
+  /**
+   * Return the variable element represented by the given expression, or `null` if there is no
+   * such element.
+   *
+   * @param expression the expression whose element is to be returned
+   * @return the variable element represented by the expression
+   */
+  static VariableElement getVariableElement(Expression expression) {
+    if (expression is Identifier) {
+      Element element = expression.staticElement;
+      if (element is VariableElement) {
+        return element;
+      }
+    }
+    return null;
+  }
+
+  /**
+   * The error reporter by which errors will be reported.
+   */
+  final ErrorReporter _errorReporter;
+
+  /**
+   * The current library that is being analyzed.
+   */
+  final LibraryElement _currentLibrary;
+
+  /**
+   * The type representing the type 'bool'.
+   */
+  InterfaceType _boolType;
+
+  /**
+   * The type representing the type 'int'.
+   */
+  InterfaceType _intType;
+
+  /**
+   * The object providing access to the types defined by the language.
+   */
+  final TypeProvider _typeProvider;
+
+  /**
+   * The manager for the inheritance mappings.
+   */
+  final InheritanceManager _inheritanceManager;
+
+  /**
+   * This is set to `true` iff the visitor is currently visiting children nodes of a
+   * [ConstructorDeclaration] and the constructor is 'const'.
+   *
+   * @see #visitConstructorDeclaration(ConstructorDeclaration)
+   */
+  bool _isEnclosingConstructorConst = false;
+
+  /**
+   * A flag indicating whether we are currently within a function body marked as being asynchronous.
+   */
+  bool _inAsync = false;
+
+  /**
+   * A flag indicating whether we are currently within a function body marked as being a generator.
+   */
+  bool _inGenerator = false;
+
+  /**
+   * This is set to `true` iff the visitor is currently visiting children nodes of a
+   * [CatchClause].
+   *
+   * @see #visitCatchClause(CatchClause)
+   */
+  bool _isInCatchClause = false;
+
+  /**
+   * This is set to `true` iff the visitor is currently visiting children nodes of an
+   * [Comment].
+   */
+  bool _isInComment = false;
+
+  /**
+   * This is set to `true` iff the visitor is currently visiting children nodes of an
+   * [InstanceCreationExpression].
+   */
+  bool _isInConstInstanceCreation = false;
+
+  /**
+   * This is set to `true` iff the visitor is currently visiting children nodes of a native
+   * [ClassDeclaration].
+   */
+  bool _isInNativeClass = false;
+
+  /**
+   * This is set to `true` iff the visitor is currently visiting a static variable
+   * declaration.
+   */
+  bool _isInStaticVariableDeclaration = false;
+
+  /**
+   * This is set to `true` iff the visitor is currently visiting an instance variable
+   * declaration.
+   */
+  bool _isInInstanceVariableDeclaration = false;
+
+  /**
+   * This is set to `true` iff the visitor is currently visiting an instance variable
+   * initializer.
+   */
+  bool _isInInstanceVariableInitializer = false;
+
+  /**
+   * This is set to `true` iff the visitor is currently visiting a
+   * [ConstructorInitializer].
+   */
+  bool _isInConstructorInitializer = false;
+
+  /**
+   * This is set to `true` iff the visitor is currently visiting a
+   * [FunctionTypedFormalParameter].
+   */
+  bool _isInFunctionTypedFormalParameter = false;
+
+  /**
+   * This is set to `true` iff the visitor is currently visiting a static method. By "method"
+   * here getter, setter and operator declarations are also implied since they are all represented
+   * with a [MethodDeclaration] in the AST structure.
+   */
+  bool _isInStaticMethod = false;
+
+  /**
+   * This is set to `true` iff the visitor is currently visiting a factory constructor.
+   */
+  bool _isInFactory = false;
+
+  /**
+   * This is set to `true` iff the visitor is currently visiting code in the SDK.
+   */
+  bool _isInSystemLibrary = false;
+
+  /**
+   * A flag indicating whether the current library contains at least one import directive with a URI
+   * that uses the "dart-ext" scheme.
+   */
+  bool _hasExtUri = false;
+
+  /**
+   * This is set to `false` on the entry of every [BlockFunctionBody], and is restored
+   * to the enclosing value on exit. The value is used in
+   * [checkForMixedReturns] to prevent both
+   * [StaticWarningCode#MIXED_RETURN_TYPES] and [StaticWarningCode#RETURN_WITHOUT_VALUE]
+   * from being generated in the same function body.
+   */
+  bool _hasReturnWithoutValue = false;
+
+  /**
+   * The class containing the AST nodes being visited, or `null` if we are not in the scope of
+   * a class.
+   */
+  ClassElement _enclosingClass;
+
+  /**
+   * The method or function that we are currently visiting, or `null` if we are not inside a
+   * method or function.
+   */
+  ExecutableElement _enclosingFunction;
+
+  /**
+   * The return statements found in the method or function that we are currently visiting that have
+   * a return value.
+   */
+  List<ReturnStatement> _returnsWith = new List<ReturnStatement>();
+
+  /**
+   * The return statements found in the method or function that we are currently visiting that do
+   * not have a return value.
+   */
+  List<ReturnStatement> _returnsWithout = new List<ReturnStatement>();
+
+  /**
+   * This map is initialized when visiting the contents of a class declaration. If the visitor is
+   * not in an enclosing class declaration, then the map is set to `null`.
+   *
+   * When set the map maps the set of [FieldElement]s in the class to an
+   * [INIT_STATE#NOT_INIT] or [INIT_STATE#INIT_IN_DECLARATION]. <code>checkFor*</code>
+   * methods, specifically [checkForAllFinalInitializedErrorCodes],
+   * can make a copy of the map to compute error code states. <code>checkFor*</code> methods should
+   * only ever make a copy, or read from this map after it has been set in
+   * [visitClassDeclaration].
+   *
+   * @see #visitClassDeclaration(ClassDeclaration)
+   * @see #checkForAllFinalInitializedErrorCodes(ConstructorDeclaration)
+   */
+  HashMap<FieldElement, INIT_STATE> _initialFieldElementsMap;
+
+  /**
+   * A table mapping name of the library to the export directive which export this library.
+   */
+  HashMap<String, LibraryElement> _nameToExportElement = new HashMap<String, LibraryElement>();
+
+  /**
+   * A table mapping name of the library to the import directive which import this library.
+   */
+  HashMap<String, LibraryElement> _nameToImportElement = new HashMap<String, LibraryElement>();
+
+  /**
+   * A table mapping names to the exported elements.
+   */
+  HashMap<String, Element> _exportedElements = new HashMap<String, Element>();
+
+  /**
+   * A set of the names of the variable initializers we are visiting now.
+   */
+  HashSet<String> _namesForReferenceToDeclaredVariableInInitializer = new HashSet<String>();
+
+  /**
+   * A list of types used by the [CompileTimeErrorCode#EXTENDS_DISALLOWED_CLASS] and
+   * [CompileTimeErrorCode#IMPLEMENTS_DISALLOWED_CLASS] error codes.
+   */
+  List<InterfaceType> _DISALLOWED_TYPES_TO_EXTEND_OR_IMPLEMENT;
+
+  /**
+   * Static final string with value `"getter "` used in the construction of the
+   * [StaticWarningCode#NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE], and similar, error
+   * code messages.
+   *
+   * @see #checkForNonAbstractClassInheritsAbstractMember(ClassDeclaration)
+   */
+  static String _GETTER_SPACE = "getter ";
+
+  /**
+   * Static final string with value `"setter "` used in the construction of the
+   * [StaticWarningCode#NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE], and similar, error
+   * code messages.
+   *
+   * @see #checkForNonAbstractClassInheritsAbstractMember(ClassDeclaration)
+   */
+  static String _SETTER_SPACE = "setter ";
+
+  /**
+   * Initialize the [ErrorVerifier] visitor.
+   */
+  ErrorVerifier(this._errorReporter, this._currentLibrary, this._typeProvider, this._inheritanceManager) {
+    this._isInSystemLibrary = _currentLibrary.source.isInSystemLibrary;
+    this._hasExtUri = _currentLibrary.hasExtUri;
+    _isEnclosingConstructorConst = false;
+    _isInCatchClause = false;
+    _isInStaticVariableDeclaration = false;
+    _isInInstanceVariableDeclaration = false;
+    _isInInstanceVariableInitializer = false;
+    _isInConstructorInitializer = false;
+    _isInStaticMethod = false;
+    _boolType = _typeProvider.boolType;
+    _intType = _typeProvider.intType;
+    _DISALLOWED_TYPES_TO_EXTEND_OR_IMPLEMENT = <InterfaceType> [
+        _typeProvider.nullType,
+        _typeProvider.numType,
+        _intType,
+        _typeProvider.doubleType,
+        _boolType,
+        _typeProvider.stringType];
+  }
+
+  @override
+  Object visitAnnotation(Annotation node) {
+    _checkForInvalidAnnotationFromDeferredLibrary(node);
+    return super.visitAnnotation(node);
+  }
+
+  @override
+  Object visitArgumentList(ArgumentList node) {
+    _checkForArgumentTypesNotAssignableInList(node);
+    return super.visitArgumentList(node);
+  }
+
+  @override
+  Object visitAsExpression(AsExpression node) {
+    _checkForTypeAnnotationDeferredClass(node.type);
+    return super.visitAsExpression(node);
+  }
+
+  @override
+  Object visitAssertStatement(AssertStatement node) {
+    _checkForNonBoolExpression(node);
+    return super.visitAssertStatement(node);
+  }
+
+  @override
+  Object visitAssignmentExpression(AssignmentExpression node) {
+    sc.TokenType operatorType = node.operator.type;
+    Expression lhs = node.leftHandSide;
+    Expression rhs = node.rightHandSide;
+    if (operatorType == sc.TokenType.EQ) {
+      _checkForInvalidAssignment(lhs, rhs);
+    } else {
+      _checkForInvalidCompoundAssignment(node, lhs, rhs);
+      _checkForArgumentTypeNotAssignableForArgument(rhs);
+    }
+    _checkForAssignmentToFinal(lhs);
+    return super.visitAssignmentExpression(node);
+  }
+
+  @override
+  Object visitAwaitExpression(AwaitExpression node) {
+    if (!_inAsync) {
+      _errorReporter.reportErrorForToken(CompileTimeErrorCode.AWAIT_IN_WRONG_CONTEXT, node.awaitKeyword, []);
+    }
+    return super.visitAwaitExpression(node);
+  }
+
+  @override
+  Object visitBinaryExpression(BinaryExpression node) {
+    sc.Token operator = node.operator;
+    sc.TokenType type = operator.type;
+    if (type == sc.TokenType.AMPERSAND_AMPERSAND || type == sc.TokenType.BAR_BAR) {
+      String lexeme = operator.lexeme;
+      _checkForAssignability(node.leftOperand, _boolType, StaticTypeWarningCode.NON_BOOL_OPERAND, [lexeme]);
+      _checkForAssignability(node.rightOperand, _boolType, StaticTypeWarningCode.NON_BOOL_OPERAND, [lexeme]);
+    } else {
+      _checkForArgumentTypeNotAssignableForArgument(node.rightOperand);
+    }
+    return super.visitBinaryExpression(node);
+  }
+
+  @override
+  Object visitBlockFunctionBody(BlockFunctionBody node) {
+    bool wasInAsync = _inAsync;
+    bool wasInGenerator = _inGenerator;
+    bool previousHasReturnWithoutValue = _hasReturnWithoutValue;
+    _hasReturnWithoutValue = false;
+    List<ReturnStatement> previousReturnsWith = _returnsWith;
+    List<ReturnStatement> previousReturnsWithout = _returnsWithout;
+    try {
+      _inAsync = node.isAsynchronous;
+      _inGenerator = node.isGenerator;
+      _returnsWith = new List<ReturnStatement>();
+      _returnsWithout = new List<ReturnStatement>();
+      super.visitBlockFunctionBody(node);
+      _checkForMixedReturns(node);
+    } finally {
+      _inAsync = wasInAsync;
+      _inGenerator = wasInGenerator;
+      _returnsWith = previousReturnsWith;
+      _returnsWithout = previousReturnsWithout;
+      _hasReturnWithoutValue = previousHasReturnWithoutValue;
+    }
+    return null;
+  }
+
+  @override
+  Object visitBreakStatement(BreakStatement node) {
+    SimpleIdentifier labelNode = node.label;
+    if (labelNode != null) {
+      Element labelElement = labelNode.staticElement;
+      if (labelElement is LabelElementImpl && labelElement.isOnSwitchMember) {
+        _errorReporter.reportErrorForNode(ResolverErrorCode.BREAK_LABEL_ON_SWITCH_MEMBER, labelNode, []);
+      }
+    }
+    return null;
+  }
+
+  @override
+  Object visitCatchClause(CatchClause node) {
+    bool previousIsInCatchClause = _isInCatchClause;
+    try {
+      _isInCatchClause = true;
+      _checkForTypeAnnotationDeferredClass(node.exceptionType);
+      return super.visitCatchClause(node);
+    } finally {
+      _isInCatchClause = previousIsInCatchClause;
+    }
+  }
+
+  @override
+  Object visitClassDeclaration(ClassDeclaration node) {
+    ClassElement outerClass = _enclosingClass;
+    try {
+      _isInNativeClass = node.nativeClause != null;
+      _enclosingClass = node.element;
+      ExtendsClause extendsClause = node.extendsClause;
+      ImplementsClause implementsClause = node.implementsClause;
+      WithClause withClause = node.withClause;
+      _checkForBuiltInIdentifierAsName(node.name, CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE_NAME);
+      _checkForMemberWithClassName();
+      _checkForNoDefaultSuperConstructorImplicit(node);
+      _checkForConflictingTypeVariableErrorCodes(node);
+      // Only do error checks on the clause nodes if there is a non-null clause
+      if (implementsClause != null || extendsClause != null || withClause != null) {
+        // Only check for all of the inheritance logic around clauses if there isn't an error code
+        // such as "Cannot extend double" already on the class.
+        if (!_checkForImplementsDisallowedClass(implementsClause) && !_checkForExtendsDisallowedClass(extendsClause) && !_checkForAllMixinErrorCodes(withClause)) {
+          _checkForExtendsDeferredClass(extendsClause);
+          _checkForImplementsDeferredClass(implementsClause);
+          _checkForNonAbstractClassInheritsAbstractMember(node.name);
+          _checkForInconsistentMethodInheritance();
+          _checkForRecursiveInterfaceInheritance(_enclosingClass);
+          _checkForConflictingGetterAndMethod();
+          _checkForConflictingInstanceGetterAndSuperclassMember();
+          _checkImplementsSuperClass(node);
+          _checkImplementsFunctionWithoutCall(node);
+        }
+      }
+      // initialize initialFieldElementsMap
+      if (_enclosingClass != null) {
+        List<FieldElement> fieldElements = _enclosingClass.fields;
+        _initialFieldElementsMap = new HashMap<FieldElement, INIT_STATE>();
+        for (FieldElement fieldElement in fieldElements) {
+          if (!fieldElement.isSynthetic) {
+            _initialFieldElementsMap[fieldElement] = fieldElement.initializer == null ? INIT_STATE.NOT_INIT : INIT_STATE.INIT_IN_DECLARATION;
+          }
+        }
+      }
+      _checkForFinalNotInitializedInClass(node);
+      _checkForDuplicateDefinitionInheritance();
+      _checkForConflictingInstanceMethodSetter(node);
+      return super.visitClassDeclaration(node);
+    } finally {
+      _isInNativeClass = false;
+      _initialFieldElementsMap = null;
+      _enclosingClass = outerClass;
+    }
+  }
+
+  @override
+  Object visitClassTypeAlias(ClassTypeAlias node) {
+    _checkForBuiltInIdentifierAsName(node.name, CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPEDEF_NAME);
+    ClassElement outerClassElement = _enclosingClass;
+    try {
+      _enclosingClass = node.element;
+      ImplementsClause implementsClause = node.implementsClause;
+      // Only check for all of the inheritance logic around clauses if there isn't an error code
+      // such as "Cannot extend double" already on the class.
+      if (!_checkForExtendsDisallowedClassInTypeAlias(node) && !_checkForImplementsDisallowedClass(implementsClause) && !_checkForAllMixinErrorCodes(node.withClause)) {
+        _checkForExtendsDeferredClassInTypeAlias(node);
+        _checkForImplementsDeferredClass(implementsClause);
+        _checkForRecursiveInterfaceInheritance(_enclosingClass);
+        _checkForNonAbstractClassInheritsAbstractMember(node.name);
+      }
+    } finally {
+      _enclosingClass = outerClassElement;
+    }
+    return super.visitClassTypeAlias(node);
+  }
+
+  @override
+  Object visitComment(Comment node) {
+    _isInComment = true;
+    try {
+      return super.visitComment(node);
+    } finally {
+      _isInComment = false;
+    }
+  }
+
+  @override
+  Object visitCompilationUnit(CompilationUnit node) {
+    _checkForDeferredPrefixCollisions(node);
+    return super.visitCompilationUnit(node);
+  }
+
+  @override
+  Object visitConditionalExpression(ConditionalExpression node) {
+    _checkForNonBoolCondition(node.condition);
+    return super.visitConditionalExpression(node);
+  }
+
+  @override
+  Object visitConstructorDeclaration(ConstructorDeclaration node) {
+    ExecutableElement outerFunction = _enclosingFunction;
+    try {
+      ConstructorElement constructorElement = node.element;
+      _enclosingFunction = constructorElement;
+      _isEnclosingConstructorConst = node.constKeyword != null;
+      _isInFactory = node.factoryKeyword != null;
+      _checkForInvalidModifierOnBody(node.body, CompileTimeErrorCode.INVALID_MODIFIER_ON_CONSTRUCTOR);
+      _checkForConstConstructorWithNonFinalField(node, constructorElement);
+      _checkForConstConstructorWithNonConstSuper(node);
+      _checkForConflictingConstructorNameAndMember(node, constructorElement);
+      _checkForAllFinalInitializedErrorCodes(node);
+      _checkForRedirectingConstructorErrorCodes(node);
+      _checkForMultipleSuperInitializers(node);
+      _checkForRecursiveConstructorRedirect(node, constructorElement);
+      if (!_checkForRecursiveFactoryRedirect(node, constructorElement)) {
+        _checkForAllRedirectConstructorErrorCodes(node);
+      }
+      _checkForUndefinedConstructorInInitializerImplicit(node);
+      _checkForRedirectToNonConstConstructor(node, constructorElement);
+      _checkForReturnInGenerativeConstructor(node);
+      return super.visitConstructorDeclaration(node);
+    } finally {
+      _isEnclosingConstructorConst = false;
+      _isInFactory = false;
+      _enclosingFunction = outerFunction;
+    }
+  }
+
+  @override
+  Object visitConstructorFieldInitializer(ConstructorFieldInitializer node) {
+    _isInConstructorInitializer = true;
+    try {
+      SimpleIdentifier fieldName = node.fieldName;
+      Element staticElement = fieldName.staticElement;
+      _checkForInvalidField(node, fieldName, staticElement);
+      _checkForFieldInitializerNotAssignable(node, staticElement);
+      return super.visitConstructorFieldInitializer(node);
+    } finally {
+      _isInConstructorInitializer = false;
+    }
+  }
+
+  @override
+  Object visitContinueStatement(ContinueStatement node) {
+    SimpleIdentifier labelNode = node.label;
+    if (labelNode != null) {
+      Element labelElement = labelNode.staticElement;
+      if (labelElement is LabelElementImpl && labelElement.isOnSwitchStatement) {
+        _errorReporter.reportErrorForNode(ResolverErrorCode.CONTINUE_LABEL_ON_SWITCH, labelNode, []);
+      }
+    }
+    return null;
+  }
+
+  @override
+  Object visitDefaultFormalParameter(DefaultFormalParameter node) {
+    _checkForInvalidAssignment(node.identifier, node.defaultValue);
+    _checkForDefaultValueInFunctionTypedParameter(node);
+    return super.visitDefaultFormalParameter(node);
+  }
+
+  @override
+  Object visitDoStatement(DoStatement node) {
+    _checkForNonBoolCondition(node.condition);
+    return super.visitDoStatement(node);
+  }
+
+  @override
+  Object visitExportDirective(ExportDirective node) {
+    ExportElement exportElement = node.element;
+    if (exportElement != null) {
+      LibraryElement exportedLibrary = exportElement.exportedLibrary;
+      _checkForAmbiguousExport(node, exportElement, exportedLibrary);
+      _checkForExportDuplicateLibraryName(node, exportElement, exportedLibrary);
+      _checkForExportInternalLibrary(node, exportElement);
+    }
+    return super.visitExportDirective(node);
+  }
+
+  @override
+  Object visitExpressionFunctionBody(ExpressionFunctionBody node) {
+    bool wasInAsync = _inAsync;
+    bool wasInGenerator = _inGenerator;
+    try {
+      _inAsync = node.isAsynchronous;
+      _inGenerator = node.isGenerator;
+      FunctionType functionType = _enclosingFunction == null ? null : _enclosingFunction.type;
+      DartType expectedReturnType = functionType == null ? DynamicTypeImpl.instance : functionType.returnType;
+      _checkForReturnOfInvalidType(node.expression, expectedReturnType);
+      return super.visitExpressionFunctionBody(node);
+    } finally {
+      _inAsync = wasInAsync;
+      _inGenerator = wasInGenerator;
+    }
+  }
+
+  @override
+  Object visitFieldDeclaration(FieldDeclaration node) {
+    _isInStaticVariableDeclaration = node.isStatic;
+    _isInInstanceVariableDeclaration = !_isInStaticVariableDeclaration;
+    if (_isInInstanceVariableDeclaration) {
+      VariableDeclarationList variables = node.fields;
+      if (variables.isConst) {
+        _errorReporter.reportErrorForToken(CompileTimeErrorCode.CONST_INSTANCE_FIELD, variables.keyword, []);
+      }
+    }
+    try {
+      _checkForAllInvalidOverrideErrorCodesForField(node);
+      return super.visitFieldDeclaration(node);
+    } finally {
+      _isInStaticVariableDeclaration = false;
+      _isInInstanceVariableDeclaration = false;
+    }
+  }
+
+  @override
+  Object visitFieldFormalParameter(FieldFormalParameter node) {
+    _checkForValidField(node);
+    _checkForConstFormalParameter(node);
+    _checkForPrivateOptionalParameter(node);
+    _checkForFieldInitializingFormalRedirectingConstructor(node);
+    _checkForTypeAnnotationDeferredClass(node.type);
+    return super.visitFieldFormalParameter(node);
+  }
+
+  @override
+  Object visitFunctionDeclaration(FunctionDeclaration node) {
+    ExecutableElement outerFunction = _enclosingFunction;
+    try {
+      SimpleIdentifier identifier = node.name;
+      String methodName = "";
+      if (identifier != null) {
+        methodName = identifier.name;
+      }
+      _enclosingFunction = node.element;
+      TypeName returnType = node.returnType;
+      if (node.isSetter || node.isGetter) {
+        _checkForMismatchedAccessorTypes(node, methodName);
+        if (node.isSetter) {
+          FunctionExpression functionExpression = node.functionExpression;
+          if (functionExpression != null) {
+            _checkForWrongNumberOfParametersForSetter(identifier, functionExpression.parameters);
+          }
+          _checkForNonVoidReturnTypeForSetter(returnType);
+        }
+      }
+      if (node.isSetter) {
+        _checkForInvalidModifierOnBody(node.functionExpression.body, CompileTimeErrorCode.INVALID_MODIFIER_ON_SETTER);
+      }
+      _checkForTypeAnnotationDeferredClass(returnType);
+      return super.visitFunctionDeclaration(node);
+    } finally {
+      _enclosingFunction = outerFunction;
+    }
+  }
+
+  @override
+  Object visitFunctionExpression(FunctionExpression node) {
+    // If this function expression is wrapped in a function declaration, don't change the
+    // enclosingFunction field.
+    if (node.parent is! FunctionDeclaration) {
+      ExecutableElement outerFunction = _enclosingFunction;
+      try {
+        _enclosingFunction = node.element;
+        return super.visitFunctionExpression(node);
+      } finally {
+        _enclosingFunction = outerFunction;
+      }
+    } else {
+      return super.visitFunctionExpression(node);
+    }
+  }
+
+  @override
+  Object visitFunctionExpressionInvocation(FunctionExpressionInvocation node) {
+    Expression functionExpression = node.function;
+    DartType expressionType = functionExpression.staticType;
+    if (!_isFunctionType(expressionType)) {
+      _errorReporter.reportErrorForNode(StaticTypeWarningCode.INVOCATION_OF_NON_FUNCTION_EXPRESSION, functionExpression, []);
+    }
+    return super.visitFunctionExpressionInvocation(node);
+  }
+
+  @override
+  Object visitFunctionTypeAlias(FunctionTypeAlias node) {
+    _checkForBuiltInIdentifierAsName(node.name, CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPEDEF_NAME);
+    _checkForDefaultValueInFunctionTypeAlias(node);
+    _checkForTypeAliasCannotReferenceItself_function(node);
+    return super.visitFunctionTypeAlias(node);
+  }
+
+  @override
+  Object visitFunctionTypedFormalParameter(FunctionTypedFormalParameter node) {
+    bool old = _isInFunctionTypedFormalParameter;
+    _isInFunctionTypedFormalParameter = true;
+    try {
+      _checkForTypeAnnotationDeferredClass(node.returnType);
+      return super.visitFunctionTypedFormalParameter(node);
+    } finally {
+      _isInFunctionTypedFormalParameter = old;
+    }
+  }
+
+  @override
+  Object visitIfStatement(IfStatement node) {
+    _checkForNonBoolCondition(node.condition);
+    return super.visitIfStatement(node);
+  }
+
+  @override
+  Object visitImportDirective(ImportDirective node) {
+    ImportElement importElement = node.element;
+    if (importElement != null) {
+      _checkForImportDuplicateLibraryName(node, importElement);
+      _checkForImportInternalLibrary(node, importElement);
+    }
+    return super.visitImportDirective(node);
+  }
+
+  @override
+  Object visitIndexExpression(IndexExpression node) {
+    _checkForArgumentTypeNotAssignableForArgument(node.index);
+    return super.visitIndexExpression(node);
+  }
+
+  @override
+  Object visitInstanceCreationExpression(InstanceCreationExpression node) {
+    bool wasInConstInstanceCreation = _isInConstInstanceCreation;
+    _isInConstInstanceCreation = node.isConst;
+    try {
+      ConstructorName constructorName = node.constructorName;
+      TypeName typeName = constructorName.type;
+      DartType type = typeName.type;
+      if (type is InterfaceType) {
+        InterfaceType interfaceType = type;
+        _checkForConstOrNewWithAbstractClass(node, typeName, interfaceType);
+        _checkForConstOrNewWithEnum(node, typeName, interfaceType);
+        if (_isInConstInstanceCreation) {
+          _checkForConstWithNonConst(node);
+          _checkForConstWithUndefinedConstructor(node, constructorName, typeName);
+          _checkForConstWithTypeParameters(typeName);
+          _checkForConstDeferredClass(node, constructorName, typeName);
+        } else {
+          _checkForNewWithUndefinedConstructor(node, constructorName, typeName);
+        }
+      }
+      return super.visitInstanceCreationExpression(node);
+    } finally {
+      _isInConstInstanceCreation = wasInConstInstanceCreation;
+    }
+  }
+
+  @override
+  Object visitIsExpression(IsExpression node) {
+    _checkForTypeAnnotationDeferredClass(node.type);
+    return super.visitIsExpression(node);
+  }
+
+  @override
+  Object visitListLiteral(ListLiteral node) {
+    TypeArgumentList typeArguments = node.typeArguments;
+    if (typeArguments != null) {
+      if (node.constKeyword != null) {
+        NodeList<TypeName> arguments = typeArguments.arguments;
+        if (arguments.length != 0) {
+          _checkForInvalidTypeArgumentInConstTypedLiteral(arguments, CompileTimeErrorCode.INVALID_TYPE_ARGUMENT_IN_CONST_LIST);
+        }
+      }
+      _checkForExpectedOneListTypeArgument(node, typeArguments);
+      _checkForListElementTypeNotAssignable(node, typeArguments);
+    }
+    return super.visitListLiteral(node);
+  }
+
+  @override
+  Object visitMapLiteral(MapLiteral node) {
+    TypeArgumentList typeArguments = node.typeArguments;
+    if (typeArguments != null) {
+      NodeList<TypeName> arguments = typeArguments.arguments;
+      if (arguments.length != 0) {
+        if (node.constKeyword != null) {
+          _checkForInvalidTypeArgumentInConstTypedLiteral(arguments, CompileTimeErrorCode.INVALID_TYPE_ARGUMENT_IN_CONST_MAP);
+        }
+      }
+      _checkExpectedTwoMapTypeArguments(typeArguments);
+      _checkForMapTypeNotAssignable(node, typeArguments);
+    }
+    _checkForNonConstMapAsExpressionStatement(node);
+    return super.visitMapLiteral(node);
+  }
+
+  @override
+  Object visitMethodDeclaration(MethodDeclaration node) {
+    ExecutableElement previousFunction = _enclosingFunction;
+    try {
+      _isInStaticMethod = node.isStatic;
+      _enclosingFunction = node.element;
+      SimpleIdentifier identifier = node.name;
+      String methodName = "";
+      if (identifier != null) {
+        methodName = identifier.name;
+      }
+      TypeName returnTypeName = node.returnType;
+      if (node.isSetter || node.isGetter) {
+        _checkForMismatchedAccessorTypes(node, methodName);
+      }
+      if (node.isGetter) {
+        _checkForVoidReturnType(node);
+        _checkForConflictingStaticGetterAndInstanceSetter(node);
+      } else if (node.isSetter) {
+        _checkForInvalidModifierOnBody(node.body, CompileTimeErrorCode.INVALID_MODIFIER_ON_SETTER);
+        _checkForWrongNumberOfParametersForSetter(node.name, node.parameters);
+        _checkForNonVoidReturnTypeForSetter(returnTypeName);
+        _checkForConflictingStaticSetterAndInstanceMember(node);
+      } else if (node.isOperator) {
+        _checkForOptionalParameterInOperator(node);
+        _checkForWrongNumberOfParametersForOperator(node);
+        _checkForNonVoidReturnTypeForOperator(node);
+      }
+      _checkForConcreteClassWithAbstractMember(node);
+      _checkForAllInvalidOverrideErrorCodesForMethod(node);
+      _checkForTypeAnnotationDeferredClass(returnTypeName);
+      return super.visitMethodDeclaration(node);
+    } finally {
+      _enclosingFunction = previousFunction;
+      _isInStaticMethod = false;
+    }
+  }
+
+  @override
+  Object visitMethodInvocation(MethodInvocation node) {
+    Expression target = node.realTarget;
+    SimpleIdentifier methodName = node.methodName;
+    if (target != null) {
+      ClassElement typeReference = ElementResolver.getTypeReference(target);
+      _checkForStaticAccessToInstanceMember(typeReference, methodName);
+      _checkForInstanceAccessToStaticMember(typeReference, methodName);
+    } else {
+      _checkForUnqualifiedReferenceToNonLocalStaticMember(methodName);
+    }
+    return super.visitMethodInvocation(node);
+  }
+
+  @override
+  Object visitNativeClause(NativeClause node) {
+    // TODO(brianwilkerson) Figure out the right rule for when 'native' is allowed.
+    if (!_isInSystemLibrary) {
+      _errorReporter.reportErrorForNode(ParserErrorCode.NATIVE_CLAUSE_IN_NON_SDK_CODE, node, []);
+    }
+    return super.visitNativeClause(node);
+  }
+
+  @override
+  Object visitNativeFunctionBody(NativeFunctionBody node) {
+    _checkForNativeFunctionBodyInNonSDKCode(node);
+    return super.visitNativeFunctionBody(node);
+  }
+
+  @override
+  Object visitPostfixExpression(PostfixExpression node) {
+    _checkForAssignmentToFinal(node.operand);
+    _checkForIntNotAssignable(node.operand);
+    return super.visitPostfixExpression(node);
+  }
+
+  @override
+  Object visitPrefixedIdentifier(PrefixedIdentifier node) {
+    if (node.parent is! Annotation) {
+      ClassElement typeReference = ElementResolver.getTypeReference(node.prefix);
+      SimpleIdentifier name = node.identifier;
+      _checkForStaticAccessToInstanceMember(typeReference, name);
+      _checkForInstanceAccessToStaticMember(typeReference, name);
+    }
+    return super.visitPrefixedIdentifier(node);
+  }
+
+  @override
+  Object visitPrefixExpression(PrefixExpression node) {
+    sc.TokenType operatorType = node.operator.type;
+    Expression operand = node.operand;
+    if (operatorType == sc.TokenType.BANG) {
+      _checkForNonBoolNegationExpression(operand);
+    } else if (operatorType.isIncrementOperator) {
+      _checkForAssignmentToFinal(operand);
+    }
+    _checkForIntNotAssignable(operand);
+    return super.visitPrefixExpression(node);
+  }
+
+  @override
+  Object visitPropertyAccess(PropertyAccess node) {
+    ClassElement typeReference = ElementResolver.getTypeReference(node.realTarget);
+    SimpleIdentifier propertyName = node.propertyName;
+    _checkForStaticAccessToInstanceMember(typeReference, propertyName);
+    _checkForInstanceAccessToStaticMember(typeReference, propertyName);
+    return super.visitPropertyAccess(node);
+  }
+
+  @override
+  Object visitRedirectingConstructorInvocation(RedirectingConstructorInvocation node) {
+    _isInConstructorInitializer = true;
+    try {
+      return super.visitRedirectingConstructorInvocation(node);
+    } finally {
+      _isInConstructorInitializer = false;
+    }
+  }
+
+  @override
+  Object visitRethrowExpression(RethrowExpression node) {
+    _checkForRethrowOutsideCatch(node);
+    return super.visitRethrowExpression(node);
+  }
+
+  @override
+  Object visitReturnStatement(ReturnStatement node) {
+    if (node.expression == null) {
+      _returnsWithout.add(node);
+    } else {
+      _returnsWith.add(node);
+    }
+    _checkForAllReturnStatementErrorCodes(node);
+    return super.visitReturnStatement(node);
+  }
+
+  @override
+  Object visitSimpleFormalParameter(SimpleFormalParameter node) {
+    _checkForConstFormalParameter(node);
+    _checkForPrivateOptionalParameter(node);
+    _checkForTypeAnnotationDeferredClass(node.type);
+    return super.visitSimpleFormalParameter(node);
+  }
+
+  @override
+  Object visitSimpleIdentifier(SimpleIdentifier node) {
+    _checkForImplicitThisReferenceInInitializer(node);
+    if (!_isUnqualifiedReferenceToNonLocalStaticMemberAllowed(node)) {
+      _checkForUnqualifiedReferenceToNonLocalStaticMember(node);
+    }
+    return super.visitSimpleIdentifier(node);
+  }
+
+  @override
+  Object visitSuperConstructorInvocation(SuperConstructorInvocation node) {
+    _isInConstructorInitializer = true;
+    try {
+      return super.visitSuperConstructorInvocation(node);
+    } finally {
+      _isInConstructorInitializer = false;
+    }
+  }
+
+  @override
+  Object visitSwitchStatement(SwitchStatement node) {
+    _checkForSwitchExpressionNotAssignable(node);
+    _checkForCaseBlocksNotTerminated(node);
+    _checkForMissingEnumConstantInSwitch(node);
+    return super.visitSwitchStatement(node);
+  }
+
+  @override
+  Object visitThisExpression(ThisExpression node) {
+    _checkForInvalidReferenceToThis(node);
+    return super.visitThisExpression(node);
+  }
+
+  @override
+  Object visitThrowExpression(ThrowExpression node) {
+    _checkForConstEvalThrowsException(node);
+    return super.visitThrowExpression(node);
+  }
+
+  @override
+  Object visitTopLevelVariableDeclaration(TopLevelVariableDeclaration node) {
+    _checkForFinalNotInitialized(node.variables);
+    return super.visitTopLevelVariableDeclaration(node);
+  }
+
+  @override
+  Object visitTypeArgumentList(TypeArgumentList node) {
+    NodeList<TypeName> list = node.arguments;
+    for (TypeName typeName in list) {
+      _checkForTypeAnnotationDeferredClass(typeName);
+    }
+    return super.visitTypeArgumentList(node);
+  }
+
+  @override
+  Object visitTypeName(TypeName node) {
+    _checkForTypeArgumentNotMatchingBounds(node);
+    _checkForTypeParameterReferencedByStatic(node);
+    return super.visitTypeName(node);
+  }
+
+  @override
+  Object visitTypeParameter(TypeParameter node) {
+    _checkForBuiltInIdentifierAsName(node.name, CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE_PARAMETER_NAME);
+    _checkForTypeParameterSupertypeOfItsBound(node);
+    _checkForTypeAnnotationDeferredClass(node.bound);
+    return super.visitTypeParameter(node);
+  }
+
+  @override
+  Object visitVariableDeclaration(VariableDeclaration node) {
+    SimpleIdentifier nameNode = node.name;
+    Expression initializerNode = node.initializer;
+    // do checks
+    _checkForInvalidAssignment(nameNode, initializerNode);
+    // visit name
+    nameNode.accept(this);
+    // visit initializer
+    String name = nameNode.name;
+    _namesForReferenceToDeclaredVariableInInitializer.add(name);
+    bool wasInInstanceVariableInitializer = _isInInstanceVariableInitializer;
+    _isInInstanceVariableInitializer = _isInInstanceVariableDeclaration;
+    try {
+      if (initializerNode != null) {
+        initializerNode.accept(this);
+      }
+    } finally {
+      _isInInstanceVariableInitializer = wasInInstanceVariableInitializer;
+      _namesForReferenceToDeclaredVariableInInitializer.remove(name);
+    }
+    // done
+    return null;
+  }
+
+  @override
+  Object visitVariableDeclarationList(VariableDeclarationList node) {
+    _checkForTypeAnnotationDeferredClass(node.type);
+    return super.visitVariableDeclarationList(node);
+  }
+
+  @override
+  Object visitVariableDeclarationStatement(VariableDeclarationStatement node) {
+    _checkForFinalNotInitialized(node.variables);
+    return super.visitVariableDeclarationStatement(node);
+  }
+
+  @override
+  Object visitWhileStatement(WhileStatement node) {
+    _checkForNonBoolCondition(node.condition);
+    return super.visitWhileStatement(node);
+  }
+
+  @override
+  Object visitYieldStatement(YieldStatement node) {
+    if (!_inGenerator) {
+      CompileTimeErrorCode errorCode;
+      if (node.star != null) {
+        errorCode = CompileTimeErrorCode.YIELD_EACH_IN_NON_GENERATOR;
+      } else {
+        errorCode = CompileTimeErrorCode.YIELD_IN_NON_GENERATOR;
+      }
+      _errorReporter.reportErrorForNode(errorCode, node, []);
+    }
+    return super.visitYieldStatement(node);
+  }
+
+  /**
+   * This verifies if the passed map literal has type arguments then there is exactly two.
+   *
+   * @param typeArguments the type arguments, always non-`null`
+   * @return `true` if and only if an error code is generated on the passed node
+   * @see StaticTypeWarningCode#EXPECTED_TWO_MAP_TYPE_ARGUMENTS
+   */
+  bool _checkExpectedTwoMapTypeArguments(TypeArgumentList typeArguments) {
+    // check number of type arguments
+    int num = typeArguments.arguments.length;
+    if (num == 2) {
+      return false;
+    }
+    // report problem
+    _errorReporter.reportErrorForNode(StaticTypeWarningCode.EXPECTED_TWO_MAP_TYPE_ARGUMENTS, typeArguments, [num]);
+    return true;
+  }
+
+  /**
+   * This verifies that the passed constructor declaration does not violate any of the error codes
+   * relating to the initialization of fields in the enclosing class.
+   *
+   * @param node the [ConstructorDeclaration] to evaluate
+   * @return `true` if and only if an error code is generated on the passed node
+   * @see #initialFieldElementsMap
+   * @see CompileTimeErrorCode#FINAL_INITIALIZED_IN_DECLARATION_AND_CONSTRUCTOR
+   * @see CompileTimeErrorCode#FINAL_INITIALIZED_MULTIPLE_TIMES
+   */
+  bool _checkForAllFinalInitializedErrorCodes(ConstructorDeclaration node) {
+    if (node.factoryKeyword != null || node.redirectedConstructor != null || node.externalKeyword != null) {
+      return false;
+    }
+    // Ignore if native class.
+    if (_isInNativeClass) {
+      return false;
+    }
+    bool foundError = false;
+    HashMap<FieldElement, INIT_STATE> fieldElementsMap = new HashMap<FieldElement, INIT_STATE>.from(_initialFieldElementsMap);
+    // Visit all of the field formal parameters
+    NodeList<FormalParameter> formalParameters = node.parameters.parameters;
+    for (FormalParameter formalParameter in formalParameters) {
+      FormalParameter parameter = formalParameter;
+      if (parameter is DefaultFormalParameter) {
+        parameter = (parameter as DefaultFormalParameter).parameter;
+      }
+      if (parameter is FieldFormalParameter) {
+        FieldElement fieldElement = (parameter.element as FieldFormalParameterElementImpl).field;
+        INIT_STATE state = fieldElementsMap[fieldElement];
+        if (state == INIT_STATE.NOT_INIT) {
+          fieldElementsMap[fieldElement] = INIT_STATE.INIT_IN_FIELD_FORMAL;
+        } else if (state == INIT_STATE.INIT_IN_DECLARATION) {
+          if (fieldElement.isFinal || fieldElement.isConst) {
+            _errorReporter.reportErrorForNode(StaticWarningCode.FINAL_INITIALIZED_IN_DECLARATION_AND_CONSTRUCTOR, formalParameter.identifier, [fieldElement.displayName]);
+            foundError = true;
+          }
+        } else if (state == INIT_STATE.INIT_IN_FIELD_FORMAL) {
+          if (fieldElement.isFinal || fieldElement.isConst) {
+            _errorReporter.reportErrorForNode(CompileTimeErrorCode.FINAL_INITIALIZED_MULTIPLE_TIMES, formalParameter.identifier, [fieldElement.displayName]);
+            foundError = true;
+          }
+        }
+      }
+    }
+    // Visit all of the initializers
+    NodeList<ConstructorInitializer> initializers = node.initializers;
+    for (ConstructorInitializer constructorInitializer in initializers) {
+      if (constructorInitializer is RedirectingConstructorInvocation) {
+        return false;
+      }
+      if (constructorInitializer is ConstructorFieldInitializer) {
+        ConstructorFieldInitializer constructorFieldInitializer = constructorInitializer;
+        SimpleIdentifier fieldName = constructorFieldInitializer.fieldName;
+        Element element = fieldName.staticElement;
+        if (element is FieldElement) {
+          FieldElement fieldElement = element;
+          INIT_STATE state = fieldElementsMap[fieldElement];
+          if (state == INIT_STATE.NOT_INIT) {
+            fieldElementsMap[fieldElement] = INIT_STATE.INIT_IN_INITIALIZERS;
+          } else if (state == INIT_STATE.INIT_IN_DECLARATION) {
+            if (fieldElement.isFinal || fieldElement.isConst) {
+              _errorReporter.reportErrorForNode(StaticWarningCode.FIELD_INITIALIZED_IN_INITIALIZER_AND_DECLARATION, fieldName, []);
+              foundError = true;
+            }
+          } else if (state == INIT_STATE.INIT_IN_FIELD_FORMAL) {
+            _errorReporter.reportErrorForNode(CompileTimeErrorCode.FIELD_INITIALIZED_IN_PARAMETER_AND_INITIALIZER, fieldName, []);
+            foundError = true;
+          } else if (state == INIT_STATE.INIT_IN_INITIALIZERS) {
+            _errorReporter.reportErrorForNode(CompileTimeErrorCode.FIELD_INITIALIZED_BY_MULTIPLE_INITIALIZERS, fieldName, [fieldElement.displayName]);
+            foundError = true;
+          }
+        }
+      }
+    }
+    // Visit all of the states in the map to ensure that none were never
+    // initialized.
+    fieldElementsMap.forEach((FieldElement fieldElement, INIT_STATE state) {
+      if (state == INIT_STATE.NOT_INIT) {
+        if (fieldElement.isConst) {
+          _errorReporter.reportErrorForNode(
+              CompileTimeErrorCode.CONST_NOT_INITIALIZED,
+                  node.returnType,
+                  [fieldElement.name]);
+          foundError = true;
+        } else if (fieldElement.isFinal) {
+          _errorReporter.reportErrorForNode(
+              StaticWarningCode.FINAL_NOT_INITIALIZED,
+                  node.returnType,
+                  [fieldElement.name]);
+          foundError = true;
+        }
+      }
+    });
+    return foundError;
+  }
+
+  /**
+   * This checks the passed executable element against override-error codes.
+   *
+   * @param executableElement a non-null [ExecutableElement] to evaluate
+   * @param overriddenExecutable the element that the executableElement is overriding
+   * @param parameters the parameters of the executable element
+   * @param errorNameTarget the node to report problems on
+   * @return `true` if and only if an error code is generated on the passed node
+   * @see StaticWarningCode#INSTANCE_METHOD_NAME_COLLIDES_WITH_SUPERCLASS_STATIC
+   * @see CompileTimeErrorCode#INVALID_OVERRIDE_REQUIRED
+   * @see CompileTimeErrorCode#INVALID_OVERRIDE_POSITIONAL
+   * @see CompileTimeErrorCode#INVALID_OVERRIDE_NAMED
+   * @see StaticWarningCode#INVALID_GETTER_OVERRIDE_RETURN_TYPE
+   * @see StaticWarningCode#INVALID_METHOD_OVERRIDE_RETURN_TYPE
+   * @see StaticWarningCode#INVALID_METHOD_OVERRIDE_NORMAL_PARAM_TYPE
+   * @see StaticWarningCode#INVALID_SETTER_OVERRIDE_NORMAL_PARAM_TYPE
+   * @see StaticWarningCode#INVALID_METHOD_OVERRIDE_OPTIONAL_PARAM_TYPE
+   * @see StaticWarningCode#INVALID_METHOD_OVERRIDE_NAMED_PARAM_TYPE
+   * @see StaticWarningCode#INVALID_OVERRIDE_DIFFERENT_DEFAULT_VALUES
+   */
+  bool _checkForAllInvalidOverrideErrorCodes(ExecutableElement executableElement, ExecutableElement overriddenExecutable, List<ParameterElement> parameters, List<AstNode> parameterLocations, SimpleIdentifier errorNameTarget) {
+    bool isGetter = false;
+    bool isSetter = false;
+    if (executableElement is PropertyAccessorElement) {
+      PropertyAccessorElement accessorElement = executableElement;
+      isGetter = accessorElement.isGetter;
+      isSetter = accessorElement.isSetter;
+    }
+    String executableElementName = executableElement.name;
+    FunctionType overridingFT = executableElement.type;
+    FunctionType overriddenFT = overriddenExecutable.type;
+    InterfaceType enclosingType = _enclosingClass.type;
+    overriddenFT = _inheritanceManager.substituteTypeArgumentsInMemberFromInheritance(overriddenFT, executableElementName, enclosingType);
+    if (overridingFT == null || overriddenFT == null) {
+      return false;
+    }
+    DartType overridingFTReturnType = overridingFT.returnType;
+    DartType overriddenFTReturnType = overriddenFT.returnType;
+    List<DartType> overridingNormalPT = overridingFT.normalParameterTypes;
+    List<DartType> overriddenNormalPT = overriddenFT.normalParameterTypes;
+    List<DartType> overridingPositionalPT = overridingFT.optionalParameterTypes;
+    List<DartType> overriddenPositionalPT = overriddenFT.optionalParameterTypes;
+    Map<String, DartType> overridingNamedPT = overridingFT.namedParameterTypes;
+    Map<String, DartType> overriddenNamedPT = overriddenFT.namedParameterTypes;
+    // CTEC.INVALID_OVERRIDE_REQUIRED, CTEC.INVALID_OVERRIDE_POSITIONAL and CTEC.INVALID_OVERRIDE_NAMED
+    if (overridingNormalPT.length > overriddenNormalPT.length) {
+      _errorReporter.reportErrorForNode(StaticWarningCode.INVALID_OVERRIDE_REQUIRED, errorNameTarget, [
+          overriddenNormalPT.length,
+          overriddenExecutable.enclosingElement.displayName]);
+      return true;
+    }
+    if (overridingNormalPT.length + overridingPositionalPT.length < overriddenPositionalPT.length + overriddenNormalPT.length) {
+      _errorReporter.reportErrorForNode(StaticWarningCode.INVALID_OVERRIDE_POSITIONAL, errorNameTarget, [
+          overriddenPositionalPT.length + overriddenNormalPT.length,
+          overriddenExecutable.enclosingElement.displayName]);
+      return true;
+    }
+    // For each named parameter in the overridden method, verify that there is
+    // the same name in the overriding method.
+    for (String overriddenParamName in overriddenNamedPT.keys) {
+      if (!overridingNamedPT.containsKey(overriddenParamName)) {
+        // The overridden method expected the overriding method to have
+        // overridingParamName, but it does not.
+        _errorReporter.reportErrorForNode(
+            StaticWarningCode.INVALID_OVERRIDE_NAMED,
+            errorNameTarget,
+            [overriddenParamName,
+            overriddenExecutable.enclosingElement.displayName]);
+        return true;
+      }
+    }
+    // SWC.INVALID_METHOD_OVERRIDE_RETURN_TYPE
+    if (overriddenFTReturnType != VoidTypeImpl.instance && !overridingFTReturnType.isAssignableTo(overriddenFTReturnType)) {
+      _errorReporter.reportTypeErrorForNode(!isGetter ? StaticWarningCode.INVALID_METHOD_OVERRIDE_RETURN_TYPE : StaticWarningCode.INVALID_GETTER_OVERRIDE_RETURN_TYPE, errorNameTarget, [
+          overridingFTReturnType,
+          overriddenFTReturnType,
+          overriddenExecutable.enclosingElement.displayName]);
+      return true;
+    }
+    // SWC.INVALID_METHOD_OVERRIDE_NORMAL_PARAM_TYPE
+    if (parameterLocations == null) {
+      return false;
+    }
+    int parameterIndex = 0;
+    for (int i = 0; i < overridingNormalPT.length; i++) {
+      if (!overridingNormalPT[i].isAssignableTo(overriddenNormalPT[i])) {
+        _errorReporter.reportTypeErrorForNode(!isSetter ? StaticWarningCode.INVALID_METHOD_OVERRIDE_NORMAL_PARAM_TYPE : StaticWarningCode.INVALID_SETTER_OVERRIDE_NORMAL_PARAM_TYPE, parameterLocations[parameterIndex], [
+            overridingNormalPT[i],
+            overriddenNormalPT[i],
+            overriddenExecutable.enclosingElement.displayName]);
+        return true;
+      }
+      parameterIndex++;
+    }
+    // SWC.INVALID_METHOD_OVERRIDE_OPTIONAL_PARAM_TYPE
+    for (int i = 0; i < overriddenPositionalPT.length; i++) {
+      if (!overridingPositionalPT[i].isAssignableTo(overriddenPositionalPT[i])) {
+        _errorReporter.reportTypeErrorForNode(StaticWarningCode.INVALID_METHOD_OVERRIDE_OPTIONAL_PARAM_TYPE, parameterLocations[parameterIndex], [
+            overridingPositionalPT[i],
+            overriddenPositionalPT[i],
+            overriddenExecutable.enclosingElement.displayName]);
+        return true;
+      }
+      parameterIndex++;
+    }
+    // SWC.INVALID_METHOD_OVERRIDE_NAMED_PARAM_TYPE & SWC.INVALID_OVERRIDE_DIFFERENT_DEFAULT_VALUES
+    for (String overriddenName in overriddenNamedPT.keys) {
+      DartType overridingType = overridingNamedPT[overriddenName];
+      if (overridingType == null) {
+        // Error, this is never reached- INVALID_OVERRIDE_NAMED would have been
+        // created above if this could be reached.
+        continue;
+      }
+      DartType overriddenType = overriddenNamedPT[overriddenName];
+      if (!overriddenType.isAssignableTo(overridingType)) {
+        // lookup the parameter for the error to select
+        ParameterElement parameterToSelect = null;
+        AstNode parameterLocationToSelect = null;
+        for (int i = 0; i < parameters.length; i++) {
+          ParameterElement parameter = parameters[i];
+          if (parameter.parameterKind == ParameterKind.NAMED
+              && overriddenName == parameter.name) {
+            parameterToSelect = parameter;
+            parameterLocationToSelect = parameterLocations[i];
+            break;
+          }
+        }
+        if (parameterToSelect != null) {
+          _errorReporter.reportTypeErrorForNode(
+              StaticWarningCode.INVALID_METHOD_OVERRIDE_NAMED_PARAM_TYPE,
+              parameterLocationToSelect,
+              [overridingType,
+              overriddenType,
+              overriddenExecutable.enclosingElement.displayName]);
+          return true;
+        }
+      }
+    }
+    // SWC.INVALID_OVERRIDE_DIFFERENT_DEFAULT_VALUES
+    //
+    // Create three arrays: an array of the optional parameter ASTs (FormalParameters), an array of
+    // the optional parameters elements from our method, and finally an array of the optional
+    // parameter elements from the method we are overriding.
+    //
+    bool foundError = false;
+    List<AstNode> formalParameters = new List<AstNode>();
+    List<ParameterElementImpl> parameterElts = new List<ParameterElementImpl>();
+    List<ParameterElementImpl> overriddenParameterElts = new List<ParameterElementImpl>();
+    List<ParameterElement> overriddenPEs = overriddenExecutable.parameters;
+    for (int i = 0; i < parameters.length; i++) {
+      ParameterElement parameter = parameters[i];
+      if (parameter.parameterKind.isOptional) {
+        formalParameters.add(parameterLocations[i]);
+        parameterElts.add(parameter as ParameterElementImpl);
+      }
+    }
+    for (ParameterElement parameterElt in overriddenPEs) {
+      if (parameterElt.parameterKind.isOptional) {
+        if (parameterElt is ParameterElementImpl) {
+          overriddenParameterElts.add(parameterElt);
+        }
+      }
+    }
+    //
+    // Next compare the list of optional parameter elements to the list of overridden optional
+    // parameter elements.
+    //
+    if (parameterElts.length > 0) {
+      if (parameterElts[0].parameterKind == ParameterKind.NAMED) {
+        // Named parameters, consider the names when matching the parameterElts to the overriddenParameterElts
+        for (int i = 0; i < parameterElts.length; i++) {
+          ParameterElementImpl parameterElt = parameterElts[i];
+          EvaluationResultImpl result = parameterElt.evaluationResult;
+          // TODO (jwren) Ignore Object types, see Dart bug 11287
+          if (_isUserDefinedObject(result)) {
+            continue;
+          }
+          String parameterName = parameterElt.name;
+          for (int j = 0; j < overriddenParameterElts.length; j++) {
+            ParameterElementImpl overriddenParameterElt = overriddenParameterElts[j];
+            String overriddenParameterName = overriddenParameterElt.name;
+            if (parameterName != null && parameterName == overriddenParameterName) {
+              EvaluationResultImpl overriddenResult = overriddenParameterElt.evaluationResult;
+              if (_isUserDefinedObject(overriddenResult)) {
+                break;
+              }
+              if (!result.equalValues(_typeProvider, overriddenResult)) {
+                _errorReporter.reportErrorForNode(StaticWarningCode.INVALID_OVERRIDE_DIFFERENT_DEFAULT_VALUES_NAMED, formalParameters[i], [
+                    overriddenExecutable.enclosingElement.displayName,
+                    overriddenExecutable.displayName,
+                    parameterName]);
+                foundError = true;
+              }
+            }
+          }
+        }
+      } else {
+        // Positional parameters, consider the positions when matching the parameterElts to the overriddenParameterElts
+        for (int i = 0; i < parameterElts.length && i < overriddenParameterElts.length; i++) {
+          ParameterElementImpl parameterElt = parameterElts[i];
+          EvaluationResultImpl result = parameterElt.evaluationResult;
+          // TODO (jwren) Ignore Object types, see Dart bug 11287
+          if (_isUserDefinedObject(result)) {
+            continue;
+          }
+          ParameterElementImpl overriddenParameterElt = overriddenParameterElts[i];
+          EvaluationResultImpl overriddenResult = overriddenParameterElt.evaluationResult;
+          if (_isUserDefinedObject(overriddenResult)) {
+            continue;
+          }
+          if (!result.equalValues(_typeProvider, overriddenResult)) {
+            _errorReporter.reportErrorForNode(StaticWarningCode.INVALID_OVERRIDE_DIFFERENT_DEFAULT_VALUES_POSITIONAL, formalParameters[i], [
+                overriddenExecutable.enclosingElement.displayName,
+                overriddenExecutable.displayName]);
+            foundError = true;
+          }
+        }
+      }
+    }
+    return foundError;
+  }
+
+  /**
+   * This checks the passed executable element against override-error codes. This method computes
+   * the passed executableElement is overriding and calls
+   * [checkForAllInvalidOverrideErrorCodes]
+   * when the [InheritanceManager] returns a [MultiplyInheritedExecutableElement], this
+   * method loops through the array in the [MultiplyInheritedExecutableElement].
+   *
+   * @param executableElement a non-null [ExecutableElement] to evaluate
+   * @param parameters the parameters of the executable element
+   * @param errorNameTarget the node to report problems on
+   * @return `true` if and only if an error code is generated on the passed node
+   */
+  bool _checkForAllInvalidOverrideErrorCodesForExecutable(ExecutableElement executableElement, List<ParameterElement> parameters, List<AstNode> parameterLocations, SimpleIdentifier errorNameTarget) {
+    //
+    // Compute the overridden executable from the InheritanceManager
+    //
+    List<ExecutableElement> overriddenExecutables = _inheritanceManager.lookupOverrides(_enclosingClass, executableElement.name);
+    if (overriddenExecutables.isEmpty) {
+      // Nothing is overridden, so we just have to check if the new name collides
+      // with a static defined in the superclass.
+      // TODO(paulberry): currently we don't do this check if the new element
+      // overrides a method in an interface (see issue 18947).
+      return _checkForInstanceMethodNameCollidesWithSuperclassStatic(executableElement, errorNameTarget);
+    }
+    for (ExecutableElement overriddenElement in overriddenExecutables) {
+      if (_checkForAllInvalidOverrideErrorCodes(executableElement, overriddenElement, parameters, parameterLocations, errorNameTarget)) {
+        return true;
+      }
+    }
+    return false;
+  }
+
+  /**
+   * This checks the passed field declaration against override-error codes.
+   *
+   * @param node the [MethodDeclaration] to evaluate
+   * @return `true` if and only if an error code is generated on the passed node
+   * @see #checkForAllInvalidOverrideErrorCodes(ExecutableElement)
+   */
+  bool _checkForAllInvalidOverrideErrorCodesForField(FieldDeclaration node) {
+    if (_enclosingClass == null || node.isStatic) {
+      return false;
+    }
+    bool hasProblems = false;
+    VariableDeclarationList fields = node.fields;
+    for (VariableDeclaration field in fields.variables) {
+      FieldElement element = field.element as FieldElement;
+      if (element == null) {
+        continue;
+      }
+      PropertyAccessorElement getter = element.getter;
+      PropertyAccessorElement setter = element.setter;
+      SimpleIdentifier fieldName = field.name;
+      if (getter != null) {
+        if (_checkForAllInvalidOverrideErrorCodesForExecutable(
+            getter,
+            ParameterElementImpl.EMPTY_ARRAY,
+            AstNode.EMPTY_ARRAY,
+            fieldName)) {
+          hasProblems = true;
+        }
+      }
+      if (setter != null) {
+        if (_checkForAllInvalidOverrideErrorCodesForExecutable(
+            setter,
+            setter.parameters,
+            <AstNode> [fieldName],
+            fieldName)) {
+          hasProblems = true;
+        }
+      }
+    }
+    return hasProblems;
+  }
+
+  /**
+   * This checks the passed method declaration against override-error codes.
+   *
+   * @param node the [MethodDeclaration] to evaluate
+   * @return `true` if and only if an error code is generated on the passed node
+   * @see #checkForAllInvalidOverrideErrorCodes(ExecutableElement)
+   */
+  bool _checkForAllInvalidOverrideErrorCodesForMethod(MethodDeclaration node) {
+    if (_enclosingClass == null || node.isStatic || node.body is NativeFunctionBody) {
+      return false;
+    }
+    ExecutableElement executableElement = node.element;
+    if (executableElement == null) {
+      return false;
+    }
+    SimpleIdentifier methodName = node.name;
+    if (methodName.isSynthetic) {
+      return false;
+    }
+    FormalParameterList formalParameterList = node.parameters;
+    NodeList<FormalParameter> parameterList = formalParameterList != null ? formalParameterList.parameters : null;
+    List<AstNode> parameters = parameterList != null ? new List.from(parameterList) : null;
+    return _checkForAllInvalidOverrideErrorCodesForExecutable(executableElement, executableElement.parameters, parameters, methodName);
+  }
+
+  /**
+   * This verifies that all classes of the passed 'with' clause are valid.
+   *
+   * @param node the 'with' clause to evaluate
+   * @return `true` if and only if an error code is generated on the passed node
+   * @see CompileTimeErrorCode#MIXIN_DECLARES_CONSTRUCTOR
+   * @see CompileTimeErrorCode#MIXIN_INHERITS_FROM_NOT_OBJECT
+   * @see CompileTimeErrorCode#MIXIN_REFERENCES_SUPER
+   */
+  bool _checkForAllMixinErrorCodes(WithClause withClause) {
+    if (withClause == null) {
+      return false;
+    }
+    bool problemReported = false;
+    for (TypeName mixinName in withClause.mixinTypes) {
+      DartType mixinType = mixinName.type;
+      if (mixinType is! InterfaceType) {
+        continue;
+      }
+      if (_checkForExtendsOrImplementsDisallowedClass(
+          mixinName,
+          CompileTimeErrorCode.MIXIN_OF_DISALLOWED_CLASS)) {
+        problemReported = true;
+      } else {
+        ClassElement mixinElement = (mixinType as InterfaceType).element;
+        if (_checkForExtendsOrImplementsDeferredClass(
+            mixinName,
+            CompileTimeErrorCode.MIXIN_DEFERRED_CLASS)) {
+          problemReported = true;
+        }
+        if (_checkForMixinDeclaresConstructor(mixinName, mixinElement)) {
+          problemReported = true;
+        }
+        if (_checkForMixinInheritsNotFromObject(mixinName, mixinElement)) {
+          problemReported = true;
+        }
+        if (_checkForMixinReferencesSuper(mixinName, mixinElement)) {
+          problemReported = true;
+        }
+      }
+    }
+    return problemReported;
+  }
+
+  /**
+   * This checks error related to the redirected constructors.
+   *
+   * @param node the constructor declaration to evaluate
+   * @return `true` if and only if an error code is generated on the passed node
+   * @see StaticWarningCode#REDIRECT_TO_INVALID_RETURN_TYPE
+   * @see StaticWarningCode#REDIRECT_TO_INVALID_FUNCTION_TYPE
+   * @see StaticWarningCode#REDIRECT_TO_MISSING_CONSTRUCTOR
+   */
+  bool _checkForAllRedirectConstructorErrorCodes(ConstructorDeclaration node) {
+    //
+    // Prepare redirected constructor node
+    //
+    ConstructorName redirectedConstructor = node.redirectedConstructor;
+    if (redirectedConstructor == null) {
+      return false;
+    }
+    //
+    // Prepare redirected constructor type
+    //
+    ConstructorElement redirectedElement = redirectedConstructor.staticElement;
+    if (redirectedElement == null) {
+      //
+      // If the element is null, we check for the REDIRECT_TO_MISSING_CONSTRUCTOR case
+      //
+      TypeName constructorTypeName = redirectedConstructor.type;
+      DartType redirectedType = constructorTypeName.type;
+      if (redirectedType != null && redirectedType.element != null && !redirectedType.isDynamic) {
+        //
+        // Prepare the constructor name
+        //
+        String constructorStrName = constructorTypeName.name.name;
+        if (redirectedConstructor.name != null) {
+          constructorStrName += ".${redirectedConstructor.name.name}";
+        }
+        ErrorCode errorCode = (node.constKeyword != null ? CompileTimeErrorCode.REDIRECT_TO_MISSING_CONSTRUCTOR : StaticWarningCode.REDIRECT_TO_MISSING_CONSTRUCTOR);
+        _errorReporter.reportErrorForNode(errorCode, redirectedConstructor, [constructorStrName, redirectedType.displayName]);
+        return true;
+      }
+      return false;
+    }
+    FunctionType redirectedType = redirectedElement.type;
+    DartType redirectedReturnType = redirectedType.returnType;
+    //
+    // Report specific problem when return type is incompatible
+    //
+    FunctionType constructorType = node.element.type;
+    DartType constructorReturnType = constructorType.returnType;
+    if (!redirectedReturnType.isAssignableTo(constructorReturnType)) {
+      _errorReporter.reportErrorForNode(StaticWarningCode.REDIRECT_TO_INVALID_RETURN_TYPE, redirectedConstructor, [redirectedReturnType, constructorReturnType]);
+      return true;
+    }
+    //
+    // Check parameters
+    //
+    if (!redirectedType.isSubtypeOf(constructorType)) {
+      _errorReporter.reportErrorForNode(StaticWarningCode.REDIRECT_TO_INVALID_FUNCTION_TYPE, redirectedConstructor, [redirectedType, constructorType]);
+      return true;
+    }
+    return false;
+  }
+
+  /**
+   * This checks that the return statement of the form <i>return e;</i> is not in a generative
+   * constructor.
+   *
+   * This checks that return statements without expressions are not in a generative constructor and
+   * the return type is not assignable to `null`; that is, we don't have `return;` if
+   * the enclosing method has a return type.
+   *
+   * This checks that the return type matches the type of the declared return type in the enclosing
+   * method or function.
+   *
+   * @param node the return statement to evaluate
+   * @return `true` if and only if an error code is generated on the passed node
+   * @see CompileTimeErrorCode#RETURN_IN_GENERATIVE_CONSTRUCTOR
+   * @see StaticWarningCode#RETURN_WITHOUT_VALUE
+   * @see StaticTypeWarningCode#RETURN_OF_INVALID_TYPE
+   */
+  bool _checkForAllReturnStatementErrorCodes(ReturnStatement node) {
+    FunctionType functionType = _enclosingFunction == null ? null : _enclosingFunction.type;
+    DartType expectedReturnType = functionType == null ? DynamicTypeImpl.instance : functionType.returnType;
+    Expression returnExpression = node.expression;
+    // RETURN_IN_GENERATIVE_CONSTRUCTOR
+    bool isGenerativeConstructor = _enclosingFunction is ConstructorElement && !(_enclosingFunction as ConstructorElement).isFactory;
+    if (isGenerativeConstructor) {
+      if (returnExpression == null) {
+        return false;
+      }
+      _errorReporter.reportErrorForNode(CompileTimeErrorCode.RETURN_IN_GENERATIVE_CONSTRUCTOR, returnExpression, []);
+      return true;
+    }
+    // RETURN_WITHOUT_VALUE
+    if (returnExpression == null) {
+      if (VoidTypeImpl.instance.isAssignableTo(expectedReturnType)) {
+        return false;
+      }
+      _hasReturnWithoutValue = true;
+      _errorReporter.reportErrorForNode(StaticWarningCode.RETURN_WITHOUT_VALUE, node, []);
+      return true;
+    } else if (_inGenerator) {
+      // RETURN_IN_GENERATOR
+      _errorReporter.reportErrorForNode(CompileTimeErrorCode.RETURN_IN_GENERATOR, node, []);
+    }
+    // RETURN_OF_INVALID_TYPE
+    return _checkForReturnOfInvalidType(returnExpression, expectedReturnType);
+  }
+
+  /**
+   * This verifies that the export namespace of the passed export directive does not export any name
+   * already exported by other export directive.
+   *
+   * @param node the export directive node to report problem on
+   * @param exportElement the [ExportElement] retrieved from the node, if the element in the
+   *          node was `null`, then this method is not called
+   * @param exportedLibrary the library element containing the exported element
+   * @return `true` if and only if an error code is generated on the passed node
+   * @see CompileTimeErrorCode#AMBIGUOUS_EXPORT
+   */
+  bool _checkForAmbiguousExport(ExportDirective node, ExportElement exportElement, LibraryElement exportedLibrary) {
+    if (exportedLibrary == null) {
+      return false;
+    }
+    // check exported names
+    Namespace namespace = new NamespaceBuilder().createExportNamespaceForDirective(exportElement);
+    Map<String, Element> definedNames = namespace.definedNames;
+    for (String name in definedNames.keys) {
+      Element element = definedNames[name];
+      Element prevElement = _exportedElements[name];
+      if (element != null && prevElement != null && prevElement != element) {
+        _errorReporter.reportErrorForNode(CompileTimeErrorCode.AMBIGUOUS_EXPORT, node, [
+            name,
+            prevElement.library.definingCompilationUnit.displayName,
+            element.library.definingCompilationUnit.displayName]);
+        return true;
+      } else {
+        _exportedElements[name] = element;
+      }
+    }
+    return false;
+  }
+
+  /**
+   * This verifies that the passed expression can be assigned to its corresponding parameters.
+   *
+   * This method corresponds to BestPracticesVerifier.checkForArgumentTypeNotAssignable.
+   *
+   * @param expression the expression to evaluate
+   * @param expectedStaticType the expected static type of the parameter
+   * @param actualStaticType the actual static type of the argument
+   * @param expectedPropagatedType the expected propagated type of the parameter, may be
+   *          `null`
+   * @param actualPropagatedType the expected propagated type of the parameter, may be `null`
+   * @return `true` if and only if an error code is generated on the passed node
+   * @see StaticWarningCode#ARGUMENT_TYPE_NOT_ASSIGNABLE
+   * @see CompileTimeErrorCode#LIST_ELEMENT_TYPE_NOT_ASSIGNABLE
+   * @see StaticWarningCode#LIST_ELEMENT_TYPE_NOT_ASSIGNABLE
+   * @see CompileTimeErrorCode#MAP_KEY_TYPE_NOT_ASSIGNABLE
+   * @see CompileTimeErrorCode#MAP_VALUE_TYPE_NOT_ASSIGNABLE
+   * @see StaticWarningCode#MAP_KEY_TYPE_NOT_ASSIGNABLE
+   * @see StaticWarningCode#MAP_VALUE_TYPE_NOT_ASSIGNABLE
+   */
+  bool _checkForArgumentTypeNotAssignable(Expression expression, DartType expectedStaticType, DartType actualStaticType, ErrorCode errorCode) {
+    //
+    // Warning case: test static type information
+    //
+    if (actualStaticType != null && expectedStaticType != null) {
+      if (!actualStaticType.isAssignableTo(expectedStaticType)) {
+        _errorReporter.reportTypeErrorForNode(errorCode, expression, [actualStaticType, expectedStaticType]);
+        return true;
+      }
+    }
+    return false;
+  }
+
+  /**
+   * This verifies that the passed argument can be assigned to its corresponding parameter.
+   *
+   * This method corresponds to BestPracticesVerifier.checkForArgumentTypeNotAssignableForArgument.
+   *
+   * @param argument the argument to evaluate
+   * @return `true` if and only if an error code is generated on the passed node
+   * @see StaticWarningCode#ARGUMENT_TYPE_NOT_ASSIGNABLE
+   */
+  bool _checkForArgumentTypeNotAssignableForArgument(Expression argument) {
+    if (argument == null) {
+      return false;
+    }
+    ParameterElement staticParameterElement = argument.staticParameterElement;
+    DartType staticParameterType = staticParameterElement == null ? null : staticParameterElement.type;
+    return _checkForArgumentTypeNotAssignableWithExpectedTypes(argument, staticParameterType, StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE);
+  }
+
+  /**
+   * This verifies that the passed expression can be assigned to its corresponding parameters.
+   *
+   * This method corresponds to
+   * BestPracticesVerifier.checkForArgumentTypeNotAssignableWithExpectedTypes.
+   *
+   * @param expression the expression to evaluate
+   * @param expectedStaticType the expected static type
+   * @param expectedPropagatedType the expected propagated type, may be `null`
+   * @return `true` if and only if an error code is generated on the passed node
+   * @see StaticWarningCode#ARGUMENT_TYPE_NOT_ASSIGNABLE
+   * @see CompileTimeErrorCode#LIST_ELEMENT_TYPE_NOT_ASSIGNABLE
+   * @see StaticWarningCode#LIST_ELEMENT_TYPE_NOT_ASSIGNABLE
+   * @see CompileTimeErrorCode#MAP_KEY_TYPE_NOT_ASSIGNABLE
+   * @see CompileTimeErrorCode#MAP_VALUE_TYPE_NOT_ASSIGNABLE
+   * @see StaticWarningCode#MAP_KEY_TYPE_NOT_ASSIGNABLE
+   * @see StaticWarningCode#MAP_VALUE_TYPE_NOT_ASSIGNABLE
+   */
+  bool _checkForArgumentTypeNotAssignableWithExpectedTypes(Expression expression, DartType expectedStaticType, ErrorCode errorCode) => _checkForArgumentTypeNotAssignable(expression, expectedStaticType, getStaticType(expression), errorCode);
+
+  /**
+   * This verifies that the passed arguments can be assigned to their corresponding parameters.
+   *
+   * This method corresponds to BestPracticesVerifier.checkForArgumentTypesNotAssignableInList.
+   *
+   * @param node the arguments to evaluate
+   * @return `true` if and only if an error code is generated on the passed node
+   * @see StaticWarningCode#ARGUMENT_TYPE_NOT_ASSIGNABLE
+   */
+  bool _checkForArgumentTypesNotAssignableInList(ArgumentList argumentList) {
+    if (argumentList == null) {
+      return false;
+    }
+    bool problemReported = false;
+    for (Expression argument in argumentList.arguments) {
+      if (_checkForArgumentTypeNotAssignableForArgument(argument)) {
+        problemReported = true;
+      }
+    }
+    return problemReported;
+  }
+
+  /**
+   * Check that the static type of the given expression is assignable to the given type. If it
+   * isn't, report an error with the given error code.
+   *
+   * @param expression the expression being tested
+   * @param type the type that the expression must be assignable to
+   * @param errorCode the error code to be reported
+   * @param arguments the arguments to pass in when creating the error
+   * @return `true` if an error was reported
+   */
+  bool _checkForAssignability(Expression expression, InterfaceType type, ErrorCode errorCode, List<Object> arguments) {
+    if (expression == null) {
+      return false;
+    }
+    DartType expressionType = expression.staticType;
+    if (expressionType == null) {
+      return false;
+    }
+    if (expressionType.isAssignableTo(type)) {
+      return false;
+    }
+    _errorReporter.reportErrorForNode(errorCode, expression, arguments);
+    return true;
+  }
+
+  /**
+   * This verifies that the passed expression is not final.
+   *
+   * @param node the expression to evaluate
+   * @return `true` if and only if an error code is generated on the passed node
+   * @see StaticWarningCode#ASSIGNMENT_TO_CONST
+   * @see StaticWarningCode#ASSIGNMENT_TO_FINAL
+   * @see StaticWarningCode#ASSIGNMENT_TO_METHOD
+   */
+  bool _checkForAssignmentToFinal(Expression expression) {
+    // prepare element
+    Element element = null;
+    AstNode highlightedNode = expression;
+    if (expression is Identifier) {
+      element = expression.staticElement;
+      if (expression is PrefixedIdentifier) {
+        highlightedNode = expression.identifier;
+      }
+    } else if (expression is PropertyAccess) {
+      PropertyAccess propertyAccess = expression;
+      element = propertyAccess.propertyName.staticElement;
+      highlightedNode = propertyAccess.propertyName;
+    }
+    // check if element is assignable
+    if (element is PropertyAccessorElement) {
+      PropertyAccessorElement accessor = element as PropertyAccessorElement;
+      element = accessor.variable;
+    }
+    if (element is VariableElement) {
+      VariableElement variable = element as VariableElement;
+      if (variable.isConst) {
+        _errorReporter.reportErrorForNode(StaticWarningCode.ASSIGNMENT_TO_CONST, expression, []);
+        return true;
+      }
+      if (variable.isFinal) {
+        if (variable is FieldElementImpl && variable.setter == null && variable.isSynthetic) {
+          _errorReporter.reportErrorForNode(StaticWarningCode.ASSIGNMENT_TO_FINAL_NO_SETTER, highlightedNode, [variable.name, variable.enclosingElement.displayName]);
+          return true;
+        }
+        _errorReporter.reportErrorForNode(StaticWarningCode.ASSIGNMENT_TO_FINAL, highlightedNode, [variable.name]);
+        return true;
+      }
+      return false;
+    }
+    if (element is FunctionElement) {
+      _errorReporter.reportErrorForNode(StaticWarningCode.ASSIGNMENT_TO_FUNCTION, expression, []);
+      return true;
+    }
+    if (element is MethodElement) {
+      _errorReporter.reportErrorForNode(StaticWarningCode.ASSIGNMENT_TO_METHOD, expression, []);
+      return true;
+    }
+    return false;
+  }
+
+  /**
+   * This verifies that the passed identifier is not a keyword, and generates the passed error code
+   * on the identifier if it is a keyword.
+   *
+   * @param identifier the identifier to check to ensure that it is not a keyword
+   * @param errorCode if the passed identifier is a keyword then this error code is created on the
+   *          identifier, the error code will be one of
+   *          [CompileTimeErrorCode#BUILT_IN_IDENTIFIER_AS_TYPE_NAME],
+   *          [CompileTimeErrorCode#BUILT_IN_IDENTIFIER_AS_TYPE_PARAMETER_NAME] or
+   *          [CompileTimeErrorCode#BUILT_IN_IDENTIFIER_AS_TYPEDEF_NAME]
+   * @return `true` if and only if an error code is generated on the passed node
+   * @see CompileTimeErrorCode#BUILT_IN_IDENTIFIER_AS_TYPE_NAME
+   * @see CompileTimeErrorCode#BUILT_IN_IDENTIFIER_AS_TYPE_PARAMETER_NAME
+   * @see CompileTimeErrorCode#BUILT_IN_IDENTIFIER_AS_TYPEDEF_NAME
+   */
+  bool _checkForBuiltInIdentifierAsName(SimpleIdentifier identifier, ErrorCode errorCode) {
+    sc.Token token = identifier.token;
+    if (token.type == sc.TokenType.KEYWORD) {
+      _errorReporter.reportErrorForNode(errorCode, identifier, [identifier.name]);
+      return true;
+    }
+    return false;
+  }
+
+  /**
+   * This verifies that the given switch case is terminated with 'break', 'continue', 'return' or
+   * 'throw'.
+   *
+   * @param node the switch case to evaluate
+   * @return `true` if and only if an error code is generated on the passed node
+   * @see StaticWarningCode#CASE_BLOCK_NOT_TERMINATED
+   */
+  bool _checkForCaseBlockNotTerminated(SwitchCase node) {
+    NodeList<Statement> statements = node.statements;
+    if (statements.isEmpty) {
+      // fall-through without statements at all
+      AstNode parent = node.parent;
+      if (parent is SwitchStatement) {
+        SwitchStatement switchStatement = parent;
+        NodeList<SwitchMember> members = switchStatement.members;
+        int index = members.indexOf(node);
+        if (index != -1 && index < members.length - 1) {
+          return false;
+        }
+      }
+      // no other switch member after this one
+    } else {
+      Statement statement = statements[statements.length - 1];
+      // terminated with statement
+      if (statement is BreakStatement || statement is ContinueStatement || statement is ReturnStatement) {
+        return false;
+      }
+      // terminated with 'throw' expression
+      if (statement is ExpressionStatement) {
+        Expression expression = statement.expression;
+        if (expression is ThrowExpression) {
+          return false;
+        }
+      }
+    }
+    // report error
+    _errorReporter.reportErrorForToken(StaticWarningCode.CASE_BLOCK_NOT_TERMINATED, node.keyword, []);
+    return true;
+  }
+
+  /**
+   * This verifies that the switch cases in the given switch statement is terminated with 'break',
+   * 'continue', 'return' or 'throw'.
+   *
+   * @param node the switch statement containing the cases to be checked
+   * @return `true` if and only if an error code is generated on the passed node
+   * @see StaticWarningCode#CASE_BLOCK_NOT_TERMINATED
+   */
+  bool _checkForCaseBlocksNotTerminated(SwitchStatement node) {
+    bool foundError = false;
+    NodeList<SwitchMember> members = node.members;
+    int lastMember = members.length - 1;
+    for (int i = 0; i < lastMember; i++) {
+      SwitchMember member = members[i];
+      if (member is SwitchCase && _checkForCaseBlockNotTerminated(member)) {
+        foundError = true;
+      }
+    }
+    return foundError;
+  }
+
+  /**
+   * This verifies that the passed method declaration is abstract only if the enclosing class is
+   * also abstract.
+   *
+   * @param node the method declaration to evaluate
+   * @return `true` if and only if an error code is generated on the passed node
+   * @see StaticWarningCode#CONCRETE_CLASS_WITH_ABSTRACT_MEMBER
+   */
+  bool _checkForConcreteClassWithAbstractMember(MethodDeclaration node) {
+    if (node.isAbstract && _enclosingClass != null && !_enclosingClass.isAbstract) {
+      SimpleIdentifier nameNode = node.name;
+      String memberName = nameNode.name;
+      ExecutableElement overriddenMember;
+      if (node.isGetter) {
+        overriddenMember = _enclosingClass.lookUpInheritedConcreteGetter(memberName, _currentLibrary);
+      } else if (node.isSetter) {
+        overriddenMember = _enclosingClass.lookUpInheritedConcreteSetter(memberName, _currentLibrary);
+      } else {
+        overriddenMember = _enclosingClass.lookUpInheritedConcreteMethod(memberName, _currentLibrary);
+      }
+      if (overriddenMember == null) {
+        _errorReporter.reportErrorForNode(StaticWarningCode.CONCRETE_CLASS_WITH_ABSTRACT_MEMBER, nameNode, [memberName, _enclosingClass.displayName]);
+        return true;
+      }
+    }
+    return false;
+  }
+
+  /**
+   * This verifies all possible conflicts of the constructor name with other constructors and
+   * members of the same class.
+   *
+   * @param node the constructor declaration to evaluate
+   * @param constructorElement the constructor element
+   * @return `true` if and only if an error code is generated on the passed node
+   * @see CompileTimeErrorCode#DUPLICATE_CONSTRUCTOR_DEFAULT
+   * @see CompileTimeErrorCode#DUPLICATE_CONSTRUCTOR_NAME
+   * @see CompileTimeErrorCode#CONFLICTING_CONSTRUCTOR_NAME_AND_FIELD
+   * @see CompileTimeErrorCode#CONFLICTING_CONSTRUCTOR_NAME_AND_METHOD
+   */
+  bool _checkForConflictingConstructorNameAndMember(ConstructorDeclaration node, ConstructorElement constructorElement) {
+    SimpleIdentifier constructorName = node.name;
+    String name = constructorElement.name;
+    ClassElement classElement = constructorElement.enclosingElement;
+    // constructors
+    List<ConstructorElement> constructors = classElement.constructors;
+    for (ConstructorElement otherConstructor in constructors) {
+      if (identical(otherConstructor, constructorElement)) {
+        continue;
+      }
+      if (name == otherConstructor.name) {
+        if (name == null || name.length == 0) {
+          _errorReporter.reportErrorForNode(CompileTimeErrorCode.DUPLICATE_CONSTRUCTOR_DEFAULT, node, []);
+        } else {
+          _errorReporter.reportErrorForNode(CompileTimeErrorCode.DUPLICATE_CONSTRUCTOR_NAME, node, [name]);
+        }
+        return true;
+      }
+    }
+    // conflict with class member
+    if (constructorName != null && constructorElement != null && !constructorName.isSynthetic) {
+      // fields
+      FieldElement field = classElement.getField(name);
+      if (field != null) {
+        _errorReporter.reportErrorForNode(CompileTimeErrorCode.CONFLICTING_CONSTRUCTOR_NAME_AND_FIELD, node, [name]);
+        return true;
+      }
+      // methods
+      MethodElement method = classElement.getMethod(name);
+      if (method != null) {
+        _errorReporter.reportErrorForNode(CompileTimeErrorCode.CONFLICTING_CONSTRUCTOR_NAME_AND_METHOD, node, [name]);
+        return true;
+      }
+    }
+    return false;
+  }
+
+  /**
+   * This verifies that the [enclosingClass] does not have a method and getter pair with the
+   * same name on, via inheritance.
+   *
+   * @return `true` if and only if an error code is generated on the passed node
+   * @see CompileTimeErrorCode#CONFLICTING_GETTER_AND_METHOD
+   * @see CompileTimeErrorCode#CONFLICTING_METHOD_AND_GETTER
+   */
+  bool _checkForConflictingGetterAndMethod() {
+    if (_enclosingClass == null) {
+      return false;
+    }
+    bool hasProblem = false;
+    // method declared in the enclosing class vs. inherited getter
+    for (MethodElement method in _enclosingClass.methods) {
+      String name = method.name;
+      // find inherited property accessor (and can be only getter)
+      ExecutableElement inherited = _inheritanceManager.lookupInheritance(_enclosingClass, name);
+      if (inherited is! PropertyAccessorElement) {
+        continue;
+      }
+      // report problem
+      hasProblem = true;
+      _errorReporter.reportErrorForOffset(CompileTimeErrorCode.CONFLICTING_GETTER_AND_METHOD, method.nameOffset, name.length, [
+          _enclosingClass.displayName,
+          inherited.enclosingElement.displayName,
+          name]);
+    }
+    // getter declared in the enclosing class vs. inherited method
+    for (PropertyAccessorElement accessor in _enclosingClass.accessors) {
+      if (!accessor.isGetter) {
+        continue;
+      }
+      String name = accessor.name;
+      // find inherited method
+      ExecutableElement inherited = _inheritanceManager.lookupInheritance(_enclosingClass, name);
+      if (inherited is! MethodElement) {
+        continue;
+      }
+      // report problem
+      hasProblem = true;
+      _errorReporter.reportErrorForOffset(CompileTimeErrorCode.CONFLICTING_METHOD_AND_GETTER, accessor.nameOffset, name.length, [
+          _enclosingClass.displayName,
+          inherited.enclosingElement.displayName,
+          name]);
+    }
+    // done
+    return hasProblem;
+  }
+
+  /**
+   * This verifies that the superclass of the [enclosingClass] does not declare accessible
+   * static members with the same name as the instance getters/setters declared in
+   * [enclosingClass].
+   *
+   * @param node the method declaration to evaluate
+   * @return `true` if and only if an error code is generated on the passed node
+   * @see StaticWarningCode#CONFLICTING_INSTANCE_GETTER_AND_SUPERCLASS_MEMBER
+   * @see StaticWarningCode#CONFLICTING_INSTANCE_SETTER_AND_SUPERCLASS_MEMBER
+   */
+  bool _checkForConflictingInstanceGetterAndSuperclassMember() {
+    if (_enclosingClass == null) {
+      return false;
+    }
+    InterfaceType enclosingType = _enclosingClass.type;
+    // check every accessor
+    bool hasProblem = false;
+    for (PropertyAccessorElement accessor in _enclosingClass.accessors) {
+      // we analyze instance accessors here
+      if (accessor.isStatic) {
+        continue;
+      }
+      // prepare accessor properties
+      String name = accessor.displayName;
+      bool getter = accessor.isGetter;
+      // if non-final variable, ignore setter - we alreay reported problem for getter
+      if (accessor.isSetter && accessor.isSynthetic) {
+        continue;
+      }
+      // try to find super element
+      ExecutableElement superElement;
+      superElement = enclosingType.lookUpGetterInSuperclass(name, _currentLibrary);
+      if (superElement == null) {
+        superElement = enclosingType.lookUpSetterInSuperclass(name, _currentLibrary);
+      }
+      if (superElement == null) {
+        superElement = enclosingType.lookUpMethodInSuperclass(name, _currentLibrary);
+      }
+      if (superElement == null) {
+        continue;
+      }
+      // OK, not static
+      if (!superElement.isStatic) {
+        continue;
+      }
+      // prepare "super" type to report its name
+      ClassElement superElementClass = superElement.enclosingElement as ClassElement;
+      InterfaceType superElementType = superElementClass.type;
+      // report problem
+      hasProblem = true;
+      if (getter) {
+        _errorReporter.reportErrorForElement(StaticWarningCode.CONFLICTING_INSTANCE_GETTER_AND_SUPERCLASS_MEMBER, accessor, [superElementType.displayName]);
+      } else {
+        _errorReporter.reportErrorForElement(StaticWarningCode.CONFLICTING_INSTANCE_SETTER_AND_SUPERCLASS_MEMBER, accessor, [superElementType.displayName]);
+      }
+    }
+    // done
+    return hasProblem;
+  }
+
+  /**
+   * This verifies that the enclosing class does not have a setter with the same name as the passed
+   * instance method declaration.
+   *
+   * TODO(jwren) add other "conflicting" error codes into algorithm/ data structure
+   *
+   * @param node the method declaration to evaluate
+   * @return `true` if and only if an error code is generated on the passed node
+   * @see StaticWarningCode#CONFLICTING_INSTANCE_METHOD_SETTER
+   */
+  bool _checkForConflictingInstanceMethodSetter(ClassDeclaration node) {
+    // Reference all of the class members in this class.
+    NodeList<ClassMember> classMembers = node.members;
+    if (classMembers.isEmpty) {
+      return false;
+    }
+    // Create a HashMap to track conflicting members, and then loop through members in the class to
+    // construct the HashMap, at the same time, look for violations.  Don't add members if they are
+    // part of a conflict, this prevents multiple warnings for one issue.
+    bool foundError = false;
+    HashMap<String, ClassMember> memberHashMap = new HashMap<String, ClassMember>();
+    for (ClassMember classMember in classMembers) {
+      if (classMember is MethodDeclaration) {
+        MethodDeclaration method = classMember;
+        if (method.isStatic) {
+          continue;
+        }
+        // prepare name
+        SimpleIdentifier name = method.name;
+        if (name == null) {
+          continue;
+        }
+        bool addThisMemberToTheMap = true;
+        bool isGetter = method.isGetter;
+        bool isSetter = method.isSetter;
+        bool isOperator = method.isOperator;
+        bool isMethod = !isGetter && !isSetter && !isOperator;
+        // Do lookups in the enclosing class (and the inherited member) if the member is a method or
+        // a setter for StaticWarningCode.CONFLICTING_INSTANCE_METHOD_SETTER warning.
+        if (isMethod) {
+          String setterName = "${name.name}=";
+          Element enclosingElementOfSetter = null;
+          ClassMember conflictingSetter = memberHashMap[setterName];
+          if (conflictingSetter != null) {
+            enclosingElementOfSetter = conflictingSetter.element.enclosingElement;
+          } else {
+            ExecutableElement elementFromInheritance = _inheritanceManager.lookupInheritance(_enclosingClass, setterName);
+            if (elementFromInheritance != null) {
+              enclosingElementOfSetter = elementFromInheritance.enclosingElement;
+            }
+          }
+          if (enclosingElementOfSetter != null) {
+            // report problem
+            _errorReporter.reportErrorForNode(StaticWarningCode.CONFLICTING_INSTANCE_METHOD_SETTER, name, [
+                _enclosingClass.displayName,
+                name.name,
+                enclosingElementOfSetter.displayName]);
+            foundError = true;
+            addThisMemberToTheMap = false;
+          }
+        } else if (isSetter) {
+          String methodName = name.name;
+          ClassMember conflictingMethod = memberHashMap[methodName];
+          if (conflictingMethod != null && conflictingMethod is MethodDeclaration && !conflictingMethod.isGetter) {
+            // report problem
+            _errorReporter.reportErrorForNode(StaticWarningCode.CONFLICTING_INSTANCE_METHOD_SETTER2, name, [_enclosingClass.displayName, name.name]);
+            foundError = true;
+            addThisMemberToTheMap = false;
+          }
+        }
+        // Finally, add this member into the HashMap.
+        if (addThisMemberToTheMap) {
+          if (method.isSetter) {
+            memberHashMap["${name.name}="] = method;
+          } else {
+            memberHashMap[name.name] = method;
+          }
+        }
+      }
+    }
+    return foundError;
+  }
+
+  /**
+   * This verifies that the enclosing class does not have an instance member with the same name as
+   * the passed static getter method declaration.
+   *
+   * @param node the method declaration to evaluate
+   * @return `true` if and only if an error code is generated on the passed node
+   * @see StaticWarningCode#CONFLICTING_STATIC_GETTER_AND_INSTANCE_SETTER
+   */
+  bool _checkForConflictingStaticGetterAndInstanceSetter(MethodDeclaration node) {
+    if (!node.isStatic) {
+      return false;
+    }
+    // prepare name
+    SimpleIdentifier nameNode = node.name;
+    if (nameNode == null) {
+      return false;
+    }
+    String name = nameNode.name;
+    // prepare enclosing type
+    if (_enclosingClass == null) {
+      return false;
+    }
+    InterfaceType enclosingType = _enclosingClass.type;
+    // try to find setter
+    ExecutableElement setter = enclosingType.lookUpSetter(name, _currentLibrary);
+    if (setter == null) {
+      return false;
+    }
+    // OK, also static
+    if (setter.isStatic) {
+      return false;
+    }
+    // prepare "setter" type to report its name
+    ClassElement setterClass = setter.enclosingElement as ClassElement;
+    InterfaceType setterType = setterClass.type;
+    // report problem
+    _errorReporter.reportErrorForNode(StaticWarningCode.CONFLICTING_STATIC_GETTER_AND_INSTANCE_SETTER, nameNode, [setterType.displayName]);
+    return true;
+  }
+
+  /**
+   * This verifies that the enclosing class does not have an instance member with the same name as
+   * the passed static getter method declaration.
+   *
+   * @param node the method declaration to evaluate
+   * @return `true` if and only if an error code is generated on the passed node
+   * @see StaticWarningCode#CONFLICTING_STATIC_SETTER_AND_INSTANCE_MEMBER
+   */
+  bool _checkForConflictingStaticSetterAndInstanceMember(MethodDeclaration node) {
+    if (!node.isStatic) {
+      return false;
+    }
+    // prepare name
+    SimpleIdentifier nameNode = node.name;
+    if (nameNode == null) {
+      return false;
+    }
+    String name = nameNode.name;
+    // prepare enclosing type
+    if (_enclosingClass == null) {
+      return false;
+    }
+    InterfaceType enclosingType = _enclosingClass.type;
+    // try to find member
+    ExecutableElement member;
+    member = enclosingType.lookUpMethod(name, _currentLibrary);
+    if (member == null) {
+      member = enclosingType.lookUpGetter(name, _currentLibrary);
+    }
+    if (member == null) {
+      member = enclosingType.lookUpSetter(name, _currentLibrary);
+    }
+    if (member == null) {
+      return false;
+    }
+    // OK, also static
+    if (member.isStatic) {
+      return false;
+    }
+    // prepare "member" type to report its name
+    ClassElement memberClass = member.enclosingElement as ClassElement;
+    InterfaceType memberType = memberClass.type;
+    // report problem
+    _errorReporter.reportErrorForNode(StaticWarningCode.CONFLICTING_STATIC_SETTER_AND_INSTANCE_MEMBER, nameNode, [memberType.displayName]);
+    return true;
+  }
+
+  /**
+   * This verifies all conflicts between type variable and enclosing class. TODO(scheglov)
+   *
+   * @param node the class declaration to evaluate
+   * @return `true` if and only if an error code is generated on the passed node
+   * @see CompileTimeErrorCode#CONFLICTING_TYPE_VARIABLE_AND_CLASS
+   * @see CompileTimeErrorCode#CONFLICTING_TYPE_VARIABLE_AND_MEMBER
+   */
+  bool _checkForConflictingTypeVariableErrorCodes(ClassDeclaration node) {
+    bool problemReported = false;
+    for (TypeParameterElement typeParameter in _enclosingClass.typeParameters) {
+      String name = typeParameter.name;
+      // name is same as the name of the enclosing class
+      if (_enclosingClass.name == name) {
+        _errorReporter.reportErrorForOffset(CompileTimeErrorCode.CONFLICTING_TYPE_VARIABLE_AND_CLASS, typeParameter.nameOffset, name.length, [name]);
+        problemReported = true;
+      }
+      // check members
+      if (_enclosingClass.getMethod(name) != null || _enclosingClass.getGetter(name) != null || _enclosingClass.getSetter(name) != null) {
+        _errorReporter.reportErrorForOffset(CompileTimeErrorCode.CONFLICTING_TYPE_VARIABLE_AND_MEMBER, typeParameter.nameOffset, name.length, [name]);
+        problemReported = true;
+      }
+    }
+    return problemReported;
+  }
+
+  /**
+   * This verifies that if the passed constructor declaration is 'const' then there are no
+   * invocations of non-'const' super constructors.
+   *
+   * @param node the constructor declaration to evaluate
+   * @return `true` if and only if an error code is generated on the passed node
+   * @see CompileTimeErrorCode#CONST_CONSTRUCTOR_WITH_NON_CONST_SUPER
+   */
+  bool _checkForConstConstructorWithNonConstSuper(ConstructorDeclaration node) {
+    if (!_isEnclosingConstructorConst) {
+      return false;
+    }
+    // OK, const factory, checked elsewhere
+    if (node.factoryKeyword != null) {
+      return false;
+    }
+    // check for mixins
+    if (_enclosingClass.mixins.length != 0) {
+      _errorReporter.reportErrorForNode(CompileTimeErrorCode.CONST_CONSTRUCTOR_WITH_MIXIN, node.returnType, []);
+      return true;
+    }
+    // try to find and check super constructor invocation
+    for (ConstructorInitializer initializer in node.initializers) {
+      if (initializer is SuperConstructorInvocation) {
+        SuperConstructorInvocation superInvocation = initializer;
+        ConstructorElement element = superInvocation.staticElement;
+        if (element == null || element.isConst) {
+          return false;
+        }
+        _errorReporter.reportErrorForNode(CompileTimeErrorCode.CONST_CONSTRUCTOR_WITH_NON_CONST_SUPER, superInvocation, [element.enclosingElement.displayName]);
+        return true;
+      }
+    }
+    // no explicit super constructor invocation, check default constructor
+    InterfaceType supertype = _enclosingClass.supertype;
+    if (supertype == null) {
+      return false;
+    }
+    if (supertype.isObject) {
+      return false;
+    }
+    ConstructorElement unnamedConstructor = supertype.element.unnamedConstructor;
+    if (unnamedConstructor == null) {
+      return false;
+    }
+    if (unnamedConstructor.isConst) {
+      return false;
+    }
+    // default constructor is not 'const', report problem
+    _errorReporter.reportErrorForNode(CompileTimeErrorCode.CONST_CONSTRUCTOR_WITH_NON_CONST_SUPER, node.returnType, [supertype.displayName]);
+    return true;
+  }
+
+  /**
+   * This verifies that if the passed constructor declaration is 'const' then there are no non-final
+   * instance variable.
+   *
+   * @param node the constructor declaration to evaluate
+   * @param constructorElement the constructor element
+   * @return `true` if and only if an error code is generated on the passed node
+   * @see CompileTimeErrorCode#CONST_CONSTRUCTOR_WITH_NON_FINAL_FIELD
+   */
+  bool _checkForConstConstructorWithNonFinalField(ConstructorDeclaration node, ConstructorElement constructorElement) {
+    if (!_isEnclosingConstructorConst) {
+      return false;
+    }
+    // check if there is non-final field
+    ClassElement classElement = constructorElement.enclosingElement;
+    if (!classElement.hasNonFinalField) {
+      return false;
+    }
+    // report problem
+    _errorReporter.reportErrorForNode(CompileTimeErrorCode.CONST_CONSTRUCTOR_WITH_NON_FINAL_FIELD, node, []);
+    return true;
+  }
+
+  /**
+   * This verifies that the passed 'const' instance creation expression is not creating a deferred
+   * type.
+   *
+   * @param node the instance creation expression to evaluate
+   * @param constructorName the constructor name, always non-`null`
+   * @param typeName the name of the type defining the constructor, always non-`null`
+   * @return `true` if and only if an error code is generated on the passed node
+   * @see CompileTimeErrorCode#CONST_DEFERRED_CLASS
+   */
+  bool _checkForConstDeferredClass(InstanceCreationExpression node, ConstructorName constructorName, TypeName typeName) {
+    if (typeName.isDeferred) {
+      _errorReporter.reportErrorForNode(CompileTimeErrorCode.CONST_DEFERRED_CLASS, constructorName, [typeName.name.name]);
+      return true;
+    }
+    return false;
+  }
+
+  /**
+   * This verifies that the passed throw expression is not enclosed in a 'const' constructor
+   * declaration.
+   *
+   * @param node the throw expression expression to evaluate
+   * @return `true` if and only if an error code is generated on the passed node
+   * @see CompileTimeErrorCode#CONST_CONSTRUCTOR_THROWS_EXCEPTION
+   */
+  bool _checkForConstEvalThrowsException(ThrowExpression node) {
+    if (_isEnclosingConstructorConst) {
+      _errorReporter.reportErrorForNode(CompileTimeErrorCode.CONST_CONSTRUCTOR_THROWS_EXCEPTION, node, []);
+      return true;
+    }
+    return false;
+  }
+
+  /**
+   * This verifies that the passed normal formal parameter is not 'const'.
+   *
+   * @param node the normal formal parameter to evaluate
+   * @return `true` if and only if an error code is generated on the passed node
+   * @see CompileTimeErrorCode#CONST_FORMAL_PARAMETER
+   */
+  bool _checkForConstFormalParameter(NormalFormalParameter node) {
+    if (node.isConst) {
+      _errorReporter.reportErrorForNode(CompileTimeErrorCode.CONST_FORMAL_PARAMETER, node, []);
+      return true;
+    }
+    return false;
+  }
+
+  /**
+   * This verifies that the passed instance creation expression is not being invoked on an abstract
+   * class.
+   *
+   * @param node the instance creation expression to evaluate
+   * @param typeName the [TypeName] of the [ConstructorName] from the
+   *          [InstanceCreationExpression], this is the AST node that the error is attached to
+   * @param type the type being constructed with this [InstanceCreationExpression]
+   * @return `true` if and only if an error code is generated on the passed node
+   * @see StaticWarningCode#CONST_WITH_ABSTRACT_CLASS
+   * @see StaticWarningCode#NEW_WITH_ABSTRACT_CLASS
+   */
+  bool _checkForConstOrNewWithAbstractClass(InstanceCreationExpression node, TypeName typeName, InterfaceType type) {
+    if (type.element.isAbstract) {
+      ConstructorElement element = node.staticElement;
+      if (element != null && !element.isFactory) {
+        if ((node.keyword as sc.KeywordToken).keyword == sc.Keyword.CONST) {
+          _errorReporter.reportErrorForNode(StaticWarningCode.CONST_WITH_ABSTRACT_CLASS, typeName, []);
+        } else {
+          _errorReporter.reportErrorForNode(StaticWarningCode.NEW_WITH_ABSTRACT_CLASS, typeName, []);
+        }
+        return true;
+      }
+    }
+    return false;
+  }
+
+  /**
+   * This verifies that the passed instance creation expression is not being invoked on an enum.
+   *
+   * @param node the instance creation expression to verify
+   * @param typeName the [TypeName] of the [ConstructorName] from the
+   *          [InstanceCreationExpression], this is the AST node that the error is attached to
+   * @param type the type being constructed with this [InstanceCreationExpression]
+   * @return `true` if and only if an error code is generated on the passed node
+   * @see CompileTimeErrorCode#INSTANTIATE_ENUM
+   */
+  bool _checkForConstOrNewWithEnum(InstanceCreationExpression node, TypeName typeName, InterfaceType type) {
+    if (type.element.isEnum) {
+      _errorReporter.reportErrorForNode(CompileTimeErrorCode.INSTANTIATE_ENUM, typeName, []);
+      return true;
+    }
+    return false;
+  }
+
+  /**
+   * This verifies that the passed 'const' instance creation expression is not being invoked on a
+   * constructor that is not 'const'.
+   *
+   * This method assumes that the instance creation was tested to be 'const' before being called.
+   *
+   * @param node the instance creation expression to verify
+   * @return `true` if and only if an error code is generated on the passed node
+   * @see CompileTimeErrorCode#CONST_WITH_NON_CONST
+   */
+  bool _checkForConstWithNonConst(InstanceCreationExpression node) {
+    ConstructorElement constructorElement = node.staticElement;
+    if (constructorElement != null && !constructorElement.isConst) {
+      _errorReporter.reportErrorForNode(CompileTimeErrorCode.CONST_WITH_NON_CONST, node, []);
+      return true;
+    }
+    return false;
+  }
+
+  /**
+   * This verifies that the passed type name does not reference any type parameters.
+   *
+   * @param typeName the type name to evaluate
+   * @return `true` if and only if an error code is generated on the passed node
+   * @see CompileTimeErrorCode#CONST_WITH_TYPE_PARAMETERS
+   */
+  bool _checkForConstWithTypeParameters(TypeName typeName) {
+    // something wrong with AST
+    if (typeName == null) {
+      return false;
+    }
+    Identifier name = typeName.name;
+    if (name == null) {
+      return false;
+    }
+    // should not be a type parameter
+    if (name.staticElement is TypeParameterElement) {
+      _errorReporter.reportErrorForNode(CompileTimeErrorCode.CONST_WITH_TYPE_PARAMETERS, name, []);
+    }
+    // check type arguments
+    TypeArgumentList typeArguments = typeName.typeArguments;
+    if (typeArguments != null) {
+      bool hasError = false;
+      for (TypeName argument in typeArguments.arguments) {
+        if (_checkForConstWithTypeParameters(argument)) {
+          hasError = true;
+        }
+      }
+      return hasError;
+    }
+    // OK
+    return false;
+  }
+
+  /**
+   * This verifies that if the passed 'const' instance creation expression is being invoked on the
+   * resolved constructor.
+   *
+   * This method assumes that the instance creation was tested to be 'const' before being called.
+   *
+   * @param node the instance creation expression to evaluate
+   * @param constructorName the constructor name, always non-`null`
+   * @param typeName the name of the type defining the constructor, always non-`null`
+   * @return `true` if and only if an error code is generated on the passed node
+   * @see CompileTimeErrorCode#CONST_WITH_UNDEFINED_CONSTRUCTOR
+   * @see CompileTimeErrorCode#CONST_WITH_UNDEFINED_CONSTRUCTOR_DEFAULT
+   */
+  bool _checkForConstWithUndefinedConstructor(InstanceCreationExpression node, ConstructorName constructorName, TypeName typeName) {
+    // OK if resolved
+    if (node.staticElement != null) {
+      return false;
+    }
+    DartType type = typeName.type;
+    if (type is InterfaceType) {
+      ClassElement element = type.element;
+      if (element != null && element.isEnum) {
+        // We have already reported the error.
+        return false;
+      }
+    }
+    Identifier className = typeName.name;
+    // report as named or default constructor absence
+    SimpleIdentifier name = constructorName.name;
+    if (name != null) {
+      _errorReporter.reportErrorForNode(CompileTimeErrorCode.CONST_WITH_UNDEFINED_CONSTRUCTOR, name, [className, name]);
+    } else {
+      _errorReporter.reportErrorForNode(CompileTimeErrorCode.CONST_WITH_UNDEFINED_CONSTRUCTOR_DEFAULT, constructorName, [className]);
+    }
+    return true;
+  }
+
+  /**
+   * This verifies that there are no default parameters in the passed function type alias.
+   *
+   * @param node the function type alias to evaluate
+   * @return `true` if and only if an error code is generated on the passed node
+   * @see CompileTimeErrorCode#DEFAULT_VALUE_IN_FUNCTION_TYPE_ALIAS
+   */
+  bool _checkForDefaultValueInFunctionTypeAlias(FunctionTypeAlias node) {
+    bool result = false;
+    FormalParameterList formalParameterList = node.parameters;
+    NodeList<FormalParameter> parameters = formalParameterList.parameters;
+    for (FormalParameter formalParameter in parameters) {
+      if (formalParameter is DefaultFormalParameter) {
+        DefaultFormalParameter defaultFormalParameter = formalParameter;
+        if (defaultFormalParameter.defaultValue != null) {
+          _errorReporter.reportErrorForNode(CompileTimeErrorCode.DEFAULT_VALUE_IN_FUNCTION_TYPE_ALIAS, node, []);
+          result = true;
+        }
+      }
+    }
+    return result;
+  }
+
+  /**
+   * This verifies that the given default formal parameter is not part of a function typed
+   * parameter.
+   *
+   * @param node the default formal parameter to evaluate
+   * @return `true` if and only if an error code is generated on the passed node
+   * @see CompileTimeErrorCode#DEFAULT_VALUE_IN_FUNCTION_TYPED_PARAMETER
+   */
+  bool _checkForDefaultValueInFunctionTypedParameter(DefaultFormalParameter node) {
+    // OK, not in a function typed parameter.
+    if (!_isInFunctionTypedFormalParameter) {
+      return false;
+    }
+    // OK, no default value.
+    if (node.defaultValue == null) {
+      return false;
+    }
+    // Report problem.
+    _errorReporter.reportErrorForNode(CompileTimeErrorCode.DEFAULT_VALUE_IN_FUNCTION_TYPED_PARAMETER, node, []);
+    return true;
+  }
+
+  /**
+   * This verifies that any deferred imports in the given compilation unit have a unique prefix.
+   *
+   * @param node the compilation unit containing the imports to be checked
+   * @return `true` if an error was generated
+   * @see CompileTimeErrorCode#SHARED_DEFERRED_PREFIX
+   */
+  bool _checkForDeferredPrefixCollisions(CompilationUnit node) {
+    bool foundError = false;
+    NodeList<Directive> directives = node.directives;
+    int count = directives.length;
+    if (count > 0) {
+      HashMap<PrefixElement, List<ImportDirective>> prefixToDirectivesMap = new HashMap<PrefixElement, List<ImportDirective>>();
+      for (int i = 0; i < count; i++) {
+        Directive directive = directives[i];
+        if (directive is ImportDirective) {
+          ImportDirective importDirective = directive;
+          SimpleIdentifier prefix = importDirective.prefix;
+          if (prefix != null) {
+            Element element = prefix.staticElement;
+            if (element is PrefixElement) {
+              PrefixElement prefixElement = element;
+              List<ImportDirective> elements = prefixToDirectivesMap[prefixElement];
+              if (elements == null) {
+                elements = new List<ImportDirective>();
+                prefixToDirectivesMap[prefixElement] = elements;
+              }
+              elements.add(importDirective);
+            }
+          }
+        }
+      }
+      for (List<ImportDirective> imports in prefixToDirectivesMap.values) {
+        if (_hasDeferredPrefixCollision(imports)) {
+          foundError = true;
+        }
+      }
+    }
+    return foundError;
+  }
+
+  /**
+   * This verifies that the enclosing class does not have an instance member with the given name of
+   * the static member.
+   *
+   * @return `true` if and only if an error code is generated on the passed node
+   * @see CompileTimeErrorCode#DUPLICATE_DEFINITION_INHERITANCE
+   */
+  bool _checkForDuplicateDefinitionInheritance() {
+    if (_enclosingClass == null) {
+      return false;
+    }
+    bool hasProblem = false;
+    for (ExecutableElement member in _enclosingClass.methods) {
+      if (member.isStatic && _checkForDuplicateDefinitionOfMember(member)) {
+        hasProblem = true;
+      }
+    }
+    for (ExecutableElement member in _enclosingClass.accessors) {
+      if (member.isStatic && _checkForDuplicateDefinitionOfMember(member)) {
+        hasProblem = true;
+      }
+    }
+    return hasProblem;
+  }
+
+  /**
+   * This verifies that the enclosing class does not have an instance member with the given name of
+   * the static member.
+   *
+   * @param staticMember the static member to check conflict for
+   * @return `true` if and only if an error code is generated on the passed node
+   * @see CompileTimeErrorCode#DUPLICATE_DEFINITION_INHERITANCE
+   */
+  bool _checkForDuplicateDefinitionOfMember(ExecutableElement staticMember) {
+    // prepare name
+    String name = staticMember.name;
+    if (name == null) {
+      return false;
+    }
+    // try to find member
+    ExecutableElement inheritedMember = _inheritanceManager.lookupInheritance(_enclosingClass, name);
+    if (inheritedMember == null) {
+      return false;
+    }
+    // OK, also static
+    if (inheritedMember.isStatic) {
+      return false;
+    }
+    // determine the display name, use the extended display name if the enclosing class of the
+    // inherited member is in a different source
+    String displayName;
+    Element enclosingElement = inheritedMember.enclosingElement;
+    if (enclosingElement.source == _enclosingClass.source) {
+      displayName = enclosingElement.displayName;
+    } else {
+      displayName = enclosingElement.getExtendedDisplayName(null);
+    }
+    // report problem
+    _errorReporter.reportErrorForOffset(CompileTimeErrorCode.DUPLICATE_DEFINITION_INHERITANCE, staticMember.nameOffset, name.length, [name, displayName]);
+    return true;
+  }
+
+  /**
+   * This verifies if the passed list literal has type arguments then there is exactly one.
+   *
+   * @param node the list literal to evaluate
+   * @param typeArguments the type arguments, always non-`null`
+   * @return `true` if and only if an error code is generated on the passed node
+   * @see StaticTypeWarningCode#EXPECTED_ONE_LIST_TYPE_ARGUMENTS
+   */
+  bool _checkForExpectedOneListTypeArgument(ListLiteral node, TypeArgumentList typeArguments) {
+    // check number of type arguments
+    int num = typeArguments.arguments.length;
+    if (num == 1) {
+      return false;
+    }
+    // report problem
+    _errorReporter.reportErrorForNode(StaticTypeWarningCode.EXPECTED_ONE_LIST_TYPE_ARGUMENTS, typeArguments, [num]);
+    return true;
+  }
+
+  /**
+   * This verifies the passed import has unique name among other exported libraries.
+   *
+   * @param node the export directive to evaluate
+   * @param exportElement the [ExportElement] retrieved from the node, if the element in the
+   *          node was `null`, then this method is not called
+   * @param exportedLibrary the library element containing the exported element
+   * @return `true` if and only if an error code is generated on the passed node
+   * @see CompileTimeErrorCode#EXPORT_DUPLICATED_LIBRARY_NAME
+   */
+  bool _checkForExportDuplicateLibraryName(ExportDirective node, ExportElement exportElement, LibraryElement exportedLibrary) {
+    if (exportedLibrary == null) {
+      return false;
+    }
+    String name = exportedLibrary.name;
+    // check if there is other exported library with the same name
+    LibraryElement prevLibrary = _nameToExportElement[name];
+    if (prevLibrary != null) {
+      if (prevLibrary != exportedLibrary) {
+        _errorReporter.reportErrorForNode(StaticWarningCode.EXPORT_DUPLICATED_LIBRARY_NAME, node, [
+            prevLibrary.definingCompilationUnit.displayName,
+            exportedLibrary.definingCompilationUnit.displayName,
+            name]);
+        return true;
+      }
+    } else {
+      _nameToExportElement[name] = exportedLibrary;
+    }
+    // OK
+    return false;
+  }
+
+  /**
+   * Check that if the visiting library is not system, then any passed library should not be SDK
+   * internal library.
+   *
+   * @param node the export directive to evaluate
+   * @param exportElement the [ExportElement] retrieved from the node, if the element in the
+   *          node was `null`, then this method is not called
+   * @return `true` if and only if an error code is generated on the passed node
+   * @see CompileTimeErrorCode#EXPORT_INTERNAL_LIBRARY
+   */
+  bool _checkForExportInternalLibrary(ExportDirective node, ExportElement exportElement) {
+    if (_isInSystemLibrary) {
+      return false;
+    }
+    // should be private
+    DartSdk sdk = _currentLibrary.context.sourceFactory.dartSdk;
+    String uri = exportElement.uri;
+    SdkLibrary sdkLibrary = sdk.getSdkLibrary(uri);
+    if (sdkLibrary == null) {
+      return false;
+    }
+    if (!sdkLibrary.isInternal) {
+      return false;
+    }
+    // report problem
+    _errorReporter.reportErrorForNode(CompileTimeErrorCode.EXPORT_INTERNAL_LIBRARY, node, [node.uri]);
+    return true;
+  }
+
+  /**
+   * This verifies that the passed extends clause does not extend a deferred class.
+   *
+   * @param node the extends clause to test
+   * @return `true` if and only if an error code is generated on the passed node
+   * @see CompileTimeErrorCode#EXTENDS_DEFERRED_CLASS
+   */
+  bool _checkForExtendsDeferredClass(ExtendsClause node) {
+    if (node == null) {
+      return false;
+    }
+    return _checkForExtendsOrImplementsDeferredClass(node.superclass, CompileTimeErrorCode.EXTENDS_DEFERRED_CLASS);
+  }
+
+  /**
+   * This verifies that the passed type alias does not extend a deferred class.
+   *
+   * @param node the extends clause to test
+   * @return `true` if and only if an error code is generated on the passed node
+   * @see CompileTimeErrorCode#EXTENDS_DISALLOWED_CLASS
+   */
+  bool _checkForExtendsDeferredClassInTypeAlias(ClassTypeAlias node) {
+    if (node == null) {
+      return false;
+    }
+    return _checkForExtendsOrImplementsDeferredClass(node.superclass, CompileTimeErrorCode.EXTENDS_DEFERRED_CLASS);
+  }
+
+  /**
+   * This verifies that the passed extends clause does not extend classes such as num or String.
+   *
+   * @param node the extends clause to test
+   * @return `true` if and only if an error code is generated on the passed node
+   * @see CompileTimeErrorCode#EXTENDS_DISALLOWED_CLASS
+   */
+  bool _checkForExtendsDisallowedClass(ExtendsClause node) {
+    if (node == null) {
+      return false;
+    }
+    return _checkForExtendsOrImplementsDisallowedClass(node.superclass, CompileTimeErrorCode.EXTENDS_DISALLOWED_CLASS);
+  }
+
+  /**
+   * This verifies that the passed type alias does not extend classes such as num or String.
+   *
+   * @param node the extends clause to test
+   * @return `true` if and only if an error code is generated on the passed node
+   * @see CompileTimeErrorCode#EXTENDS_DISALLOWED_CLASS
+   */
+  bool _checkForExtendsDisallowedClassInTypeAlias(ClassTypeAlias node) {
+    if (node == null) {
+      return false;
+    }
+    return _checkForExtendsOrImplementsDisallowedClass(node.superclass, CompileTimeErrorCode.EXTENDS_DISALLOWED_CLASS);
+  }
+
+  /**
+   * This verifies that the passed type name does not extend, implement or mixin classes that are
+   * deferred.
+   *
+   * @param node the type name to test
+   * @return `true` if and only if an error code is generated on the passed node
+   * @see #checkForExtendsDeferredClass(ExtendsClause)
+   * @see #checkForExtendsDeferredClassInTypeAlias(ClassTypeAlias)
+   * @see #checkForImplementsDeferredClass(ImplementsClause)
+   * @see #checkForAllMixinErrorCodes(WithClause)
+   * @see CompileTimeErrorCode#EXTENDS_DEFERRED_CLASS
+   * @see CompileTimeErrorCode#IMPLEMENTS_DEFERRED_CLASS
+   * @see CompileTimeErrorCode#MIXIN_DEFERRED_CLASS
+   */
+  bool _checkForExtendsOrImplementsDeferredClass(TypeName typeName, ErrorCode errorCode) {
+    if (typeName.isSynthetic) {
+      return false;
+    }
+    if (typeName.isDeferred) {
+      _errorReporter.reportErrorForNode(errorCode, typeName, [typeName.name.name]);
+      return true;
+    }
+    return false;
+  }
+
+  /**
+   * This verifies that the passed type name does not extend, implement or mixin classes such as
+   * 'num' or 'String'.
+   *
+   * @param node the type name to test
+   * @return `true` if and only if an error code is generated on the passed node
+   * @see #checkForExtendsDisallowedClass(ExtendsClause)
+   * @see #checkForExtendsDisallowedClassInTypeAlias(ClassTypeAlias)
+   * @see #checkForImplementsDisallowedClass(ImplementsClause)
+   * @see #checkForAllMixinErrorCodes(WithClause)
+   * @see CompileTimeErrorCode#EXTENDS_DISALLOWED_CLASS
+   * @see CompileTimeErrorCode#IMPLEMENTS_DISALLOWED_CLASS
+   * @see CompileTimeErrorCode#MIXIN_OF_DISALLOWED_CLASS
+   */
+  bool _checkForExtendsOrImplementsDisallowedClass(TypeName typeName, ErrorCode errorCode) {
+    if (typeName.isSynthetic) {
+      return false;
+    }
+    DartType superType = typeName.type;
+    for (InterfaceType disallowedType in _DISALLOWED_TYPES_TO_EXTEND_OR_IMPLEMENT) {
+      if (superType != null && superType == disallowedType) {
+        // if the violating type happens to be 'num', we need to rule out the case where the
+        // enclosing class is 'int' or 'double'
+        if (superType == _typeProvider.numType) {
+          AstNode grandParent = typeName.parent.parent;
+          // Note: this is a corner case that won't happen often, so adding a field currentClass
+          // (see currentFunction) to ErrorVerifier isn't worth if for this case, but if the field
+          // currentClass is added, then this message should become a todo to not lookup the
+          // grandparent node
+          if (grandParent is ClassDeclaration) {
+            ClassElement classElement = grandParent.element;
+            DartType classType = classElement.type;
+            if (classType != null && (classType == _intType || classType == _typeProvider.doubleType)) {
+              return false;
+            }
+          }
+        }
+        // otherwise, report the error
+        _errorReporter.reportErrorForNode(errorCode, typeName, [disallowedType.displayName]);
+        return true;
+      }
+    }
+    return false;
+  }
+
+  /**
+   * This verifies that the passed constructor field initializer has compatible field and
+   * initializer expression types.
+   *
+   * @param node the constructor field initializer to test
+   * @param staticElement the static element from the name in the
+   *          [ConstructorFieldInitializer]
+   * @return `true` if and only if an error code is generated on the passed node
+   * @see CompileTimeErrorCode#CONST_FIELD_INITIALIZER_NOT_ASSIGNABLE
+   * @see StaticWarningCode#FIELD_INITIALIZER_NOT_ASSIGNABLE
+   */
+  bool _checkForFieldInitializerNotAssignable(ConstructorFieldInitializer node, Element staticElement) {
+    // prepare field element
+    if (staticElement is! FieldElement) {
+      return false;
+    }
+    FieldElement fieldElement = staticElement as FieldElement;
+    // prepare field type
+    DartType fieldType = fieldElement.type;
+    // prepare expression type
+    Expression expression = node.expression;
+    if (expression == null) {
+      return false;
+    }
+    // test the static type of the expression
+    DartType staticType = getStaticType(expression);
+    if (staticType == null) {
+      return false;
+    }
+    if (staticType.isAssignableTo(fieldType)) {
+      return false;
+    }
+    // report problem
+    if (_isEnclosingConstructorConst) {
+      // TODO(paulberry): this error should be based on the actual type of the constant, not the
+      // static type.  See dartbug.com/21119.
+      _errorReporter.reportTypeErrorForNode(CheckedModeCompileTimeErrorCode.CONST_FIELD_INITIALIZER_NOT_ASSIGNABLE, expression, [staticType, fieldType]);
+    }
+    _errorReporter.reportTypeErrorForNode(StaticWarningCode.FIELD_INITIALIZER_NOT_ASSIGNABLE, expression, [staticType, fieldType]);
+    return true;
+    // TODO(brianwilkerson) Define a hint corresponding to these errors and report it if appropriate.
+    //    // test the propagated type of the expression
+    //    Type propagatedType = expression.getPropagatedType();
+    //    if (propagatedType != null && propagatedType.isAssignableTo(fieldType)) {
+    //      return false;
+    //    }
+    //    // report problem
+    //    if (isEnclosingConstructorConst) {
+    //      errorReporter.reportTypeErrorForNode(
+    //          CompileTimeErrorCode.CONST_FIELD_INITIALIZER_NOT_ASSIGNABLE,
+    //          expression,
+    //          propagatedType == null ? staticType : propagatedType,
+    //          fieldType);
+    //    } else {
+    //      errorReporter.reportTypeErrorForNode(
+    //          StaticWarningCode.FIELD_INITIALIZER_NOT_ASSIGNABLE,
+    //          expression,
+    //          propagatedType == null ? staticType : propagatedType,
+    //          fieldType);
+    //    }
+    //    return true;
+  }
+
+  /**
+   * This verifies that the passed field formal parameter is in a constructor declaration.
+   *
+   * @param node the field formal parameter to test
+   * @return `true` if and only if an error code is generated on the passed node
+   * @see CompileTimeErrorCode#FIELD_INITIALIZER_OUTSIDE_CONSTRUCTOR
+   */
+  bool _checkForFieldInitializingFormalRedirectingConstructor(FieldFormalParameter node) {
+    ConstructorDeclaration constructor = node.getAncestor((node) => node is ConstructorDeclaration);
+    if (constructor == null) {
+      _errorReporter.reportErrorForNode(CompileTimeErrorCode.FIELD_INITIALIZER_OUTSIDE_CONSTRUCTOR, node, []);
+      return true;
+    }
+    // constructor cannot be a factory
+    if (constructor.factoryKeyword != null) {
+      _errorReporter.reportErrorForNode(CompileTimeErrorCode.FIELD_INITIALIZER_FACTORY_CONSTRUCTOR, node, []);
+      return true;
+    }
+    // constructor cannot have a redirection
+    for (ConstructorInitializer initializer in constructor.initializers) {
+      if (initializer is RedirectingConstructorInvocation) {
+        _errorReporter.reportErrorForNode(CompileTimeErrorCode.FIELD_INITIALIZER_REDIRECTING_CONSTRUCTOR, node, []);
+        return true;
+      }
+    }
+    // OK
+    return false;
+  }
+
+  /**
+   * This verifies that the passed variable declaration list has only initialized variables if the
+   * list is final or const. This method is called by
+   * [checkForFinalNotInitializedInClass],
+   * [visitTopLevelVariableDeclaration] and
+   * [visitVariableDeclarationStatement].
+   *
+   * @param node the class declaration to test
+   * @return `true` if and only if an error code is generated on the passed node
+   * @see CompileTimeErrorCode#CONST_NOT_INITIALIZED
+   * @see StaticWarningCode#FINAL_NOT_INITIALIZED
+   */
+  bool _checkForFinalNotInitialized(VariableDeclarationList node) {
+    if (_isInNativeClass) {
+      return false;
+    }
+    bool foundError = false;
+    if (!node.isSynthetic) {
+      NodeList<VariableDeclaration> variables = node.variables;
+      for (VariableDeclaration variable in variables) {
+        if (variable.initializer == null) {
+          if (node.isConst) {
+            _errorReporter.reportErrorForNode(CompileTimeErrorCode.CONST_NOT_INITIALIZED, variable.name, [variable.name.name]);
+          } else if (node.isFinal) {
+            _errorReporter.reportErrorForNode(StaticWarningCode.FINAL_NOT_INITIALIZED, variable.name, [variable.name.name]);
+          }
+          foundError = true;
+        }
+      }
+    }
+    return foundError;
+  }
+
+  /**
+   * This verifies that final fields that are declared, without any constructors in the enclosing
+   * class, are initialized. Cases in which there is at least one constructor are handled at the end
+   * of [checkForAllFinalInitializedErrorCodes].
+   *
+   * @param node the class declaration to test
+   * @return `true` if and only if an error code is generated on the passed node
+   * @see CompileTimeErrorCode#CONST_NOT_INITIALIZED
+   * @see StaticWarningCode#FINAL_NOT_INITIALIZED
+   */
+  bool _checkForFinalNotInitializedInClass(ClassDeclaration node) {
+    NodeList<ClassMember> classMembers = node.members;
+    for (ClassMember classMember in classMembers) {
+      if (classMember is ConstructorDeclaration) {
+        return false;
+      }
+    }
+    bool foundError = false;
+    for (ClassMember classMember in classMembers) {
+      if (classMember is FieldDeclaration
+          && _checkForFinalNotInitialized(classMember.fields)) {
+        foundError = true;
+      }
+    }
+    return foundError;
+  }
+
+  /**
+   * This verifies that the passed implements clause does not implement classes that are deferred.
+   *
+   * @param node the implements clause to test
+   * @return `true` if and only if an error code is generated on the passed node
+   * @see CompileTimeErrorCode#IMPLEMENTS_DEFERRED_CLASS
+   */
+  bool _checkForImplementsDeferredClass(ImplementsClause node) {
+    if (node == null) {
+      return false;
+    }
+    bool foundError = false;
+    for (TypeName type in node.interfaces) {
+      if (_checkForExtendsOrImplementsDeferredClass(
+          type,
+          CompileTimeErrorCode.IMPLEMENTS_DEFERRED_CLASS)) {
+        foundError = true;
+      }
+    }
+    return foundError;
+  }
+
+  /**
+   * This verifies that the passed implements clause does not implement classes such as 'num' or
+   * 'String'.
+   *
+   * @param node the implements clause to test
+   * @return `true` if and only if an error code is generated on the passed node
+   * @see CompileTimeErrorCode#IMPLEMENTS_DISALLOWED_CLASS
+   */
+  bool _checkForImplementsDisallowedClass(ImplementsClause node) {
+    if (node == null) {
+      return false;
+    }
+    bool foundError = false;
+    for (TypeName type in node.interfaces) {
+      if (_checkForExtendsOrImplementsDisallowedClass(
+          type,
+          CompileTimeErrorCode.IMPLEMENTS_DISALLOWED_CLASS)) {
+        foundError = true;
+      }
+    }
+    return foundError;
+  }
+
+  /**
+   * This verifies that if the passed identifier is part of constructor initializer, then it does
+   * not reference implicitly 'this' expression.
+   *
+   * @param node the simple identifier to test
+   * @return `true` if and only if an error code is generated on the passed node
+   * @see CompileTimeErrorCode#IMPLICIT_THIS_REFERENCE_IN_INITIALIZER
+   * @see CompileTimeErrorCode#INSTANCE_MEMBER_ACCESS_FROM_STATIC TODO(scheglov) rename thid method
+   */
+  bool _checkForImplicitThisReferenceInInitializer(SimpleIdentifier node) {
+    if (!_isInConstructorInitializer && !_isInStaticMethod && !_isInFactory && !_isInInstanceVariableInitializer && !_isInStaticVariableDeclaration) {
+      return false;
+    }
+    // prepare element
+    Element element = node.staticElement;
+    if (!(element is MethodElement || element is PropertyAccessorElement)) {
+      return false;
+    }
+    // static element
+    ExecutableElement executableElement = element as ExecutableElement;
+    if (executableElement.isStatic) {
+      return false;
+    }
+    // not a class member
+    Element enclosingElement = element.enclosingElement;
+    if (enclosingElement is! ClassElement) {
+      return false;
+    }
+    // comment
+    AstNode parent = node.parent;
+    if (parent is CommentReference) {
+      return false;
+    }
+    // qualified method invocation
+    if (parent is MethodInvocation) {
+      MethodInvocation invocation = parent;
+      if (identical(invocation.methodName, node) && invocation.realTarget != null) {
+        return false;
+      }
+    }
+    // qualified property access
+    if (parent is PropertyAccess) {
+      PropertyAccess access = parent;
+      if (identical(access.propertyName, node) && access.realTarget != null) {
+        return false;
+      }
+    }
+    if (parent is PrefixedIdentifier) {
+      PrefixedIdentifier prefixed = parent;
+      if (identical(prefixed.identifier, node)) {
+        return false;
+      }
+    }
+    // report problem
+    if (_isInStaticMethod) {
+      _errorReporter.reportErrorForNode(CompileTimeErrorCode.INSTANCE_MEMBER_ACCESS_FROM_STATIC, node, []);
+    } else if (_isInFactory) {
+      _errorReporter.reportErrorForNode(CompileTimeErrorCode.INSTANCE_MEMBER_ACCESS_FROM_FACTORY, node, []);
+    } else {
+      _errorReporter.reportErrorForNode(CompileTimeErrorCode.IMPLICIT_THIS_REFERENCE_IN_INITIALIZER, node, []);
+    }
+    return true;
+  }
+
+  /**
+   * This verifies the passed import has unique name among other imported libraries.
+   *
+   * @param node the import directive to evaluate
+   * @param importElement the [ImportElement] retrieved from the node, if the element in the
+   *          node was `null`, then this method is not called
+   * @return `true` if and only if an error code is generated on the passed node
+   * @see CompileTimeErrorCode#IMPORT_DUPLICATED_LIBRARY_NAME
+   */
+  bool _checkForImportDuplicateLibraryName(ImportDirective node, ImportElement importElement) {
+    // prepare imported library
+    LibraryElement nodeLibrary = importElement.importedLibrary;
+    if (nodeLibrary == null) {
+      return false;
+    }
+    String name = nodeLibrary.name;
+    // check if there is other imported library with the same name
+    LibraryElement prevLibrary = _nameToImportElement[name];
+    if (prevLibrary != null) {
+      if (prevLibrary != nodeLibrary) {
+        _errorReporter.reportErrorForNode(StaticWarningCode.IMPORT_DUPLICATED_LIBRARY_NAME, node, [
+            prevLibrary.definingCompilationUnit.displayName,
+            nodeLibrary.definingCompilationUnit.displayName,
+            name]);
+        return true;
+      }
+    } else {
+      _nameToImportElement[name] = nodeLibrary;
+    }
+    // OK
+    return false;
+  }
+
+  /**
+   * Check that if the visiting library is not system, then any passed library should not be SDK
+   * internal library.
+   *
+   * @param node the import directive to evaluate
+   * @param importElement the [ImportElement] retrieved from the node, if the element in the
+   *          node was `null`, then this method is not called
+   * @return `true` if and only if an error code is generated on the passed node
+   * @see CompileTimeErrorCode#IMPORT_INTERNAL_LIBRARY
+   */
+  bool _checkForImportInternalLibrary(ImportDirective node, ImportElement importElement) {
+    if (_isInSystemLibrary) {
+      return false;
+    }
+    // should be private
+    DartSdk sdk = _currentLibrary.context.sourceFactory.dartSdk;
+    String uri = importElement.uri;
+    SdkLibrary sdkLibrary = sdk.getSdkLibrary(uri);
+    if (sdkLibrary == null) {
+      return false;
+    }
+    if (!sdkLibrary.isInternal) {
+      return false;
+    }
+    // report problem
+    _errorReporter.reportErrorForNode(CompileTimeErrorCode.IMPORT_INTERNAL_LIBRARY, node, [node.uri]);
+    return true;
+  }
+
+  /**
+   * For each class declaration, this method is called which verifies that all inherited members are
+   * inherited consistently.
+   *
+   * @return `true` if and only if an error code is generated on the passed node
+   * @see StaticTypeWarningCode#INCONSISTENT_METHOD_INHERITANCE
+   */
+  bool _checkForInconsistentMethodInheritance() {
+    // Ensure that the inheritance manager has a chance to generate all errors we may care about,
+    // note that we ensure that the interfaces data since there are no errors.
+    _inheritanceManager.getMapOfMembersInheritedFromInterfaces(_enclosingClass);
+    HashSet<AnalysisError> errors = _inheritanceManager.getErrors(_enclosingClass);
+    if (errors == null || errors.isEmpty) {
+      return false;
+    }
+    for (AnalysisError error in errors) {
+      _errorReporter.reportError(error);
+    }
+    return true;
+  }
+
+  /**
+   * This checks the given "typeReference" is not a type reference and that then the "name" is
+   * reference to an instance member.
+   *
+   * @param typeReference the resolved [ClassElement] of the left hand side of the expression,
+   *          or `null`, aka, the class element of 'C' in 'C.x', see
+   *          [getTypeReference]
+   * @param name the accessed name to evaluate
+   * @return `true` if and only if an error code is generated on the passed node
+   * @see StaticTypeWarningCode#INSTANCE_ACCESS_TO_STATIC_MEMBER
+   */
+  bool _checkForInstanceAccessToStaticMember(ClassElement typeReference, SimpleIdentifier name) {
+    // OK, in comment
+    if (_isInComment) {
+      return false;
+    }
+    // OK, target is a type
+    if (typeReference != null) {
+      return false;
+    }
+    // prepare member Element
+    Element element = name.staticElement;
+    if (element is! ExecutableElement) {
+      return false;
+    }
+    ExecutableElement executableElement = element as ExecutableElement;
+    // OK, top-level element
+    if (executableElement.enclosingElement is! ClassElement) {
+      return false;
+    }
+    // OK, instance member
+    if (!executableElement.isStatic) {
+      return false;
+    }
+    // report problem
+    _errorReporter.reportErrorForNode(StaticTypeWarningCode.INSTANCE_ACCESS_TO_STATIC_MEMBER, name, [name.name]);
+    return true;
+  }
+
+  /**
+   * This checks whether the given [executableElement] collides with the name of a static
+   * method in one of its superclasses, and reports the appropriate warning if it does.
+   *
+   * @param executableElement the method to check.
+   * @param errorNameTarget the node to report problems on.
+   * @return `true` if and only if a warning was generated.
+   * @see StaticTypeWarningCode#INSTANCE_METHOD_NAME_COLLIDES_WITH_SUPERCLASS_STATIC
+   */
+  bool _checkForInstanceMethodNameCollidesWithSuperclassStatic(ExecutableElement executableElement, SimpleIdentifier errorNameTarget) {
+    String executableElementName = executableElement.name;
+    if (executableElement is! PropertyAccessorElement && !executableElement.isOperator) {
+      HashSet<ClassElement> visitedClasses = new HashSet<ClassElement>();
+      InterfaceType superclassType = _enclosingClass.supertype;
+      ClassElement superclassElement = superclassType == null ? null : superclassType.element;
+      bool executableElementPrivate = Identifier.isPrivateName(executableElementName);
+      while (superclassElement != null && !visitedClasses.contains(superclassElement)) {
+        visitedClasses.add(superclassElement);
+        LibraryElement superclassLibrary = superclassElement.library;
+        // Check fields.
+        List<FieldElement> fieldElts = superclassElement.fields;
+        for (FieldElement fieldElt in fieldElts) {
+          // We need the same name.
+          if (fieldElt.name != executableElementName) {
+            continue;
+          }
+          // Ignore if private in a different library - cannot collide.
+          if (executableElementPrivate && _currentLibrary != superclassLibrary) {
+            continue;
+          }
+          // instance vs. static
+          if (fieldElt.isStatic) {
+            _errorReporter.reportErrorForNode(StaticWarningCode.INSTANCE_METHOD_NAME_COLLIDES_WITH_SUPERCLASS_STATIC, errorNameTarget, [
+                executableElementName,
+                fieldElt.enclosingElement.displayName]);
+            return true;
+          }
+        }
+        // Check methods.
+        List<MethodElement> methodElements = superclassElement.methods;
+        for (MethodElement methodElement in methodElements) {
+          // We need the same name.
+          if (methodElement.name != executableElementName) {
+            continue;
+          }
+          // Ignore if private in a different library - cannot collide.
+          if (executableElementPrivate && _currentLibrary != superclassLibrary) {
+            continue;
+          }
+          // instance vs. static
+          if (methodElement.isStatic) {
+            _errorReporter.reportErrorForNode(StaticWarningCode.INSTANCE_METHOD_NAME_COLLIDES_WITH_SUPERCLASS_STATIC, errorNameTarget, [
+                executableElementName,
+                methodElement.enclosingElement.displayName]);
+            return true;
+          }
+        }
+        superclassType = superclassElement.supertype;
+        superclassElement = superclassType == null ? null : superclassType.element;
+      }
+    }
+    return false;
+  }
+
+  /**
+   * This verifies that an 'int' can be assigned to the parameter corresponding to the given
+   * expression. This is used for prefix and postfix expressions where the argument value is
+   * implicit.
+   *
+   * @param argument the expression to which the operator is being applied
+   * @return `true` if and only if an error code is generated on the passed node
+   * @see StaticWarningCode#ARGUMENT_TYPE_NOT_ASSIGNABLE
+   */
+  bool _checkForIntNotAssignable(Expression argument) {
+    if (argument == null) {
+      return false;
+    }
+    ParameterElement staticParameterElement = argument.staticParameterElement;
+    DartType staticParameterType = staticParameterElement == null ? null : staticParameterElement.type;
+    return _checkForArgumentTypeNotAssignable(argument, staticParameterType, _intType, StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE);
+  }
+
+  /**
+   * This verifies that the passed [Annotation] isn't defined in a deferred library.
+   *
+   * @param node the [Annotation]
+   * @return `true` if and only if an error code is generated on the passed node
+   * @see CompileTimeErrorCode.INVALID_ANNOTATION_FROM_DEFERRED_LIBRARY
+   */
+  bool _checkForInvalidAnnotationFromDeferredLibrary(Annotation node) {
+    Identifier nameIdentifier = node.name;
+    if (nameIdentifier is PrefixedIdentifier) {
+      if (nameIdentifier.isDeferred) {
+        _errorReporter.reportErrorForNode(CompileTimeErrorCode.INVALID_ANNOTATION_FROM_DEFERRED_LIBRARY, node.name, []);
+        return true;
+      }
+    }
+    return false;
+  }
+
+  /**
+   * This verifies that the passed left hand side and right hand side represent a valid assignment.
+   *
+   * @param lhs the left hand side expression
+   * @param rhs the right hand side expression
+   * @return `true` if and only if an error code is generated on the passed node
+   * @see StaticTypeWarningCode#INVALID_ASSIGNMENT
+   */
+  bool _checkForInvalidAssignment(Expression lhs, Expression rhs) {
+    if (lhs == null || rhs == null) {
+      return false;
+    }
+    VariableElement leftVariableElement = getVariableElement(lhs);
+    DartType leftType = (leftVariableElement == null) ? getStaticType(lhs) : leftVariableElement.type;
+    DartType staticRightType = getStaticType(rhs);
+    if (!staticRightType.isAssignableTo(leftType)) {
+      _errorReporter.reportTypeErrorForNode(StaticTypeWarningCode.INVALID_ASSIGNMENT, rhs, [staticRightType, leftType]);
+      return true;
+    }
+    return false;
+  }
+
+  /**
+   * Given an assignment using a compound assignment operator, this verifies that the given
+   * assignment is valid.
+   *
+   * @param node the assignment expression being tested
+   * @param lhs the left hand side expression
+   * @param rhs the right hand side expression
+   * @return `true` if and only if an error code is generated on the passed node
+   * @see StaticTypeWarningCode#INVALID_ASSIGNMENT
+   */
+  bool _checkForInvalidCompoundAssignment(AssignmentExpression node, Expression lhs, Expression rhs) {
+    if (lhs == null) {
+      return false;
+    }
+    VariableElement leftVariableElement = getVariableElement(lhs);
+    DartType leftType = (leftVariableElement == null) ? getStaticType(lhs) : leftVariableElement.type;
+    MethodElement invokedMethod = node.staticElement;
+    if (invokedMethod == null) {
+      return false;
+    }
+    DartType rightType = invokedMethod.type.returnType;
+    if (leftType == null || rightType == null) {
+      return false;
+    }
+    if (!rightType.isAssignableTo(leftType)) {
+      _errorReporter.reportTypeErrorForNode(StaticTypeWarningCode.INVALID_ASSIGNMENT, rhs, [rightType, leftType]);
+      return true;
+    }
+    return false;
+  }
+
+  /**
+   * Check the given initializer to ensure that the field being initialized is a valid field.
+   *
+   * @param node the field initializer being checked
+   * @param fieldName the field name from the [ConstructorFieldInitializer]
+   * @param staticElement the static element from the name in the
+   *          [ConstructorFieldInitializer]
+   */
+  void _checkForInvalidField(ConstructorFieldInitializer node, SimpleIdentifier fieldName, Element staticElement) {
+    if (staticElement is FieldElement) {
+      FieldElement fieldElement = staticElement;
+      if (fieldElement.isSynthetic) {
+        _errorReporter.reportErrorForNode(CompileTimeErrorCode.INITIALIZER_FOR_NON_EXISTENT_FIELD, node, [fieldName]);
+      } else if (fieldElement.isStatic) {
+        _errorReporter.reportErrorForNode(CompileTimeErrorCode.INITIALIZER_FOR_STATIC_FIELD, node, [fieldName]);
+      }
+    } else {
+      _errorReporter.reportErrorForNode(CompileTimeErrorCode.INITIALIZER_FOR_NON_EXISTENT_FIELD, node, [fieldName]);
+      return;
+    }
+  }
+
+  /**
+   * Check to see whether the given function body has a modifier associated with it, and report it
+   * as an error if it does.
+   *
+   * @param body the function body being checked
+   * @param errorCode the error code to be reported if a modifier is found
+   * @return `true` if an error was reported
+   */
+  bool _checkForInvalidModifierOnBody(FunctionBody body, CompileTimeErrorCode errorCode) {
+    sc.Token keyword = body.keyword;
+    if (keyword != null) {
+      _errorReporter.reportErrorForToken(errorCode, keyword, [keyword.lexeme]);
+      return true;
+    }
+    return false;
+  }
+
+  /**
+   * This verifies that the usage of the passed 'this' is valid.
+   *
+   * @param node the 'this' expression to evaluate
+   * @return `true` if and only if an error code is generated on the passed node
+   * @see CompileTimeErrorCode#INVALID_REFERENCE_TO_THIS
+   */
+  bool _checkForInvalidReferenceToThis(ThisExpression node) {
+    if (!_isThisInValidContext(node)) {
+      _errorReporter.reportErrorForNode(CompileTimeErrorCode.INVALID_REFERENCE_TO_THIS, node, []);
+      return true;
+    }
+    return false;
+  }
+
+  /**
+   * Checks to ensure that the passed [ListLiteral] or [MapLiteral] does not have a type
+   * parameter as a type argument.
+   *
+   * @param arguments a non-`null`, non-empty [TypeName] node list from the respective
+   *          [ListLiteral] or [MapLiteral]
+   * @param errorCode either [CompileTimeErrorCode#INVALID_TYPE_ARGUMENT_IN_CONST_LIST] or
+   *          [CompileTimeErrorCode#INVALID_TYPE_ARGUMENT_IN_CONST_MAP]
+   * @return `true` if and only if an error code is generated on the passed node
+   */
+  bool _checkForInvalidTypeArgumentInConstTypedLiteral(NodeList<TypeName> arguments, ErrorCode errorCode) {
+    bool foundError = false;
+    for (TypeName typeName in arguments) {
+      if (typeName.type is TypeParameterType) {
+        _errorReporter.reportErrorForNode(errorCode, typeName, [typeName.name]);
+        foundError = true;
+      }
+    }
+    return foundError;
+  }
+
+  /**
+   * This verifies that the elements given [ListLiteral] are subtypes of the specified element
+   * type.
+   *
+   * @param node the list literal to evaluate
+   * @param typeArguments the type arguments, always non-`null`
+   * @return `true` if and only if an error code is generated on the passed node
+   * @see CompileTimeErrorCode#LIST_ELEMENT_TYPE_NOT_ASSIGNABLE
+   * @see StaticWarningCode#LIST_ELEMENT_TYPE_NOT_ASSIGNABLE
+   */
+  bool _checkForListElementTypeNotAssignable(ListLiteral node, TypeArgumentList typeArguments) {
+    NodeList<TypeName> typeNames = typeArguments.arguments;
+    if (typeNames.length < 1) {
+      return false;
+    }
+    DartType listElementType = typeNames[0].type;
+    // Check every list element.
+    bool hasProblems = false;
+    for (Expression element in node.elements) {
+      if (node.constKeyword != null) {
+        // TODO(paulberry): this error should be based on the actual type of the
+        // list element, not the static type.  See dartbug.com/21119.
+        if (_checkForArgumentTypeNotAssignableWithExpectedTypes(
+            element,
+            listElementType,
+            CheckedModeCompileTimeErrorCode.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE)) {
+          hasProblems = true;
+        }
+      }
+      if (_checkForArgumentTypeNotAssignableWithExpectedTypes(
+          element,
+          listElementType,
+          StaticWarningCode.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE)) {
+        hasProblems = true;
+      }
+    }
+    return hasProblems;
+  }
+
+  /**
+   * This verifies that the key/value of entries of the given [MapLiteral] are subtypes of the
+   * key/value types specified in the type arguments.
+   *
+   * @param node the map literal to evaluate
+   * @param typeArguments the type arguments, always non-`null`
+   * @return `true` if and only if an error code is generated on the passed node
+   * @see CompileTimeErrorCode#MAP_KEY_TYPE_NOT_ASSIGNABLE
+   * @see CompileTimeErrorCode#MAP_VALUE_TYPE_NOT_ASSIGNABLE
+   * @see StaticWarningCode#MAP_KEY_TYPE_NOT_ASSIGNABLE
+   * @see StaticWarningCode#MAP_VALUE_TYPE_NOT_ASSIGNABLE
+   */
+  bool _checkForMapTypeNotAssignable(MapLiteral node, TypeArgumentList typeArguments) {
+    // Prepare maps key/value types.
+    NodeList<TypeName> typeNames = typeArguments.arguments;
+    if (typeNames.length < 2) {
+      return false;
+    }
+    DartType keyType = typeNames[0].type;
+    DartType valueType = typeNames[1].type;
+    // Check every map entry.
+    bool hasProblems = false;
+    NodeList<MapLiteralEntry> entries = node.entries;
+    for (MapLiteralEntry entry in entries) {
+      Expression key = entry.key;
+      Expression value = entry.value;
+      if (node.constKeyword != null) {
+        // TODO(paulberry): this error should be based on the actual type of the
+        // list element, not the static type.  See dartbug.com/21119.
+        if (_checkForArgumentTypeNotAssignableWithExpectedTypes(
+            key,
+            keyType,
+            CheckedModeCompileTimeErrorCode.MAP_KEY_TYPE_NOT_ASSIGNABLE)) {
+          hasProblems = true;
+        }
+        if (_checkForArgumentTypeNotAssignableWithExpectedTypes(
+            value,
+            valueType,
+            CheckedModeCompileTimeErrorCode.MAP_VALUE_TYPE_NOT_ASSIGNABLE)) {
+          hasProblems = true;
+        }
+      }
+      if (_checkForArgumentTypeNotAssignableWithExpectedTypes(
+          key,
+          keyType,
+          StaticWarningCode.MAP_KEY_TYPE_NOT_ASSIGNABLE)) {
+        hasProblems = true;
+      }
+      if (_checkForArgumentTypeNotAssignableWithExpectedTypes(
+          value,
+          valueType,
+          StaticWarningCode.MAP_VALUE_TYPE_NOT_ASSIGNABLE)) {
+        hasProblems = true;
+      }
+    }
+    return hasProblems;
+  }
+
+  /**
+   * This verifies that the [enclosingClass] does not define members with the same name as
+   * the enclosing class.
+   *
+   * @return `true` if and only if an error code is generated on the passed node
+   * @see CompileTimeErrorCode#MEMBER_WITH_CLASS_NAME
+   */
+  bool _checkForMemberWithClassName() {
+    if (_enclosingClass == null) {
+      return false;
+    }
+    String className = _enclosingClass.name;
+    if (className == null) {
+      return false;
+    }
+    bool problemReported = false;
+    // check accessors
+    for (PropertyAccessorElement accessor in _enclosingClass.accessors) {
+      if (className == accessor.name) {
+        _errorReporter.reportErrorForOffset(CompileTimeErrorCode.MEMBER_WITH_CLASS_NAME, accessor.nameOffset, className.length, []);
+        problemReported = true;
+      }
+    }
+    // don't check methods, they would be constructors
+    // done
+    return problemReported;
+  }
+
+  /**
+   * Check to make sure that all similarly typed accessors are of the same type (including inherited
+   * accessors).
+   *
+   * @param node the accessor currently being visited
+   * @return `true` if and only if an error code is generated on the passed node
+   * @see StaticWarningCode.MISMATCHED_GETTER_AND_SETTER_TYPES
+   * @see StaticWarningCode.MISMATCHED_GETTER_AND_SETTER_TYPES_FROM_SUPERTYPE
+   */
+  bool _checkForMismatchedAccessorTypes(Declaration accessorDeclaration, String accessorTextName) {
+    ExecutableElement accessorElement = accessorDeclaration.element as ExecutableElement;
+    if (accessorElement is! PropertyAccessorElement) {
+      return false;
+    }
+    PropertyAccessorElement propertyAccessorElement = accessorElement as PropertyAccessorElement;
+    PropertyAccessorElement counterpartAccessor = null;
+    ClassElement enclosingClassForCounterpart = null;
+    if (propertyAccessorElement.isGetter) {
+      counterpartAccessor = propertyAccessorElement.correspondingSetter;
+    } else {
+      counterpartAccessor = propertyAccessorElement.correspondingGetter;
+      // If the setter and getter are in the same enclosing element, return, this prevents having
+      // MISMATCHED_GETTER_AND_SETTER_TYPES reported twice.
+      if (counterpartAccessor != null && identical(counterpartAccessor.enclosingElement, propertyAccessorElement.enclosingElement)) {
+        return false;
+      }
+    }
+    if (counterpartAccessor == null) {
+      // If the accessor is declared in a class, check the superclasses.
+      if (_enclosingClass != null) {
+        // Figure out the correct identifier to lookup in the inheritance graph, if 'x', then 'x=',
+        // or if 'x=', then 'x'.
+        String lookupIdentifier = propertyAccessorElement.name;
+        if (StringUtilities.endsWithChar(lookupIdentifier, 0x3D)) {
+          lookupIdentifier = lookupIdentifier.substring(0, lookupIdentifier.length - 1);
+        } else {
+          lookupIdentifier += "=";
+        }
+        // lookup with the identifier.
+        ExecutableElement elementFromInheritance = _inheritanceManager.lookupInheritance(_enclosingClass, lookupIdentifier);
+        // Verify that we found something, and that it is an accessor
+        if (elementFromInheritance != null && elementFromInheritance is PropertyAccessorElement) {
+          enclosingClassForCounterpart = elementFromInheritance.enclosingElement as ClassElement;
+          counterpartAccessor = elementFromInheritance;
+        }
+      }
+      if (counterpartAccessor == null) {
+        return false;
+      }
+    }
+    // Default of null == no accessor or no type (dynamic)
+    DartType getterType = null;
+    DartType setterType = null;
+    // Get an existing counterpart accessor if any.
+    if (propertyAccessorElement.isGetter) {
+      getterType = _getGetterType(propertyAccessorElement);
+      setterType = _getSetterType(counterpartAccessor);
+    } else if (propertyAccessorElement.isSetter) {
+      setterType = _getSetterType(propertyAccessorElement);
+      getterType = _getGetterType(counterpartAccessor);
+    }
+    // If either types are not assignable to each other, report an error (if the getter is null,
+    // it is dynamic which is assignable to everything).
+    if (setterType != null && getterType != null && !getterType.isAssignableTo(setterType)) {
+      if (enclosingClassForCounterpart == null) {
+        _errorReporter.reportTypeErrorForNode(StaticWarningCode.MISMATCHED_GETTER_AND_SETTER_TYPES, accessorDeclaration, [accessorTextName, setterType, getterType]);
+        return true;
+      } else {
+        _errorReporter.reportTypeErrorForNode(StaticWarningCode.MISMATCHED_GETTER_AND_SETTER_TYPES_FROM_SUPERTYPE, accessorDeclaration, [
+            accessorTextName,
+            setterType,
+            getterType,
+            enclosingClassForCounterpart.displayName]);
+      }
+    }
+    return false;
+  }
+
+  /**
+   * Check to make sure that switch statements whose static type is an enum type either have a
+   * default case or include all of the enum constants.
+   *
+   * @param statement the switch statement to check
+   * @return `true` if and only if an error code is generated on the passed node
+   */
+  bool _checkForMissingEnumConstantInSwitch(SwitchStatement statement) {
+    // TODO(brianwilkerson) This needs to be checked after constant values have been computed.
+    Expression expression = statement.expression;
+    DartType expressionType = getStaticType(expression);
+    if (expressionType == null) {
+      return false;
+    }
+    Element expressionElement = expressionType.element;
+    if (expressionElement is! ClassElement) {
+      return false;
+    }
+    ClassElement classElement = expressionElement as ClassElement;
+    if (!classElement.isEnum) {
+      return false;
+    }
+    List<String> constantNames = new List<String>();
+    List<FieldElement> fields = classElement.fields;
+    int fieldCount = fields.length;
+    for (int i = 0; i < fieldCount; i++) {
+      FieldElement field = fields[i];
+      if (field.isStatic && !field.isSynthetic) {
+        constantNames.add(field.name);
+      }
+    }
+    NodeList<SwitchMember> members = statement.members;
+    int memberCount = members.length;
+    for (int i = 0; i < memberCount; i++) {
+      SwitchMember member = members[i];
+      if (member is SwitchDefault) {
+        return false;
+      }
+      String constantName = _getConstantName((member as SwitchCase).expression);
+      if (constantName != null) {
+        constantNames.remove(constantName);
+      }
+    }
+    int nameCount = constantNames.length;
+    if (nameCount == 0) {
+      return false;
+    }
+    for (int i = 0; i < nameCount; i++) {
+      _errorReporter.reportErrorForNode(CompileTimeErrorCode.MISSING_ENUM_CONSTANT_IN_SWITCH, statement, [constantNames[i]]);
+    }
+    return true;
+  }
+
+  /**
+   * This verifies that the given function body does not contain return statements that both have
+   * and do not have return values.
+   *
+   * @param node the function body being tested
+   * @return `true` if and only if an error code is generated on the passed node
+   * @see StaticWarningCode#MIXED_RETURN_TYPES
+   */
+  bool _checkForMixedReturns(BlockFunctionBody node) {
+    if (_hasReturnWithoutValue) {
+      return false;
+    }
+    int withCount = _returnsWith.length;
+    int withoutCount = _returnsWithout.length;
+    if (withCount > 0 && withoutCount > 0) {
+      for (int i = 0; i < withCount; i++) {
+        _errorReporter.reportErrorForToken(StaticWarningCode.MIXED_RETURN_TYPES, _returnsWith[i].keyword, []);
+      }
+      for (int i = 0; i < withoutCount; i++) {
+        _errorReporter.reportErrorForToken(StaticWarningCode.MIXED_RETURN_TYPES, _returnsWithout[i].keyword, []);
+      }
+      return true;
+    }
+    return false;
+  }
+
+  /**
+   * This verifies that the passed mixin does not have an explicitly declared constructor.
+   *
+   * @param mixinName the node to report problem on
+   * @param mixinElement the mixing to evaluate
+   * @return `true` if and only if an error code is generated on the passed node
+   * @see CompileTimeErrorCode#MIXIN_DECLARES_CONSTRUCTOR
+   */
+  bool _checkForMixinDeclaresConstructor(TypeName mixinName, ClassElement mixinElement) {
+    for (ConstructorElement constructor in mixinElement.constructors) {
+      if (!constructor.isSynthetic && !constructor.isFactory) {
+        _errorReporter.reportErrorForNode(CompileTimeErrorCode.MIXIN_DECLARES_CONSTRUCTOR, mixinName, [mixinElement.name]);
+        return true;
+      }
+    }
+    return false;
+  }
+
+  /**
+   * This verifies that the passed mixin has the 'Object' superclass.
+   *
+   * @param mixinName the node to report problem on
+   * @param mixinElement the mixing to evaluate
+   * @return `true` if and only if an error code is generated on the passed node
+   * @see CompileTimeErrorCode#MIXIN_INHERITS_FROM_NOT_OBJECT
+   */
+  bool _checkForMixinInheritsNotFromObject(TypeName mixinName, ClassElement mixinElement) {
+    InterfaceType mixinSupertype = mixinElement.supertype;
+    if (mixinSupertype != null) {
+      if (!mixinSupertype.isObject || !mixinElement.isTypedef && mixinElement.mixins.length != 0) {
+        _errorReporter.reportErrorForNode(CompileTimeErrorCode.MIXIN_INHERITS_FROM_NOT_OBJECT, mixinName, [mixinElement.name]);
+        return true;
+      }
+    }
+    return false;
+  }
+
+  /**
+   * This verifies that the passed mixin does not reference 'super'.
+   *
+   * @param mixinName the node to report problem on
+   * @param mixinElement the mixing to evaluate
+   * @return `true` if and only if an error code is generated on the passed node
+   * @see CompileTimeErrorCode#MIXIN_REFERENCES_SUPER
+   */
+  bool _checkForMixinReferencesSuper(TypeName mixinName, ClassElement mixinElement) {
+    if (mixinElement.hasReferenceToSuper) {
+      _errorReporter.reportErrorForNode(CompileTimeErrorCode.MIXIN_REFERENCES_SUPER, mixinName, [mixinElement.name]);
+    }
+    return false;
+  }
+
+  /**
+   * This verifies that the passed constructor has at most one 'super' initializer.
+   *
+   * @param node the constructor declaration to evaluate
+   * @return `true` if and only if an error code is generated on the passed node
+   * @see CompileTimeErrorCode#MULTIPLE_SUPER_INITIALIZERS
+   */
+  bool _checkForMultipleSuperInitializers(ConstructorDeclaration node) {
+    int numSuperInitializers = 0;
+    for (ConstructorInitializer initializer in node.initializers) {
+      if (initializer is SuperConstructorInvocation) {
+        numSuperInitializers++;
+        if (numSuperInitializers > 1) {
+          _errorReporter.reportErrorForNode(CompileTimeErrorCode.MULTIPLE_SUPER_INITIALIZERS, initializer, []);
+        }
+      }
+    }
+    return numSuperInitializers > 0;
+  }
+
+  /**
+   * Checks to ensure that native function bodies can only in SDK code.
+   *
+   * @param node the native function body to test
+   * @return `true` if and only if an error code is generated on the passed node
+   * @see ParserErrorCode#NATIVE_FUNCTION_BODY_IN_NON_SDK_CODE
+   */
+  bool _checkForNativeFunctionBodyInNonSDKCode(NativeFunctionBody node) {
+    if (!_isInSystemLibrary && !_hasExtUri) {
+      _errorReporter.reportErrorForNode(ParserErrorCode.NATIVE_FUNCTION_BODY_IN_NON_SDK_CODE, node, []);
+      return true;
+    }
+    return false;
+  }
+
+  /**
+   * This verifies that the passed 'new' instance creation expression invokes existing constructor.
+   *
+   * This method assumes that the instance creation was tested to be 'new' before being called.
+   *
+   * @param node the instance creation expression to evaluate
+   * @param constructorName the constructor name, always non-`null`
+   * @param typeName the name of the type defining the constructor, always non-`null`
+   * @return `true` if and only if an error code is generated on the passed node
+   * @see StaticWarningCode#NEW_WITH_UNDEFINED_CONSTRUCTOR
+   */
+  bool _checkForNewWithUndefinedConstructor(InstanceCreationExpression node, ConstructorName constructorName, TypeName typeName) {
+    // OK if resolved
+    if (node.staticElement != null) {
+      return false;
+    }
+    DartType type = typeName.type;
+    if (type is InterfaceType) {
+      ClassElement element = type.element;
+      if (element != null && element.isEnum) {
+        // We have already reported the error.
+        return false;
+      }
+    }
+    // prepare class name
+    Identifier className = typeName.name;
+    // report as named or default constructor absence
+    SimpleIdentifier name = constructorName.name;
+    if (name != null) {
+      _errorReporter.reportErrorForNode(StaticWarningCode.NEW_WITH_UNDEFINED_CONSTRUCTOR, name, [className, name]);
+    } else {
+      _errorReporter.reportErrorForNode(StaticWarningCode.NEW_WITH_UNDEFINED_CONSTRUCTOR_DEFAULT, constructorName, [className]);
+    }
+    return true;
+  }
+
+  /**
+   * This checks that if the passed class declaration implicitly calls default constructor of its
+   * superclass, there should be such default constructor - implicit or explicit.
+   *
+   * @param node the [ClassDeclaration] to evaluate
+   * @return `true` if and only if an error code is generated on the passed node
+   * @see CompileTimeErrorCode#NO_DEFAULT_SUPER_CONSTRUCTOR_IMPLICIT
+   */
+  bool _checkForNoDefaultSuperConstructorImplicit(ClassDeclaration node) {
+    // do nothing if there is explicit constructor
+    List<ConstructorElement> constructors = _enclosingClass.constructors;
+    if (!constructors[0].isSynthetic) {
+      return false;
+    }
+    // prepare super
+    InterfaceType superType = _enclosingClass.supertype;
+    if (superType == null) {
+      return false;
+    }
+    ClassElement superElement = superType.element;
+    // try to find default generative super constructor
+    ConstructorElement superUnnamedConstructor = superElement.unnamedConstructor;
+    if (superUnnamedConstructor != null) {
+      if (superUnnamedConstructor.isFactory) {
+        _errorReporter.reportErrorForNode(CompileTimeErrorCode.NON_GENERATIVE_CONSTRUCTOR, node.name, [superUnnamedConstructor]);
+        return true;
+      }
+      if (superUnnamedConstructor.isDefaultConstructor) {
+        return true;
+      }
+    }
+    // report problem
+    _errorReporter.reportErrorForNode(CompileTimeErrorCode.NO_DEFAULT_SUPER_CONSTRUCTOR_IMPLICIT, node.name, [superType.displayName]);
+    return true;
+  }
+
+  /**
+   * This checks that passed class declaration overrides all members required by its superclasses
+   * and interfaces.
+   *
+   * @param classNameNode the [SimpleIdentifier] to be used if there is a violation, this is
+   *          either the named from the [ClassDeclaration] or from the [ClassTypeAlias].
+   * @return `true` if and only if an error code is generated on the passed node
+   * @see StaticWarningCode#NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE
+   * @see StaticWarningCode#NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_TWO
+   * @see StaticWarningCode#NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_THREE
+   * @see StaticWarningCode#NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_FOUR
+   * @see StaticWarningCode#NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_FIVE_PLUS
+   */
+  bool _checkForNonAbstractClassInheritsAbstractMember(SimpleIdentifier classNameNode) {
+    if (_enclosingClass.isAbstract) {
+      return false;
+    }
+    //
+    // Store in local sets the set of all method and accessor names
+    //
+    List<MethodElement> methods = _enclosingClass.methods;
+    for (MethodElement method in methods) {
+      String methodName = method.name;
+      // If the enclosing class declares the method noSuchMethod(), then return.
+      // From Spec:  It is a static warning if a concrete class does not have an implementation for
+      // a method in any of its superinterfaces unless it declares its own noSuchMethod
+      // method (7.10).
+      if (methodName == FunctionElement.NO_SUCH_METHOD_METHOD_NAME) {
+        return false;
+      }
+    }
+    HashSet<ExecutableElement> missingOverrides = new HashSet<ExecutableElement>();
+    //
+    // Loop through the set of all executable elements declared in the implicit interface.
+    //
+    MemberMap membersInheritedFromInterfaces = _inheritanceManager.getMapOfMembersInheritedFromInterfaces(_enclosingClass);
+    MemberMap membersInheritedFromSuperclasses = _inheritanceManager.getMapOfMembersInheritedFromClasses(_enclosingClass);
+    for (int i = 0; i < membersInheritedFromInterfaces.size; i++) {
+      String memberName = membersInheritedFromInterfaces.getKey(i);
+      ExecutableElement executableElt = membersInheritedFromInterfaces.getValue(i);
+      if (memberName == null) {
+        break;
+      }
+      // If the element is not synthetic and can be determined to be defined in Object, skip it.
+      if (executableElt.enclosingElement != null && (executableElt.enclosingElement as ClassElement).type.isObject) {
+        continue;
+      }
+      // Check to see if some element is in local enclosing class that matches the name of the
+      // required member.
+      if (_isMemberInClassOrMixin(executableElt, _enclosingClass)) {
+        // We do not have to verify that this implementation of the found method matches the
+        // required function type: the set of StaticWarningCode.INVALID_METHOD_OVERRIDE_* warnings
+        // break out the different specific situations.
+        continue;
+      }
+      // First check to see if this element was declared in the superclass chain, in which case
+      // there is already a concrete implementation.
+      ExecutableElement elt = membersInheritedFromSuperclasses.get(memberName);
+      // Check to see if an element was found in the superclass chain with the correct name.
+      if (elt != null) {
+        // Reference the types, if any are null then continue.
+        InterfaceType enclosingType = _enclosingClass.type;
+        FunctionType concreteType = elt.type;
+        FunctionType requiredMemberType = executableElt.type;
+        if (enclosingType == null || concreteType == null || requiredMemberType == null) {
+          continue;
+        }
+        // Some element was found in the superclass chain that matches the name of the required
+        // member.
+        // If it is not abstract and it is the correct one (types match- the version of this method
+        // that we have has the correct number of parameters, etc), then this class has a valid
+        // implementation of this method, so skip it.
+        if ((elt is MethodElement && !elt.isAbstract) || (elt is PropertyAccessorElement && !elt.isAbstract)) {
+          // Since we are comparing two function types, we need to do the appropriate type
+          // substitutions first ().
+          FunctionType foundConcreteFT = _inheritanceManager.substituteTypeArgumentsInMemberFromInheritance(concreteType, memberName, enclosingType);
+          FunctionType requiredMemberFT = _inheritanceManager.substituteTypeArgumentsInMemberFromInheritance(requiredMemberType, memberName, enclosingType);
+          if (foundConcreteFT.isSubtypeOf(requiredMemberFT)) {
+            continue;
+          }
+        }
+      }
+      // The not qualifying concrete executable element was found, add it to the list.
+      missingOverrides.add(executableElt);
+    }
+    // Now that we have the set of missing overrides, generate a warning on this class
+    int missingOverridesSize = missingOverrides.length;
+    if (missingOverridesSize == 0) {
+      return false;
+    }
+    List<ExecutableElement> missingOverridesArray = new List.from(missingOverrides);
+    List<String> stringMembersArrayListSet = new List<String>();
+    for (int i = 0; i < missingOverridesArray.length; i++) {
+      String newStrMember;
+      Element enclosingElement = missingOverridesArray[i].enclosingElement;
+      String prefix = StringUtilities.EMPTY;
+      if (missingOverridesArray[i] is PropertyAccessorElement) {
+        PropertyAccessorElement propertyAccessorElement = missingOverridesArray[i] as PropertyAccessorElement;
+        if (propertyAccessorElement.isGetter) {
+          prefix = _GETTER_SPACE;
+          // "getter "
+        } else {
+          prefix = _SETTER_SPACE;
+          // "setter "
+        }
+      }
+      if (enclosingElement != null) {
+        newStrMember = "$prefix'${enclosingElement.displayName}.${missingOverridesArray[i].displayName}'";
+      } else {
+        newStrMember = "$prefix'${missingOverridesArray[i].displayName}'";
+      }
+      stringMembersArrayListSet.add(newStrMember);
+    }
+    List<String> stringMembersArray = new List.from(stringMembersArrayListSet);
+    AnalysisErrorWithProperties analysisError;
+    if (stringMembersArray.length == 1) {
+      analysisError = _errorReporter.newErrorWithProperties(StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE, classNameNode, [stringMembersArray[0]]);
+    } else if (stringMembersArray.length == 2) {
+      analysisError = _errorReporter.newErrorWithProperties(StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_TWO, classNameNode, [stringMembersArray[0], stringMembersArray[1]]);
+    } else if (stringMembersArray.length == 3) {
+      analysisError = _errorReporter.newErrorWithProperties(StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_THREE, classNameNode, [
+          stringMembersArray[0],
+          stringMembersArray[1],
+          stringMembersArray[2]]);
+    } else if (stringMembersArray.length == 4) {
+      analysisError = _errorReporter.newErrorWithProperties(StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_FOUR, classNameNode, [
+          stringMembersArray[0],
+          stringMembersArray[1],
+          stringMembersArray[2],
+          stringMembersArray[3]]);
+    } else {
+      analysisError = _errorReporter.newErrorWithProperties(StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_FIVE_PLUS, classNameNode, [
+          stringMembersArray[0],
+          stringMembersArray[1],
+          stringMembersArray[2],
+          stringMembersArray[3],
+          stringMembersArray.length - 4]);
+    }
+    analysisError.setProperty(ErrorProperty.UNIMPLEMENTED_METHODS, missingOverridesArray);
+    _errorReporter.reportError(analysisError);
+    return true;
+  }
+
+  /**
+   * Checks to ensure that the expressions that need to be of type bool, are. Otherwise an error is
+   * reported on the expression.
+   *
+   * @param condition the conditional expression to test
+   * @return `true` if and only if an error code is generated on the passed node
+   * @see StaticTypeWarningCode#NON_BOOL_CONDITION
+   */
+  bool _checkForNonBoolCondition(Expression condition) {
+    DartType conditionType = getStaticType(condition);
+    if (conditionType != null && !conditionType.isAssignableTo(_boolType)) {
+      _errorReporter.reportErrorForNode(StaticTypeWarningCode.NON_BOOL_CONDITION, condition, []);
+      return true;
+    }
+    return false;
+  }
+
+  /**
+   * This verifies that the passed assert statement has either a 'bool' or '() -> bool' input.
+   *
+   * @param node the assert statement to evaluate
+   * @return `true` if and only if an error code is generated on the passed node
+   * @see StaticTypeWarningCode#NON_BOOL_EXPRESSION
+   */
+  bool _checkForNonBoolExpression(AssertStatement node) {
+    Expression expression = node.condition;
+    DartType type = getStaticType(expression);
+    if (type is InterfaceType) {
+      if (!type.isAssignableTo(_boolType)) {
+        _errorReporter.reportErrorForNode(StaticTypeWarningCode.NON_BOOL_EXPRESSION, expression, []);
+        return true;
+      }
+    } else if (type is FunctionType) {
+      FunctionType functionType = type;
+      if (functionType.typeArguments.length == 0 && !functionType.returnType.isAssignableTo(_boolType)) {
+        _errorReporter.reportErrorForNode(StaticTypeWarningCode.NON_BOOL_EXPRESSION, expression, []);
+        return true;
+      }
+    }
+    return false;
+  }
+
+  /**
+   * Checks to ensure that the given expression is assignable to bool.
+   *
+   * @param expression the expression expression to test
+   * @return `true` if and only if an error code is generated on the passed node
+   * @see StaticTypeWarningCode#NON_BOOL_NEGATION_EXPRESSION
+   */
+  bool _checkForNonBoolNegationExpression(Expression expression) {
+    DartType conditionType = getStaticType(expression);
+    if (conditionType != null && !conditionType.isAssignableTo(_boolType)) {
+      _errorReporter.reportErrorForNode(StaticTypeWarningCode.NON_BOOL_NEGATION_EXPRESSION, expression, []);
+      return true;
+    }
+    return false;
+  }
+
+  /**
+   * This verifies the passed map literal either:
+   * * has `const modifier`
+   * * has explicit type arguments
+   * * is not start of the statement
+   *
+   * @param node the map literal to evaluate
+   * @return `true` if and only if an error code is generated on the passed node
+   * @see CompileTimeErrorCode#NON_CONST_MAP_AS_EXPRESSION_STATEMENT
+   */
+  bool _checkForNonConstMapAsExpressionStatement(MapLiteral node) {
+    // "const"
+    if (node.constKeyword != null) {
+      return false;
+    }
+    // has type arguments
+    if (node.typeArguments != null) {
+      return false;
+    }
+    // prepare statement
+    Statement statement = node.getAncestor((node) => node is ExpressionStatement);
+    if (statement == null) {
+      return false;
+    }
+    // OK, statement does not start with map
+    if (!identical(statement.beginToken, node.beginToken)) {
+      return false;
+    }
+    // report problem
+    _errorReporter.reportErrorForNode(CompileTimeErrorCode.NON_CONST_MAP_AS_EXPRESSION_STATEMENT, node, []);
+    return true;
+  }
+
+  /**
+   * This verifies the passed method declaration of operator `[]=`, has `void` return
+   * type.
+   *
+   * @param node the method declaration to evaluate
+   * @return `true` if and only if an error code is generated on the passed node
+   * @see StaticWarningCode#NON_VOID_RETURN_FOR_OPERATOR
+   */
+  bool _checkForNonVoidReturnTypeForOperator(MethodDeclaration node) {
+    // check that []= operator
+    SimpleIdentifier name = node.name;
+    if (name.name != "[]=") {
+      return false;
+    }
+    // check return type
+    TypeName typeName = node.returnType;
+    if (typeName != null) {
+      DartType type = typeName.type;
+      if (type != null && !type.isVoid) {
+        _errorReporter.reportErrorForNode(StaticWarningCode.NON_VOID_RETURN_FOR_OPERATOR, typeName, []);
+      }
+    }
+    // no warning
+    return false;
+  }
+
+  /**
+   * This verifies the passed setter has no return type or the `void` return type.
+   *
+   * @param typeName the type name to evaluate
+   * @return `true` if and only if an error code is generated on the passed node
+   * @see StaticWarningCode#NON_VOID_RETURN_FOR_SETTER
+   */
+  bool _checkForNonVoidReturnTypeForSetter(TypeName typeName) {
+    if (typeName != null) {
+      DartType type = typeName.type;
+      if (type != null && !type.isVoid) {
+        _errorReporter.reportErrorForNode(StaticWarningCode.NON_VOID_RETURN_FOR_SETTER, typeName, []);
+      }
+    }
+    return false;
+  }
+
+  /**
+   * This verifies the passed operator-method declaration, does not have an optional parameter.
+   *
+   * This method assumes that the method declaration was tested to be an operator declaration before
+   * being called.
+   *
+   * @param node the method declaration to evaluate
+   * @return `true` if and only if an error code is generated on the passed node
+   * @see CompileTimeErrorCode#OPTIONAL_PARAMETER_IN_OPERATOR
+   */
+  bool _checkForOptionalParameterInOperator(MethodDeclaration node) {
+    FormalParameterList parameterList = node.parameters;
+    if (parameterList == null) {
+      return false;
+    }
+    bool foundError = false;
+    NodeList<FormalParameter> formalParameters = parameterList.parameters;
+    for (FormalParameter formalParameter in formalParameters) {
+      if (formalParameter.kind.isOptional) {
+        _errorReporter.reportErrorForNode(CompileTimeErrorCode.OPTIONAL_PARAMETER_IN_OPERATOR, formalParameter, []);
+        foundError = true;
+      }
+    }
+    return foundError;
+  }
+
+  /**
+   * This checks for named optional parameters that begin with '_'.
+   *
+   * @param node the default formal parameter to evaluate
+   * @return `true` if and only if an error code is generated on the passed node
+   * @see CompileTimeErrorCode#PRIVATE_OPTIONAL_PARAMETER
+   */
+  bool _checkForPrivateOptionalParameter(FormalParameter node) {
+    // should be named parameter
+    if (node.kind != ParameterKind.NAMED) {
+      return false;
+    }
+    // name should start with '_'
+    SimpleIdentifier name = node.identifier;
+    if (name.isSynthetic || !StringUtilities.startsWithChar(name.name, 0x5F)) {
+      return false;
+    }
+    // report problem
+    _errorReporter.reportErrorForNode(CompileTimeErrorCode.PRIVATE_OPTIONAL_PARAMETER, node, []);
+    return true;
+  }
+
+  /**
+   * This checks if the passed constructor declaration is the redirecting generative constructor and
+   * references itself directly or indirectly.
+   *
+   * @param node the constructor declaration to evaluate
+   * @param constructorElement the constructor element
+   * @return `true` if and only if an error code is generated on the passed node
+   * @see CompileTimeErrorCode#RECURSIVE_CONSTRUCTOR_REDIRECT
+   */
+  bool _checkForRecursiveConstructorRedirect(ConstructorDeclaration node, ConstructorElement constructorElement) {
+    // we check generative constructor here
+    if (node.factoryKeyword != null) {
+      return false;
+    }
+    // try to find redirecting constructor invocation and analyzer it for recursion
+    for (ConstructorInitializer initializer in node.initializers) {
+      if (initializer is RedirectingConstructorInvocation) {
+        // OK if no cycle
+        if (!_hasRedirectingFactoryConstructorCycle(constructorElement)) {
+          return false;
+        }
+        // report error
+        _errorReporter.reportErrorForNode(CompileTimeErrorCode.RECURSIVE_CONSTRUCTOR_REDIRECT, initializer, []);
+        return true;
+      }
+    }
+    // OK, no redirecting constructor invocation
+    return false;
+  }
+
+  /**
+   * This checks if the passed constructor declaration has redirected constructor and references
+   * itself directly or indirectly.
+   *
+   * @param node the constructor declaration to evaluate
+   * @param constructorElement the constructor element
+   * @return `true` if and only if an error code is generated on the passed node
+   * @see CompileTimeErrorCode#RECURSIVE_FACTORY_REDIRECT
+   */
+  bool _checkForRecursiveFactoryRedirect(ConstructorDeclaration node, ConstructorElement constructorElement) {
+    // prepare redirected constructor
+    ConstructorName redirectedConstructorNode = node.redirectedConstructor;
+    if (redirectedConstructorNode == null) {
+      return false;
+    }
+    // OK if no cycle
+    if (!_hasRedirectingFactoryConstructorCycle(constructorElement)) {
+      return false;
+    }
+    // report error
+    _errorReporter.reportErrorForNode(CompileTimeErrorCode.RECURSIVE_FACTORY_REDIRECT, redirectedConstructorNode, []);
+    return true;
+  }
+
+  /**
+   * This checks the class declaration is not a superinterface to itself.
+   *
+   * @param classElt the class element to test
+   * @return `true` if and only if an error code is generated on the passed element
+   * @see CompileTimeErrorCode#RECURSIVE_INTERFACE_INHERITANCE
+   * @see CompileTimeErrorCode#RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_EXTENDS
+   * @see CompileTimeErrorCode#RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_IMPLEMENTS
+   */
+  bool _checkForRecursiveInterfaceInheritance(ClassElement classElt) {
+    if (classElt == null) {
+      return false;
+    }
+    return _safeCheckForRecursiveInterfaceInheritance(classElt, new List<ClassElement>());
+  }
+
+  /**
+   * This checks the passed constructor declaration has a valid combination of redirected
+   * constructor invocation(s), super constructor invocations and field initializers.
+   *
+   * @param node the constructor declaration to evaluate
+   * @return `true` if and only if an error code is generated on the passed node
+   * @see CompileTimeErrorCode#DEFAULT_VALUE_IN_REDIRECTING_FACTORY_CONSTRUCTOR
+   * @see CompileTimeErrorCode#FIELD_INITIALIZER_REDIRECTING_CONSTRUCTOR
+   * @see CompileTimeErrorCode#MULTIPLE_REDIRECTING_CONSTRUCTOR_INVOCATIONS
+   * @see CompileTimeErrorCode#SUPER_IN_REDIRECTING_CONSTRUCTOR
+   * @see CompileTimeErrorCode#REDIRECT_GENERATIVE_TO_NON_GENERATIVE_CONSTRUCTOR
+   */
+  bool _checkForRedirectingConstructorErrorCodes(ConstructorDeclaration node) {
+    bool errorReported = false;
+    //
+    // Check for default values in the parameters
+    //
+    ConstructorName redirectedConstructor = node.redirectedConstructor;
+    if (redirectedConstructor != null) {
+      for (FormalParameter parameter in node.parameters.parameters) {
+        if (parameter is DefaultFormalParameter && parameter.defaultValue != null) {
+          _errorReporter.reportErrorForNode(CompileTimeErrorCode.DEFAULT_VALUE_IN_REDIRECTING_FACTORY_CONSTRUCTOR, parameter.identifier, []);
+          errorReported = true;
+        }
+      }
+    }
+    // check if there are redirected invocations
+    int numRedirections = 0;
+    for (ConstructorInitializer initializer in node.initializers) {
+      if (initializer is RedirectingConstructorInvocation) {
+        if (numRedirections > 0) {
+          _errorReporter.reportErrorForNode(CompileTimeErrorCode.MULTIPLE_REDIRECTING_CONSTRUCTOR_INVOCATIONS, initializer, []);
+          errorReported = true;
+        }
+        if (node.factoryKeyword == null) {
+          RedirectingConstructorInvocation invocation = initializer;
+          ConstructorElement redirectingElement = invocation.staticElement;
+          if (redirectingElement == null) {
+            String enclosingTypeName = _enclosingClass.displayName;
+            String constructorStrName = enclosingTypeName;
+            if (invocation.constructorName != null) {
+              constructorStrName += ".${invocation.constructorName.name}";
+            }
+            _errorReporter.reportErrorForNode(CompileTimeErrorCode.REDIRECT_GENERATIVE_TO_MISSING_CONSTRUCTOR, invocation, [constructorStrName, enclosingTypeName]);
+          } else {
+            if (redirectingElement.isFactory) {
+              _errorReporter.reportErrorForNode(CompileTimeErrorCode.REDIRECT_GENERATIVE_TO_NON_GENERATIVE_CONSTRUCTOR, initializer, []);
+            }
+          }
+        }
+        numRedirections++;
+      }
+    }
+    // check for other initializers
+    if (numRedirections > 0) {
+      for (ConstructorInitializer initializer in node.initializers) {
+        if (initializer is SuperConstructorInvocation) {
+          _errorReporter.reportErrorForNode(CompileTimeErrorCode.SUPER_IN_REDIRECTING_CONSTRUCTOR, initializer, []);
+          errorReported = true;
+        }
+        if (initializer is ConstructorFieldInitializer) {
+          _errorReporter.reportErrorForNode(CompileTimeErrorCode.FIELD_INITIALIZER_REDIRECTING_CONSTRUCTOR, initializer, []);
+          errorReported = true;
+        }
+      }
+    }
+    // done
+    return errorReported;
+  }
+
+  /**
+   * This checks if the passed constructor declaration has redirected constructor and references
+   * itself directly or indirectly.
+   *
+   * @param node the constructor declaration to evaluate
+   * @param constructorElement the constructor element
+   * @return `true` if and only if an error code is generated on the passed node
+   * @see CompileTimeErrorCode#REDIRECT_TO_NON_CONST_CONSTRUCTOR
+   */
+  bool _checkForRedirectToNonConstConstructor(ConstructorDeclaration node, ConstructorElement constructorElement) {
+    // prepare redirected constructor
+    ConstructorName redirectedConstructorNode = node.redirectedConstructor;
+    if (redirectedConstructorNode == null) {
+      return false;
+    }
+    // prepare element
+    if (constructorElement == null) {
+      return false;
+    }
+    // OK, it is not 'const'
+    if (!constructorElement.isConst) {
+      return false;
+    }
+    // prepare redirected constructor
+    ConstructorElement redirectedConstructor = constructorElement.redirectedConstructor;
+    if (redirectedConstructor == null) {
+      return false;
+    }
+    // OK, it is also 'const'
+    if (redirectedConstructor.isConst) {
+      return false;
+    }
+    // report error
+    _errorReporter.reportErrorForNode(CompileTimeErrorCode.REDIRECT_TO_NON_CONST_CONSTRUCTOR, redirectedConstructorNode, []);
+    return true;
+  }
+
+  /**
+   * This checks that the rethrow is inside of a catch clause.
+   *
+   * @param node the rethrow expression to evaluate
+   * @return `true` if and only if an error code is generated on the passed node
+   * @see CompileTimeErrorCode#RETHROW_OUTSIDE_CATCH
+   */
+  bool _checkForRethrowOutsideCatch(RethrowExpression node) {
+    if (!_isInCatchClause) {
+      _errorReporter.reportErrorForNode(CompileTimeErrorCode.RETHROW_OUTSIDE_CATCH, node, []);
+      return true;
+    }
+    return false;
+  }
+
+  /**
+   * This checks that if the the given constructor declaration is generative, then it does not have
+   * an expression function body.
+   *
+   * @param node the constructor to evaluate
+   * @return `true` if and only if an error code is generated on the passed node
+   * @see CompileTimeErrorCode#RETURN_IN_GENERATIVE_CONSTRUCTOR
+   */
+  bool _checkForReturnInGenerativeConstructor(ConstructorDeclaration node) {
+    // ignore factory
+    if (node.factoryKeyword != null) {
+      return false;
+    }
+    // block body (with possible return statement) is checked elsewhere
+    FunctionBody body = node.body;
+    if (body is! ExpressionFunctionBody) {
+      return false;
+    }
+    // report error
+    _errorReporter.reportErrorForNode(CompileTimeErrorCode.RETURN_IN_GENERATIVE_CONSTRUCTOR, body, []);
+    return true;
+  }
+
+  /**
+   * This checks that a type mis-match between the return type and the expressed return type by the
+   * enclosing method or function.
+   *
+   * This method is called both by [checkForAllReturnStatementErrorCodes]
+   * and [visitExpressionFunctionBody].
+   *
+   * @param returnExpression the returned expression to evaluate
+   * @param expectedReturnType the expressed return type by the enclosing method or function
+   * @return `true` if and only if an error code is generated on the passed node
+   * @see StaticTypeWarningCode#RETURN_OF_INVALID_TYPE
+   */
+  bool _checkForReturnOfInvalidType(Expression returnExpression, DartType expectedReturnType) {
+    if (_enclosingFunction == null) {
+      return false;
+    }
+    DartType staticReturnType = getStaticType(returnExpression);
+    if (expectedReturnType.isVoid) {
+      if (staticReturnType.isVoid || staticReturnType.isDynamic || staticReturnType.isBottom) {
+        return false;
+      }
+      _errorReporter.reportTypeErrorForNode(StaticTypeWarningCode.RETURN_OF_INVALID_TYPE, returnExpression, [
+          staticReturnType,
+          expectedReturnType,
+          _enclosingFunction.displayName]);
+      return true;
+    }
+    if (_enclosingFunction.isAsynchronous && !_enclosingFunction.isGenerator) {
+      // TODO(brianwilkerson) Figure out how to get the type "Future" so that we can build the type
+      // we need to test against.
+      //      InterfaceType impliedType = "Future<" + flatten(staticReturnType) + ">"
+      //      if (impliedType.isAssignableTo(expectedReturnType)) {
+      //        return false;
+      //      }
+      //      errorReporter.reportTypeErrorForNode(
+      //          StaticTypeWarningCode.RETURN_OF_INVALID_TYPE,
+      //          returnExpression,
+      //          impliedType,
+      //          expectedReturnType.getDisplayName(),
+      //          enclosingFunction.getDisplayName());
+      //      return true;
+      return false;
+    }
+    if (staticReturnType.isAssignableTo(expectedReturnType)) {
+      return false;
+    }
+    _errorReporter.reportTypeErrorForNode(StaticTypeWarningCode.RETURN_OF_INVALID_TYPE, returnExpression, [
+        staticReturnType,
+        expectedReturnType,
+        _enclosingFunction.displayName]);
+    return true;
+    // TODO(brianwilkerson) Define a hint corresponding to the warning and report it if appropriate.
+    //    Type propagatedReturnType = returnExpression.getPropagatedType();
+    //    boolean isPropagatedAssignable = propagatedReturnType.isAssignableTo(expectedReturnType);
+    //    if (isStaticAssignable || isPropagatedAssignable) {
+    //      return false;
+    //    }
+    //    errorReporter.reportTypeErrorForNode(
+    //        StaticTypeWarningCode.RETURN_OF_INVALID_TYPE,
+    //        returnExpression,
+    //        staticReturnType,
+    //        expectedReturnType,
+    //        enclosingFunction.getDisplayName());
+    //    return true;
+  }
+
+  /**
+   * This checks the given "typeReference" and that the "name" is not the reference to an instance
+   * member.
+   *
+   * @param typeReference the resolved [ClassElement] of the left hand side of the expression,
+   *          or `null`, aka, the class element of 'C' in 'C.x', see
+   *          [getTypeReference]
+   * @param name the accessed name to evaluate
+   * @return `true` if and only if an error code is generated on the passed node
+   * @see StaticWarningCode#STATIC_ACCESS_TO_INSTANCE_MEMBER
+   */
+  bool _checkForStaticAccessToInstanceMember(ClassElement typeReference, SimpleIdentifier name) {
+    // OK, target is not a type
+    if (typeReference == null) {
+      return false;
+    }
+    // prepare member Element
+    Element element = name.staticElement;
+    if (element is! ExecutableElement) {
+      return false;
+    }
+    ExecutableElement memberElement = element as ExecutableElement;
+    // OK, static
+    if (memberElement.isStatic) {
+      return false;
+    }
+    // report problem
+    _errorReporter.reportErrorForNode(StaticWarningCode.STATIC_ACCESS_TO_INSTANCE_MEMBER, name, [name.name]);
+    return true;
+  }
+
+  /**
+   * This checks that the type of the passed 'switch' expression is assignable to the type of the
+   * 'case' members.
+   *
+   * @param node the 'switch' statement to evaluate
+   * @return `true` if and only if an error code is generated on the passed node
+   * @see StaticWarningCode#SWITCH_EXPRESSION_NOT_ASSIGNABLE
+   */
+  bool _checkForSwitchExpressionNotAssignable(SwitchStatement node) {
+    // prepare 'switch' expression type
+    Expression expression = node.expression;
+    DartType expressionType = getStaticType(expression);
+    if (expressionType == null) {
+      return false;
+    }
+    // compare with type of the first 'case'
+    NodeList<SwitchMember> members = node.members;
+    for (SwitchMember switchMember in members) {
+      if (switchMember is! SwitchCase) {
+        continue;
+      }
+      SwitchCase switchCase = switchMember as SwitchCase;
+      // prepare 'case' type
+      Expression caseExpression = switchCase.expression;
+      DartType caseType = getStaticType(caseExpression);
+      // check types
+      if (expressionType.isAssignableTo(caseType)) {
+        return false;
+      }
+      // report problem
+      _errorReporter.reportErrorForNode(StaticWarningCode.SWITCH_EXPRESSION_NOT_ASSIGNABLE, expression, [expressionType, caseType]);
+      return true;
+    }
+    return false;
+  }
+
+  /**
+   * This verifies that the passed function type alias does not reference itself directly.
+   *
+   * @param node the function type alias to evaluate
+   * @return `true` if and only if an error code is generated on the passed node
+   * @see CompileTimeErrorCode#TYPE_ALIAS_CANNOT_REFERENCE_ITSELF
+   */
+  bool _checkForTypeAliasCannotReferenceItself_function(FunctionTypeAlias node) {
+    FunctionTypeAliasElement element = node.element;
+    if (!_hasTypedefSelfReference(element)) {
+      return false;
+    }
+    _errorReporter.reportErrorForNode(CompileTimeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF, node, []);
+    return true;
+  }
+
+  /**
+   * This verifies that the passed type name is not a deferred type.
+   *
+   * @param expression the expression to evaluate
+   * @return `true` if and only if an error code is generated on the passed node
+   * @see StaticWarningCode#TYPE_ANNOTATION_DEFERRED_CLASS
+   */
+  bool _checkForTypeAnnotationDeferredClass(TypeName node) {
+    if (node != null && node.isDeferred) {
+      _errorReporter.reportErrorForNode(StaticWarningCode.TYPE_ANNOTATION_DEFERRED_CLASS, node, [node.name]);
+    }
+    return false;
+  }
+
+  /**
+   * This verifies that the type arguments in the passed type name are all within their bounds.
+   *
+   * @param node the [TypeName] to evaluate
+   * @return `true` if and only if an error code is generated on the passed node
+   * @see StaticTypeWarningCode#TYPE_ARGUMENT_NOT_MATCHING_BOUNDS
+   */
+  bool _checkForTypeArgumentNotMatchingBounds(TypeName node) {
+    if (node.typeArguments == null) {
+      return false;
+    }
+    // prepare Type
+    DartType type = node.type;
+    if (type == null) {
+      return false;
+    }
+    // prepare ClassElement
+    Element element = type.element;
+    if (element is! ClassElement) {
+      return false;
+    }
+    ClassElement classElement = element as ClassElement;
+    // prepare type parameters
+    List<DartType> typeParameters = classElement.type.typeArguments;
+    List<TypeParameterElement> boundingElts = classElement.typeParameters;
+    // iterate over each bounded type parameter and corresponding argument
+    NodeList<TypeName> typeNameArgList = node.typeArguments.arguments;
+    List<DartType> typeArguments = (type as InterfaceType).typeArguments;
+    int loopThroughIndex = math.min(typeNameArgList.length, boundingElts.length);
+    bool foundError = false;
+    for (int i = 0; i < loopThroughIndex; i++) {
+      TypeName argTypeName = typeNameArgList[i];
+      DartType argType = argTypeName.type;
+      DartType boundType = boundingElts[i].bound;
+      if (argType != null && boundType != null) {
+        if (typeArguments.length != 0 && typeArguments.length == typeParameters.length) {
+          boundType = boundType.substitute2(typeArguments, typeParameters);
+        }
+        if (!argType.isSubtypeOf(boundType)) {
+          ErrorCode errorCode;
+          if (_isInConstInstanceCreation) {
+            errorCode = CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS;
+          } else {
+            errorCode = StaticTypeWarningCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS;
+          }
+          _errorReporter.reportTypeErrorForNode(errorCode, argTypeName, [argType, boundType]);
+          foundError = true;
+        }
+      }
+    }
+    return foundError;
+  }
+
+  /**
+   * This checks that if the passed type name is a type parameter being used to define a static
+   * member.
+   *
+   * @param node the type name to evaluate
+   * @return `true` if and only if an error code is generated on the passed node
+   * @see StaticWarningCode#TYPE_PARAMETER_REFERENCED_BY_STATIC
+   */
+  bool _checkForTypeParameterReferencedByStatic(TypeName node) {
+    if (_isInStaticMethod || _isInStaticVariableDeclaration) {
+      DartType type = node.type;
+      if (type is TypeParameterType) {
+        _errorReporter.reportErrorForNode(StaticWarningCode.TYPE_PARAMETER_REFERENCED_BY_STATIC, node, []);
+        return true;
+      }
+    }
+    return false;
+  }
+
+  /**
+   * This checks that if the passed type parameter is a supertype of its bound.
+   *
+   * @param node the type parameter to evaluate
+   * @return `true` if and only if an error code is generated on the passed node
+   * @see StaticTypeWarningCode#TYPE_PARAMETER_SUPERTYPE_OF_ITS_BOUND
+   */
+  bool _checkForTypeParameterSupertypeOfItsBound(TypeParameter node) {
+    TypeParameterElement element = node.element;
+    // prepare bound
+    DartType bound = element.bound;
+    if (bound == null) {
+      return false;
+    }
+    // OK, type parameter is not supertype of its bound
+    if (!bound.isMoreSpecificThan(element.type)) {
+      return false;
+    }
+    // report problem
+    _errorReporter.reportErrorForNode(StaticTypeWarningCode.TYPE_PARAMETER_SUPERTYPE_OF_ITS_BOUND, node, [element.displayName]);
+    return true;
+  }
+
+  /**
+   * This checks that if the passed generative constructor has neither an explicit super constructor
+   * invocation nor a redirecting constructor invocation, that the superclass has a default
+   * generative constructor.
+   *
+   * @param node the constructor declaration to evaluate
+   * @return `true` if and only if an error code is generated on the passed node
+   * @see CompileTimeErrorCode#UNDEFINED_CONSTRUCTOR_IN_INITIALIZER_DEFAULT
+   * @see CompileTimeErrorCode#NON_GENERATIVE_CONSTRUCTOR
+   * @see StaticWarningCode#NO_DEFAULT_SUPER_CONSTRUCTOR_EXPLICIT
+   */
+  bool _checkForUndefinedConstructorInInitializerImplicit(ConstructorDeclaration node) {
+    //
+    // Ignore if the constructor is not generative.
+    //
+    if (node.factoryKeyword != null) {
+      return false;
+    }
+    //
+    // Ignore if the constructor has either an implicit super constructor invocation or a
+    // redirecting constructor invocation.
+    //
+    for (ConstructorInitializer constructorInitializer in node.initializers) {
+      if (constructorInitializer is SuperConstructorInvocation || constructorInitializer is RedirectingConstructorInvocation) {
+        return false;
+      }
+    }
+    //
+    // Check to see whether the superclass has a non-factory unnamed constructor.
+    //
+    if (_enclosingClass == null) {
+      return false;
+    }
+    InterfaceType superType = _enclosingClass.supertype;
+    if (superType == null) {
+      return false;
+    }
+    ClassElement superElement = superType.element;
+    ConstructorElement superUnnamedConstructor = superElement.unnamedConstructor;
+    if (superUnnamedConstructor != null) {
+      if (superUnnamedConstructor.isFactory) {
+        _errorReporter.reportErrorForNode(CompileTimeErrorCode.NON_GENERATIVE_CONSTRUCTOR, node.returnType, [superUnnamedConstructor]);
+        return true;
+      }
+      if (!superUnnamedConstructor.isDefaultConstructor) {
+        int offset;
+        int length;
+        {
+          Identifier returnType = node.returnType;
+          SimpleIdentifier name = node.name;
+          offset = returnType.offset;
+          length = (name != null ? name.end : returnType.end) - offset;
+        }
+        _errorReporter.reportErrorForOffset(CompileTimeErrorCode.NO_DEFAULT_SUPER_CONSTRUCTOR_EXPLICIT, offset, length, [superType.displayName]);
+      }
+      return false;
+    }
+    _errorReporter.reportErrorForNode(CompileTimeErrorCode.UNDEFINED_CONSTRUCTOR_IN_INITIALIZER_DEFAULT, node.returnType, [superElement.name]);
+    return true;
+  }
+
+  /**
+   * This checks that if the given name is a reference to a static member it is defined in the
+   * enclosing class rather than in a superclass.
+   *
+   * @param name the name to be evaluated
+   * @return `true` if and only if an error code is generated on the passed node
+   * @see StaticTypeWarningCode#UNQUALIFIED_REFERENCE_TO_NON_LOCAL_STATIC_MEMBER
+   */
+  bool _checkForUnqualifiedReferenceToNonLocalStaticMember(SimpleIdentifier name) {
+    Element element = name.staticElement;
+    if (element == null || element is TypeParameterElement) {
+      return false;
+    }
+    Element enclosingElement = element.enclosingElement;
+    if (enclosingElement is! ClassElement) {
+      return false;
+    }
+    if ((element is MethodElement && !element.isStatic) || (element is PropertyAccessorElement && !element.isStatic)) {
+      return false;
+    }
+    if (identical(enclosingElement, _enclosingClass)) {
+      return false;
+    }
+    _errorReporter.reportErrorForNode(StaticTypeWarningCode.UNQUALIFIED_REFERENCE_TO_NON_LOCAL_STATIC_MEMBER, name, [name.name]);
+    return true;
+  }
+
+  void _checkForValidField(FieldFormalParameter node) {
+    ParameterElement element = node.element;
+    if (element is FieldFormalParameterElement) {
+      FieldElement fieldElement = element.field;
+      if (fieldElement == null || fieldElement.isSynthetic) {
+        _errorReporter.reportErrorForNode(CompileTimeErrorCode.INITIALIZING_FORMAL_FOR_NON_EXISTENT_FIELD, node, [node.identifier.name]);
+      } else {
+        ParameterElement parameterElement = node.element;
+        if (parameterElement is FieldFormalParameterElementImpl) {
+          FieldFormalParameterElementImpl fieldFormal = parameterElement;
+          DartType declaredType = fieldFormal.type;
+          DartType fieldType = fieldElement.type;
+          if (fieldElement.isSynthetic) {
+            _errorReporter.reportErrorForNode(CompileTimeErrorCode.INITIALIZING_FORMAL_FOR_NON_EXISTENT_FIELD, node, [node.identifier.name]);
+          } else if (fieldElement.isStatic) {
+            _errorReporter.reportErrorForNode(CompileTimeErrorCode.INITIALIZING_FORMAL_FOR_STATIC_FIELD, node, [node.identifier.name]);
+          } else if (declaredType != null && fieldType != null && !declaredType.isAssignableTo(fieldType)) {
+            _errorReporter.reportTypeErrorForNode(StaticWarningCode.FIELD_INITIALIZING_FORMAL_NOT_ASSIGNABLE, node, [declaredType, fieldType]);
+          }
+        } else {
+          if (fieldElement.isSynthetic) {
+            _errorReporter.reportErrorForNode(CompileTimeErrorCode.INITIALIZING_FORMAL_FOR_NON_EXISTENT_FIELD, node, [node.identifier.name]);
+          } else if (fieldElement.isStatic) {
+            _errorReporter.reportErrorForNode(CompileTimeErrorCode.INITIALIZING_FORMAL_FOR_STATIC_FIELD, node, [node.identifier.name]);
+          }
+        }
+      }
+    }
+    //    else {
+    //    // TODO(jwren) Report error, constructor initializer variable is a top level element
+    //    // (Either here or in ErrorVerifier#checkForAllFinalInitializedErrorCodes)
+    //    }
+  }
+
+  /**
+   * This verifies that the given getter does not have a return type of 'void'.
+   *
+   * @param node the method declaration to evaluate
+   * @return `true` if and only if an error code is generated on the passed node
+   * @see StaticWarningCode#VOID_RETURN_FOR_GETTER
+   */
+  bool _checkForVoidReturnType(MethodDeclaration node) {
+    TypeName returnType = node.returnType;
+    if (returnType == null || returnType.name.name != "void") {
+      return false;
+    }
+    _errorReporter.reportErrorForNode(StaticWarningCode.VOID_RETURN_FOR_GETTER, returnType, []);
+    return true;
+  }
+
+  /**
+   * This verifies the passed operator-method declaration, has correct number of parameters.
+   *
+   * This method assumes that the method declaration was tested to be an operator declaration before
+   * being called.
+   *
+   * @param node the method declaration to evaluate
+   * @return `true` if and only if an error code is generated on the passed node
+   * @see CompileTimeErrorCode#WRONG_NUMBER_OF_PARAMETERS_FOR_OPERATOR
+   */
+  bool _checkForWrongNumberOfParametersForOperator(MethodDeclaration node) {
+    // prepare number of parameters
+    FormalParameterList parameterList = node.parameters;
+    if (parameterList == null) {
+      return false;
+    }
+    int numParameters = parameterList.parameters.length;
+    // prepare operator name
+    SimpleIdentifier nameNode = node.name;
+    if (nameNode == null) {
+      return false;
+    }
+    String name = nameNode.name;
+    // check for exact number of parameters
+    int expected = -1;
+    if ("[]=" == name) {
+      expected = 2;
+    } else if ("<" == name || ">" == name || "<=" == name || ">=" == name || "==" == name || "+" == name || "/" == name || "~/" == name || "*" == name || "%" == name || "|" == name || "^" == name || "&" == name || "<<" == name || ">>" == name || "[]" == name) {
+      expected = 1;
+    } else if ("~" == name) {
+      expected = 0;
+    }
+    if (expected != -1 && numParameters != expected) {
+      _errorReporter.reportErrorForNode(CompileTimeErrorCode.WRONG_NUMBER_OF_PARAMETERS_FOR_OPERATOR, nameNode, [name, expected, numParameters]);
+      return true;
+    }
+    // check for operator "-"
+    if ("-" == name && numParameters > 1) {
+      _errorReporter.reportErrorForNode(CompileTimeErrorCode.WRONG_NUMBER_OF_PARAMETERS_FOR_OPERATOR_MINUS, nameNode, [numParameters]);
+      return true;
+    }
+    // OK
+    return false;
+  }
+
+  /**
+   * This verifies if the passed setter parameter list have only one required parameter.
+   *
+   * This method assumes that the method declaration was tested to be a setter before being called.
+   *
+   * @param setterName the name of the setter to report problems on
+   * @param parameterList the parameter list to evaluate
+   * @return `true` if and only if an error code is generated on the passed node
+   * @see CompileTimeErrorCode#WRONG_NUMBER_OF_PARAMETERS_FOR_SETTER
+   */
+  bool _checkForWrongNumberOfParametersForSetter(SimpleIdentifier setterName, FormalParameterList parameterList) {
+    if (setterName == null) {
+      return false;
+    }
+    if (parameterList == null) {
+      return false;
+    }
+    NodeList<FormalParameter> parameters = parameterList.parameters;
+    if (parameters.length != 1 || parameters[0].kind != ParameterKind.REQUIRED) {
+      _errorReporter.reportErrorForNode(CompileTimeErrorCode.WRONG_NUMBER_OF_PARAMETERS_FOR_SETTER, setterName, []);
+      return true;
+    }
+    return false;
+  }
+
+  /**
+   * This verifies that if the given class declaration implements the class Function that it has a
+   * concrete implementation of the call method.
+   *
+   * @return `true` if and only if an error code is generated on the passed node
+   * @see StaticWarningCode#FUNCTION_WITHOUT_CALL
+   */
+  bool _checkImplementsFunctionWithoutCall(ClassDeclaration node) {
+    if (node.isAbstract) {
+      return false;
+    }
+    ClassElement classElement = node.element;
+    if (classElement == null) {
+      return false;
+    }
+    if (!classElement.type.isSubtypeOf(_typeProvider.functionType)) {
+      return false;
+    }
+    // If there is a noSuchMethod method, then don't report the warning, see dartbug.com/16078
+    if (classElement.getMethod(FunctionElement.NO_SUCH_METHOD_METHOD_NAME) != null) {
+      return false;
+    }
+    ExecutableElement callMethod = _inheritanceManager.lookupMember(classElement, "call");
+    if (callMethod == null || callMethod is! MethodElement || (callMethod as MethodElement).isAbstract) {
+      _errorReporter.reportErrorForNode(StaticWarningCode.FUNCTION_WITHOUT_CALL, node.name, []);
+      return true;
+    }
+    return false;
+  }
+
+  /**
+   * This verifies that the given class declaration does not have the same class in the 'extends'
+   * and 'implements' clauses.
+   *
+   * @return `true` if and only if an error code is generated on the passed node
+   * @see CompileTimeErrorCode#IMPLEMENTS_SUPER_CLASS
+   */
+  bool _checkImplementsSuperClass(ClassDeclaration node) {
+    // prepare super type
+    InterfaceType superType = _enclosingClass.supertype;
+    if (superType == null) {
+      return false;
+    }
+    // prepare interfaces
+    ImplementsClause implementsClause = node.implementsClause;
+    if (implementsClause == null) {
+      return false;
+    }
+    // check interfaces
+    bool hasProblem = false;
+    for (TypeName interfaceNode in implementsClause.interfaces) {
+      if (interfaceNode.type == superType) {
+        hasProblem = true;
+        _errorReporter.reportErrorForNode(CompileTimeErrorCode.IMPLEMENTS_SUPER_CLASS, interfaceNode, [superType.displayName]);
+      }
+    }
+    // done
+    return hasProblem;
+  }
+
+  /**
+   * Return the error code that should be used when the given class references itself directly.
+   *
+   * @param classElt the class that references itself
+   * @return the error code that should be used
+   */
+  ErrorCode _getBaseCaseErrorCode(ClassElement classElt) {
+    InterfaceType supertype = classElt.supertype;
+    if (supertype != null && _enclosingClass == supertype.element) {
+      return CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_EXTENDS;
+    }
+    List<InterfaceType> mixins = classElt.mixins;
+    for (int i = 0; i < mixins.length; i++) {
+      if (_enclosingClass == mixins[i].element) {
+        return CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_WITH;
+      }
+    }
+    return CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_IMPLEMENTS;
+  }
+
+  /**
+   * Given an expression in a switch case whose value is expected to be an enum constant, return the
+   * name of the constant.
+   *
+   * @param expression the expression from the switch case
+   * @return the name of the constant referenced by the expression
+   */
+  String _getConstantName(Expression expression) {
+    // TODO(brianwilkerson) Convert this to return the element representing the constant.
+    if (expression is SimpleIdentifier) {
+      return expression.name;
+    } else if (expression is PrefixedIdentifier) {
+      return expression.identifier.name;
+    } else if (expression is PropertyAccess) {
+      return expression.propertyName.name;
+    }
+    return null;
+  }
+
+  /**
+   * Returns the Type (return type) for a given getter.
+   *
+   * @param propertyAccessorElement
+   * @return The type of the given getter.
+   */
+  DartType _getGetterType(PropertyAccessorElement propertyAccessorElement) {
+    FunctionType functionType = propertyAccessorElement.type;
+    if (functionType != null) {
+      return functionType.returnType;
+    } else {
+      return null;
+    }
+  }
+
+  /**
+   * Returns the Type (first and only parameter) for a given setter.
+   *
+   * @param propertyAccessorElement
+   * @return The type of the given setter.
+   */
+  DartType _getSetterType(PropertyAccessorElement propertyAccessorElement) {
+    // Get the parameters for MethodDeclaration or FunctionDeclaration
+    List<ParameterElement> setterParameters = propertyAccessorElement.parameters;
+    // If there are no setter parameters, return no type.
+    if (setterParameters.length == 0) {
+      return null;
+    }
+    return setterParameters[0].type;
+  }
+
+  /**
+   * Given a list of directives that have the same prefix, generate an error if there is more than
+   * one import and any of those imports is deferred.
+   *
+   * @param directives the list of directives that have the same prefix
+   * @return `true` if an error was generated
+   * @see CompileTimeErrorCode#SHARED_DEFERRED_PREFIX
+   */
+  bool _hasDeferredPrefixCollision(List<ImportDirective> directives) {
+    bool foundError = false;
+    int count = directives.length;
+    if (count > 1) {
+      for (int i = 0; i < count; i++) {
+        sc.Token deferredToken = directives[i].deferredToken;
+        if (deferredToken != null) {
+          _errorReporter.reportErrorForToken(CompileTimeErrorCode.SHARED_DEFERRED_PREFIX, deferredToken, []);
+          foundError = true;
+        }
+      }
+    }
+    return foundError;
+  }
+
+  /**
+   * @return `true` if the given constructor redirects to itself, directly or indirectly
+   */
+  bool _hasRedirectingFactoryConstructorCycle(ConstructorElement element) {
+    Set<ConstructorElement> constructors = new HashSet<ConstructorElement>();
+    ConstructorElement current = element;
+    while (current != null) {
+      if (constructors.contains(current)) {
+        return identical(current, element);
+      }
+      constructors.add(current);
+      current = current.redirectedConstructor;
+      if (current is ConstructorMember) {
+        current = (current as ConstructorMember).baseElement;
+      }
+    }
+    return false;
+  }
+
+  /**
+   * @return <code>true</code> if given [Element] has direct or indirect reference to itself
+   *         from anywhere except [ClassElement] or type parameter bounds.
+   */
+  bool _hasTypedefSelfReference(Element target) {
+    Set<Element> checked = new HashSet<Element>();
+    List<Element> toCheck = new List<Element>();
+    toCheck.add(target);
+    bool firstIteration = true;
+    while (true) {
+      Element current;
+      // get next element
+      while (true) {
+        // may be no more elements to check
+        if (toCheck.isEmpty) {
+          return false;
+        }
+        // try to get next element
+        current = toCheck.removeAt(toCheck.length - 1);
+        if (target == current) {
+          if (firstIteration) {
+            firstIteration = false;
+            break;
+          } else {
+            return true;
+          }
+        }
+        if (current != null && !checked.contains(current)) {
+          break;
+        }
+      }
+      // check current element
+      current.accept(new GeneralizingElementVisitor_ErrorVerifier_hasTypedefSelfReference(target, toCheck));
+      checked.add(current);
+    }
+  }
+
+  bool _isFunctionType(DartType type) {
+    if (type.isDynamic || type.isBottom) {
+      return true;
+    } else if (type is FunctionType || type.isDartCoreFunction) {
+      return true;
+    } else if (type is InterfaceType) {
+      MethodElement callMethod = type.lookUpMethod(FunctionElement.CALL_METHOD_NAME, _currentLibrary);
+      return callMethod != null;
+    }
+    return false;
+  }
+
+  /**
+   * Return `true` if the given type represents the class `Future` from the
+   * `dart:async` library.
+   *
+   * @param type the type to be tested
+   * @return `true` if the given type represents the class `Future` from the
+   *         `dart:async` library
+   */
+  bool _isFuture(DartType type) {
+    if (type is InterfaceType) {
+      InterfaceType interfaceType = type;
+      if (interfaceType.name == "Future") {
+        ClassElement element = interfaceType.element;
+        if (element != null) {
+          LibraryElement library = element.library;
+          if (library.name == "dart.async") {
+            return true;
+          }
+        }
+      }
+    }
+    return false;
+  }
+
+  /**
+   * Return `true` iff the passed [ClassElement] has a method, getter or setter that
+   * matches the name of the passed [ExecutableElement] in either the class itself, or one of
+   * its' mixins that is concrete.
+   *
+   * By "match", only the name of the member is tested to match, it does not have to equal or be a
+   * subtype of the passed executable element, this is due to the specific use where this method is
+   * used in [checkForNonAbstractClassInheritsAbstractMember].
+   *
+   * @param executableElt the executable to search for in the passed class element
+   * @param classElt the class method to search through the members of
+   * @return `true` iff the passed member is found in the passed class element
+   */
+  bool _isMemberInClassOrMixin(ExecutableElement executableElt, ClassElement classElt) {
+    ExecutableElement foundElt = null;
+    String executableName = executableElt.name;
+    if (executableElt is MethodElement) {
+      foundElt = classElt.getMethod(executableName);
+      if (foundElt != null && !(foundElt as MethodElement).isAbstract) {
+        return true;
+      }
+      List<InterfaceType> mixins = classElt.mixins;
+      for (int i = 0; i < mixins.length && foundElt == null; i++) {
+        foundElt = mixins[i].getMethod(executableName);
+      }
+      if (foundElt != null && !(foundElt as MethodElement).isAbstract) {
+        return true;
+      }
+    } else if (executableElt is PropertyAccessorElement) {
+      PropertyAccessorElement propertyAccessorElement = executableElt;
+      if (propertyAccessorElement.isGetter) {
+        foundElt = classElt.getGetter(executableName);
+      }
+      if (foundElt == null && propertyAccessorElement.isSetter) {
+        foundElt = classElt.getSetter(executableName);
+      }
+      if (foundElt != null && !(foundElt as PropertyAccessorElement).isAbstract) {
+        return true;
+      }
+      List<InterfaceType> mixins = classElt.mixins;
+      for (int i = 0; i < mixins.length && foundElt == null; i++) {
+        foundElt = mixins[i].getGetter(executableName);
+        if (foundElt == null) {
+          foundElt = mixins[i].getSetter(executableName);
+        }
+      }
+      if (foundElt != null && !(foundElt as PropertyAccessorElement).isAbstract) {
+        return true;
+      }
+    }
+    return false;
+  }
+
+  /**
+   * @param node the 'this' expression to analyze
+   * @return `true` if the given 'this' expression is in the valid context
+   */
+  bool _isThisInValidContext(ThisExpression node) {
+    for (AstNode n = node; n != null; n = n.parent) {
+      if (n is CompilationUnit) {
+        return false;
+      }
+      if (n is ConstructorDeclaration) {
+        ConstructorDeclaration constructor = n as ConstructorDeclaration;
+        return constructor.factoryKeyword == null;
+      }
+      if (n is ConstructorInitializer) {
+        return false;
+      }
+      if (n is MethodDeclaration) {
+        MethodDeclaration method = n as MethodDeclaration;
+        return !method.isStatic;
+      }
+    }
+    return false;
+  }
+
+  /**
+   * Return `true` if the given identifier is in a location where it is allowed to resolve to
+   * a static member of a supertype.
+   *
+   * @param node the node being tested
+   * @return `true` if the given identifier is in a location where it is allowed to resolve to
+   *         a static member of a supertype
+   */
+  bool _isUnqualifiedReferenceToNonLocalStaticMemberAllowed(SimpleIdentifier node) {
+    if (node.inDeclarationContext()) {
+      return true;
+    }
+    AstNode parent = node.parent;
+    if (parent is ConstructorName || parent is MethodInvocation || parent is PropertyAccess || parent is SuperConstructorInvocation) {
+      return true;
+    }
+    if (parent is PrefixedIdentifier && identical(parent.identifier, node)) {
+      return true;
+    }
+    if (parent is Annotation && identical(parent.constructorName, node)) {
+      return true;
+    }
+    if (parent is CommentReference) {
+      CommentReference commentReference = parent;
+      if (commentReference.newKeyword != null) {
+        return true;
+      }
+    }
+    return false;
+  }
+
+  bool _isUserDefinedObject(EvaluationResultImpl result) => result == null || (result.value != null && result.value.isUserDefinedObject);
+
+  /**
+   * This checks the class declaration is not a superinterface to itself.
+   *
+   * @param classElt the class element to test
+   * @param path a list containing the potentially cyclic implements path
+   * @return `true` if and only if an error code is generated on the passed element
+   * @see CompileTimeErrorCode#RECURSIVE_INTERFACE_INHERITANCE
+   * @see CompileTimeErrorCode#RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_EXTENDS
+   * @see CompileTimeErrorCode#RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_IMPLEMENTS
+   * @see CompileTimeErrorCode#RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_WITH
+   */
+  bool _safeCheckForRecursiveInterfaceInheritance(ClassElement classElt, List<ClassElement> path) {
+    // Detect error condition.
+    int size = path.length;
+    // If this is not the base case (size > 0), and the enclosing class is the passed class
+    // element then an error an error.
+    if (size > 0 && _enclosingClass == classElt) {
+      String enclosingClassName = _enclosingClass.displayName;
+      if (size > 1) {
+        // Construct a string showing the cyclic implements path: "A, B, C, D, A"
+        String separator = ", ";
+        StringBuffer buffer = new StringBuffer();
+        for (int i = 0; i < size; i++) {
+          buffer.write(path[i].displayName);
+          buffer.write(separator);
+        }
+        buffer.write(classElt.displayName);
+        _errorReporter.reportErrorForOffset(CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE, _enclosingClass.nameOffset, enclosingClassName.length, [enclosingClassName, buffer.toString()]);
+        return true;
+      } else {
+        // RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_EXTENDS or
+        // RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_IMPLEMENTS or
+        // RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_WITH
+        _errorReporter.reportErrorForOffset(_getBaseCaseErrorCode(classElt), _enclosingClass.nameOffset, enclosingClassName.length, [enclosingClassName]);
+        return true;
+      }
+    }
+    if (path.indexOf(classElt) > 0) {
+      return false;
+    }
+    path.add(classElt);
+    // n-case
+    InterfaceType supertype = classElt.supertype;
+    if (supertype != null && _safeCheckForRecursiveInterfaceInheritance(supertype.element, path)) {
+      return true;
+    }
+    List<InterfaceType> interfaceTypes = classElt.interfaces;
+    for (InterfaceType interfaceType in interfaceTypes) {
+      if (_safeCheckForRecursiveInterfaceInheritance(interfaceType.element, path)) {
+        return true;
+      }
+    }
+    List<InterfaceType> mixinTypes = classElt.mixins;
+    for (InterfaceType mixinType in mixinTypes) {
+      if (_safeCheckForRecursiveInterfaceInheritance(mixinType.element, path)) {
+        return true;
+      }
+    }
+    path.removeAt(path.length - 1);
+    return false;
+  }
+}
+
+class GeneralizingElementVisitor_ErrorVerifier_hasTypedefSelfReference extends GeneralizingElementVisitor<Object> {
+  Element target;
+
+  List<Element> toCheck;
+
+  GeneralizingElementVisitor_ErrorVerifier_hasTypedefSelfReference(this.target, this.toCheck) : super();
+
+  bool _inClass = false;
+
+  @override
+  Object visitClassElement(ClassElement element) {
+    _addTypeToCheck(element.supertype);
+    for (InterfaceType mixin in element.mixins) {
+      _addTypeToCheck(mixin);
+    }
+    _inClass = !element.isTypedef;
+    try {
+      return super.visitClassElement(element);
+    } finally {
+      _inClass = false;
+    }
+  }
+
+  @override
+  Object visitExecutableElement(ExecutableElement element) {
+    if (element.isSynthetic) {
+      return null;
+    }
+    _addTypeToCheck(element.returnType);
+    return super.visitExecutableElement(element);
+  }
+
+  @override
+  Object visitFunctionTypeAliasElement(FunctionTypeAliasElement element) {
+    _addTypeToCheck(element.returnType);
+    return super.visitFunctionTypeAliasElement(element);
+  }
+
+  @override
+  Object visitParameterElement(ParameterElement element) {
+    _addTypeToCheck(element.type);
+    return super.visitParameterElement(element);
+  }
+
+  @override
+  Object visitTypeParameterElement(TypeParameterElement element) {
+    _addTypeToCheck(element.bound);
+    return super.visitTypeParameterElement(element);
+  }
+
+  @override
+  Object visitVariableElement(VariableElement element) {
+    _addTypeToCheck(element.type);
+    return super.visitVariableElement(element);
+  }
+
+  void _addTypeToCheck(DartType type) {
+    if (type == null) {
+      return;
+    }
+    Element element = type.element;
+    // it is OK to reference target from class
+    if (_inClass && target == element) {
+      return;
+    }
+    // schedule for checking
+    toCheck.add(element);
+    // type arguments
+    if (type is InterfaceType) {
+      InterfaceType interfaceType = type;
+      for (DartType typeArgument in interfaceType.typeArguments) {
+        _addTypeToCheck(typeArgument);
+      }
+    }
+  }
+}
diff --git a/pkg/analyzer/lib/src/generated/html.dart b/pkg/analyzer/lib/src/generated/html.dart
index 41ae5ea..50743a1 100644
--- a/pkg/analyzer/lib/src/generated/html.dart
+++ b/pkg/analyzer/lib/src/generated/html.dart
@@ -1543,7 +1543,11 @@
     XmlNode current = newParent;
     while (current != null) {
       if (identical(current, this)) {
-        AnalysisEngine.instance.logger.logError2("Circular structure while setting an XML node's parent", new IllegalArgumentException(_buildRecursiveStructureMessage(newParent)));
+        AnalysisEngine.instance.logger.logError(
+            "Circular structure while setting an XML node's parent",
+            new CaughtException(
+                new ArgumentError(_buildRecursiveStructureMessage(newParent)),
+                null));
         return;
       }
       current = current.parent;
diff --git a/pkg/analyzer/lib/src/generated/parser.dart b/pkg/analyzer/lib/src/generated/parser.dart
index a609a4a..0e7d123 100644
--- a/pkg/analyzer/lib/src/generated/parser.dart
+++ b/pkg/analyzer/lib/src/generated/parser.dart
@@ -8820,7 +8820,7 @@
         _isEqualTokens(node.leftParenthesis, toNode.leftParenthesis),
         _isEqualNodes(node.loopVariable, toNode.loopVariable),
         _isEqualTokens(node.inKeyword, toNode.inKeyword),
-        _isEqualNodes(node.iterator, toNode.iterator),
+        _isEqualNodes(node.iterable, toNode.iterable),
         _isEqualTokens(node.rightParenthesis, toNode.rightParenthesis),
         _isEqualNodes(node.body, toNode.body));
   }
diff --git a/pkg/analyzer/lib/src/generated/resolver.dart b/pkg/analyzer/lib/src/generated/resolver.dart
index c1c4bed..aeaa972 100644
--- a/pkg/analyzer/lib/src/generated/resolver.dart
+++ b/pkg/analyzer/lib/src/generated/resolver.dart
@@ -2,9 +2,6 @@
 // for 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 code was auto-generated, is not intended to be edited, and is subject to
-// significant change. Please see the README file for more information.
-
 library engine.resolver;
 
 import 'dart:collection';
@@ -19,12 +16,14 @@
 import 'utilities_dart.dart';
 import 'utilities_general.dart';
 import 'ast.dart';
-import 'parser.dart' show Parser, ParserErrorCode;
 import 'sdk.dart' show DartSdk, SdkLibrary;
 import 'element.dart';
 import 'html.dart' as ht;
 import 'engine.dart';
 import 'constant.dart';
+import 'error_verifier.dart';
+import 'element_resolver.dart';
+import 'static_type_analyzer.dart';
 
 /**
  * Instances of the class `AngularCompilationUnitBuilder` build an Angular specific element
@@ -3385,7 +3384,9 @@
         buffer.writeln("---------");
         parent = parent.parent;
       }
-      AnalysisEngine.instance.logger.logError2(buffer.toString(), new CaughtException(new AnalysisException(), null));
+      AnalysisEngine.instance.logger.logError(
+          buffer.toString(),
+          new CaughtException(new AnalysisException(), null));
     }
     return element;
   }
@@ -3986,7 +3987,7 @@
         }
       }
       holder.validate();
-    } catch (ex) {
+    } catch (exception, stackTrace) {
       if (node.name.staticElement == null) {
         ClassDeclaration classNode = node.getAncestor((node) => node is ClassDeclaration);
         StringBuffer buffer = new StringBuffer();
@@ -3995,10 +3996,14 @@
         buffer.write(" in ");
         buffer.write(classNode.name);
         buffer.write(" was not set while trying to build the element model.");
-        AnalysisEngine.instance.logger.logError2(buffer.toString(), new AnalysisException(buffer.toString(), new CaughtException(ex, null)));
+        AnalysisEngine.instance.logger.logError(
+            buffer.toString(),
+            new CaughtException(exception, stackTrace));
       } else {
         String message = "Exception caught in ElementBuilder.visitMethodDeclaration()";
-        AnalysisEngine.instance.logger.logError2(message, new AnalysisException(message, new CaughtException(ex, null)));
+        AnalysisEngine.instance.logger.logError(
+            message,
+            new CaughtException(exception, stackTrace));
       }
     } finally {
       if (node.name.staticElement == null) {
@@ -4009,7 +4014,9 @@
         buffer.write(" in ");
         buffer.write(classNode.name);
         buffer.write(" was not set while trying to resolve types.");
-        AnalysisEngine.instance.logger.logError2(buffer.toString(), new CaughtException(new AnalysisException(buffer.toString()), null));
+        AnalysisEngine.instance.logger.logError(
+            buffer.toString(),
+            new CaughtException(new AnalysisException(buffer.toString()), null));
       }
     }
     return null;
@@ -4646,2627 +4653,6 @@
 }
 
 /**
- * Instances of the class `ElementResolver` are used by instances of [ResolverVisitor]
- * to resolve references within the AST structure to the elements being referenced. The requirements
- * for the element resolver are:
- * <ol>
- * * Every [SimpleIdentifier] should be resolved to the element to which it refers.
- * Specifically:
- * * An identifier within the declaration of that name should resolve to the element being
- * declared.
- * * An identifier denoting a prefix should resolve to the element representing the import that
- * defines the prefix (an [ImportElement]).
- * * An identifier denoting a variable should resolve to the element representing the variable (a
- * [VariableElement]).
- * * An identifier denoting a parameter should resolve to the element representing the parameter
- * (a [ParameterElement]).
- * * An identifier denoting a field should resolve to the element representing the getter or
- * setter being invoked (a [PropertyAccessorElement]).
- * * An identifier denoting the name of a method or function being invoked should resolve to the
- * element representing the method or function (a [ExecutableElement]).
- * * An identifier denoting a label should resolve to the element representing the label (a
- * [LabelElement]).
- * The identifiers within directives are exceptions to this rule and are covered below.
- * * Every node containing a token representing an operator that can be overridden (
- * [BinaryExpression], [PrefixExpression], [PostfixExpression]) should resolve to
- * the element representing the method invoked by that operator (a [MethodElement]).
- * * Every [FunctionExpressionInvocation] should resolve to the element representing the
- * function being invoked (a [FunctionElement]). This will be the same element as that to
- * which the name is resolved if the function has a name, but is provided for those cases where an
- * unnamed function is being invoked.
- * * Every [LibraryDirective] and [PartOfDirective] should resolve to the element
- * representing the library being specified by the directive (a [LibraryElement]) unless, in
- * the case of a part-of directive, the specified library does not exist.
- * * Every [ImportDirective] and [ExportDirective] should resolve to the element
- * representing the library being specified by the directive unless the specified library does not
- * exist (an [ImportElement] or [ExportElement]).
- * * The identifier representing the prefix in an [ImportDirective] should resolve to the
- * element representing the prefix (a [PrefixElement]).
- * * The identifiers in the hide and show combinators in [ImportDirective]s and
- * [ExportDirective]s should resolve to the elements that are being hidden or shown,
- * respectively, unless those names are not defined in the specified library (or the specified
- * library does not exist).
- * * Every [PartDirective] should resolve to the element representing the compilation unit
- * being specified by the string unless the specified compilation unit does not exist (a
- * [CompilationUnitElement]).
- * </ol>
- * Note that AST nodes that would represent elements that are not defined are not resolved to
- * anything. This includes such things as references to undeclared variables (which is an error) and
- * names in hide and show combinators that are not defined in the imported library (which is not an
- * error).
- */
-class ElementResolver extends SimpleAstVisitor<Object> {
-  /**
-   * Checks whether the given expression is a reference to a class. If it is then the
-   * [ClassElement] is returned, otherwise `null` is returned.
-   *
-   * @param expression the expression to evaluate
-   * @return the element representing the class
-   */
-  static ClassElementImpl getTypeReference(Expression expression) {
-    if (expression is Identifier) {
-      Element staticElement = expression.staticElement;
-      if (staticElement is ClassElementImpl) {
-        return staticElement;
-      }
-    }
-    return null;
-  }
-
-  /**
-   * Helper function for `maybeMergeExecutableElements` that does the actual merging.
-   *
-   * @param elementArrayToMerge non-empty array of elements to merge.
-   * @return
-   */
-  static ExecutableElement _computeMergedExecutableElement(List<ExecutableElement> elementArrayToMerge) {
-    // Flatten methods structurally. Based on
-    // [InheritanceManager.computeMergedExecutableElement] and
-    // [InheritanceManager.createSyntheticExecutableElement].
-    //
-    // However, the approach we take here is much simpler, but expected to work
-    // well in the common case. It degrades gracefully in the uncommon case,
-    // by computing the type [dynamic] for the method, preventing any
-    // hints from being generated (TODO: not done yet).
-    //
-    // The approach is: we require that each [ExecutableElement] has the
-    // same shape: the same number of required, optional positional, and optional named
-    // parameters, in the same positions, and with the named parameters in the
-    // same order. We compute a type by unioning pointwise.
-    ExecutableElement e_0 = elementArrayToMerge[0];
-    List<ParameterElement> ps_0 = e_0.parameters;
-    List<ParameterElementImpl> ps_out = new List<ParameterElementImpl>(ps_0.length);
-    for (int j = 0; j < ps_out.length; j++) {
-      ps_out[j] = new ParameterElementImpl(ps_0[j].name, 0);
-      ps_out[j].synthetic = true;
-      ps_out[j].type = ps_0[j].type;
-      ps_out[j].parameterKind = ps_0[j].parameterKind;
-    }
-    DartType r_out = e_0.returnType;
-    for (int i = 1; i < elementArrayToMerge.length; i++) {
-      ExecutableElement e_i = elementArrayToMerge[i];
-      r_out = UnionTypeImpl.union([r_out, e_i.returnType]);
-      List<ParameterElement> ps_i = e_i.parameters;
-      // Each function must have the same number of params.
-      if (ps_0.length != ps_i.length) {
-        return null;
-        // TODO (collinsn): return an element representing [dynamic] here instead.
-      } else {
-        // Each function must have the same kind of params, with the same names,
-        // in the same order.
-        for (int j = 0; j < ps_i.length; j++) {
-          if (ps_0[j].parameterKind != ps_i[j].parameterKind || !identical(ps_0[j].name, ps_i[j].name)) {
-            return null;
-          } else {
-            // The output parameter type is the union of the input parameter types.
-            ps_out[j].type = UnionTypeImpl.union([ps_out[j].type, ps_i[j].type]);
-          }
-        }
-      }
-    }
-    // TODO (collinsn): this code should work for functions and methods,
-    // so we may want [FunctionElementImpl]
-    // instead here in some cases? And then there are constructors and property accessors.
-    // Maybe the answer is to create a new subclass of [ExecutableElementImpl] which
-    // is used for merged executable elements, in analogy with [MultiplyInheritedMethodElementImpl]
-    // and [MultiplyInheritedPropertyAcessorElementImpl].
-    ExecutableElementImpl e_out = new MethodElementImpl(e_0.name, 0);
-    e_out.synthetic = true;
-    e_out.returnType = r_out;
-    e_out.parameters = ps_out;
-    e_out.type = new FunctionTypeImpl.con1(e_out);
-    // Get NPE in [toString()] w/o this.
-    e_out.enclosingElement = e_0.enclosingElement;
-    return e_out;
-  }
-
-  /**
-   * Return `true` if the given identifier is the return type of a constructor declaration.
-   *
-   * @return `true` if the given identifier is the return type of a constructor declaration.
-   */
-  static bool _isConstructorReturnType(SimpleIdentifier identifier) {
-    AstNode parent = identifier.parent;
-    if (parent is ConstructorDeclaration) {
-      return identical(parent.returnType, identifier);
-    }
-    return false;
-  }
-
-  /**
-   * Return `true` if the given identifier is the return type of a factory constructor.
-   *
-   * @return `true` if the given identifier is the return type of a factory constructor
-   *         declaration.
-   */
-  static bool _isFactoryConstructorReturnType(SimpleIdentifier node) {
-    AstNode parent = node.parent;
-    if (parent is ConstructorDeclaration) {
-      ConstructorDeclaration constructor = parent;
-      return identical(constructor.returnType, node) && constructor.factoryKeyword != null;
-    }
-    return false;
-  }
-
-  /**
-   * Return `true` if the given 'super' expression is used in a valid context.
-   *
-   * @param node the 'super' expression to analyze
-   * @return `true` if the 'super' expression is in a valid context
-   */
-  static bool _isSuperInValidContext(SuperExpression node) {
-    for (AstNode n = node; n != null; n = n.parent) {
-      if (n is CompilationUnit) {
-        return false;
-      }
-      if (n is ConstructorDeclaration) {
-        ConstructorDeclaration constructor = n as ConstructorDeclaration;
-        return constructor.factoryKeyword == null;
-      }
-      if (n is ConstructorFieldInitializer) {
-        return false;
-      }
-      if (n is MethodDeclaration) {
-        MethodDeclaration method = n as MethodDeclaration;
-        return !method.isStatic;
-      }
-    }
-    return false;
-  }
-
-  /**
-   * Return a method representing the merge of the given elements. The type of the merged element is
-   * the component-wise union of the types of the given elements. If not all input elements have the
-   * same shape then [null] is returned.
-   *
-   * @param elements the `ExecutableElement`s to merge
-   * @return an `ExecutableElement` representing the merge of `elements`
-   */
-  static ExecutableElement _maybeMergeExecutableElements(Set<ExecutableElement> elements) {
-    List<ExecutableElement> elementArrayToMerge = new List.from(elements);
-    if (elementArrayToMerge.length == 0) {
-      return null;
-    } else if (elementArrayToMerge.length == 1) {
-      // If all methods are equal, don't bother building a new one.
-      return elementArrayToMerge[0];
-    } else {
-      return _computeMergedExecutableElement(elementArrayToMerge);
-    }
-  }
-
-  /**
-   * The resolver driving this participant.
-   */
-  final ResolverVisitor _resolver;
-
-  /**
-   * The element for the library containing the compilation unit being visited.
-   */
-  LibraryElement _definingLibrary;
-
-  /**
-   * A flag indicating whether we should generate hints.
-   */
-  bool _enableHints = false;
-
-  /**
-   * The type representing the type 'dynamic'.
-   */
-  DartType _dynamicType;
-
-  /**
-   * The type representing the type 'type'.
-   */
-  DartType _typeType;
-
-  /**
-   * A utility class for the resolver to answer the question of "what are my subtypes?".
-   */
-  SubtypeManager _subtypeManager;
-
-  /**
-   * The object keeping track of which elements have had their types promoted.
-   */
-  TypePromotionManager _promoteManager;
-
-  /**
-   * Initialize a newly created visitor to resolve the nodes in a compilation unit.
-   *
-   * @param resolver the resolver driving this participant
-   */
-  ElementResolver(this._resolver) {
-    this._definingLibrary = _resolver.definingLibrary;
-    AnalysisOptions options = _definingLibrary.context.analysisOptions;
-    _enableHints = options.hint;
-    _dynamicType = _resolver.typeProvider.dynamicType;
-    _typeType = _resolver.typeProvider.typeType;
-    _subtypeManager = new SubtypeManager();
-    _promoteManager = _resolver.promoteManager;
-  }
-
-  @override
-  Object visitAssignmentExpression(AssignmentExpression node) {
-    sc.Token operator = node.operator;
-    sc.TokenType operatorType = operator.type;
-    if (operatorType != sc.TokenType.EQ) {
-      operatorType = _operatorFromCompoundAssignment(operatorType);
-      Expression leftHandSide = node.leftHandSide;
-      if (leftHandSide != null) {
-        String methodName = operatorType.lexeme;
-        DartType staticType = _getStaticType(leftHandSide);
-        MethodElement staticMethod = _lookUpMethod(leftHandSide, staticType, methodName);
-        node.staticElement = staticMethod;
-        DartType propagatedType = _getPropagatedType(leftHandSide);
-        MethodElement propagatedMethod = _lookUpMethod(leftHandSide, propagatedType, methodName);
-        node.propagatedElement = propagatedMethod;
-        if (_shouldReportMissingMember(staticType, staticMethod)) {
-          _recordUndefinedToken(staticType.element, StaticTypeWarningCode.UNDEFINED_METHOD, operator, [methodName, staticType.displayName]);
-        } else if (_enableHints && _shouldReportMissingMember(propagatedType, propagatedMethod) && !_memberFoundInSubclass(propagatedType.element, methodName, true, false)) {
-          _recordUndefinedToken(propagatedType.element, HintCode.UNDEFINED_METHOD, operator, [methodName, propagatedType.displayName]);
-        }
-      }
-    }
-    return null;
-  }
-
-  @override
-  Object visitBinaryExpression(BinaryExpression node) {
-    sc.Token operator = node.operator;
-    if (operator.isUserDefinableOperator) {
-      Expression leftOperand = node.leftOperand;
-      if (leftOperand != null) {
-        String methodName = operator.lexeme;
-        DartType staticType = _getStaticType(leftOperand);
-        MethodElement staticMethod = _lookUpMethod(leftOperand, staticType, methodName);
-        node.staticElement = staticMethod;
-        DartType propagatedType = _getPropagatedType(leftOperand);
-        MethodElement propagatedMethod = _lookUpMethod(leftOperand, propagatedType, methodName);
-        node.propagatedElement = propagatedMethod;
-        if (_shouldReportMissingMember(staticType, staticMethod)) {
-          _recordUndefinedToken(staticType.element, StaticTypeWarningCode.UNDEFINED_OPERATOR, operator, [methodName, staticType.displayName]);
-        } else if (_enableHints && _shouldReportMissingMember(propagatedType, propagatedMethod) && !_memberFoundInSubclass(propagatedType.element, methodName, true, false)) {
-          _recordUndefinedToken(propagatedType.element, HintCode.UNDEFINED_OPERATOR, operator, [methodName, propagatedType.displayName]);
-        }
-      }
-    }
-    return null;
-  }
-
-  @override
-  Object visitBreakStatement(BreakStatement node) {
-    _lookupLabel(node, node.label);
-    return null;
-  }
-
-  @override
-  Object visitClassDeclaration(ClassDeclaration node) {
-    _setMetadata(node.element, node);
-    return null;
-  }
-
-  @override
-  Object visitClassTypeAlias(ClassTypeAlias node) {
-    _setMetadata(node.element, node);
-    return null;
-  }
-
-  @override
-  Object visitCommentReference(CommentReference node) {
-    Identifier identifier = node.identifier;
-    if (identifier is SimpleIdentifier) {
-      SimpleIdentifier simpleIdentifier = identifier;
-      Element element = _resolveSimpleIdentifier(simpleIdentifier);
-      if (element == null) {
-        //
-        // This might be a reference to an imported name that is missing the prefix.
-        //
-        element = _findImportWithoutPrefix(simpleIdentifier);
-        if (element is MultiplyDefinedElement) {
-          // TODO(brianwilkerson) Report this error?
-          element = null;
-        }
-      }
-      if (element == null) {
-        // TODO(brianwilkerson) Report this error?
-        //        resolver.reportError(
-        //            StaticWarningCode.UNDEFINED_IDENTIFIER,
-        //            simpleIdentifier,
-        //            simpleIdentifier.getName());
-      } else {
-        if (element.library == null || element.library != _definingLibrary) {
-          // TODO(brianwilkerson) Report this error?
-        }
-        simpleIdentifier.staticElement = element;
-        if (node.newKeyword != null) {
-          if (element is ClassElement) {
-            ConstructorElement constructor = (element as ClassElement).unnamedConstructor;
-            if (constructor == null) {
-              // TODO(brianwilkerson) Report this error.
-            } else {
-              simpleIdentifier.staticElement = constructor;
-            }
-          } else {
-            // TODO(brianwilkerson) Report this error.
-          }
-        }
-      }
-    } else if (identifier is PrefixedIdentifier) {
-      PrefixedIdentifier prefixedIdentifier = identifier;
-      SimpleIdentifier prefix = prefixedIdentifier.prefix;
-      SimpleIdentifier name = prefixedIdentifier.identifier;
-      Element element = _resolveSimpleIdentifier(prefix);
-      if (element == null) {
-        //        resolver.reportError(StaticWarningCode.UNDEFINED_IDENTIFIER, prefix, prefix.getName());
-      } else {
-        if (element is PrefixElement) {
-          prefix.staticElement = element;
-          // TODO(brianwilkerson) Report this error?
-          element = _resolver.nameScope.lookup(identifier, _definingLibrary);
-          name.staticElement = element;
-          return null;
-        }
-        LibraryElement library = element.library;
-        if (library == null) {
-          // TODO(brianwilkerson) We need to understand how the library could ever be null.
-          AnalysisEngine.instance.logger.logError("Found element with null library: ${element.name}");
-        } else if (library != _definingLibrary) {
-          // TODO(brianwilkerson) Report this error.
-        }
-        name.staticElement = element;
-        if (node.newKeyword == null) {
-          if (element is ClassElement) {
-            Element memberElement = _lookupGetterOrMethod((element as ClassElement).type, name.name);
-            if (memberElement == null) {
-              memberElement = (element as ClassElement).getNamedConstructor(name.name);
-              if (memberElement == null) {
-                memberElement = _lookUpSetter(prefix, (element as ClassElement).type, name.name);
-              }
-            }
-            if (memberElement == null) {
-              //              reportGetterOrSetterNotFound(prefixedIdentifier, name, element.getDisplayName());
-            } else {
-              name.staticElement = memberElement;
-            }
-          } else {
-            // TODO(brianwilkerson) Report this error.
-          }
-        } else {
-          if (element is ClassElement) {
-            ConstructorElement constructor = (element as ClassElement).getNamedConstructor(name.name);
-            if (constructor == null) {
-              // TODO(brianwilkerson) Report this error.
-            } else {
-              name.staticElement = constructor;
-            }
-          } else {
-            // TODO(brianwilkerson) Report this error.
-          }
-        }
-      }
-    }
-    return null;
-  }
-
-  @override
-  Object visitConstructorDeclaration(ConstructorDeclaration node) {
-    super.visitConstructorDeclaration(node);
-    ConstructorElement element = node.element;
-    if (element is ConstructorElementImpl) {
-      ConstructorElementImpl constructorElement = element;
-      ConstructorName redirectedNode = node.redirectedConstructor;
-      if (redirectedNode != null) {
-        // set redirected factory constructor
-        ConstructorElement redirectedElement = redirectedNode.staticElement;
-        constructorElement.redirectedConstructor = redirectedElement;
-      } else {
-        // set redirected generative constructor
-        for (ConstructorInitializer initializer in node.initializers) {
-          if (initializer is RedirectingConstructorInvocation) {
-            ConstructorElement redirectedElement = initializer.staticElement;
-            constructorElement.redirectedConstructor = redirectedElement;
-          }
-        }
-      }
-      _setMetadata(constructorElement, node);
-    }
-    return null;
-  }
-
-  @override
-  Object visitConstructorFieldInitializer(ConstructorFieldInitializer node) {
-    SimpleIdentifier fieldName = node.fieldName;
-    ClassElement enclosingClass = _resolver.enclosingClass;
-    FieldElement fieldElement = enclosingClass.getField(fieldName.name);
-    fieldName.staticElement = fieldElement;
-    return null;
-  }
-
-  @override
-  Object visitConstructorName(ConstructorName node) {
-    DartType type = node.type.type;
-    if (type != null && type.isDynamic) {
-      return null;
-    } else if (type is! InterfaceType) {
-      // TODO(brianwilkerson) Report these errors.
-      //      ASTNode parent = node.getParent();
-      //      if (parent instanceof InstanceCreationExpression) {
-      //        if (((InstanceCreationExpression) parent).isConst()) {
-      //          // CompileTimeErrorCode.CONST_WITH_NON_TYPE
-      //        } else {
-      //          // StaticWarningCode.NEW_WITH_NON_TYPE
-      //        }
-      //      } else {
-      //        // This is part of a redirecting factory constructor; not sure which error code to use
-      //      }
-      return null;
-    }
-    // look up ConstructorElement
-    ConstructorElement constructor;
-    SimpleIdentifier name = node.name;
-    InterfaceType interfaceType = type as InterfaceType;
-    if (name == null) {
-      constructor = interfaceType.lookUpConstructor(null, _definingLibrary);
-    } else {
-      constructor = interfaceType.lookUpConstructor(name.name, _definingLibrary);
-      name.staticElement = constructor;
-    }
-    node.staticElement = constructor;
-    return null;
-  }
-
-  @override
-  Object visitContinueStatement(ContinueStatement node) {
-    _lookupLabel(node, node.label);
-    return null;
-  }
-
-  @override
-  Object visitDeclaredIdentifier(DeclaredIdentifier node) {
-    _setMetadata(node.element, node);
-    return null;
-  }
-
-  @override
-  Object visitExportDirective(ExportDirective node) {
-    ExportElement exportElement = node.element;
-    if (exportElement != null) {
-      // The element is null when the URI is invalid
-      // TODO(brianwilkerson) Figure out whether the element can ever be something other than an
-      // ExportElement
-      _resolveCombinators(exportElement.exportedLibrary, node.combinators);
-      _setMetadata(exportElement, node);
-    }
-    return null;
-  }
-
-  @override
-  Object visitFieldFormalParameter(FieldFormalParameter node) {
-    _setMetadataForParameter(node.element, node);
-    return super.visitFieldFormalParameter(node);
-  }
-
-  @override
-  Object visitFunctionDeclaration(FunctionDeclaration node) {
-    _setMetadata(node.element, node);
-    return null;
-  }
-
-  @override
-  Object visitFunctionExpressionInvocation(FunctionExpressionInvocation node) {
-    // TODO(brianwilkerson) Can we ever resolve the function being invoked?
-    Expression expression = node.function;
-    if (expression is FunctionExpression) {
-      FunctionExpression functionExpression = expression;
-      ExecutableElement functionElement = functionExpression.element;
-      ArgumentList argumentList = node.argumentList;
-      List<ParameterElement> parameters = _resolveArgumentsToFunction(false, argumentList, functionElement);
-      if (parameters != null) {
-        argumentList.correspondingStaticParameters = parameters;
-      }
-    }
-    return null;
-  }
-
-  @override
-  Object visitFunctionTypeAlias(FunctionTypeAlias node) {
-    _setMetadata(node.element, node);
-    return null;
-  }
-
-  @override
-  Object visitFunctionTypedFormalParameter(FunctionTypedFormalParameter node) {
-    _setMetadataForParameter(node.element, node);
-    return null;
-  }
-
-  @override
-  Object visitImportDirective(ImportDirective node) {
-    SimpleIdentifier prefixNode = node.prefix;
-    if (prefixNode != null) {
-      String prefixName = prefixNode.name;
-      for (PrefixElement prefixElement in _definingLibrary.prefixes) {
-        if (prefixElement.displayName == prefixName) {
-          prefixNode.staticElement = prefixElement;
-          break;
-        }
-      }
-    }
-    ImportElement importElement = node.element;
-    if (importElement != null) {
-      // The element is null when the URI is invalid
-      LibraryElement library = importElement.importedLibrary;
-      if (library != null) {
-        _resolveCombinators(library, node.combinators);
-      }
-      _setMetadata(importElement, node);
-    }
-    return null;
-  }
-
-  @override
-  Object visitIndexExpression(IndexExpression node) {
-    Expression target = node.realTarget;
-    DartType staticType = _getStaticType(target);
-    DartType propagatedType = _getPropagatedType(target);
-    String getterMethodName = sc.TokenType.INDEX.lexeme;
-    String setterMethodName = sc.TokenType.INDEX_EQ.lexeme;
-    bool isInGetterContext = node.inGetterContext();
-    bool isInSetterContext = node.inSetterContext();
-    if (isInGetterContext && isInSetterContext) {
-      // lookup setter
-      MethodElement setterStaticMethod = _lookUpMethod(target, staticType, setterMethodName);
-      MethodElement setterPropagatedMethod = _lookUpMethod(target, propagatedType, setterMethodName);
-      // set setter element
-      node.staticElement = setterStaticMethod;
-      node.propagatedElement = setterPropagatedMethod;
-      // generate undefined method warning
-      _checkForUndefinedIndexOperator(node, target, getterMethodName, setterStaticMethod, setterPropagatedMethod, staticType, propagatedType);
-      // lookup getter method
-      MethodElement getterStaticMethod = _lookUpMethod(target, staticType, getterMethodName);
-      MethodElement getterPropagatedMethod = _lookUpMethod(target, propagatedType, getterMethodName);
-      // set getter element
-      AuxiliaryElements auxiliaryElements = new AuxiliaryElements(getterStaticMethod, getterPropagatedMethod);
-      node.auxiliaryElements = auxiliaryElements;
-      // generate undefined method warning
-      _checkForUndefinedIndexOperator(node, target, getterMethodName, getterStaticMethod, getterPropagatedMethod, staticType, propagatedType);
-    } else if (isInGetterContext) {
-      // lookup getter method
-      MethodElement staticMethod = _lookUpMethod(target, staticType, getterMethodName);
-      MethodElement propagatedMethod = _lookUpMethod(target, propagatedType, getterMethodName);
-      // set getter element
-      node.staticElement = staticMethod;
-      node.propagatedElement = propagatedMethod;
-      // generate undefined method warning
-      _checkForUndefinedIndexOperator(node, target, getterMethodName, staticMethod, propagatedMethod, staticType, propagatedType);
-    } else if (isInSetterContext) {
-      // lookup setter method
-      MethodElement staticMethod = _lookUpMethod(target, staticType, setterMethodName);
-      MethodElement propagatedMethod = _lookUpMethod(target, propagatedType, setterMethodName);
-      // set setter element
-      node.staticElement = staticMethod;
-      node.propagatedElement = propagatedMethod;
-      // generate undefined method warning
-      _checkForUndefinedIndexOperator(node, target, setterMethodName, staticMethod, propagatedMethod, staticType, propagatedType);
-    }
-    return null;
-  }
-
-  @override
-  Object visitInstanceCreationExpression(InstanceCreationExpression node) {
-    ConstructorElement invokedConstructor = node.constructorName.staticElement;
-    node.staticElement = invokedConstructor;
-    ArgumentList argumentList = node.argumentList;
-    List<ParameterElement> parameters = _resolveArgumentsToFunction(node.isConst, argumentList, invokedConstructor);
-    if (parameters != null) {
-      argumentList.correspondingStaticParameters = parameters;
-    }
-    return null;
-  }
-
-  @override
-  Object visitLibraryDirective(LibraryDirective node) {
-    _setMetadata(node.element, node);
-    return null;
-  }
-
-  @override
-  Object visitMethodDeclaration(MethodDeclaration node) {
-    _setMetadata(node.element, node);
-    return null;
-  }
-
-  @override
-  Object visitMethodInvocation(MethodInvocation node) {
-    SimpleIdentifier methodName = node.methodName;
-    //
-    // Synthetic identifiers have been already reported during parsing.
-    //
-    if (methodName.isSynthetic) {
-      return null;
-    }
-    //
-    // We have a method invocation of one of two forms: 'e.m(a1, ..., an)' or 'm(a1, ..., an)'. The
-    // first step is to figure out which executable is being invoked, using both the static and the
-    // propagated type information.
-    //
-    Expression target = node.realTarget;
-    if (target is SuperExpression && !_isSuperInValidContext(target)) {
-      return null;
-    }
-    Element staticElement;
-    Element propagatedElement;
-    DartType staticType = null;
-    DartType propagatedType = null;
-    if (target == null) {
-      staticElement = _resolveInvokedElement(methodName);
-      propagatedElement = null;
-    } else if (methodName.name == FunctionElement.LOAD_LIBRARY_NAME && _isDeferredPrefix(target)) {
-      LibraryElement importedLibrary = _getImportedLibrary(target);
-      methodName.staticElement = importedLibrary.loadLibraryFunction;
-      return null;
-    } else {
-      staticType = _getStaticType(target);
-      propagatedType = _getPropagatedType(target);
-      //
-      // If this method invocation is of the form 'C.m' where 'C' is a class, then we don't call
-      // resolveInvokedElement(..) which walks up the class hierarchy, instead we just look for the
-      // member in the type only.
-      //
-      ClassElementImpl typeReference = getTypeReference(target);
-      if (typeReference != null) {
-        staticElement = propagatedElement = _resolveElement(typeReference, methodName);
-      } else {
-        staticElement = _resolveInvokedElementWithTarget(target, staticType, methodName);
-        propagatedElement = _resolveInvokedElementWithTarget(target, propagatedType, methodName);
-      }
-    }
-    staticElement = _convertSetterToGetter(staticElement);
-    propagatedElement = _convertSetterToGetter(propagatedElement);
-    //
-    // Record the results.
-    //
-    methodName.staticElement = staticElement;
-    methodName.propagatedElement = propagatedElement;
-    ArgumentList argumentList = node.argumentList;
-    if (staticElement != null) {
-      List<ParameterElement> parameters = _computeCorrespondingParameters(argumentList, staticElement);
-      if (parameters != null) {
-        argumentList.correspondingStaticParameters = parameters;
-      }
-    }
-    if (propagatedElement != null) {
-      List<ParameterElement> parameters = _computeCorrespondingParameters(argumentList, propagatedElement);
-      if (parameters != null) {
-        argumentList.correspondingPropagatedParameters = parameters;
-      }
-    }
-    //
-    // Then check for error conditions.
-    //
-    ErrorCode errorCode = _checkForInvocationError(target, true, staticElement);
-    bool generatedWithTypePropagation = false;
-    if (_enableHints && errorCode == null && staticElement == null) {
-      // The method lookup may have failed because there were multiple
-      // incompatible choices. In this case we don't want to generate a hint.
-      if (propagatedElement == null && propagatedType is UnionType) {
-        // TODO(collinsn): an improvement here is to make the propagated type of the method call
-        // the union of the propagated types of all possible calls.
-        if (_lookupMethods(target, propagatedType as UnionType, methodName.name).length > 1) {
-          return null;
-        }
-      }
-      errorCode = _checkForInvocationError(target, false, propagatedElement);
-      if (identical(errorCode, StaticTypeWarningCode.UNDEFINED_METHOD)) {
-        ClassElement classElementContext = null;
-        if (target == null) {
-          classElementContext = _resolver.enclosingClass;
-        } else {
-          DartType type = target.bestType;
-          if (type != null) {
-            if (type.element is ClassElement) {
-              classElementContext = type.element as ClassElement;
-            }
-          }
-        }
-        if (classElementContext != null) {
-          _subtypeManager.ensureLibraryVisited(_definingLibrary);
-          HashSet<ClassElement> subtypeElements = _subtypeManager.computeAllSubtypes(classElementContext);
-          for (ClassElement subtypeElement in subtypeElements) {
-            if (subtypeElement.getMethod(methodName.name) != null) {
-              errorCode = null;
-            }
-          }
-        }
-      }
-      generatedWithTypePropagation = true;
-    }
-    if (errorCode == null) {
-      return null;
-    }
-    if (identical(errorCode, StaticTypeWarningCode.INVOCATION_OF_NON_FUNCTION)) {
-      _resolver.reportErrorForNode(StaticTypeWarningCode.INVOCATION_OF_NON_FUNCTION, methodName, [methodName.name]);
-    } else if (identical(errorCode, StaticTypeWarningCode.UNDEFINED_FUNCTION)) {
-      _resolver.reportErrorForNode(StaticTypeWarningCode.UNDEFINED_FUNCTION, methodName, [methodName.name]);
-    } else if (identical(errorCode, StaticTypeWarningCode.UNDEFINED_METHOD)) {
-      String targetTypeName;
-      if (target == null) {
-        ClassElement enclosingClass = _resolver.enclosingClass;
-        targetTypeName = enclosingClass.displayName;
-        ErrorCode proxyErrorCode = (generatedWithTypePropagation ? HintCode.UNDEFINED_METHOD : StaticTypeWarningCode.UNDEFINED_METHOD);
-        _recordUndefinedNode(_resolver.enclosingClass, proxyErrorCode, methodName, [methodName.name, targetTypeName]);
-      } else {
-        // ignore Function "call"
-        // (if we are about to create a hint using type propagation, then we can use type
-        // propagation here as well)
-        DartType targetType = null;
-        if (!generatedWithTypePropagation) {
-          targetType = _getStaticType(target);
-        } else {
-          // choose the best type
-          targetType = _getPropagatedType(target);
-          if (targetType == null) {
-            targetType = _getStaticType(target);
-          }
-        }
-        if (targetType != null && targetType.isDartCoreFunction && methodName.name == FunctionElement.CALL_METHOD_NAME) {
-          // TODO(brianwilkerson) Can we ever resolve the function being invoked?
-          //resolveArgumentsToParameters(node.getArgumentList(), invokedFunction);
-          return null;
-        }
-        targetTypeName = targetType == null ? null : targetType.displayName;
-        ErrorCode proxyErrorCode = (generatedWithTypePropagation ? HintCode.UNDEFINED_METHOD : StaticTypeWarningCode.UNDEFINED_METHOD);
-        _recordUndefinedNode(targetType.element, proxyErrorCode, methodName, [methodName.name, targetTypeName]);
-      }
-    } else if (identical(errorCode, StaticTypeWarningCode.UNDEFINED_SUPER_METHOD)) {
-      // Generate the type name.
-      // The error code will never be generated via type propagation
-      DartType targetType = _getStaticType(target);
-      if (targetType is InterfaceType && !targetType.isObject) {
-        targetType = (targetType as InterfaceType).superclass;
-      }
-      String targetTypeName = targetType == null ? null : targetType.name;
-      _resolver.reportErrorForNode(StaticTypeWarningCode.UNDEFINED_SUPER_METHOD, methodName, [methodName.name, targetTypeName]);
-    }
-    return null;
-  }
-
-  @override
-  Object visitPartDirective(PartDirective node) {
-    _setMetadata(node.element, node);
-    return null;
-  }
-
-  @override
-  Object visitPartOfDirective(PartOfDirective node) {
-    _setMetadata(node.element, node);
-    return null;
-  }
-
-  @override
-  Object visitPostfixExpression(PostfixExpression node) {
-    Expression operand = node.operand;
-    String methodName = _getPostfixOperator(node);
-    DartType staticType = _getStaticType(operand);
-    MethodElement staticMethod = _lookUpMethod(operand, staticType, methodName);
-    node.staticElement = staticMethod;
-    DartType propagatedType = _getPropagatedType(operand);
-    MethodElement propagatedMethod = _lookUpMethod(operand, propagatedType, methodName);
-    node.propagatedElement = propagatedMethod;
-    if (_shouldReportMissingMember(staticType, staticMethod)) {
-      _recordUndefinedToken(staticType.element, StaticTypeWarningCode.UNDEFINED_OPERATOR, node.operator, [methodName, staticType.displayName]);
-    } else if (_enableHints && _shouldReportMissingMember(propagatedType, propagatedMethod) && !_memberFoundInSubclass(propagatedType.element, methodName, true, false)) {
-      _recordUndefinedToken(propagatedType.element, HintCode.UNDEFINED_OPERATOR, node.operator, [methodName, propagatedType.displayName]);
-    }
-    return null;
-  }
-
-  @override
-  Object visitPrefixedIdentifier(PrefixedIdentifier node) {
-    SimpleIdentifier prefix = node.prefix;
-    SimpleIdentifier identifier = node.identifier;
-    //
-    // First, check the "lib.loadLibrary" case
-    //
-    if (identifier.name == FunctionElement.LOAD_LIBRARY_NAME && _isDeferredPrefix(prefix)) {
-      LibraryElement importedLibrary = _getImportedLibrary(prefix);
-      identifier.staticElement = importedLibrary.loadLibraryFunction;
-      return null;
-    }
-    //
-    // Check to see whether the prefix is really a prefix.
-    //
-    Element prefixElement = prefix.staticElement;
-    if (prefixElement is PrefixElement) {
-      Element element = _resolver.nameScope.lookup(node, _definingLibrary);
-      if (element == null && identifier.inSetterContext()) {
-        element = _resolver.nameScope.lookup(new ElementResolver_SyntheticIdentifier("${node.name}="), _definingLibrary);
-      }
-      if (element == null) {
-        if (identifier.inSetterContext()) {
-          _resolver.reportErrorForNode(StaticWarningCode.UNDEFINED_SETTER, identifier, [identifier.name, prefixElement.name]);
-        } else if (node.parent is Annotation) {
-          Annotation annotation = node.parent as Annotation;
-          _resolver.reportErrorForNode(CompileTimeErrorCode.INVALID_ANNOTATION, annotation, []);
-          return null;
-        } else {
-          _resolver.reportErrorForNode(StaticWarningCode.UNDEFINED_GETTER, identifier, [identifier.name, prefixElement.name]);
-        }
-        return null;
-      }
-      if (element is PropertyAccessorElement && identifier.inSetterContext()) {
-        PropertyInducingElement variable = (element as PropertyAccessorElement).variable;
-        if (variable != null) {
-          PropertyAccessorElement setter = variable.setter;
-          if (setter != null) {
-            element = setter;
-          }
-        }
-      }
-      // TODO(brianwilkerson) The prefix needs to be resolved to the element for the import that
-      // defines the prefix, not the prefix's element.
-      identifier.staticElement = element;
-      // Validate annotation element.
-      if (node.parent is Annotation) {
-        Annotation annotation = node.parent as Annotation;
-        _resolveAnnotationElement(annotation);
-        return null;
-      }
-      return null;
-    }
-    // May be annotation, resolve invocation of "const" constructor.
-    if (node.parent is Annotation) {
-      Annotation annotation = node.parent as Annotation;
-      _resolveAnnotationElement(annotation);
-    }
-    //
-    // Otherwise, the prefix is really an expression that happens to be a simple identifier and this
-    // is really equivalent to a property access node.
-    //
-    _resolvePropertyAccess(prefix, identifier);
-    return null;
-  }
-
-  @override
-  Object visitPrefixExpression(PrefixExpression node) {
-    sc.Token operator = node.operator;
-    sc.TokenType operatorType = operator.type;
-    if (operatorType.isUserDefinableOperator || operatorType == sc.TokenType.PLUS_PLUS || operatorType == sc.TokenType.MINUS_MINUS) {
-      Expression operand = node.operand;
-      String methodName = _getPrefixOperator(node);
-      DartType staticType = _getStaticType(operand);
-      MethodElement staticMethod = _lookUpMethod(operand, staticType, methodName);
-      node.staticElement = staticMethod;
-      DartType propagatedType = _getPropagatedType(operand);
-      MethodElement propagatedMethod = _lookUpMethod(operand, propagatedType, methodName);
-      node.propagatedElement = propagatedMethod;
-      if (_shouldReportMissingMember(staticType, staticMethod)) {
-        _recordUndefinedToken(staticType.element, StaticTypeWarningCode.UNDEFINED_OPERATOR, operator, [methodName, staticType.displayName]);
-      } else if (_enableHints && _shouldReportMissingMember(propagatedType, propagatedMethod) && !_memberFoundInSubclass(propagatedType.element, methodName, true, false)) {
-        _recordUndefinedToken(propagatedType.element, HintCode.UNDEFINED_OPERATOR, operator, [methodName, propagatedType.displayName]);
-      }
-    }
-    return null;
-  }
-
-  @override
-  Object visitPropertyAccess(PropertyAccess node) {
-    Expression target = node.realTarget;
-    if (target is SuperExpression && !_isSuperInValidContext(target)) {
-      return null;
-    }
-    SimpleIdentifier propertyName = node.propertyName;
-    _resolvePropertyAccess(target, propertyName);
-    return null;
-  }
-
-  @override
-  Object visitRedirectingConstructorInvocation(RedirectingConstructorInvocation node) {
-    ClassElement enclosingClass = _resolver.enclosingClass;
-    if (enclosingClass == null) {
-      // TODO(brianwilkerson) Report this error.
-      return null;
-    }
-    SimpleIdentifier name = node.constructorName;
-    ConstructorElement element;
-    if (name == null) {
-      element = enclosingClass.unnamedConstructor;
-    } else {
-      element = enclosingClass.getNamedConstructor(name.name);
-    }
-    if (element == null) {
-      // TODO(brianwilkerson) Report this error and decide what element to associate with the node.
-      return null;
-    }
-    if (name != null) {
-      name.staticElement = element;
-    }
-    node.staticElement = element;
-    ArgumentList argumentList = node.argumentList;
-    List<ParameterElement> parameters = _resolveArgumentsToFunction(false, argumentList, element);
-    if (parameters != null) {
-      argumentList.correspondingStaticParameters = parameters;
-    }
-    return null;
-  }
-
-  @override
-  Object visitSimpleFormalParameter(SimpleFormalParameter node) {
-    _setMetadataForParameter(node.element, node);
-    return null;
-  }
-
-  @override
-  Object visitSimpleIdentifier(SimpleIdentifier node) {
-    //
-    // Synthetic identifiers have been already reported during parsing.
-    //
-    if (node.isSynthetic) {
-      return null;
-    }
-    //
-    // We ignore identifiers that have already been resolved, such as identifiers representing the
-    // name in a declaration.
-    //
-    if (node.staticElement != null) {
-      return null;
-    }
-    //
-    // The name dynamic denotes a Type object even though dynamic is not a class.
-    //
-    if (node.name == _dynamicType.name) {
-      node.staticElement = _dynamicType.element;
-      node.staticType = _typeType;
-      return null;
-    }
-    //
-    // Otherwise, the node should be resolved.
-    //
-    Element element = _resolveSimpleIdentifier(node);
-    ClassElement enclosingClass = _resolver.enclosingClass;
-    if (_isFactoryConstructorReturnType(node) && !identical(element, enclosingClass)) {
-      _resolver.reportErrorForNode(CompileTimeErrorCode.INVALID_FACTORY_NAME_NOT_A_CLASS, node, []);
-    } else if (_isConstructorReturnType(node) && !identical(element, enclosingClass)) {
-      _resolver.reportErrorForNode(CompileTimeErrorCode.INVALID_CONSTRUCTOR_NAME, node, []);
-      element = null;
-    } else if (element == null || (element is PrefixElement && !_isValidAsPrefix(node))) {
-      // TODO(brianwilkerson) Recover from this error.
-      if (_isConstructorReturnType(node)) {
-        _resolver.reportErrorForNode(CompileTimeErrorCode.INVALID_CONSTRUCTOR_NAME, node, []);
-      } else if (node.parent is Annotation) {
-        Annotation annotation = node.parent as Annotation;
-        _resolver.reportErrorForNode(CompileTimeErrorCode.INVALID_ANNOTATION, annotation, []);
-      } else {
-        _recordUndefinedNode(_resolver.enclosingClass, StaticWarningCode.UNDEFINED_IDENTIFIER, node, [node.name]);
-      }
-    }
-    node.staticElement = element;
-    if (node.inSetterContext() && node.inGetterContext() && enclosingClass != null) {
-      InterfaceType enclosingType = enclosingClass.type;
-      AuxiliaryElements auxiliaryElements = new AuxiliaryElements(_lookUpGetter(null, enclosingType, node.name), null);
-      node.auxiliaryElements = auxiliaryElements;
-    }
-    //
-    // Validate annotation element.
-    //
-    if (node.parent is Annotation) {
-      Annotation annotation = node.parent as Annotation;
-      _resolveAnnotationElement(annotation);
-    }
-    return null;
-  }
-
-  @override
-  Object visitSuperConstructorInvocation(SuperConstructorInvocation node) {
-    ClassElement enclosingClass = _resolver.enclosingClass;
-    if (enclosingClass == null) {
-      // TODO(brianwilkerson) Report this error.
-      return null;
-    }
-    InterfaceType superType = enclosingClass.supertype;
-    if (superType == null) {
-      // TODO(brianwilkerson) Report this error.
-      return null;
-    }
-    SimpleIdentifier name = node.constructorName;
-    String superName = name != null ? name.name : null;
-    ConstructorElement element = superType.lookUpConstructor(superName, _definingLibrary);
-    if (element == null) {
-      if (name != null) {
-        _resolver.reportErrorForNode(CompileTimeErrorCode.UNDEFINED_CONSTRUCTOR_IN_INITIALIZER, node, [superType.displayName, name]);
-      } else {
-        _resolver.reportErrorForNode(CompileTimeErrorCode.UNDEFINED_CONSTRUCTOR_IN_INITIALIZER_DEFAULT, node, [superType.displayName]);
-      }
-      return null;
-    } else {
-      if (element.isFactory) {
-        _resolver.reportErrorForNode(CompileTimeErrorCode.NON_GENERATIVE_CONSTRUCTOR, node, [element]);
-      }
-    }
-    if (name != null) {
-      name.staticElement = element;
-    }
-    node.staticElement = element;
-    ArgumentList argumentList = node.argumentList;
-    List<ParameterElement> parameters = _resolveArgumentsToFunction(isInConstConstructor, argumentList, element);
-    if (parameters != null) {
-      argumentList.correspondingStaticParameters = parameters;
-    }
-    return null;
-  }
-
-  @override
-  Object visitSuperExpression(SuperExpression node) {
-    if (!_isSuperInValidContext(node)) {
-      _resolver.reportErrorForNode(CompileTimeErrorCode.SUPER_IN_INVALID_CONTEXT, node, []);
-    }
-    return super.visitSuperExpression(node);
-  }
-
-  @override
-  Object visitTypeParameter(TypeParameter node) {
-    _setMetadata(node.element, node);
-    return null;
-  }
-
-  @override
-  Object visitVariableDeclaration(VariableDeclaration node) {
-    _setMetadata(node.element, node);
-    return null;
-  }
-
-  /**
-   * Generate annotation elements for each of the annotations in the given node list and add them to
-   * the given list of elements.
-   *
-   * @param annotationList the list of elements to which new elements are to be added
-   * @param annotations the AST nodes used to generate new elements
-   */
-  void _addAnnotations(List<ElementAnnotationImpl> annotationList, NodeList<Annotation> annotations) {
-    int annotationCount = annotations.length;
-    for (int i = 0; i < annotationCount; i++) {
-      Annotation annotation = annotations[i];
-      Element resolvedElement = annotation.element;
-      if (resolvedElement != null) {
-        ElementAnnotationImpl elementAnnotation = new ElementAnnotationImpl(resolvedElement);
-        annotation.elementAnnotation = elementAnnotation;
-        annotationList.add(elementAnnotation);
-      }
-    }
-  }
-
-  /**
-   * Given that we have found code to invoke the given element, return the error code that should be
-   * reported, or `null` if no error should be reported.
-   *
-   * @param target the target of the invocation, or `null` if there was no target
-   * @param useStaticContext
-   * @param element the element to be invoked
-   * @return the error code that should be reported
-   */
-  ErrorCode _checkForInvocationError(Expression target, bool useStaticContext, Element element) {
-    // Prefix is not declared, instead "prefix.id" are declared.
-    if (element is PrefixElement) {
-      element = null;
-    }
-    if (element is PropertyAccessorElement) {
-      //
-      // This is really a function expression invocation.
-      //
-      // TODO(brianwilkerson) Consider the possibility of re-writing the AST.
-      FunctionType getterType = element.type;
-      if (getterType != null) {
-        DartType returnType = getterType.returnType;
-        if (!_isExecutableType(returnType)) {
-          return StaticTypeWarningCode.INVOCATION_OF_NON_FUNCTION;
-        }
-      }
-    } else if (element is ExecutableElement) {
-      return null;
-    } else if (element is MultiplyDefinedElement) {
-      // The error has already been reported
-      return null;
-    } else if (element == null && target is SuperExpression) {
-      // TODO(jwren) We should split the UNDEFINED_METHOD into two error codes, this one, and
-      // a code that describes the situation where the method was found, but it was not
-      // accessible from the current library.
-      return StaticTypeWarningCode.UNDEFINED_SUPER_METHOD;
-    } else {
-      //
-      // This is really a function expression invocation.
-      //
-      // TODO(brianwilkerson) Consider the possibility of re-writing the AST.
-      if (element is PropertyInducingElement) {
-        PropertyAccessorElement getter = element.getter;
-        FunctionType getterType = getter.type;
-        if (getterType != null) {
-          DartType returnType = getterType.returnType;
-          if (!_isExecutableType(returnType)) {
-            return StaticTypeWarningCode.INVOCATION_OF_NON_FUNCTION;
-          }
-        }
-      } else if (element is VariableElement) {
-        DartType variableType = element.type;
-        if (!_isExecutableType(variableType)) {
-          return StaticTypeWarningCode.INVOCATION_OF_NON_FUNCTION;
-        }
-      } else {
-        if (target == null) {
-          ClassElement enclosingClass = _resolver.enclosingClass;
-          if (enclosingClass == null) {
-            return StaticTypeWarningCode.UNDEFINED_FUNCTION;
-          } else if (element == null) {
-            // Proxy-conditional warning, based on state of resolver.getEnclosingClass()
-            return StaticTypeWarningCode.UNDEFINED_METHOD;
-          } else {
-            return StaticTypeWarningCode.INVOCATION_OF_NON_FUNCTION;
-          }
-        } else {
-          DartType targetType;
-          if (useStaticContext) {
-            targetType = _getStaticType(target);
-          } else {
-            // Compute and use the propagated type, if it is null, then it may be the case that
-            // static type is some type, in which the static type should be used.
-            targetType = target.bestType;
-          }
-          if (targetType == null) {
-            return StaticTypeWarningCode.UNDEFINED_FUNCTION;
-          } else if (!targetType.isDynamic && !targetType.isBottom) {
-            // Proxy-conditional warning, based on state of targetType.getElement()
-            return StaticTypeWarningCode.UNDEFINED_METHOD;
-          }
-        }
-      }
-    }
-    return null;
-  }
-
-  /**
-   * Check that the for some index expression that the method element was resolved, otherwise a
-   * [StaticWarningCode#UNDEFINED_OPERATOR] is generated.
-   *
-   * @param node the index expression to resolve
-   * @param target the target of the expression
-   * @param methodName the name of the operator associated with the context of using of the given
-   *          index expression
-   * @return `true` if and only if an error code is generated on the passed node
-   */
-  bool _checkForUndefinedIndexOperator(IndexExpression node, Expression target, String methodName, MethodElement staticMethod, MethodElement propagatedMethod, DartType staticType, DartType propagatedType) {
-    bool shouldReportMissingMember_static = _shouldReportMissingMember(staticType, staticMethod);
-    bool shouldReportMissingMember_propagated = !shouldReportMissingMember_static && _enableHints && _shouldReportMissingMember(propagatedType, propagatedMethod) && !_memberFoundInSubclass(propagatedType.element, methodName, true, false);
-    if (shouldReportMissingMember_static || shouldReportMissingMember_propagated) {
-      sc.Token leftBracket = node.leftBracket;
-      sc.Token rightBracket = node.rightBracket;
-      ErrorCode errorCode = (shouldReportMissingMember_static ? StaticTypeWarningCode.UNDEFINED_OPERATOR : HintCode.UNDEFINED_OPERATOR);
-      if (leftBracket == null || rightBracket == null) {
-        _recordUndefinedNode(shouldReportMissingMember_static ? staticType.element : propagatedType.element, errorCode, node, [
-            methodName,
-            shouldReportMissingMember_static ? staticType.displayName : propagatedType.displayName]);
-      } else {
-        int offset = leftBracket.offset;
-        int length = rightBracket.offset - offset + 1;
-        _recordUndefinedOffset(shouldReportMissingMember_static ? staticType.element : propagatedType.element, errorCode, offset, length, [
-            methodName,
-            shouldReportMissingMember_static ? staticType.displayName : propagatedType.displayName]);
-      }
-      return true;
-    }
-    return false;
-  }
-
-  /**
-   * Given a list of arguments and the element that will be invoked using those argument, compute
-   * the list of parameters that correspond to the list of arguments. Return the parameters that
-   * correspond to the arguments, or `null` if no correspondence could be computed.
-   *
-   * @param argumentList the list of arguments being passed to the element
-   * @param executableElement the element that will be invoked with the arguments
-   * @return the parameters that correspond to the arguments
-   */
-  List<ParameterElement> _computeCorrespondingParameters(ArgumentList argumentList, Element element) {
-    if (element is PropertyAccessorElement) {
-      //
-      // This is an invocation of the call method defined on the value returned by the getter.
-      //
-      FunctionType getterType = element.type;
-      if (getterType != null) {
-        DartType getterReturnType = getterType.returnType;
-        if (getterReturnType is InterfaceType) {
-          MethodElement callMethod = getterReturnType.lookUpMethod(FunctionElement.CALL_METHOD_NAME, _definingLibrary);
-          if (callMethod != null) {
-            return _resolveArgumentsToFunction(false, argumentList, callMethod);
-          }
-        } else if (getterReturnType is FunctionType) {
-          List<ParameterElement> parameters = getterReturnType.parameters;
-          return _resolveArgumentsToParameters(false, argumentList, parameters);
-        }
-      }
-    } else if (element is ExecutableElement) {
-      return _resolveArgumentsToFunction(false, argumentList, element);
-    } else if (element is VariableElement) {
-      VariableElement variable = element;
-      DartType type = _promoteManager.getStaticType(variable);
-      if (type is FunctionType) {
-        FunctionType functionType = type;
-        List<ParameterElement> parameters = functionType.parameters;
-        return _resolveArgumentsToParameters(false, argumentList, parameters);
-      } else if (type is InterfaceType) {
-        // "call" invocation
-        MethodElement callMethod = type.lookUpMethod(FunctionElement.CALL_METHOD_NAME, _definingLibrary);
-        if (callMethod != null) {
-          List<ParameterElement> parameters = callMethod.parameters;
-          return _resolveArgumentsToParameters(false, argumentList, parameters);
-        }
-      }
-    }
-    return null;
-  }
-
-  /**
-   * If the given element is a setter, return the getter associated with it. Otherwise, return the
-   * element unchanged.
-   *
-   * @param element the element to be normalized
-   * @return a non-setter element derived from the given element
-   */
-  Element _convertSetterToGetter(Element element) {
-    // TODO(brianwilkerson) Determine whether and why the element could ever be a setter.
-    if (element is PropertyAccessorElement) {
-      return element.variable.getter;
-    }
-    return element;
-  }
-
-  /**
-   * Return `true` if the given element is not a proxy.
-   *
-   * @param element the enclosing element. If null, `true` will be returned.
-   * @return `false` iff the passed [Element] is a [ClassElement] that is a proxy
-   *         or inherits proxy
-   * @see ClassElement#isOrInheritsProxy()
-   */
-  bool _doesntHaveProxy(Element element) => !(element is ClassElement && element.isOrInheritsProxy);
-
-  /**
-   * Look for any declarations of the given identifier that are imported using a prefix. Return the
-   * element that was found, or `null` if the name is not imported using a prefix.
-   *
-   * @param identifier the identifier that might have been imported using a prefix
-   * @return the element that was found
-   */
-  Element _findImportWithoutPrefix(SimpleIdentifier identifier) {
-    Element element = null;
-    Scope nameScope = _resolver.nameScope;
-    for (ImportElement importElement in _definingLibrary.imports) {
-      PrefixElement prefixElement = importElement.prefix;
-      if (prefixElement != null) {
-        Identifier prefixedIdentifier = new ElementResolver_SyntheticIdentifier("${prefixElement.name}.${identifier.name}");
-        Element importedElement = nameScope.lookup(prefixedIdentifier, _definingLibrary);
-        if (importedElement != null) {
-          if (element == null) {
-            element = importedElement;
-          } else {
-            element = MultiplyDefinedElementImpl.fromElements(_definingLibrary.context, element, importedElement);
-          }
-        }
-      }
-    }
-    return element;
-  }
-
-  /**
-   * Assuming that the given expression is a prefix for a deferred import, return the library that
-   * is being imported.
-   *
-   * @param expression the expression representing the deferred import's prefix
-   * @return the library that is being imported by the import associated with the prefix
-   */
-  LibraryElement _getImportedLibrary(Expression expression) {
-    PrefixElement prefixElement = (expression as SimpleIdentifier).staticElement as PrefixElement;
-    List<ImportElement> imports = prefixElement.enclosingElement.getImportsWithPrefix(prefixElement);
-    return imports[0].importedLibrary;
-  }
-
-  /**
-   * Return the name of the method invoked by the given postfix expression.
-   *
-   * @param node the postfix expression being invoked
-   * @return the name of the method invoked by the expression
-   */
-  String _getPostfixOperator(PostfixExpression node) => (node.operator.type == sc.TokenType.PLUS_PLUS) ? sc.TokenType.PLUS.lexeme : sc.TokenType.MINUS.lexeme;
-
-  /**
-   * Return the name of the method invoked by the given postfix expression.
-   *
-   * @param node the postfix expression being invoked
-   * @return the name of the method invoked by the expression
-   */
-  String _getPrefixOperator(PrefixExpression node) {
-    sc.Token operator = node.operator;
-    sc.TokenType operatorType = operator.type;
-    if (operatorType == sc.TokenType.PLUS_PLUS) {
-      return sc.TokenType.PLUS.lexeme;
-    } else if (operatorType == sc.TokenType.MINUS_MINUS) {
-      return sc.TokenType.MINUS.lexeme;
-    } else if (operatorType == sc.TokenType.MINUS) {
-      return "unary-";
-    } else {
-      return operator.lexeme;
-    }
-  }
-
-  /**
-   * Return the propagated type of the given expression that is to be used for type analysis.
-   *
-   * @param expression the expression whose type is to be returned
-   * @return the type of the given expression
-   */
-  DartType _getPropagatedType(Expression expression) {
-    DartType propagatedType = _resolveTypeParameter(expression.propagatedType);
-    if (propagatedType is FunctionType) {
-      //
-      // All function types are subtypes of 'Function', which is itself a subclass of 'Object'.
-      //
-      propagatedType = _resolver.typeProvider.functionType;
-    }
-    return propagatedType;
-  }
-
-  /**
-   * Return the static type of the given expression that is to be used for type analysis.
-   *
-   * @param expression the expression whose type is to be returned
-   * @return the type of the given expression
-   */
-  DartType _getStaticType(Expression expression) {
-    if (expression is NullLiteral) {
-      return _resolver.typeProvider.bottomType;
-    }
-    DartType staticType = _resolveTypeParameter(expression.staticType);
-    if (staticType is FunctionType) {
-      //
-      // All function types are subtypes of 'Function', which is itself a subclass of 'Object'.
-      //
-      staticType = _resolver.typeProvider.functionType;
-    }
-    return staticType;
-  }
-
-  /**
-   * Return `true` if the given expression is a prefix for a deferred import.
-   *
-   * @param expression the expression being tested
-   * @return `true` if the given expression is a prefix for a deferred import
-   */
-  bool _isDeferredPrefix(Expression expression) {
-    if (expression is! SimpleIdentifier) {
-      return false;
-    }
-    Element element = (expression as SimpleIdentifier).staticElement;
-    if (element is! PrefixElement) {
-      return false;
-    }
-    PrefixElement prefixElement = element as PrefixElement;
-    List<ImportElement> imports = prefixElement.enclosingElement.getImportsWithPrefix(prefixElement);
-    if (imports.length != 1) {
-      return false;
-    }
-    return imports[0].isDeferred;
-  }
-
-  /**
-   * Return `true` if the given type represents an object that could be invoked using the call
-   * operator '()'.
-   *
-   * @param type the type being tested
-   * @return `true` if the given type represents an object that could be invoked
-   */
-  bool _isExecutableType(DartType type) {
-    if (type.isDynamic || (type is FunctionType) || type.isDartCoreFunction || type.isObject) {
-      return true;
-    } else if (type is InterfaceType) {
-      ClassElement classElement = type.element;
-      // 16078 from Gilad: If the type is a Functor with the @proxy annotation, treat it as an
-      // executable type.
-      // example code: NonErrorResolverTest.test_invocationOfNonFunction_proxyOnFunctionClass()
-      if (classElement.isProxy && type.isSubtypeOf(_resolver.typeProvider.functionType)) {
-        return true;
-      }
-      MethodElement methodElement = classElement.lookUpMethod(FunctionElement.CALL_METHOD_NAME, _definingLibrary);
-      return methodElement != null;
-    }
-    return false;
-  }
-
-  /**
-   * @return `true` iff current enclosing function is constant constructor declaration.
-   */
-  bool get isInConstConstructor {
-    ExecutableElement function = _resolver.enclosingFunction;
-    if (function is ConstructorElement) {
-      return function.isConst;
-    }
-    return false;
-  }
-
-  /**
-   * Return `true` if the given element is a static element.
-   *
-   * @param element the element being tested
-   * @return `true` if the given element is a static element
-   */
-  bool _isStatic(Element element) {
-    if (element is ExecutableElement) {
-      return element.isStatic;
-    } else if (element is PropertyInducingElement) {
-      return element.isStatic;
-    }
-    return false;
-  }
-
-  /**
-   * Return `true` if the given node can validly be resolved to a prefix:
-   * * it is the prefix in an import directive, or
-   * * it is the prefix in a prefixed identifier.
-   *
-   * @param node the node being tested
-   * @return `true` if the given node is the prefix in an import directive
-   */
-  bool _isValidAsPrefix(SimpleIdentifier node) {
-    AstNode parent = node.parent;
-    if (parent is ImportDirective) {
-      return identical(parent.prefix, node);
-    } else if (parent is PrefixedIdentifier) {
-      return true;
-    } else if (parent is MethodInvocation) {
-      return identical(parent.target, node);
-    }
-    return false;
-  }
-
-  /**
-   * Look up the getter with the given name in the given type. Return the element representing the
-   * getter that was found, or `null` if there is no getter with the given name.
-   *
-   * @param target the target of the invocation, or `null` if there is no target
-   * @param type the type in which the getter is defined
-   * @param getterName the name of the getter being looked up
-   * @return the element representing the getter that was found
-   */
-  PropertyAccessorElement _lookUpGetter(Expression target, DartType type, String getterName) {
-    type = _resolveTypeParameter(type);
-    if (type is InterfaceType) {
-      InterfaceType interfaceType = type;
-      PropertyAccessorElement accessor;
-      if (target is SuperExpression) {
-        accessor = interfaceType.lookUpGetterInSuperclass(getterName, _definingLibrary);
-      } else {
-        accessor = interfaceType.lookUpGetter(getterName, _definingLibrary);
-      }
-      if (accessor != null) {
-        return accessor;
-      }
-      return _lookUpGetterInInterfaces(interfaceType, false, getterName, new HashSet<ClassElement>());
-    }
-    return null;
-  }
-
-  /**
-   * Look up the getter with the given name in the interfaces implemented by the given type, either
-   * directly or indirectly. Return the element representing the getter that was found, or
-   * `null` if there is no getter with the given name.
-   *
-   * @param targetType the type in which the getter might be defined
-   * @param includeTargetType `true` if the search should include the target type
-   * @param getterName the name of the getter being looked up
-   * @param visitedInterfaces a set containing all of the interfaces that have been examined, used
-   *          to prevent infinite recursion and to optimize the search
-   * @return the element representing the getter that was found
-   */
-  PropertyAccessorElement _lookUpGetterInInterfaces(InterfaceType targetType, bool includeTargetType, String getterName, HashSet<ClassElement> visitedInterfaces) {
-    // TODO(brianwilkerson) This isn't correct. Section 8.1.1 of the specification (titled
-    // "Inheritance and Overriding" under "Interfaces") describes a much more complex scheme for
-    // finding the inherited member. We need to follow that scheme. The code below should cover the
-    // 80% case.
-    ClassElement targetClass = targetType.element;
-    if (visitedInterfaces.contains(targetClass)) {
-      return null;
-    }
-    visitedInterfaces.add(targetClass);
-    if (includeTargetType) {
-      PropertyAccessorElement getter = targetType.getGetter(getterName);
-      if (getter != null && getter.isAccessibleIn(_definingLibrary)) {
-        return getter;
-      }
-    }
-    for (InterfaceType interfaceType in targetType.interfaces) {
-      PropertyAccessorElement getter = _lookUpGetterInInterfaces(interfaceType, true, getterName, visitedInterfaces);
-      if (getter != null) {
-        return getter;
-      }
-    }
-    for (InterfaceType mixinType in targetType.mixins) {
-      PropertyAccessorElement getter = _lookUpGetterInInterfaces(mixinType, true, getterName, visitedInterfaces);
-      if (getter != null) {
-        return getter;
-      }
-    }
-    InterfaceType superclass = targetType.superclass;
-    if (superclass == null) {
-      return null;
-    }
-    return _lookUpGetterInInterfaces(superclass, true, getterName, visitedInterfaces);
-  }
-
-  /**
-   * Look up the method or getter with the given name in the given type. Return the element
-   * representing the method or getter that was found, or `null` if there is no method or
-   * getter with the given name.
-   *
-   * @param type the type in which the method or getter is defined
-   * @param memberName the name of the method or getter being looked up
-   * @return the element representing the method or getter that was found
-   */
-  ExecutableElement _lookupGetterOrMethod(DartType type, String memberName) {
-    type = _resolveTypeParameter(type);
-    if (type is InterfaceType) {
-      InterfaceType interfaceType = type;
-      ExecutableElement member = interfaceType.lookUpMethod(memberName, _definingLibrary);
-      if (member != null) {
-        return member;
-      }
-      member = interfaceType.lookUpGetter(memberName, _definingLibrary);
-      if (member != null) {
-        return member;
-      }
-      return _lookUpGetterOrMethodInInterfaces(interfaceType, false, memberName, new HashSet<ClassElement>());
-    }
-    return null;
-  }
-
-  /**
-   * Look up the method or getter with the given name in the interfaces implemented by the given
-   * type, either directly or indirectly. Return the element representing the method or getter that
-   * was found, or `null` if there is no method or getter with the given name.
-   *
-   * @param targetType the type in which the method or getter might be defined
-   * @param includeTargetType `true` if the search should include the target type
-   * @param memberName the name of the method or getter being looked up
-   * @param visitedInterfaces a set containing all of the interfaces that have been examined, used
-   *          to prevent infinite recursion and to optimize the search
-   * @return the element representing the method or getter that was found
-   */
-  ExecutableElement _lookUpGetterOrMethodInInterfaces(InterfaceType targetType, bool includeTargetType, String memberName, HashSet<ClassElement> visitedInterfaces) {
-    // TODO(brianwilkerson) This isn't correct. Section 8.1.1 of the specification (titled
-    // "Inheritance and Overriding" under "Interfaces") describes a much more complex scheme for
-    // finding the inherited member. We need to follow that scheme. The code below should cover the
-    // 80% case.
-    ClassElement targetClass = targetType.element;
-    if (visitedInterfaces.contains(targetClass)) {
-      return null;
-    }
-    visitedInterfaces.add(targetClass);
-    if (includeTargetType) {
-      ExecutableElement member = targetType.getMethod(memberName);
-      if (member != null) {
-        return member;
-      }
-      member = targetType.getGetter(memberName);
-      if (member != null) {
-        return member;
-      }
-    }
-    for (InterfaceType interfaceType in targetType.interfaces) {
-      ExecutableElement member = _lookUpGetterOrMethodInInterfaces(interfaceType, true, memberName, visitedInterfaces);
-      if (member != null) {
-        return member;
-      }
-    }
-    for (InterfaceType mixinType in targetType.mixins) {
-      ExecutableElement member = _lookUpGetterOrMethodInInterfaces(mixinType, true, memberName, visitedInterfaces);
-      if (member != null) {
-        return member;
-      }
-    }
-    InterfaceType superclass = targetType.superclass;
-    if (superclass == null) {
-      return null;
-    }
-    return _lookUpGetterOrMethodInInterfaces(superclass, true, memberName, visitedInterfaces);
-  }
-
-  /**
-   * Find the element corresponding to the given label node in the current label scope.
-   *
-   * @param parentNode the node containing the given label
-   * @param labelNode the node representing the label being looked up
-   * @return the element corresponding to the given label node in the current scope
-   */
-  LabelElementImpl _lookupLabel(AstNode parentNode, SimpleIdentifier labelNode) {
-    LabelScope labelScope = _resolver.labelScope;
-    LabelElementImpl labelElement = null;
-    if (labelNode == null) {
-      if (labelScope == null) {
-        // TODO(brianwilkerson) Do we need to report this error, or is this condition always caught in the parser?
-        // reportError(ResolverErrorCode.BREAK_OUTSIDE_LOOP);
-      } else {
-        labelElement = labelScope.lookup(LabelScope.EMPTY_LABEL) as LabelElementImpl;
-        if (labelElement == null) {
-          // TODO(brianwilkerson) Do we need to report this error, or is this condition always caught in the parser?
-          // reportError(ResolverErrorCode.BREAK_OUTSIDE_LOOP);
-        }
-        //
-        // The label element that was returned was a marker for look-up and isn't stored in the
-        // element model.
-        //
-        labelElement = null;
-      }
-    } else {
-      if (labelScope == null) {
-        _resolver.reportErrorForNode(CompileTimeErrorCode.LABEL_UNDEFINED, labelNode, [labelNode.name]);
-      } else {
-        labelElement = labelScope.lookup(labelNode.name) as LabelElementImpl;
-        if (labelElement == null) {
-          _resolver.reportErrorForNode(CompileTimeErrorCode.LABEL_UNDEFINED, labelNode, [labelNode.name]);
-        } else {
-          labelNode.staticElement = labelElement;
-        }
-      }
-    }
-    if (labelElement != null) {
-      ExecutableElement labelContainer = labelElement.getAncestor((element) => element is ExecutableElement);
-      if (!identical(labelContainer, _resolver.enclosingFunction)) {
-        _resolver.reportErrorForNode(CompileTimeErrorCode.LABEL_IN_OUTER_SCOPE, labelNode, [labelNode.name]);
-        labelElement = null;
-      }
-    }
-    return labelElement;
-  }
-
-  /**
-   * Look up the method with the given name in the given type. Return the element representing the
-   * method that was found, or `null` if there is no method with the given name.
-   *
-   * @param target the target of the invocation, or `null` if there is no target
-   * @param type the type in which the method is defined
-   * @param methodName the name of the method being looked up
-   * @return the element representing the method that was found
-   */
-  MethodElement _lookUpMethod(Expression target, DartType type, String methodName) {
-    type = _resolveTypeParameter(type);
-    if (type is InterfaceType) {
-      InterfaceType interfaceType = type;
-      MethodElement method;
-      if (target is SuperExpression) {
-        method = interfaceType.lookUpMethodInSuperclass(methodName, _definingLibrary);
-      } else {
-        method = interfaceType.lookUpMethod(methodName, _definingLibrary);
-      }
-      if (method != null) {
-        return method;
-      }
-      return _lookUpMethodInInterfaces(interfaceType, false, methodName, new HashSet<ClassElement>());
-    } else if (type is UnionType) {
-      // TODO (collinsn): I want [computeMergedExecutableElement] to be general
-      // and work with functions, methods, constructors, and property accessors. However,
-      // I won't be able to assume it returns [MethodElement] here then.
-      return _maybeMergeExecutableElements(_lookupMethods(target, type, methodName)) as MethodElement;
-    }
-    return null;
-  }
-
-  /**
-   * Look up the method with the given name in the interfaces implemented by the given type, either
-   * directly or indirectly. Return the element representing the method that was found, or
-   * `null` if there is no method with the given name.
-   *
-   * @param targetType the type in which the member might be defined
-   * @param includeTargetType `true` if the search should include the target type
-   * @param methodName the name of the method being looked up
-   * @param visitedInterfaces a set containing all of the interfaces that have been examined, used
-   *          to prevent infinite recursion and to optimize the search
-   * @return the element representing the method that was found
-   */
-  MethodElement _lookUpMethodInInterfaces(InterfaceType targetType, bool includeTargetType, String methodName, HashSet<ClassElement> visitedInterfaces) {
-    // TODO(brianwilkerson) This isn't correct. Section 8.1.1 of the specification (titled
-    // "Inheritance and Overriding" under "Interfaces") describes a much more complex scheme for
-    // finding the inherited member. We need to follow that scheme. The code below should cover the
-    // 80% case.
-    ClassElement targetClass = targetType.element;
-    if (visitedInterfaces.contains(targetClass)) {
-      return null;
-    }
-    visitedInterfaces.add(targetClass);
-    if (includeTargetType) {
-      MethodElement method = targetType.getMethod(methodName);
-      if (method != null && method.isAccessibleIn(_definingLibrary)) {
-        return method;
-      }
-    }
-    for (InterfaceType interfaceType in targetType.interfaces) {
-      MethodElement method = _lookUpMethodInInterfaces(interfaceType, true, methodName, visitedInterfaces);
-      if (method != null) {
-        return method;
-      }
-    }
-    for (InterfaceType mixinType in targetType.mixins) {
-      MethodElement method = _lookUpMethodInInterfaces(mixinType, true, methodName, visitedInterfaces);
-      if (method != null) {
-        return method;
-      }
-    }
-    InterfaceType superclass = targetType.superclass;
-    if (superclass == null) {
-      return null;
-    }
-    return _lookUpMethodInInterfaces(superclass, true, methodName, visitedInterfaces);
-  }
-
-  /**
-   * Look up all methods of a given name defined on a union type.
-   *
-   * @param target
-   * @param type
-   * @param methodName
-   * @return all methods named `methodName` defined on the union type `type`.
-   */
-  Set<ExecutableElement> _lookupMethods(Expression target, UnionType type, String methodName) {
-    Set<ExecutableElement> methods = new HashSet<ExecutableElement>();
-    bool allElementsHaveMethod = true;
-    for (DartType t in type.elements) {
-      MethodElement m = _lookUpMethod(target, t, methodName);
-      if (m != null) {
-        methods.add(m);
-      } else {
-        allElementsHaveMethod = false;
-      }
-    }
-    // For strict union types we require that all types in the union define the method.
-    if (AnalysisEngine.instance.strictUnionTypes) {
-      if (allElementsHaveMethod) {
-        return methods;
-      } else {
-        return new Set<ExecutableElement>();
-      }
-    } else {
-      return methods;
-    }
-  }
-
-  /**
-   * Look up the setter with the given name in the given type. Return the element representing the
-   * setter that was found, or `null` if there is no setter with the given name.
-   *
-   * @param target the target of the invocation, or `null` if there is no target
-   * @param type the type in which the setter is defined
-   * @param setterName the name of the setter being looked up
-   * @return the element representing the setter that was found
-   */
-  PropertyAccessorElement _lookUpSetter(Expression target, DartType type, String setterName) {
-    type = _resolveTypeParameter(type);
-    if (type is InterfaceType) {
-      InterfaceType interfaceType = type;
-      PropertyAccessorElement accessor;
-      if (target is SuperExpression) {
-        accessor = interfaceType.lookUpSetterInSuperclass(setterName, _definingLibrary);
-      } else {
-        accessor = interfaceType.lookUpSetter(setterName, _definingLibrary);
-      }
-      if (accessor != null) {
-        return accessor;
-      }
-      return _lookUpSetterInInterfaces(interfaceType, false, setterName, new HashSet<ClassElement>());
-    }
-    return null;
-  }
-
-  /**
-   * Look up the setter with the given name in the interfaces implemented by the given type, either
-   * directly or indirectly. Return the element representing the setter that was found, or
-   * `null` if there is no setter with the given name.
-   *
-   * @param targetType the type in which the setter might be defined
-   * @param includeTargetType `true` if the search should include the target type
-   * @param setterName the name of the setter being looked up
-   * @param visitedInterfaces a set containing all of the interfaces that have been examined, used
-   *          to prevent infinite recursion and to optimize the search
-   * @return the element representing the setter that was found
-   */
-  PropertyAccessorElement _lookUpSetterInInterfaces(InterfaceType targetType, bool includeTargetType, String setterName, HashSet<ClassElement> visitedInterfaces) {
-    // TODO(brianwilkerson) This isn't correct. Section 8.1.1 of the specification (titled
-    // "Inheritance and Overriding" under "Interfaces") describes a much more complex scheme for
-    // finding the inherited member. We need to follow that scheme. The code below should cover the
-    // 80% case.
-    ClassElement targetClass = targetType.element;
-    if (visitedInterfaces.contains(targetClass)) {
-      return null;
-    }
-    visitedInterfaces.add(targetClass);
-    if (includeTargetType) {
-      PropertyAccessorElement setter = targetType.getSetter(setterName);
-      if (setter != null && setter.isAccessibleIn(_definingLibrary)) {
-        return setter;
-      }
-    }
-    for (InterfaceType interfaceType in targetType.interfaces) {
-      PropertyAccessorElement setter = _lookUpSetterInInterfaces(interfaceType, true, setterName, visitedInterfaces);
-      if (setter != null) {
-        return setter;
-      }
-    }
-    for (InterfaceType mixinType in targetType.mixins) {
-      PropertyAccessorElement setter = _lookUpSetterInInterfaces(mixinType, true, setterName, visitedInterfaces);
-      if (setter != null) {
-        return setter;
-      }
-    }
-    InterfaceType superclass = targetType.superclass;
-    if (superclass == null) {
-      return null;
-    }
-    return _lookUpSetterInInterfaces(superclass, true, setterName, visitedInterfaces);
-  }
-
-  /**
-   * Given some class element, this method uses [subtypeManager] to find the set of all
-   * subtypes; the subtypes are then searched for a member (method, getter, or setter), that matches
-   * a passed
-   *
-   * @param element the class element to search the subtypes of, if a non-ClassElement element is
-   *          passed, then `false` is returned
-   * @param memberName the member name to search for
-   * @param asMethod `true` if the methods should be searched for in the subtypes
-   * @param asAccessor `true` if the accessors (getters and setters) should be searched for in
-   *          the subtypes
-   * @return `true` if and only if the passed memberName was found in a subtype
-   */
-  bool _memberFoundInSubclass(Element element, String memberName, bool asMethod, bool asAccessor) {
-    if (element is ClassElement) {
-      _subtypeManager.ensureLibraryVisited(_definingLibrary);
-      HashSet<ClassElement> subtypeElements = _subtypeManager.computeAllSubtypes(element);
-      for (ClassElement subtypeElement in subtypeElements) {
-        if (asMethod && subtypeElement.getMethod(memberName) != null) {
-          return true;
-        } else if (asAccessor && (subtypeElement.getGetter(memberName) != null || subtypeElement.getSetter(memberName) != null)) {
-          return true;
-        }
-      }
-    }
-    return false;
-  }
-
-  /**
-   * Return the binary operator that is invoked by the given compound assignment operator.
-   *
-   * @param operator the assignment operator being mapped
-   * @return the binary operator that invoked by the given assignment operator
-   */
-  sc.TokenType _operatorFromCompoundAssignment(sc.TokenType operator) {
-    while (true) {
-      if (operator == sc.TokenType.AMPERSAND_EQ) {
-        return sc.TokenType.AMPERSAND;
-      } else if (operator == sc.TokenType.BAR_EQ) {
-        return sc.TokenType.BAR;
-      } else if (operator == sc.TokenType.CARET_EQ) {
-        return sc.TokenType.CARET;
-      } else if (operator == sc.TokenType.GT_GT_EQ) {
-        return sc.TokenType.GT_GT;
-      } else if (operator == sc.TokenType.LT_LT_EQ) {
-        return sc.TokenType.LT_LT;
-      } else if (operator == sc.TokenType.MINUS_EQ) {
-        return sc.TokenType.MINUS;
-      } else if (operator == sc.TokenType.PERCENT_EQ) {
-        return sc.TokenType.PERCENT;
-      } else if (operator == sc.TokenType.PLUS_EQ) {
-        return sc.TokenType.PLUS;
-      } else if (operator == sc.TokenType.SLASH_EQ) {
-        return sc.TokenType.SLASH;
-      } else if (operator == sc.TokenType.STAR_EQ) {
-        return sc.TokenType.STAR;
-      } else if (operator == sc.TokenType.TILDE_SLASH_EQ) {
-        return sc.TokenType.TILDE_SLASH;
-      } else {
-        // Internal error: Unmapped assignment operator.
-        AnalysisEngine.instance.logger.logError("Failed to map ${operator.lexeme} to it's corresponding operator");
-        return operator;
-      }
-      break;
-    }
-  }
-
-  /**
-   * Record that the given node is undefined, causing an error to be reported if appropriate.
-   *
-   * @param declaringElement the element inside which no declaration was found. If this element is a
-   *          proxy, no error will be reported. If null, then an error will always be reported.
-   * @param errorCode the error code to report.
-   * @param node the node which is undefined.
-   * @param arguments arguments to the error message.
-   */
-  void _recordUndefinedNode(Element declaringElement, ErrorCode errorCode, AstNode node, List<Object> arguments) {
-    if (_doesntHaveProxy(declaringElement)) {
-      _resolver.reportErrorForNode(errorCode, node, arguments);
-    }
-  }
-
-  /**
-   * Record that the given offset/length is undefined, causing an error to be reported if
-   * appropriate.
-   *
-   * @param declaringElement the element inside which no declaration was found. If this element is a
-   *          proxy, no error will be reported. If null, then an error will always be reported.
-   * @param errorCode the error code to report.
-   * @param offset the offset to the text which is undefined.
-   * @param length the length of the text which is undefined.
-   * @param arguments arguments to the error message.
-   */
-  void _recordUndefinedOffset(Element declaringElement, ErrorCode errorCode, int offset, int length, List<Object> arguments) {
-    if (_doesntHaveProxy(declaringElement)) {
-      _resolver.reportErrorForOffset(errorCode, offset, length, arguments);
-    }
-  }
-
-  /**
-   * Record that the given token is undefined, causing an error to be reported if appropriate.
-   *
-   * @param declaringElement the element inside which no declaration was found. If this element is a
-   *          proxy, no error will be reported. If null, then an error will always be reported.
-   * @param errorCode the error code to report.
-   * @param token the token which is undefined.
-   * @param arguments arguments to the error message.
-   */
-  void _recordUndefinedToken(Element declaringElement, ErrorCode errorCode, sc.Token token, List<Object> arguments) {
-    if (_doesntHaveProxy(declaringElement)) {
-      _resolver.reportErrorForToken(errorCode, token, arguments);
-    }
-  }
-
-  void _resolveAnnotationConstructorInvocationArguments(Annotation annotation, ConstructorElement constructor) {
-    ArgumentList argumentList = annotation.arguments;
-    // error will be reported in ConstantVerifier
-    if (argumentList == null) {
-      return;
-    }
-    // resolve arguments to parameters
-    List<ParameterElement> parameters = _resolveArgumentsToFunction(true, argumentList, constructor);
-    if (parameters != null) {
-      argumentList.correspondingStaticParameters = parameters;
-    }
-  }
-
-  /**
-   * Continues resolution of the given [Annotation].
-   *
-   * @param annotation the [Annotation] to resolve
-   */
-  void _resolveAnnotationElement(Annotation annotation) {
-    SimpleIdentifier nameNode1;
-    SimpleIdentifier nameNode2;
-    {
-      Identifier annName = annotation.name;
-      if (annName is PrefixedIdentifier) {
-        PrefixedIdentifier prefixed = annName;
-        nameNode1 = prefixed.prefix;
-        nameNode2 = prefixed.identifier;
-      } else {
-        nameNode1 = annName as SimpleIdentifier;
-        nameNode2 = null;
-      }
-    }
-    SimpleIdentifier nameNode3 = annotation.constructorName;
-    ConstructorElement constructor = null;
-    //
-    // CONST or Class(args)
-    //
-    if (nameNode1 != null && nameNode2 == null && nameNode3 == null) {
-      Element element1 = nameNode1.staticElement;
-      // CONST
-      if (element1 is PropertyAccessorElement) {
-        _resolveAnnotationElementGetter(annotation, element1);
-        return;
-      }
-      // Class(args)
-      if (element1 is ClassElement) {
-        ClassElement classElement = element1;
-        constructor = new InterfaceTypeImpl.con1(classElement).lookUpConstructor(null, _definingLibrary);
-      }
-    }
-    //
-    // prefix.CONST or prefix.Class() or Class.CONST or Class.constructor(args)
-    //
-    if (nameNode1 != null && nameNode2 != null && nameNode3 == null) {
-      Element element1 = nameNode1.staticElement;
-      Element element2 = nameNode2.staticElement;
-      // Class.CONST - not resolved yet
-      if (element1 is ClassElement) {
-        ClassElement classElement = element1;
-        element2 = classElement.lookUpGetter(nameNode2.name, _definingLibrary);
-      }
-      // prefix.CONST or Class.CONST
-      if (element2 is PropertyAccessorElement) {
-        nameNode2.staticElement = element2;
-        annotation.element = element2;
-        _resolveAnnotationElementGetter(annotation, element2 as PropertyAccessorElement);
-        return;
-      }
-      // prefix.Class()
-      if (element2 is ClassElement) {
-        ClassElement classElement = element2 as ClassElement;
-        constructor = classElement.unnamedConstructor;
-      }
-      // Class.constructor(args)
-      if (element1 is ClassElement) {
-        ClassElement classElement = element1;
-        constructor = new InterfaceTypeImpl.con1(classElement).lookUpConstructor(nameNode2.name, _definingLibrary);
-        nameNode2.staticElement = constructor;
-      }
-    }
-    //
-    // prefix.Class.CONST or prefix.Class.constructor(args)
-    //
-    if (nameNode1 != null && nameNode2 != null && nameNode3 != null) {
-      Element element2 = nameNode2.staticElement;
-      // element2 should be ClassElement
-      if (element2 is ClassElement) {
-        ClassElement classElement = element2;
-        String name3 = nameNode3.name;
-        // prefix.Class.CONST
-        PropertyAccessorElement getter = classElement.lookUpGetter(name3, _definingLibrary);
-        if (getter != null) {
-          nameNode3.staticElement = getter;
-          annotation.element = element2;
-          _resolveAnnotationElementGetter(annotation, getter);
-          return;
-        }
-        // prefix.Class.constructor(args)
-        constructor = new InterfaceTypeImpl.con1(classElement).lookUpConstructor(name3, _definingLibrary);
-        nameNode3.staticElement = constructor;
-      }
-    }
-    // we need constructor
-    if (constructor == null) {
-      _resolver.reportErrorForNode(CompileTimeErrorCode.INVALID_ANNOTATION, annotation, []);
-      return;
-    }
-    // record element
-    annotation.element = constructor;
-    // resolve arguments
-    _resolveAnnotationConstructorInvocationArguments(annotation, constructor);
-  }
-
-  void _resolveAnnotationElementGetter(Annotation annotation, PropertyAccessorElement accessorElement) {
-    // accessor should be synthetic
-    if (!accessorElement.isSynthetic) {
-      _resolver.reportErrorForNode(CompileTimeErrorCode.INVALID_ANNOTATION, annotation, []);
-      return;
-    }
-    // variable should be constant
-    VariableElement variableElement = accessorElement.variable;
-    if (!variableElement.isConst) {
-      _resolver.reportErrorForNode(CompileTimeErrorCode.INVALID_ANNOTATION, annotation, []);
-    }
-    // OK
-    return;
-  }
-
-  /**
-   * Given a list of arguments and the element that will be invoked using those argument, compute
-   * the list of parameters that correspond to the list of arguments. Return the parameters that
-   * correspond to the arguments, or `null` if no correspondence could be computed.
-   *
-   * @param reportError if `true` then compile-time error should be reported; if `false`
-   *          then compile-time warning
-   * @param argumentList the list of arguments being passed to the element
-   * @param executableElement the element that will be invoked with the arguments
-   * @return the parameters that correspond to the arguments
-   */
-  List<ParameterElement> _resolveArgumentsToFunction(bool reportError, ArgumentList argumentList, ExecutableElement executableElement) {
-    if (executableElement == null) {
-      return null;
-    }
-    List<ParameterElement> parameters = executableElement.parameters;
-    return _resolveArgumentsToParameters(reportError, argumentList, parameters);
-  }
-
-  /**
-   * Given a list of arguments and the parameters related to the element that will be invoked using
-   * those argument, compute the list of parameters that correspond to the list of arguments. Return
-   * the parameters that correspond to the arguments.
-   *
-   * @param reportError if `true` then compile-time error should be reported; if `false`
-   *          then compile-time warning
-   * @param argumentList the list of arguments being passed to the element
-   * @param parameters the of the function that will be invoked with the arguments
-   * @return the parameters that correspond to the arguments
-   */
-  List<ParameterElement> _resolveArgumentsToParameters(bool reportError, ArgumentList argumentList, List<ParameterElement> parameters) {
-    List<ParameterElement> requiredParameters = new List<ParameterElement>();
-    List<ParameterElement> positionalParameters = new List<ParameterElement>();
-    HashMap<String, ParameterElement> namedParameters = new HashMap<String, ParameterElement>();
-    for (ParameterElement parameter in parameters) {
-      ParameterKind kind = parameter.parameterKind;
-      if (kind == ParameterKind.REQUIRED) {
-        requiredParameters.add(parameter);
-      } else if (kind == ParameterKind.POSITIONAL) {
-        positionalParameters.add(parameter);
-      } else {
-        namedParameters[parameter.name] = parameter;
-      }
-    }
-    List<ParameterElement> unnamedParameters = new List<ParameterElement>.from(requiredParameters);
-    unnamedParameters.addAll(positionalParameters);
-    int unnamedParameterCount = unnamedParameters.length;
-    int unnamedIndex = 0;
-    NodeList<Expression> arguments = argumentList.arguments;
-    int argumentCount = arguments.length;
-    List<ParameterElement> resolvedParameters = new List<ParameterElement>(argumentCount);
-    int positionalArgumentCount = 0;
-    HashSet<String> usedNames = new HashSet<String>();
-    bool noBlankArguments = true;
-    for (int i = 0; i < argumentCount; i++) {
-      Expression argument = arguments[i];
-      if (argument is NamedExpression) {
-        SimpleIdentifier nameNode = argument.name.label;
-        String name = nameNode.name;
-        ParameterElement element = namedParameters[name];
-        if (element == null) {
-          ErrorCode errorCode = (reportError ? CompileTimeErrorCode.UNDEFINED_NAMED_PARAMETER : StaticWarningCode.UNDEFINED_NAMED_PARAMETER);
-          _resolver.reportErrorForNode(errorCode, nameNode, [name]);
-        } else {
-          resolvedParameters[i] = element;
-          nameNode.staticElement = element;
-        }
-        if (!usedNames.add(name)) {
-          _resolver.reportErrorForNode(CompileTimeErrorCode.DUPLICATE_NAMED_ARGUMENT, nameNode, [name]);
-        }
-      } else {
-        if (argument is SimpleIdentifier && argument.name.isEmpty) {
-          noBlankArguments = false;
-        }
-        positionalArgumentCount++;
-        if (unnamedIndex < unnamedParameterCount) {
-          resolvedParameters[i] = unnamedParameters[unnamedIndex++];
-        }
-      }
-    }
-    if (positionalArgumentCount < requiredParameters.length && noBlankArguments) {
-      ErrorCode errorCode = (reportError ? CompileTimeErrorCode.NOT_ENOUGH_REQUIRED_ARGUMENTS : StaticWarningCode.NOT_ENOUGH_REQUIRED_ARGUMENTS);
-      _resolver.reportErrorForNode(errorCode, argumentList, [requiredParameters.length, positionalArgumentCount]);
-    } else if (positionalArgumentCount > unnamedParameterCount && noBlankArguments) {
-      ErrorCode errorCode = (reportError ? CompileTimeErrorCode.EXTRA_POSITIONAL_ARGUMENTS : StaticWarningCode.EXTRA_POSITIONAL_ARGUMENTS);
-      _resolver.reportErrorForNode(errorCode, argumentList, [unnamedParameterCount, positionalArgumentCount]);
-    }
-    return resolvedParameters;
-  }
-
-  /**
-   * Resolve the names in the given combinators in the scope of the given library.
-   *
-   * @param library the library that defines the names
-   * @param combinators the combinators containing the names to be resolved
-   */
-  void _resolveCombinators(LibraryElement library, NodeList<Combinator> combinators) {
-    if (library == null) {
-      //
-      // The library will be null if the directive containing the combinators has a URI that is not
-      // valid.
-      //
-      return;
-    }
-    Namespace namespace = new NamespaceBuilder().createExportNamespaceForLibrary(library);
-    for (Combinator combinator in combinators) {
-      NodeList<SimpleIdentifier> names;
-      if (combinator is HideCombinator) {
-        names = combinator.hiddenNames;
-      } else {
-        names = (combinator as ShowCombinator).shownNames;
-      }
-      for (SimpleIdentifier name in names) {
-        String nameStr = name.name;
-        Element element = namespace.get(nameStr);
-        if (element == null) {
-          element = namespace.get("$nameStr=");
-        }
-        if (element != null) {
-          // Ensure that the name always resolves to a top-level variable
-          // rather than a getter or setter
-          if (element is PropertyAccessorElement) {
-            element = (element as PropertyAccessorElement).variable;
-          }
-          name.staticElement = element;
-        }
-      }
-    }
-  }
-
-  /**
-   * Given an invocation of the form 'C.x()' where 'C' is a class, find and return the element 'x'
-   * in 'C'.
-   *
-   * @param classElement the class element
-   * @param nameNode the member name node
-   */
-  Element _resolveElement(ClassElementImpl classElement, SimpleIdentifier nameNode) {
-    String name = nameNode.name;
-    Element element = classElement.getMethod(name);
-    if (element == null && nameNode.inSetterContext()) {
-      element = classElement.getSetter(name);
-    }
-    if (element == null && nameNode.inGetterContext()) {
-      element = classElement.getGetter(name);
-    }
-    if (element != null && element.isAccessibleIn(_definingLibrary)) {
-      return element;
-    }
-    return null;
-  }
-
-  /**
-   * Given an invocation of the form 'm(a1, ..., an)', resolve 'm' to the element being invoked. If
-   * the returned element is a method, then the method will be invoked. If the returned element is a
-   * getter, the getter will be invoked without arguments and the result of that invocation will
-   * then be invoked with the arguments.
-   *
-   * @param methodName the name of the method being invoked ('m')
-   * @return the element being invoked
-   */
-  Element _resolveInvokedElement(SimpleIdentifier methodName) {
-    //
-    // Look first in the lexical scope.
-    //
-    Element element = _resolver.nameScope.lookup(methodName, _definingLibrary);
-    if (element == null) {
-      //
-      // If it isn't defined in the lexical scope, and the invocation is within a class, then look
-      // in the inheritance scope.
-      //
-      ClassElement enclosingClass = _resolver.enclosingClass;
-      if (enclosingClass != null) {
-        InterfaceType enclosingType = enclosingClass.type;
-        element = _lookUpMethod(null, enclosingType, methodName.name);
-        if (element == null) {
-          //
-          // If there's no method, then it's possible that 'm' is a getter that returns a function.
-          //
-          element = _lookUpGetter(null, enclosingType, methodName.name);
-        }
-      }
-    }
-    // TODO(brianwilkerson) Report this error.
-    return element;
-  }
-
-  /**
-   * Given an invocation of the form 'e.m(a1, ..., an)', resolve 'e.m' to the element being invoked.
-   * If the returned element is a method, then the method will be invoked. If the returned element
-   * is a getter, the getter will be invoked without arguments and the result of that invocation
-   * will then be invoked with the arguments.
-   *
-   * @param target the target of the invocation ('e')
-   * @param targetType the type of the target
-   * @param methodName the name of the method being invoked ('m')
-   * @return the element being invoked
-   */
-  Element _resolveInvokedElementWithTarget(Expression target, DartType targetType, SimpleIdentifier methodName) {
-    if (targetType is InterfaceType || targetType is UnionType) {
-      Element element = _lookUpMethod(target, targetType, methodName.name);
-      if (element == null) {
-        //
-        // If there's no method, then it's possible that 'm' is a getter that returns a function.
-        //
-        // TODO (collinsn): need to add union type support here too, in the style of [lookUpMethod].
-        element = _lookUpGetter(target, targetType, methodName.name);
-      }
-      return element;
-    } else if (target is SimpleIdentifier) {
-      Element targetElement = target.staticElement;
-      if (targetElement is PrefixElement) {
-        //
-        // Look to see whether the name of the method is really part of a prefixed identifier for an
-        // imported top-level function or top-level getter that returns a function.
-        //
-        String name = "${target.name}.$methodName";
-        Identifier functionName = new ElementResolver_SyntheticIdentifier(name);
-        Element element = _resolver.nameScope.lookup(functionName, _definingLibrary);
-        if (element != null) {
-          // TODO(brianwilkerson) This isn't a method invocation, it's a function invocation where
-          // the function name is a prefixed identifier. Consider re-writing the AST.
-          return element;
-        }
-      }
-    }
-    // TODO(brianwilkerson) Report this error.
-    return null;
-  }
-
-  /**
-   * Given that we are accessing a property of the given type with the given name, return the
-   * element that represents the property.
-   *
-   * @param target the target of the invocation ('e')
-   * @param targetType the type in which the search for the property should begin
-   * @param propertyName the name of the property being accessed
-   * @return the element that represents the property
-   */
-  ExecutableElement _resolveProperty(Expression target, DartType targetType, SimpleIdentifier propertyName) {
-    ExecutableElement memberElement = null;
-    if (propertyName.inSetterContext()) {
-      memberElement = _lookUpSetter(target, targetType, propertyName.name);
-    }
-    if (memberElement == null) {
-      memberElement = _lookUpGetter(target, targetType, propertyName.name);
-    }
-    if (memberElement == null) {
-      memberElement = _lookUpMethod(target, targetType, propertyName.name);
-    }
-    return memberElement;
-  }
-
-  void _resolvePropertyAccess(Expression target, SimpleIdentifier propertyName) {
-    DartType staticType = _getStaticType(target);
-    DartType propagatedType = _getPropagatedType(target);
-    Element staticElement = null;
-    Element propagatedElement = null;
-    //
-    // If this property access is of the form 'C.m' where 'C' is a class, then we don't call
-    // resolveProperty(..) which walks up the class hierarchy, instead we just look for the
-    // member in the type only.
-    //
-    ClassElementImpl typeReference = getTypeReference(target);
-    if (typeReference != null) {
-      // TODO(brianwilkerson) Why are we setting the propagated element here? It looks wrong.
-      staticElement = propagatedElement = _resolveElement(typeReference, propertyName);
-    } else {
-      staticElement = _resolveProperty(target, staticType, propertyName);
-      propagatedElement = _resolveProperty(target, propagatedType, propertyName);
-    }
-    // May be part of annotation, record property element only if exists.
-    // Error was already reported in validateAnnotationElement().
-    if (target.parent.parent is Annotation) {
-      if (staticElement != null) {
-        propertyName.staticElement = staticElement;
-      }
-      return;
-    }
-    propertyName.staticElement = staticElement;
-    propertyName.propagatedElement = propagatedElement;
-    bool shouldReportMissingMember_static = _shouldReportMissingMember(staticType, staticElement);
-    bool shouldReportMissingMember_propagated = !shouldReportMissingMember_static && _enableHints && _shouldReportMissingMember(propagatedType, propagatedElement) && !_memberFoundInSubclass(propagatedType.element, propertyName.name, false, true);
-    // TODO(collinsn): add support for errors on union types by extending
-    // [lookupGetter] and [lookupSetter] in analogy with the earlier [lookupMethod] extensions.
-    if (propagatedType is UnionType) {
-      shouldReportMissingMember_propagated = false;
-    }
-    if (shouldReportMissingMember_static || shouldReportMissingMember_propagated) {
-      Element staticOrPropagatedEnclosingElt = shouldReportMissingMember_static ? staticType.element : propagatedType.element;
-      bool isStaticProperty = _isStatic(staticOrPropagatedEnclosingElt);
-      String displayName = staticOrPropagatedEnclosingElt != null ? staticOrPropagatedEnclosingElt.displayName : propagatedType != null ? propagatedType.displayName : staticType.displayName;
-      // Special getter cases.
-      if (propertyName.inGetterContext()) {
-        if (!isStaticProperty && staticOrPropagatedEnclosingElt is ClassElement) {
-          ClassElement classElement = staticOrPropagatedEnclosingElt;
-          InterfaceType targetType = classElement.type;
-          if (targetType != null && targetType.isDartCoreFunction && propertyName.name == FunctionElement.CALL_METHOD_NAME) {
-            // TODO(brianwilkerson) Can we ever resolve the function being invoked?
-            //resolveArgumentsToParameters(node.getArgumentList(), invokedFunction);
-            return;
-          } else if (classElement.isEnum && propertyName.name == "_name") {
-            _resolver.reportErrorForNode(CompileTimeErrorCode.ACCESS_PRIVATE_ENUM_FIELD, propertyName, [propertyName.name]);
-            return;
-          }
-        }
-      }
-      Element declaringElement = staticType.isVoid ? null : staticOrPropagatedEnclosingElt;
-      if (propertyName.inSetterContext()) {
-        ErrorCode staticErrorCode = (isStaticProperty && !staticType.isVoid ? StaticWarningCode.UNDEFINED_SETTER : StaticTypeWarningCode.UNDEFINED_SETTER);
-        ErrorCode errorCode = shouldReportMissingMember_static ? staticErrorCode : HintCode.UNDEFINED_SETTER;
-        _recordUndefinedNode(declaringElement, errorCode, propertyName, [propertyName.name, displayName]);
-      } else if (propertyName.inGetterContext()) {
-        ErrorCode staticErrorCode = (isStaticProperty && !staticType.isVoid ? StaticWarningCode.UNDEFINED_GETTER : StaticTypeWarningCode.UNDEFINED_GETTER);
-        ErrorCode errorCode = shouldReportMissingMember_static ? staticErrorCode : HintCode.UNDEFINED_GETTER;
-        _recordUndefinedNode(declaringElement, errorCode, propertyName, [propertyName.name, displayName]);
-      } else {
-        _recordUndefinedNode(declaringElement, StaticWarningCode.UNDEFINED_IDENTIFIER, propertyName, [propertyName.name]);
-      }
-    }
-  }
-
-  /**
-   * Resolve the given simple identifier if possible. Return the element to which it could be
-   * resolved, or `null` if it could not be resolved. This does not record the results of the
-   * resolution.
-   *
-   * @param node the identifier to be resolved
-   * @return the element to which the identifier could be resolved
-   */
-  Element _resolveSimpleIdentifier(SimpleIdentifier node) {
-    Element element = _resolver.nameScope.lookup(node, _definingLibrary);
-    if (element is PropertyAccessorElement && node.inSetterContext()) {
-      PropertyInducingElement variable = (element as PropertyAccessorElement).variable;
-      if (variable != null) {
-        PropertyAccessorElement setter = variable.setter;
-        if (setter == null) {
-          //
-          // Check to see whether there might be a locally defined getter and an inherited setter.
-          //
-          ClassElement enclosingClass = _resolver.enclosingClass;
-          if (enclosingClass != null) {
-            setter = _lookUpSetter(null, enclosingClass.type, node.name);
-          }
-        }
-        if (setter != null) {
-          element = setter;
-        }
-      }
-    } else if (element == null && (node.inSetterContext() || node.parent is CommentReference)) {
-      element = _resolver.nameScope.lookup(new ElementResolver_SyntheticIdentifier("${node.name}="), _definingLibrary);
-    }
-    ClassElement enclosingClass = _resolver.enclosingClass;
-    if (element == null && enclosingClass != null) {
-      InterfaceType enclosingType = enclosingClass.type;
-      if (element == null && (node.inSetterContext() || node.parent is CommentReference)) {
-        element = _lookUpSetter(null, enclosingType, node.name);
-      }
-      if (element == null && node.inGetterContext()) {
-        element = _lookUpGetter(null, enclosingType, node.name);
-      }
-      if (element == null) {
-        element = _lookUpMethod(null, enclosingType, node.name);
-      }
-    }
-    return element;
-  }
-
-  /**
-   * If the given type is a type parameter, resolve it to the type that should be used when looking
-   * up members. Otherwise, return the original type.
-   *
-   * @param type the type that is to be resolved if it is a type parameter
-   * @return the type that should be used in place of the argument if it is a type parameter, or the
-   *         original argument if it isn't a type parameter
-   */
-  DartType _resolveTypeParameter(DartType type) {
-    if (type is TypeParameterType) {
-      DartType bound = type.element.bound;
-      if (bound == null) {
-        return _resolver.typeProvider.objectType;
-      }
-      return bound;
-    }
-    return type;
-  }
-
-  /**
-   * Given a node that can have annotations associated with it and the element to which that node
-   * has been resolved, create the annotations in the element model representing the annotations on
-   * the node.
-   *
-   * @param element the element to which the node has been resolved
-   * @param node the node that can have annotations associated with it
-   */
-  void _setMetadata(Element element, AnnotatedNode node) {
-    if (element is! ElementImpl) {
-      return;
-    }
-    List<ElementAnnotationImpl> annotationList = new List<ElementAnnotationImpl>();
-    _addAnnotations(annotationList, node.metadata);
-    if (node is VariableDeclaration && node.parent is VariableDeclarationList) {
-      VariableDeclarationList list = node.parent as VariableDeclarationList;
-      _addAnnotations(annotationList, list.metadata);
-      if (list.parent is FieldDeclaration) {
-        FieldDeclaration fieldDeclaration = list.parent as FieldDeclaration;
-        _addAnnotations(annotationList, fieldDeclaration.metadata);
-      } else if (list.parent is TopLevelVariableDeclaration) {
-        TopLevelVariableDeclaration variableDeclaration = list.parent as TopLevelVariableDeclaration;
-        _addAnnotations(annotationList, variableDeclaration.metadata);
-      }
-    }
-    if (!annotationList.isEmpty) {
-      (element as ElementImpl).metadata = annotationList;
-    }
-  }
-
-  /**
-   * Given a node that can have annotations associated with it and the element to which that node
-   * has been resolved, create the annotations in the element model representing the annotations on
-   * the node.
-   *
-   * @param element the element to which the node has been resolved
-   * @param node the node that can have annotations associated with it
-   */
-  void _setMetadataForParameter(Element element, NormalFormalParameter node) {
-    if (element is! ElementImpl) {
-      return;
-    }
-    List<ElementAnnotationImpl> annotationList = new List<ElementAnnotationImpl>();
-    _addAnnotations(annotationList, node.metadata);
-    if (!annotationList.isEmpty) {
-      (element as ElementImpl).metadata = annotationList;
-    }
-  }
-
-  /**
-   * Return `true` if we should report an error as a result of looking up a member in the
-   * given type and not finding any member.
-   *
-   * @param type the type in which we attempted to perform the look-up
-   * @param member the result of the look-up
-   * @return `true` if we should report an error
-   */
-  bool _shouldReportMissingMember(DartType type, Element member) {
-    if (member != null || type == null || type.isDynamic || type.isBottom) {
-      return false;
-    }
-    return true;
-  }
-}
-
-/**
- * Instances of the class `SyntheticIdentifier` implement an identifier that can be used to
- * look up names in the lexical scope when there is no identifier in the AST structure. There is
- * no identifier in the AST when the parser could not distinguish between a method invocation and
- * an invocation of a top-level function imported with a prefix.
- */
-class ElementResolver_SyntheticIdentifier extends Identifier {
-  /**
-   * The name of the synthetic identifier.
-   */
-  final String name;
-
-  /**
-   * Initialize a newly created synthetic identifier to have the given name.
-   *
-   * @param name the name of the synthetic identifier
-   */
-  ElementResolver_SyntheticIdentifier(this.name);
-
-  @override
-  accept(AstVisitor visitor) => null;
-
-  @override
-  sc.Token get beginToken => null;
-
-  @override
-  Element get bestElement => null;
-
-  @override
-  sc.Token get endToken => null;
-
-  @override
-  int get precedence => 16;
-
-  @override
-  Element get propagatedElement => null;
-
-  @override
-  Element get staticElement => null;
-
-  @override
-  void visitChildren(AstVisitor visitor) {
-  }
-}
-
-/**
  * Instances of the class `EnclosedScope` implement a scope that is lexically enclosed in
  * another scope.
  */
@@ -7428,5405 +4814,6 @@
 }
 
 /**
- * Instances of the class `ErrorVerifier` traverse an AST structure looking for additional
- * errors and warnings not covered by the parser and resolver.
- */
-class ErrorVerifier extends RecursiveAstVisitor<Object> {
-  /**
-   * Return the static type of the given expression that is to be used for type analysis.
-   *
-   * @param expression the expression whose type is to be returned
-   * @return the static type of the given expression
-   */
-  static DartType getStaticType(Expression expression) {
-    DartType type = expression.staticType;
-    if (type == null) {
-      // TODO(brianwilkerson) This should never happen.
-      return DynamicTypeImpl.instance;
-    }
-    return type;
-  }
-
-  /**
-   * Return the variable element represented by the given expression, or `null` if there is no
-   * such element.
-   *
-   * @param expression the expression whose element is to be returned
-   * @return the variable element represented by the expression
-   */
-  static VariableElement getVariableElement(Expression expression) {
-    if (expression is Identifier) {
-      Element element = expression.staticElement;
-      if (element is VariableElement) {
-        return element;
-      }
-    }
-    return null;
-  }
-
-  /**
-   * The error reporter by which errors will be reported.
-   */
-  final ErrorReporter _errorReporter;
-
-  /**
-   * The current library that is being analyzed.
-   */
-  final LibraryElement _currentLibrary;
-
-  /**
-   * The type representing the type 'bool'.
-   */
-  InterfaceType _boolType;
-
-  /**
-   * The type representing the type 'int'.
-   */
-  InterfaceType _intType;
-
-  /**
-   * The object providing access to the types defined by the language.
-   */
-  final TypeProvider _typeProvider;
-
-  /**
-   * The manager for the inheritance mappings.
-   */
-  final InheritanceManager _inheritanceManager;
-
-  /**
-   * This is set to `true` iff the visitor is currently visiting children nodes of a
-   * [ConstructorDeclaration] and the constructor is 'const'.
-   *
-   * @see #visitConstructorDeclaration(ConstructorDeclaration)
-   */
-  bool _isEnclosingConstructorConst = false;
-
-  /**
-   * A flag indicating whether we are currently within a function body marked as being asynchronous.
-   */
-  bool _inAsync = false;
-
-  /**
-   * A flag indicating whether we are currently within a function body marked as being a generator.
-   */
-  bool _inGenerator = false;
-
-  /**
-   * This is set to `true` iff the visitor is currently visiting children nodes of a
-   * [CatchClause].
-   *
-   * @see #visitCatchClause(CatchClause)
-   */
-  bool _isInCatchClause = false;
-
-  /**
-   * This is set to `true` iff the visitor is currently visiting children nodes of an
-   * [Comment].
-   */
-  bool _isInComment = false;
-
-  /**
-   * This is set to `true` iff the visitor is currently visiting children nodes of an
-   * [InstanceCreationExpression].
-   */
-  bool _isInConstInstanceCreation = false;
-
-  /**
-   * This is set to `true` iff the visitor is currently visiting children nodes of a native
-   * [ClassDeclaration].
-   */
-  bool _isInNativeClass = false;
-
-  /**
-   * This is set to `true` iff the visitor is currently visiting a static variable
-   * declaration.
-   */
-  bool _isInStaticVariableDeclaration = false;
-
-  /**
-   * This is set to `true` iff the visitor is currently visiting an instance variable
-   * declaration.
-   */
-  bool _isInInstanceVariableDeclaration = false;
-
-  /**
-   * This is set to `true` iff the visitor is currently visiting an instance variable
-   * initializer.
-   */
-  bool _isInInstanceVariableInitializer = false;
-
-  /**
-   * This is set to `true` iff the visitor is currently visiting a
-   * [ConstructorInitializer].
-   */
-  bool _isInConstructorInitializer = false;
-
-  /**
-   * This is set to `true` iff the visitor is currently visiting a
-   * [FunctionTypedFormalParameter].
-   */
-  bool _isInFunctionTypedFormalParameter = false;
-
-  /**
-   * This is set to `true` iff the visitor is currently visiting a static method. By "method"
-   * here getter, setter and operator declarations are also implied since they are all represented
-   * with a [MethodDeclaration] in the AST structure.
-   */
-  bool _isInStaticMethod = false;
-
-  /**
-   * This is set to `true` iff the visitor is currently visiting a factory constructor.
-   */
-  bool _isInFactory = false;
-
-  /**
-   * This is set to `true` iff the visitor is currently visiting code in the SDK.
-   */
-  bool _isInSystemLibrary = false;
-
-  /**
-   * A flag indicating whether the current library contains at least one import directive with a URI
-   * that uses the "dart-ext" scheme.
-   */
-  bool _hasExtUri = false;
-
-  /**
-   * This is set to `false` on the entry of every [BlockFunctionBody], and is restored
-   * to the enclosing value on exit. The value is used in
-   * [checkForMixedReturns] to prevent both
-   * [StaticWarningCode#MIXED_RETURN_TYPES] and [StaticWarningCode#RETURN_WITHOUT_VALUE]
-   * from being generated in the same function body.
-   */
-  bool _hasReturnWithoutValue = false;
-
-  /**
-   * The class containing the AST nodes being visited, or `null` if we are not in the scope of
-   * a class.
-   */
-  ClassElement _enclosingClass;
-
-  /**
-   * The method or function that we are currently visiting, or `null` if we are not inside a
-   * method or function.
-   */
-  ExecutableElement _enclosingFunction;
-
-  /**
-   * The return statements found in the method or function that we are currently visiting that have
-   * a return value.
-   */
-  List<ReturnStatement> _returnsWith = new List<ReturnStatement>();
-
-  /**
-   * The return statements found in the method or function that we are currently visiting that do
-   * not have a return value.
-   */
-  List<ReturnStatement> _returnsWithout = new List<ReturnStatement>();
-
-  /**
-   * This map is initialized when visiting the contents of a class declaration. If the visitor is
-   * not in an enclosing class declaration, then the map is set to `null`.
-   *
-   * When set the map maps the set of [FieldElement]s in the class to an
-   * [INIT_STATE#NOT_INIT] or [INIT_STATE#INIT_IN_DECLARATION]. <code>checkFor*</code>
-   * methods, specifically [checkForAllFinalInitializedErrorCodes],
-   * can make a copy of the map to compute error code states. <code>checkFor*</code> methods should
-   * only ever make a copy, or read from this map after it has been set in
-   * [visitClassDeclaration].
-   *
-   * @see #visitClassDeclaration(ClassDeclaration)
-   * @see #checkForAllFinalInitializedErrorCodes(ConstructorDeclaration)
-   */
-  HashMap<FieldElement, INIT_STATE> _initialFieldElementsMap;
-
-  /**
-   * A table mapping name of the library to the export directive which export this library.
-   */
-  HashMap<String, LibraryElement> _nameToExportElement = new HashMap<String, LibraryElement>();
-
-  /**
-   * A table mapping name of the library to the import directive which import this library.
-   */
-  HashMap<String, LibraryElement> _nameToImportElement = new HashMap<String, LibraryElement>();
-
-  /**
-   * A table mapping names to the exported elements.
-   */
-  HashMap<String, Element> _exportedElements = new HashMap<String, Element>();
-
-  /**
-   * A set of the names of the variable initializers we are visiting now.
-   */
-  HashSet<String> _namesForReferenceToDeclaredVariableInInitializer = new HashSet<String>();
-
-  /**
-   * A list of types used by the [CompileTimeErrorCode#EXTENDS_DISALLOWED_CLASS] and
-   * [CompileTimeErrorCode#IMPLEMENTS_DISALLOWED_CLASS] error codes.
-   */
-  List<InterfaceType> _DISALLOWED_TYPES_TO_EXTEND_OR_IMPLEMENT;
-
-  /**
-   * Static final string with value `"getter "` used in the construction of the
-   * [StaticWarningCode#NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE], and similar, error
-   * code messages.
-   *
-   * @see #checkForNonAbstractClassInheritsAbstractMember(ClassDeclaration)
-   */
-  static String _GETTER_SPACE = "getter ";
-
-  /**
-   * Static final string with value `"setter "` used in the construction of the
-   * [StaticWarningCode#NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE], and similar, error
-   * code messages.
-   *
-   * @see #checkForNonAbstractClassInheritsAbstractMember(ClassDeclaration)
-   */
-  static String _SETTER_SPACE = "setter ";
-
-  /**
-   * Initialize the [ErrorVerifier] visitor.
-   */
-  ErrorVerifier(this._errorReporter, this._currentLibrary, this._typeProvider, this._inheritanceManager) {
-    this._isInSystemLibrary = _currentLibrary.source.isInSystemLibrary;
-    this._hasExtUri = _currentLibrary.hasExtUri;
-    _isEnclosingConstructorConst = false;
-    _isInCatchClause = false;
-    _isInStaticVariableDeclaration = false;
-    _isInInstanceVariableDeclaration = false;
-    _isInInstanceVariableInitializer = false;
-    _isInConstructorInitializer = false;
-    _isInStaticMethod = false;
-    _boolType = _typeProvider.boolType;
-    _intType = _typeProvider.intType;
-    _DISALLOWED_TYPES_TO_EXTEND_OR_IMPLEMENT = <InterfaceType> [
-        _typeProvider.nullType,
-        _typeProvider.numType,
-        _intType,
-        _typeProvider.doubleType,
-        _boolType,
-        _typeProvider.stringType];
-  }
-
-  @override
-  Object visitAnnotation(Annotation node) {
-    _checkForInvalidAnnotationFromDeferredLibrary(node);
-    return super.visitAnnotation(node);
-  }
-
-  @override
-  Object visitArgumentList(ArgumentList node) {
-    _checkForArgumentTypesNotAssignableInList(node);
-    return super.visitArgumentList(node);
-  }
-
-  @override
-  Object visitAsExpression(AsExpression node) {
-    _checkForTypeAnnotationDeferredClass(node.type);
-    return super.visitAsExpression(node);
-  }
-
-  @override
-  Object visitAssertStatement(AssertStatement node) {
-    _checkForNonBoolExpression(node);
-    return super.visitAssertStatement(node);
-  }
-
-  @override
-  Object visitAssignmentExpression(AssignmentExpression node) {
-    sc.TokenType operatorType = node.operator.type;
-    Expression lhs = node.leftHandSide;
-    Expression rhs = node.rightHandSide;
-    if (operatorType == sc.TokenType.EQ) {
-      _checkForInvalidAssignment(lhs, rhs);
-    } else {
-      _checkForInvalidCompoundAssignment(node, lhs, rhs);
-      _checkForArgumentTypeNotAssignableForArgument(rhs);
-    }
-    _checkForAssignmentToFinal(lhs);
-    return super.visitAssignmentExpression(node);
-  }
-
-  @override
-  Object visitAwaitExpression(AwaitExpression node) {
-    if (!_inAsync) {
-      _errorReporter.reportErrorForToken(CompileTimeErrorCode.AWAIT_IN_WRONG_CONTEXT, node.awaitKeyword, []);
-    }
-    return super.visitAwaitExpression(node);
-  }
-
-  @override
-  Object visitBinaryExpression(BinaryExpression node) {
-    sc.Token operator = node.operator;
-    sc.TokenType type = operator.type;
-    if (type == sc.TokenType.AMPERSAND_AMPERSAND || type == sc.TokenType.BAR_BAR) {
-      String lexeme = operator.lexeme;
-      _checkForAssignability(node.leftOperand, _boolType, StaticTypeWarningCode.NON_BOOL_OPERAND, [lexeme]);
-      _checkForAssignability(node.rightOperand, _boolType, StaticTypeWarningCode.NON_BOOL_OPERAND, [lexeme]);
-    } else {
-      _checkForArgumentTypeNotAssignableForArgument(node.rightOperand);
-    }
-    return super.visitBinaryExpression(node);
-  }
-
-  @override
-  Object visitBlockFunctionBody(BlockFunctionBody node) {
-    bool wasInAsync = _inAsync;
-    bool wasInGenerator = _inGenerator;
-    bool previousHasReturnWithoutValue = _hasReturnWithoutValue;
-    _hasReturnWithoutValue = false;
-    List<ReturnStatement> previousReturnsWith = _returnsWith;
-    List<ReturnStatement> previousReturnsWithout = _returnsWithout;
-    try {
-      _inAsync = node.isAsynchronous;
-      _inGenerator = node.isGenerator;
-      _returnsWith = new List<ReturnStatement>();
-      _returnsWithout = new List<ReturnStatement>();
-      super.visitBlockFunctionBody(node);
-      _checkForMixedReturns(node);
-    } finally {
-      _inAsync = wasInAsync;
-      _inGenerator = wasInGenerator;
-      _returnsWith = previousReturnsWith;
-      _returnsWithout = previousReturnsWithout;
-      _hasReturnWithoutValue = previousHasReturnWithoutValue;
-    }
-    return null;
-  }
-
-  @override
-  Object visitBreakStatement(BreakStatement node) {
-    SimpleIdentifier labelNode = node.label;
-    if (labelNode != null) {
-      Element labelElement = labelNode.staticElement;
-      if (labelElement is LabelElementImpl && labelElement.isOnSwitchMember) {
-        _errorReporter.reportErrorForNode(ResolverErrorCode.BREAK_LABEL_ON_SWITCH_MEMBER, labelNode, []);
-      }
-    }
-    return null;
-  }
-
-  @override
-  Object visitCatchClause(CatchClause node) {
-    bool previousIsInCatchClause = _isInCatchClause;
-    try {
-      _isInCatchClause = true;
-      _checkForTypeAnnotationDeferredClass(node.exceptionType);
-      return super.visitCatchClause(node);
-    } finally {
-      _isInCatchClause = previousIsInCatchClause;
-    }
-  }
-
-  @override
-  Object visitClassDeclaration(ClassDeclaration node) {
-    ClassElement outerClass = _enclosingClass;
-    try {
-      _isInNativeClass = node.nativeClause != null;
-      _enclosingClass = node.element;
-      ExtendsClause extendsClause = node.extendsClause;
-      ImplementsClause implementsClause = node.implementsClause;
-      WithClause withClause = node.withClause;
-      _checkForBuiltInIdentifierAsName(node.name, CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE_NAME);
-      _checkForMemberWithClassName();
-      _checkForNoDefaultSuperConstructorImplicit(node);
-      _checkForConflictingTypeVariableErrorCodes(node);
-      // Only do error checks on the clause nodes if there is a non-null clause
-      if (implementsClause != null || extendsClause != null || withClause != null) {
-        // Only check for all of the inheritance logic around clauses if there isn't an error code
-        // such as "Cannot extend double" already on the class.
-        if (!_checkForImplementsDisallowedClass(implementsClause) && !_checkForExtendsDisallowedClass(extendsClause) && !_checkForAllMixinErrorCodes(withClause)) {
-          _checkForExtendsDeferredClass(extendsClause);
-          _checkForImplementsDeferredClass(implementsClause);
-          _checkForNonAbstractClassInheritsAbstractMember(node.name);
-          _checkForInconsistentMethodInheritance();
-          _checkForRecursiveInterfaceInheritance(_enclosingClass);
-          _checkForConflictingGetterAndMethod();
-          _checkForConflictingInstanceGetterAndSuperclassMember();
-          _checkImplementsSuperClass(node);
-          _checkImplementsFunctionWithoutCall(node);
-        }
-      }
-      // initialize initialFieldElementsMap
-      if (_enclosingClass != null) {
-        List<FieldElement> fieldElements = _enclosingClass.fields;
-        _initialFieldElementsMap = new HashMap<FieldElement, INIT_STATE>();
-        for (FieldElement fieldElement in fieldElements) {
-          if (!fieldElement.isSynthetic) {
-            _initialFieldElementsMap[fieldElement] = fieldElement.initializer == null ? INIT_STATE.NOT_INIT : INIT_STATE.INIT_IN_DECLARATION;
-          }
-        }
-      }
-      _checkForFinalNotInitializedInClass(node);
-      _checkForDuplicateDefinitionInheritance();
-      _checkForConflictingInstanceMethodSetter(node);
-      return super.visitClassDeclaration(node);
-    } finally {
-      _isInNativeClass = false;
-      _initialFieldElementsMap = null;
-      _enclosingClass = outerClass;
-    }
-  }
-
-  @override
-  Object visitClassTypeAlias(ClassTypeAlias node) {
-    _checkForBuiltInIdentifierAsName(node.name, CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPEDEF_NAME);
-    ClassElement outerClassElement = _enclosingClass;
-    try {
-      _enclosingClass = node.element;
-      ImplementsClause implementsClause = node.implementsClause;
-      // Only check for all of the inheritance logic around clauses if there isn't an error code
-      // such as "Cannot extend double" already on the class.
-      if (!_checkForExtendsDisallowedClassInTypeAlias(node) && !_checkForImplementsDisallowedClass(implementsClause) && !_checkForAllMixinErrorCodes(node.withClause)) {
-        _checkForExtendsDeferredClassInTypeAlias(node);
-        _checkForImplementsDeferredClass(implementsClause);
-        _checkForRecursiveInterfaceInheritance(_enclosingClass);
-        _checkForNonAbstractClassInheritsAbstractMember(node.name);
-      }
-    } finally {
-      _enclosingClass = outerClassElement;
-    }
-    return super.visitClassTypeAlias(node);
-  }
-
-  @override
-  Object visitComment(Comment node) {
-    _isInComment = true;
-    try {
-      return super.visitComment(node);
-    } finally {
-      _isInComment = false;
-    }
-  }
-
-  @override
-  Object visitCompilationUnit(CompilationUnit node) {
-    _checkForDeferredPrefixCollisions(node);
-    return super.visitCompilationUnit(node);
-  }
-
-  @override
-  Object visitConditionalExpression(ConditionalExpression node) {
-    _checkForNonBoolCondition(node.condition);
-    return super.visitConditionalExpression(node);
-  }
-
-  @override
-  Object visitConstructorDeclaration(ConstructorDeclaration node) {
-    ExecutableElement outerFunction = _enclosingFunction;
-    try {
-      ConstructorElement constructorElement = node.element;
-      _enclosingFunction = constructorElement;
-      _isEnclosingConstructorConst = node.constKeyword != null;
-      _isInFactory = node.factoryKeyword != null;
-      _checkForInvalidModifierOnBody(node.body, CompileTimeErrorCode.INVALID_MODIFIER_ON_CONSTRUCTOR);
-      _checkForConstConstructorWithNonFinalField(node, constructorElement);
-      _checkForConstConstructorWithNonConstSuper(node);
-      _checkForConflictingConstructorNameAndMember(node, constructorElement);
-      _checkForAllFinalInitializedErrorCodes(node);
-      _checkForRedirectingConstructorErrorCodes(node);
-      _checkForMultipleSuperInitializers(node);
-      _checkForRecursiveConstructorRedirect(node, constructorElement);
-      if (!_checkForRecursiveFactoryRedirect(node, constructorElement)) {
-        _checkForAllRedirectConstructorErrorCodes(node);
-      }
-      _checkForUndefinedConstructorInInitializerImplicit(node);
-      _checkForRedirectToNonConstConstructor(node, constructorElement);
-      _checkForReturnInGenerativeConstructor(node);
-      return super.visitConstructorDeclaration(node);
-    } finally {
-      _isEnclosingConstructorConst = false;
-      _isInFactory = false;
-      _enclosingFunction = outerFunction;
-    }
-  }
-
-  @override
-  Object visitConstructorFieldInitializer(ConstructorFieldInitializer node) {
-    _isInConstructorInitializer = true;
-    try {
-      SimpleIdentifier fieldName = node.fieldName;
-      Element staticElement = fieldName.staticElement;
-      _checkForInvalidField(node, fieldName, staticElement);
-      _checkForFieldInitializerNotAssignable(node, staticElement);
-      return super.visitConstructorFieldInitializer(node);
-    } finally {
-      _isInConstructorInitializer = false;
-    }
-  }
-
-  @override
-  Object visitContinueStatement(ContinueStatement node) {
-    SimpleIdentifier labelNode = node.label;
-    if (labelNode != null) {
-      Element labelElement = labelNode.staticElement;
-      if (labelElement is LabelElementImpl && labelElement.isOnSwitchStatement) {
-        _errorReporter.reportErrorForNode(ResolverErrorCode.CONTINUE_LABEL_ON_SWITCH, labelNode, []);
-      }
-    }
-    return null;
-  }
-
-  @override
-  Object visitDefaultFormalParameter(DefaultFormalParameter node) {
-    _checkForInvalidAssignment(node.identifier, node.defaultValue);
-    _checkForDefaultValueInFunctionTypedParameter(node);
-    return super.visitDefaultFormalParameter(node);
-  }
-
-  @override
-  Object visitDoStatement(DoStatement node) {
-    _checkForNonBoolCondition(node.condition);
-    return super.visitDoStatement(node);
-  }
-
-  @override
-  Object visitExportDirective(ExportDirective node) {
-    ExportElement exportElement = node.element;
-    if (exportElement != null) {
-      LibraryElement exportedLibrary = exportElement.exportedLibrary;
-      _checkForAmbiguousExport(node, exportElement, exportedLibrary);
-      _checkForExportDuplicateLibraryName(node, exportElement, exportedLibrary);
-      _checkForExportInternalLibrary(node, exportElement);
-    }
-    return super.visitExportDirective(node);
-  }
-
-  @override
-  Object visitExpressionFunctionBody(ExpressionFunctionBody node) {
-    bool wasInAsync = _inAsync;
-    bool wasInGenerator = _inGenerator;
-    try {
-      _inAsync = node.isAsynchronous;
-      _inGenerator = node.isGenerator;
-      FunctionType functionType = _enclosingFunction == null ? null : _enclosingFunction.type;
-      DartType expectedReturnType = functionType == null ? DynamicTypeImpl.instance : functionType.returnType;
-      _checkForReturnOfInvalidType(node.expression, expectedReturnType);
-      return super.visitExpressionFunctionBody(node);
-    } finally {
-      _inAsync = wasInAsync;
-      _inGenerator = wasInGenerator;
-    }
-  }
-
-  @override
-  Object visitFieldDeclaration(FieldDeclaration node) {
-    _isInStaticVariableDeclaration = node.isStatic;
-    _isInInstanceVariableDeclaration = !_isInStaticVariableDeclaration;
-    if (_isInInstanceVariableDeclaration) {
-      VariableDeclarationList variables = node.fields;
-      if (variables.isConst) {
-        _errorReporter.reportErrorForToken(CompileTimeErrorCode.CONST_INSTANCE_FIELD, variables.keyword, []);
-      }
-    }
-    try {
-      _checkForAllInvalidOverrideErrorCodesForField(node);
-      return super.visitFieldDeclaration(node);
-    } finally {
-      _isInStaticVariableDeclaration = false;
-      _isInInstanceVariableDeclaration = false;
-    }
-  }
-
-  @override
-  Object visitFieldFormalParameter(FieldFormalParameter node) {
-    _checkForValidField(node);
-    _checkForConstFormalParameter(node);
-    _checkForPrivateOptionalParameter(node);
-    _checkForFieldInitializingFormalRedirectingConstructor(node);
-    _checkForTypeAnnotationDeferredClass(node.type);
-    return super.visitFieldFormalParameter(node);
-  }
-
-  @override
-  Object visitFunctionDeclaration(FunctionDeclaration node) {
-    ExecutableElement outerFunction = _enclosingFunction;
-    try {
-      SimpleIdentifier identifier = node.name;
-      String methodName = "";
-      if (identifier != null) {
-        methodName = identifier.name;
-      }
-      _enclosingFunction = node.element;
-      TypeName returnType = node.returnType;
-      if (node.isSetter || node.isGetter) {
-        _checkForMismatchedAccessorTypes(node, methodName);
-        if (node.isSetter) {
-          FunctionExpression functionExpression = node.functionExpression;
-          if (functionExpression != null) {
-            _checkForWrongNumberOfParametersForSetter(identifier, functionExpression.parameters);
-          }
-          _checkForNonVoidReturnTypeForSetter(returnType);
-        }
-      }
-      if (node.isSetter) {
-        _checkForInvalidModifierOnBody(node.functionExpression.body, CompileTimeErrorCode.INVALID_MODIFIER_ON_SETTER);
-      }
-      _checkForTypeAnnotationDeferredClass(returnType);
-      return super.visitFunctionDeclaration(node);
-    } finally {
-      _enclosingFunction = outerFunction;
-    }
-  }
-
-  @override
-  Object visitFunctionExpression(FunctionExpression node) {
-    // If this function expression is wrapped in a function declaration, don't change the
-    // enclosingFunction field.
-    if (node.parent is! FunctionDeclaration) {
-      ExecutableElement outerFunction = _enclosingFunction;
-      try {
-        _enclosingFunction = node.element;
-        return super.visitFunctionExpression(node);
-      } finally {
-        _enclosingFunction = outerFunction;
-      }
-    } else {
-      return super.visitFunctionExpression(node);
-    }
-  }
-
-  @override
-  Object visitFunctionExpressionInvocation(FunctionExpressionInvocation node) {
-    Expression functionExpression = node.function;
-    DartType expressionType = functionExpression.staticType;
-    if (!_isFunctionType(expressionType)) {
-      _errorReporter.reportErrorForNode(StaticTypeWarningCode.INVOCATION_OF_NON_FUNCTION_EXPRESSION, functionExpression, []);
-    }
-    return super.visitFunctionExpressionInvocation(node);
-  }
-
-  @override
-  Object visitFunctionTypeAlias(FunctionTypeAlias node) {
-    _checkForBuiltInIdentifierAsName(node.name, CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPEDEF_NAME);
-    _checkForDefaultValueInFunctionTypeAlias(node);
-    _checkForTypeAliasCannotReferenceItself_function(node);
-    return super.visitFunctionTypeAlias(node);
-  }
-
-  @override
-  Object visitFunctionTypedFormalParameter(FunctionTypedFormalParameter node) {
-    bool old = _isInFunctionTypedFormalParameter;
-    _isInFunctionTypedFormalParameter = true;
-    try {
-      _checkForTypeAnnotationDeferredClass(node.returnType);
-      return super.visitFunctionTypedFormalParameter(node);
-    } finally {
-      _isInFunctionTypedFormalParameter = old;
-    }
-  }
-
-  @override
-  Object visitIfStatement(IfStatement node) {
-    _checkForNonBoolCondition(node.condition);
-    return super.visitIfStatement(node);
-  }
-
-  @override
-  Object visitImportDirective(ImportDirective node) {
-    ImportElement importElement = node.element;
-    if (importElement != null) {
-      _checkForImportDuplicateLibraryName(node, importElement);
-      _checkForImportInternalLibrary(node, importElement);
-    }
-    return super.visitImportDirective(node);
-  }
-
-  @override
-  Object visitIndexExpression(IndexExpression node) {
-    _checkForArgumentTypeNotAssignableForArgument(node.index);
-    return super.visitIndexExpression(node);
-  }
-
-  @override
-  Object visitInstanceCreationExpression(InstanceCreationExpression node) {
-    _isInConstInstanceCreation = node.isConst;
-    try {
-      ConstructorName constructorName = node.constructorName;
-      TypeName typeName = constructorName.type;
-      DartType type = typeName.type;
-      if (type is InterfaceType) {
-        InterfaceType interfaceType = type;
-        _checkForConstOrNewWithAbstractClass(node, typeName, interfaceType);
-        _checkForConstOrNewWithEnum(node, typeName, interfaceType);
-        if (_isInConstInstanceCreation) {
-          _checkForConstWithNonConst(node);
-          _checkForConstWithUndefinedConstructor(node, constructorName, typeName);
-          _checkForConstWithTypeParameters(typeName);
-          _checkForConstDeferredClass(node, constructorName, typeName);
-        } else {
-          _checkForNewWithUndefinedConstructor(node, constructorName, typeName);
-        }
-      }
-      return super.visitInstanceCreationExpression(node);
-    } finally {
-      _isInConstInstanceCreation = false;
-    }
-  }
-
-  @override
-  Object visitIsExpression(IsExpression node) {
-    _checkForTypeAnnotationDeferredClass(node.type);
-    return super.visitIsExpression(node);
-  }
-
-  @override
-  Object visitListLiteral(ListLiteral node) {
-    TypeArgumentList typeArguments = node.typeArguments;
-    if (typeArguments != null) {
-      if (node.constKeyword != null) {
-        NodeList<TypeName> arguments = typeArguments.arguments;
-        if (arguments.length != 0) {
-          _checkForInvalidTypeArgumentInConstTypedLiteral(arguments, CompileTimeErrorCode.INVALID_TYPE_ARGUMENT_IN_CONST_LIST);
-        }
-      }
-      _checkForExpectedOneListTypeArgument(node, typeArguments);
-      _checkForListElementTypeNotAssignable(node, typeArguments);
-    }
-    return super.visitListLiteral(node);
-  }
-
-  @override
-  Object visitMapLiteral(MapLiteral node) {
-    TypeArgumentList typeArguments = node.typeArguments;
-    if (typeArguments != null) {
-      NodeList<TypeName> arguments = typeArguments.arguments;
-      if (arguments.length != 0) {
-        if (node.constKeyword != null) {
-          _checkForInvalidTypeArgumentInConstTypedLiteral(arguments, CompileTimeErrorCode.INVALID_TYPE_ARGUMENT_IN_CONST_MAP);
-        }
-      }
-      _checkExpectedTwoMapTypeArguments(typeArguments);
-      _checkForMapTypeNotAssignable(node, typeArguments);
-    }
-    _checkForNonConstMapAsExpressionStatement(node);
-    return super.visitMapLiteral(node);
-  }
-
-  @override
-  Object visitMethodDeclaration(MethodDeclaration node) {
-    ExecutableElement previousFunction = _enclosingFunction;
-    try {
-      _isInStaticMethod = node.isStatic;
-      _enclosingFunction = node.element;
-      SimpleIdentifier identifier = node.name;
-      String methodName = "";
-      if (identifier != null) {
-        methodName = identifier.name;
-      }
-      TypeName returnTypeName = node.returnType;
-      if (node.isSetter || node.isGetter) {
-        _checkForMismatchedAccessorTypes(node, methodName);
-      }
-      if (node.isGetter) {
-        _checkForVoidReturnType(node);
-        _checkForConflictingStaticGetterAndInstanceSetter(node);
-      } else if (node.isSetter) {
-        _checkForInvalidModifierOnBody(node.body, CompileTimeErrorCode.INVALID_MODIFIER_ON_SETTER);
-        _checkForWrongNumberOfParametersForSetter(node.name, node.parameters);
-        _checkForNonVoidReturnTypeForSetter(returnTypeName);
-        _checkForConflictingStaticSetterAndInstanceMember(node);
-      } else if (node.isOperator) {
-        _checkForOptionalParameterInOperator(node);
-        _checkForWrongNumberOfParametersForOperator(node);
-        _checkForNonVoidReturnTypeForOperator(node);
-      }
-      _checkForConcreteClassWithAbstractMember(node);
-      _checkForAllInvalidOverrideErrorCodesForMethod(node);
-      _checkForTypeAnnotationDeferredClass(returnTypeName);
-      return super.visitMethodDeclaration(node);
-    } finally {
-      _enclosingFunction = previousFunction;
-      _isInStaticMethod = false;
-    }
-  }
-
-  @override
-  Object visitMethodInvocation(MethodInvocation node) {
-    Expression target = node.realTarget;
-    SimpleIdentifier methodName = node.methodName;
-    if (target != null) {
-      ClassElement typeReference = ElementResolver.getTypeReference(target);
-      _checkForStaticAccessToInstanceMember(typeReference, methodName);
-      _checkForInstanceAccessToStaticMember(typeReference, methodName);
-    } else {
-      _checkForUnqualifiedReferenceToNonLocalStaticMember(methodName);
-    }
-    return super.visitMethodInvocation(node);
-  }
-
-  @override
-  Object visitNativeClause(NativeClause node) {
-    // TODO(brianwilkerson) Figure out the right rule for when 'native' is allowed.
-    if (!_isInSystemLibrary) {
-      _errorReporter.reportErrorForNode(ParserErrorCode.NATIVE_CLAUSE_IN_NON_SDK_CODE, node, []);
-    }
-    return super.visitNativeClause(node);
-  }
-
-  @override
-  Object visitNativeFunctionBody(NativeFunctionBody node) {
-    _checkForNativeFunctionBodyInNonSDKCode(node);
-    return super.visitNativeFunctionBody(node);
-  }
-
-  @override
-  Object visitPostfixExpression(PostfixExpression node) {
-    _checkForAssignmentToFinal(node.operand);
-    _checkForIntNotAssignable(node.operand);
-    return super.visitPostfixExpression(node);
-  }
-
-  @override
-  Object visitPrefixedIdentifier(PrefixedIdentifier node) {
-    if (node.parent is! Annotation) {
-      ClassElement typeReference = ElementResolver.getTypeReference(node.prefix);
-      SimpleIdentifier name = node.identifier;
-      _checkForStaticAccessToInstanceMember(typeReference, name);
-      _checkForInstanceAccessToStaticMember(typeReference, name);
-    }
-    return super.visitPrefixedIdentifier(node);
-  }
-
-  @override
-  Object visitPrefixExpression(PrefixExpression node) {
-    sc.TokenType operatorType = node.operator.type;
-    Expression operand = node.operand;
-    if (operatorType == sc.TokenType.BANG) {
-      _checkForNonBoolNegationExpression(operand);
-    } else if (operatorType.isIncrementOperator) {
-      _checkForAssignmentToFinal(operand);
-    }
-    _checkForIntNotAssignable(operand);
-    return super.visitPrefixExpression(node);
-  }
-
-  @override
-  Object visitPropertyAccess(PropertyAccess node) {
-    ClassElement typeReference = ElementResolver.getTypeReference(node.realTarget);
-    SimpleIdentifier propertyName = node.propertyName;
-    _checkForStaticAccessToInstanceMember(typeReference, propertyName);
-    _checkForInstanceAccessToStaticMember(typeReference, propertyName);
-    return super.visitPropertyAccess(node);
-  }
-
-  @override
-  Object visitRedirectingConstructorInvocation(RedirectingConstructorInvocation node) {
-    _isInConstructorInitializer = true;
-    try {
-      return super.visitRedirectingConstructorInvocation(node);
-    } finally {
-      _isInConstructorInitializer = false;
-    }
-  }
-
-  @override
-  Object visitRethrowExpression(RethrowExpression node) {
-    _checkForRethrowOutsideCatch(node);
-    return super.visitRethrowExpression(node);
-  }
-
-  @override
-  Object visitReturnStatement(ReturnStatement node) {
-    if (node.expression == null) {
-      _returnsWithout.add(node);
-    } else {
-      _returnsWith.add(node);
-    }
-    _checkForAllReturnStatementErrorCodes(node);
-    return super.visitReturnStatement(node);
-  }
-
-  @override
-  Object visitSimpleFormalParameter(SimpleFormalParameter node) {
-    _checkForConstFormalParameter(node);
-    _checkForPrivateOptionalParameter(node);
-    _checkForTypeAnnotationDeferredClass(node.type);
-    return super.visitSimpleFormalParameter(node);
-  }
-
-  @override
-  Object visitSimpleIdentifier(SimpleIdentifier node) {
-    _checkForImplicitThisReferenceInInitializer(node);
-    if (!_isUnqualifiedReferenceToNonLocalStaticMemberAllowed(node)) {
-      _checkForUnqualifiedReferenceToNonLocalStaticMember(node);
-    }
-    return super.visitSimpleIdentifier(node);
-  }
-
-  @override
-  Object visitSuperConstructorInvocation(SuperConstructorInvocation node) {
-    _isInConstructorInitializer = true;
-    try {
-      return super.visitSuperConstructorInvocation(node);
-    } finally {
-      _isInConstructorInitializer = false;
-    }
-  }
-
-  @override
-  Object visitSwitchStatement(SwitchStatement node) {
-    _checkForSwitchExpressionNotAssignable(node);
-    _checkForCaseBlocksNotTerminated(node);
-    _checkForMissingEnumConstantInSwitch(node);
-    return super.visitSwitchStatement(node);
-  }
-
-  @override
-  Object visitThisExpression(ThisExpression node) {
-    _checkForInvalidReferenceToThis(node);
-    return super.visitThisExpression(node);
-  }
-
-  @override
-  Object visitThrowExpression(ThrowExpression node) {
-    _checkForConstEvalThrowsException(node);
-    return super.visitThrowExpression(node);
-  }
-
-  @override
-  Object visitTopLevelVariableDeclaration(TopLevelVariableDeclaration node) {
-    _checkForFinalNotInitialized(node.variables);
-    return super.visitTopLevelVariableDeclaration(node);
-  }
-
-  @override
-  Object visitTypeArgumentList(TypeArgumentList node) {
-    NodeList<TypeName> list = node.arguments;
-    for (TypeName typeName in list) {
-      _checkForTypeAnnotationDeferredClass(typeName);
-    }
-    return super.visitTypeArgumentList(node);
-  }
-
-  @override
-  Object visitTypeName(TypeName node) {
-    _checkForTypeArgumentNotMatchingBounds(node);
-    _checkForTypeParameterReferencedByStatic(node);
-    return super.visitTypeName(node);
-  }
-
-  @override
-  Object visitTypeParameter(TypeParameter node) {
-    _checkForBuiltInIdentifierAsName(node.name, CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE_PARAMETER_NAME);
-    _checkForTypeParameterSupertypeOfItsBound(node);
-    _checkForTypeAnnotationDeferredClass(node.bound);
-    return super.visitTypeParameter(node);
-  }
-
-  @override
-  Object visitVariableDeclaration(VariableDeclaration node) {
-    SimpleIdentifier nameNode = node.name;
-    Expression initializerNode = node.initializer;
-    // do checks
-    _checkForInvalidAssignment(nameNode, initializerNode);
-    // visit name
-    nameNode.accept(this);
-    // visit initializer
-    String name = nameNode.name;
-    _namesForReferenceToDeclaredVariableInInitializer.add(name);
-    _isInInstanceVariableInitializer = _isInInstanceVariableDeclaration;
-    try {
-      if (initializerNode != null) {
-        initializerNode.accept(this);
-      }
-    } finally {
-      _isInInstanceVariableInitializer = false;
-      _namesForReferenceToDeclaredVariableInInitializer.remove(name);
-    }
-    // done
-    return null;
-  }
-
-  @override
-  Object visitVariableDeclarationList(VariableDeclarationList node) {
-    _checkForTypeAnnotationDeferredClass(node.type);
-    return super.visitVariableDeclarationList(node);
-  }
-
-  @override
-  Object visitVariableDeclarationStatement(VariableDeclarationStatement node) {
-    _checkForFinalNotInitialized(node.variables);
-    return super.visitVariableDeclarationStatement(node);
-  }
-
-  @override
-  Object visitWhileStatement(WhileStatement node) {
-    _checkForNonBoolCondition(node.condition);
-    return super.visitWhileStatement(node);
-  }
-
-  @override
-  Object visitYieldStatement(YieldStatement node) {
-    if (!_inGenerator) {
-      CompileTimeErrorCode errorCode;
-      if (node.star != null) {
-        errorCode = CompileTimeErrorCode.YIELD_EACH_IN_NON_GENERATOR;
-      } else {
-        errorCode = CompileTimeErrorCode.YIELD_IN_NON_GENERATOR;
-      }
-      _errorReporter.reportErrorForNode(errorCode, node, []);
-    }
-    return super.visitYieldStatement(node);
-  }
-
-  /**
-   * This verifies if the passed map literal has type arguments then there is exactly two.
-   *
-   * @param typeArguments the type arguments, always non-`null`
-   * @return `true` if and only if an error code is generated on the passed node
-   * @see StaticTypeWarningCode#EXPECTED_TWO_MAP_TYPE_ARGUMENTS
-   */
-  bool _checkExpectedTwoMapTypeArguments(TypeArgumentList typeArguments) {
-    // check number of type arguments
-    int num = typeArguments.arguments.length;
-    if (num == 2) {
-      return false;
-    }
-    // report problem
-    _errorReporter.reportErrorForNode(StaticTypeWarningCode.EXPECTED_TWO_MAP_TYPE_ARGUMENTS, typeArguments, [num]);
-    return true;
-  }
-
-  /**
-   * This verifies that the passed constructor declaration does not violate any of the error codes
-   * relating to the initialization of fields in the enclosing class.
-   *
-   * @param node the [ConstructorDeclaration] to evaluate
-   * @return `true` if and only if an error code is generated on the passed node
-   * @see #initialFieldElementsMap
-   * @see CompileTimeErrorCode#FINAL_INITIALIZED_IN_DECLARATION_AND_CONSTRUCTOR
-   * @see CompileTimeErrorCode#FINAL_INITIALIZED_MULTIPLE_TIMES
-   */
-  bool _checkForAllFinalInitializedErrorCodes(ConstructorDeclaration node) {
-    if (node.factoryKeyword != null || node.redirectedConstructor != null || node.externalKeyword != null) {
-      return false;
-    }
-    // Ignore if native class.
-    if (_isInNativeClass) {
-      return false;
-    }
-    bool foundError = false;
-    HashMap<FieldElement, INIT_STATE> fieldElementsMap = new HashMap<FieldElement, INIT_STATE>.from(_initialFieldElementsMap);
-    // Visit all of the field formal parameters
-    NodeList<FormalParameter> formalParameters = node.parameters.parameters;
-    for (FormalParameter formalParameter in formalParameters) {
-      FormalParameter parameter = formalParameter;
-      if (parameter is DefaultFormalParameter) {
-        parameter = (parameter as DefaultFormalParameter).parameter;
-      }
-      if (parameter is FieldFormalParameter) {
-        FieldElement fieldElement = (parameter.element as FieldFormalParameterElementImpl).field;
-        INIT_STATE state = fieldElementsMap[fieldElement];
-        if (state == INIT_STATE.NOT_INIT) {
-          fieldElementsMap[fieldElement] = INIT_STATE.INIT_IN_FIELD_FORMAL;
-        } else if (state == INIT_STATE.INIT_IN_DECLARATION) {
-          if (fieldElement.isFinal || fieldElement.isConst) {
-            _errorReporter.reportErrorForNode(StaticWarningCode.FINAL_INITIALIZED_IN_DECLARATION_AND_CONSTRUCTOR, formalParameter.identifier, [fieldElement.displayName]);
-            foundError = true;
-          }
-        } else if (state == INIT_STATE.INIT_IN_FIELD_FORMAL) {
-          if (fieldElement.isFinal || fieldElement.isConst) {
-            _errorReporter.reportErrorForNode(CompileTimeErrorCode.FINAL_INITIALIZED_MULTIPLE_TIMES, formalParameter.identifier, [fieldElement.displayName]);
-            foundError = true;
-          }
-        }
-      }
-    }
-    // Visit all of the initializers
-    NodeList<ConstructorInitializer> initializers = node.initializers;
-    for (ConstructorInitializer constructorInitializer in initializers) {
-      if (constructorInitializer is RedirectingConstructorInvocation) {
-        return false;
-      }
-      if (constructorInitializer is ConstructorFieldInitializer) {
-        ConstructorFieldInitializer constructorFieldInitializer = constructorInitializer;
-        SimpleIdentifier fieldName = constructorFieldInitializer.fieldName;
-        Element element = fieldName.staticElement;
-        if (element is FieldElement) {
-          FieldElement fieldElement = element;
-          INIT_STATE state = fieldElementsMap[fieldElement];
-          if (state == INIT_STATE.NOT_INIT) {
-            fieldElementsMap[fieldElement] = INIT_STATE.INIT_IN_INITIALIZERS;
-          } else if (state == INIT_STATE.INIT_IN_DECLARATION) {
-            if (fieldElement.isFinal || fieldElement.isConst) {
-              _errorReporter.reportErrorForNode(StaticWarningCode.FIELD_INITIALIZED_IN_INITIALIZER_AND_DECLARATION, fieldName, []);
-              foundError = true;
-            }
-          } else if (state == INIT_STATE.INIT_IN_FIELD_FORMAL) {
-            _errorReporter.reportErrorForNode(CompileTimeErrorCode.FIELD_INITIALIZED_IN_PARAMETER_AND_INITIALIZER, fieldName, []);
-            foundError = true;
-          } else if (state == INIT_STATE.INIT_IN_INITIALIZERS) {
-            _errorReporter.reportErrorForNode(CompileTimeErrorCode.FIELD_INITIALIZED_BY_MULTIPLE_INITIALIZERS, fieldName, [fieldElement.displayName]);
-            foundError = true;
-          }
-        }
-      }
-    }
-    // Visit all of the states in the map to ensure that none were never
-    // initialized.
-    fieldElementsMap.forEach((FieldElement fieldElement, INIT_STATE state) {
-      if (state == INIT_STATE.NOT_INIT) {
-        if (fieldElement.isConst) {
-          _errorReporter.reportErrorForNode(
-              CompileTimeErrorCode.CONST_NOT_INITIALIZED,
-                  node.returnType,
-                  [fieldElement.name]);
-          foundError = true;
-        } else if (fieldElement.isFinal) {
-          _errorReporter.reportErrorForNode(
-              StaticWarningCode.FINAL_NOT_INITIALIZED,
-                  node.returnType,
-                  [fieldElement.name]);
-          foundError = true;
-        }
-      }
-    });
-    return foundError;
-  }
-
-  /**
-   * This checks the passed executable element against override-error codes.
-   *
-   * @param executableElement a non-null [ExecutableElement] to evaluate
-   * @param overriddenExecutable the element that the executableElement is overriding
-   * @param parameters the parameters of the executable element
-   * @param errorNameTarget the node to report problems on
-   * @return `true` if and only if an error code is generated on the passed node
-   * @see StaticWarningCode#INSTANCE_METHOD_NAME_COLLIDES_WITH_SUPERCLASS_STATIC
-   * @see CompileTimeErrorCode#INVALID_OVERRIDE_REQUIRED
-   * @see CompileTimeErrorCode#INVALID_OVERRIDE_POSITIONAL
-   * @see CompileTimeErrorCode#INVALID_OVERRIDE_NAMED
-   * @see StaticWarningCode#INVALID_GETTER_OVERRIDE_RETURN_TYPE
-   * @see StaticWarningCode#INVALID_METHOD_OVERRIDE_RETURN_TYPE
-   * @see StaticWarningCode#INVALID_METHOD_OVERRIDE_NORMAL_PARAM_TYPE
-   * @see StaticWarningCode#INVALID_SETTER_OVERRIDE_NORMAL_PARAM_TYPE
-   * @see StaticWarningCode#INVALID_METHOD_OVERRIDE_OPTIONAL_PARAM_TYPE
-   * @see StaticWarningCode#INVALID_METHOD_OVERRIDE_NAMED_PARAM_TYPE
-   * @see StaticWarningCode#INVALID_OVERRIDE_DIFFERENT_DEFAULT_VALUES
-   */
-  bool _checkForAllInvalidOverrideErrorCodes(ExecutableElement executableElement, ExecutableElement overriddenExecutable, List<ParameterElement> parameters, List<AstNode> parameterLocations, SimpleIdentifier errorNameTarget) {
-    bool isGetter = false;
-    bool isSetter = false;
-    if (executableElement is PropertyAccessorElement) {
-      PropertyAccessorElement accessorElement = executableElement;
-      isGetter = accessorElement.isGetter;
-      isSetter = accessorElement.isSetter;
-    }
-    String executableElementName = executableElement.name;
-    FunctionType overridingFT = executableElement.type;
-    FunctionType overriddenFT = overriddenExecutable.type;
-    InterfaceType enclosingType = _enclosingClass.type;
-    overriddenFT = _inheritanceManager.substituteTypeArgumentsInMemberFromInheritance(overriddenFT, executableElementName, enclosingType);
-    if (overridingFT == null || overriddenFT == null) {
-      return false;
-    }
-    DartType overridingFTReturnType = overridingFT.returnType;
-    DartType overriddenFTReturnType = overriddenFT.returnType;
-    List<DartType> overridingNormalPT = overridingFT.normalParameterTypes;
-    List<DartType> overriddenNormalPT = overriddenFT.normalParameterTypes;
-    List<DartType> overridingPositionalPT = overridingFT.optionalParameterTypes;
-    List<DartType> overriddenPositionalPT = overriddenFT.optionalParameterTypes;
-    Map<String, DartType> overridingNamedPT = overridingFT.namedParameterTypes;
-    Map<String, DartType> overriddenNamedPT = overriddenFT.namedParameterTypes;
-    // CTEC.INVALID_OVERRIDE_REQUIRED, CTEC.INVALID_OVERRIDE_POSITIONAL and CTEC.INVALID_OVERRIDE_NAMED
-    if (overridingNormalPT.length > overriddenNormalPT.length) {
-      _errorReporter.reportErrorForNode(StaticWarningCode.INVALID_OVERRIDE_REQUIRED, errorNameTarget, [
-          overriddenNormalPT.length,
-          overriddenExecutable.enclosingElement.displayName]);
-      return true;
-    }
-    if (overridingNormalPT.length + overridingPositionalPT.length < overriddenPositionalPT.length + overriddenNormalPT.length) {
-      _errorReporter.reportErrorForNode(StaticWarningCode.INVALID_OVERRIDE_POSITIONAL, errorNameTarget, [
-          overriddenPositionalPT.length + overriddenNormalPT.length,
-          overriddenExecutable.enclosingElement.displayName]);
-      return true;
-    }
-    // For each named parameter in the overridden method, verify that there is
-    // the same name in the overriding method.
-    for (String overriddenParamName in overriddenNamedPT.keys) {
-      if (!overridingNamedPT.containsKey(overriddenParamName)) {
-        // The overridden method expected the overriding method to have
-        // overridingParamName, but it does not.
-        _errorReporter.reportErrorForNode(
-            StaticWarningCode.INVALID_OVERRIDE_NAMED,
-            errorNameTarget,
-            [overriddenParamName,
-            overriddenExecutable.enclosingElement.displayName]);
-        return true;
-      }
-    }
-    // SWC.INVALID_METHOD_OVERRIDE_RETURN_TYPE
-    if (overriddenFTReturnType != VoidTypeImpl.instance && !overridingFTReturnType.isAssignableTo(overriddenFTReturnType)) {
-      _errorReporter.reportTypeErrorForNode(!isGetter ? StaticWarningCode.INVALID_METHOD_OVERRIDE_RETURN_TYPE : StaticWarningCode.INVALID_GETTER_OVERRIDE_RETURN_TYPE, errorNameTarget, [
-          overridingFTReturnType,
-          overriddenFTReturnType,
-          overriddenExecutable.enclosingElement.displayName]);
-      return true;
-    }
-    // SWC.INVALID_METHOD_OVERRIDE_NORMAL_PARAM_TYPE
-    if (parameterLocations == null) {
-      return false;
-    }
-    int parameterIndex = 0;
-    for (int i = 0; i < overridingNormalPT.length; i++) {
-      if (!overridingNormalPT[i].isAssignableTo(overriddenNormalPT[i])) {
-        _errorReporter.reportTypeErrorForNode(!isSetter ? StaticWarningCode.INVALID_METHOD_OVERRIDE_NORMAL_PARAM_TYPE : StaticWarningCode.INVALID_SETTER_OVERRIDE_NORMAL_PARAM_TYPE, parameterLocations[parameterIndex], [
-            overridingNormalPT[i],
-            overriddenNormalPT[i],
-            overriddenExecutable.enclosingElement.displayName]);
-        return true;
-      }
-      parameterIndex++;
-    }
-    // SWC.INVALID_METHOD_OVERRIDE_OPTIONAL_PARAM_TYPE
-    for (int i = 0; i < overriddenPositionalPT.length; i++) {
-      if (!overridingPositionalPT[i].isAssignableTo(overriddenPositionalPT[i])) {
-        _errorReporter.reportTypeErrorForNode(StaticWarningCode.INVALID_METHOD_OVERRIDE_OPTIONAL_PARAM_TYPE, parameterLocations[parameterIndex], [
-            overridingPositionalPT[i],
-            overriddenPositionalPT[i],
-            overriddenExecutable.enclosingElement.displayName]);
-        return true;
-      }
-      parameterIndex++;
-    }
-    // SWC.INVALID_METHOD_OVERRIDE_NAMED_PARAM_TYPE & SWC.INVALID_OVERRIDE_DIFFERENT_DEFAULT_VALUES
-    for (String overriddenName in overriddenNamedPT.keys) {
-      DartType overridingType = overridingNamedPT[overriddenName];
-      if (overridingType == null) {
-        // Error, this is never reached- INVALID_OVERRIDE_NAMED would have been
-        // created above if this could be reached.
-        continue;
-      }
-      DartType overriddenType = overriddenNamedPT[overriddenName];
-      if (!overriddenType.isAssignableTo(overridingType)) {
-        // lookup the parameter for the error to select
-        ParameterElement parameterToSelect = null;
-        AstNode parameterLocationToSelect = null;
-        for (int i = 0; i < parameters.length; i++) {
-          ParameterElement parameter = parameters[i];
-          if (parameter.parameterKind == ParameterKind.NAMED
-              && overriddenName == parameter.name) {
-            parameterToSelect = parameter;
-            parameterLocationToSelect = parameterLocations[i];
-            break;
-          }
-        }
-        if (parameterToSelect != null) {
-          _errorReporter.reportTypeErrorForNode(
-              StaticWarningCode.INVALID_METHOD_OVERRIDE_NAMED_PARAM_TYPE,
-              parameterLocationToSelect,
-              [overridingType,
-              overriddenType,
-              overriddenExecutable.enclosingElement.displayName]);
-          return true;
-        }
-      }
-    }
-    // SWC.INVALID_OVERRIDE_DIFFERENT_DEFAULT_VALUES
-    //
-    // Create three arrays: an array of the optional parameter ASTs (FormalParameters), an array of
-    // the optional parameters elements from our method, and finally an array of the optional
-    // parameter elements from the method we are overriding.
-    //
-    bool foundError = false;
-    List<AstNode> formalParameters = new List<AstNode>();
-    List<ParameterElementImpl> parameterElts = new List<ParameterElementImpl>();
-    List<ParameterElementImpl> overriddenParameterElts = new List<ParameterElementImpl>();
-    List<ParameterElement> overriddenPEs = overriddenExecutable.parameters;
-    for (int i = 0; i < parameters.length; i++) {
-      ParameterElement parameter = parameters[i];
-      if (parameter.parameterKind.isOptional) {
-        formalParameters.add(parameterLocations[i]);
-        parameterElts.add(parameter as ParameterElementImpl);
-      }
-    }
-    for (ParameterElement parameterElt in overriddenPEs) {
-      if (parameterElt.parameterKind.isOptional) {
-        if (parameterElt is ParameterElementImpl) {
-          overriddenParameterElts.add(parameterElt);
-        }
-      }
-    }
-    //
-    // Next compare the list of optional parameter elements to the list of overridden optional
-    // parameter elements.
-    //
-    if (parameterElts.length > 0) {
-      if (parameterElts[0].parameterKind == ParameterKind.NAMED) {
-        // Named parameters, consider the names when matching the parameterElts to the overriddenParameterElts
-        for (int i = 0; i < parameterElts.length; i++) {
-          ParameterElementImpl parameterElt = parameterElts[i];
-          EvaluationResultImpl result = parameterElt.evaluationResult;
-          // TODO (jwren) Ignore Object types, see Dart bug 11287
-          if (_isUserDefinedObject(result)) {
-            continue;
-          }
-          String parameterName = parameterElt.name;
-          for (int j = 0; j < overriddenParameterElts.length; j++) {
-            ParameterElementImpl overriddenParameterElt = overriddenParameterElts[j];
-            String overriddenParameterName = overriddenParameterElt.name;
-            if (parameterName != null && parameterName == overriddenParameterName) {
-              EvaluationResultImpl overriddenResult = overriddenParameterElt.evaluationResult;
-              if (_isUserDefinedObject(overriddenResult)) {
-                break;
-              }
-              if (!result.equalValues(_typeProvider, overriddenResult)) {
-                _errorReporter.reportErrorForNode(StaticWarningCode.INVALID_OVERRIDE_DIFFERENT_DEFAULT_VALUES_NAMED, formalParameters[i], [
-                    overriddenExecutable.enclosingElement.displayName,
-                    overriddenExecutable.displayName,
-                    parameterName]);
-                foundError = true;
-              }
-            }
-          }
-        }
-      } else {
-        // Positional parameters, consider the positions when matching the parameterElts to the overriddenParameterElts
-        for (int i = 0; i < parameterElts.length && i < overriddenParameterElts.length; i++) {
-          ParameterElementImpl parameterElt = parameterElts[i];
-          EvaluationResultImpl result = parameterElt.evaluationResult;
-          // TODO (jwren) Ignore Object types, see Dart bug 11287
-          if (_isUserDefinedObject(result)) {
-            continue;
-          }
-          ParameterElementImpl overriddenParameterElt = overriddenParameterElts[i];
-          EvaluationResultImpl overriddenResult = overriddenParameterElt.evaluationResult;
-          if (_isUserDefinedObject(overriddenResult)) {
-            continue;
-          }
-          if (!result.equalValues(_typeProvider, overriddenResult)) {
-            _errorReporter.reportErrorForNode(StaticWarningCode.INVALID_OVERRIDE_DIFFERENT_DEFAULT_VALUES_POSITIONAL, formalParameters[i], [
-                overriddenExecutable.enclosingElement.displayName,
-                overriddenExecutable.displayName]);
-            foundError = true;
-          }
-        }
-      }
-    }
-    return foundError;
-  }
-
-  /**
-   * This checks the passed executable element against override-error codes. This method computes
-   * the passed executableElement is overriding and calls
-   * [checkForAllInvalidOverrideErrorCodes]
-   * when the [InheritanceManager] returns a [MultiplyInheritedExecutableElement], this
-   * method loops through the array in the [MultiplyInheritedExecutableElement].
-   *
-   * @param executableElement a non-null [ExecutableElement] to evaluate
-   * @param parameters the parameters of the executable element
-   * @param errorNameTarget the node to report problems on
-   * @return `true` if and only if an error code is generated on the passed node
-   */
-  bool _checkForAllInvalidOverrideErrorCodesForExecutable(ExecutableElement executableElement, List<ParameterElement> parameters, List<AstNode> parameterLocations, SimpleIdentifier errorNameTarget) {
-    //
-    // Compute the overridden executable from the InheritanceManager
-    //
-    List<ExecutableElement> overriddenExecutables = _inheritanceManager.lookupOverrides(_enclosingClass, executableElement.name);
-    if (overriddenExecutables.isEmpty) {
-      // Nothing is overridden, so we just have to check if the new name collides
-      // with a static defined in the superclass.
-      // TODO(paulberry): currently we don't do this check if the new element
-      // overrides a method in an interface (see issue 18947).
-      return _checkForInstanceMethodNameCollidesWithSuperclassStatic(executableElement, errorNameTarget);
-    }
-    for (ExecutableElement overriddenElement in overriddenExecutables) {
-      if (_checkForAllInvalidOverrideErrorCodes(executableElement, overriddenElement, parameters, parameterLocations, errorNameTarget)) {
-        return true;
-      }
-    }
-    return false;
-  }
-
-  /**
-   * This checks the passed field declaration against override-error codes.
-   *
-   * @param node the [MethodDeclaration] to evaluate
-   * @return `true` if and only if an error code is generated on the passed node
-   * @see #checkForAllInvalidOverrideErrorCodes(ExecutableElement)
-   */
-  bool _checkForAllInvalidOverrideErrorCodesForField(FieldDeclaration node) {
-    if (_enclosingClass == null || node.isStatic) {
-      return false;
-    }
-    bool hasProblems = false;
-    VariableDeclarationList fields = node.fields;
-    for (VariableDeclaration field in fields.variables) {
-      FieldElement element = field.element as FieldElement;
-      if (element == null) {
-        continue;
-      }
-      PropertyAccessorElement getter = element.getter;
-      PropertyAccessorElement setter = element.setter;
-      SimpleIdentifier fieldName = field.name;
-      if (getter != null) {
-        if (_checkForAllInvalidOverrideErrorCodesForExecutable(
-            getter,
-            ParameterElementImpl.EMPTY_ARRAY,
-            AstNode.EMPTY_ARRAY,
-            fieldName)) {
-          hasProblems = true;
-        }
-      }
-      if (setter != null) {
-        if (_checkForAllInvalidOverrideErrorCodesForExecutable(
-            setter,
-            setter.parameters,
-            <AstNode> [fieldName],
-            fieldName)) {
-          hasProblems = true;
-        }
-      }
-    }
-    return hasProblems;
-  }
-
-  /**
-   * This checks the passed method declaration against override-error codes.
-   *
-   * @param node the [MethodDeclaration] to evaluate
-   * @return `true` if and only if an error code is generated on the passed node
-   * @see #checkForAllInvalidOverrideErrorCodes(ExecutableElement)
-   */
-  bool _checkForAllInvalidOverrideErrorCodesForMethod(MethodDeclaration node) {
-    if (_enclosingClass == null || node.isStatic || node.body is NativeFunctionBody) {
-      return false;
-    }
-    ExecutableElement executableElement = node.element;
-    if (executableElement == null) {
-      return false;
-    }
-    SimpleIdentifier methodName = node.name;
-    if (methodName.isSynthetic) {
-      return false;
-    }
-    FormalParameterList formalParameterList = node.parameters;
-    NodeList<FormalParameter> parameterList = formalParameterList != null ? formalParameterList.parameters : null;
-    List<AstNode> parameters = parameterList != null ? new List.from(parameterList) : null;
-    return _checkForAllInvalidOverrideErrorCodesForExecutable(executableElement, executableElement.parameters, parameters, methodName);
-  }
-
-  /**
-   * This verifies that all classes of the passed 'with' clause are valid.
-   *
-   * @param node the 'with' clause to evaluate
-   * @return `true` if and only if an error code is generated on the passed node
-   * @see CompileTimeErrorCode#MIXIN_DECLARES_CONSTRUCTOR
-   * @see CompileTimeErrorCode#MIXIN_INHERITS_FROM_NOT_OBJECT
-   * @see CompileTimeErrorCode#MIXIN_REFERENCES_SUPER
-   */
-  bool _checkForAllMixinErrorCodes(WithClause withClause) {
-    if (withClause == null) {
-      return false;
-    }
-    bool problemReported = false;
-    for (TypeName mixinName in withClause.mixinTypes) {
-      DartType mixinType = mixinName.type;
-      if (mixinType is! InterfaceType) {
-        continue;
-      }
-      if (_checkForExtendsOrImplementsDisallowedClass(
-          mixinName,
-          CompileTimeErrorCode.MIXIN_OF_DISALLOWED_CLASS)) {
-        problemReported = true;
-      } else {
-        ClassElement mixinElement = (mixinType as InterfaceType).element;
-        if (_checkForExtendsOrImplementsDeferredClass(
-            mixinName,
-            CompileTimeErrorCode.MIXIN_DEFERRED_CLASS)) {
-          problemReported = true;
-        }
-        if (_checkForMixinDeclaresConstructor(mixinName, mixinElement)) {
-          problemReported = true;
-        }
-        if (_checkForMixinInheritsNotFromObject(mixinName, mixinElement)) {
-          problemReported = true;
-        }
-        if (_checkForMixinReferencesSuper(mixinName, mixinElement)) {
-          problemReported = true;
-        }
-      }
-    }
-    return problemReported;
-  }
-
-  /**
-   * This checks error related to the redirected constructors.
-   *
-   * @param node the constructor declaration to evaluate
-   * @return `true` if and only if an error code is generated on the passed node
-   * @see StaticWarningCode#REDIRECT_TO_INVALID_RETURN_TYPE
-   * @see StaticWarningCode#REDIRECT_TO_INVALID_FUNCTION_TYPE
-   * @see StaticWarningCode#REDIRECT_TO_MISSING_CONSTRUCTOR
-   */
-  bool _checkForAllRedirectConstructorErrorCodes(ConstructorDeclaration node) {
-    //
-    // Prepare redirected constructor node
-    //
-    ConstructorName redirectedConstructor = node.redirectedConstructor;
-    if (redirectedConstructor == null) {
-      return false;
-    }
-    //
-    // Prepare redirected constructor type
-    //
-    ConstructorElement redirectedElement = redirectedConstructor.staticElement;
-    if (redirectedElement == null) {
-      //
-      // If the element is null, we check for the REDIRECT_TO_MISSING_CONSTRUCTOR case
-      //
-      TypeName constructorTypeName = redirectedConstructor.type;
-      DartType redirectedType = constructorTypeName.type;
-      if (redirectedType != null && redirectedType.element != null && !redirectedType.isDynamic) {
-        //
-        // Prepare the constructor name
-        //
-        String constructorStrName = constructorTypeName.name.name;
-        if (redirectedConstructor.name != null) {
-          constructorStrName += ".${redirectedConstructor.name.name}";
-        }
-        ErrorCode errorCode = (node.constKeyword != null ? CompileTimeErrorCode.REDIRECT_TO_MISSING_CONSTRUCTOR : StaticWarningCode.REDIRECT_TO_MISSING_CONSTRUCTOR);
-        _errorReporter.reportErrorForNode(errorCode, redirectedConstructor, [constructorStrName, redirectedType.displayName]);
-        return true;
-      }
-      return false;
-    }
-    FunctionType redirectedType = redirectedElement.type;
-    DartType redirectedReturnType = redirectedType.returnType;
-    //
-    // Report specific problem when return type is incompatible
-    //
-    FunctionType constructorType = node.element.type;
-    DartType constructorReturnType = constructorType.returnType;
-    if (!redirectedReturnType.isAssignableTo(constructorReturnType)) {
-      _errorReporter.reportErrorForNode(StaticWarningCode.REDIRECT_TO_INVALID_RETURN_TYPE, redirectedConstructor, [redirectedReturnType, constructorReturnType]);
-      return true;
-    }
-    //
-    // Check parameters
-    //
-    if (!redirectedType.isSubtypeOf(constructorType)) {
-      _errorReporter.reportErrorForNode(StaticWarningCode.REDIRECT_TO_INVALID_FUNCTION_TYPE, redirectedConstructor, [redirectedType, constructorType]);
-      return true;
-    }
-    return false;
-  }
-
-  /**
-   * This checks that the return statement of the form <i>return e;</i> is not in a generative
-   * constructor.
-   *
-   * This checks that return statements without expressions are not in a generative constructor and
-   * the return type is not assignable to `null`; that is, we don't have `return;` if
-   * the enclosing method has a return type.
-   *
-   * This checks that the return type matches the type of the declared return type in the enclosing
-   * method or function.
-   *
-   * @param node the return statement to evaluate
-   * @return `true` if and only if an error code is generated on the passed node
-   * @see CompileTimeErrorCode#RETURN_IN_GENERATIVE_CONSTRUCTOR
-   * @see StaticWarningCode#RETURN_WITHOUT_VALUE
-   * @see StaticTypeWarningCode#RETURN_OF_INVALID_TYPE
-   */
-  bool _checkForAllReturnStatementErrorCodes(ReturnStatement node) {
-    FunctionType functionType = _enclosingFunction == null ? null : _enclosingFunction.type;
-    DartType expectedReturnType = functionType == null ? DynamicTypeImpl.instance : functionType.returnType;
-    Expression returnExpression = node.expression;
-    // RETURN_IN_GENERATIVE_CONSTRUCTOR
-    bool isGenerativeConstructor = _enclosingFunction is ConstructorElement && !(_enclosingFunction as ConstructorElement).isFactory;
-    if (isGenerativeConstructor) {
-      if (returnExpression == null) {
-        return false;
-      }
-      _errorReporter.reportErrorForNode(CompileTimeErrorCode.RETURN_IN_GENERATIVE_CONSTRUCTOR, returnExpression, []);
-      return true;
-    }
-    // RETURN_WITHOUT_VALUE
-    if (returnExpression == null) {
-      if (VoidTypeImpl.instance.isAssignableTo(expectedReturnType)) {
-        return false;
-      }
-      _hasReturnWithoutValue = true;
-      _errorReporter.reportErrorForNode(StaticWarningCode.RETURN_WITHOUT_VALUE, node, []);
-      return true;
-    } else if (_inGenerator) {
-      // RETURN_IN_GENERATOR
-      _errorReporter.reportErrorForNode(CompileTimeErrorCode.RETURN_IN_GENERATOR, node, []);
-    }
-    // RETURN_OF_INVALID_TYPE
-    return _checkForReturnOfInvalidType(returnExpression, expectedReturnType);
-  }
-
-  /**
-   * This verifies that the export namespace of the passed export directive does not export any name
-   * already exported by other export directive.
-   *
-   * @param node the export directive node to report problem on
-   * @param exportElement the [ExportElement] retrieved from the node, if the element in the
-   *          node was `null`, then this method is not called
-   * @param exportedLibrary the library element containing the exported element
-   * @return `true` if and only if an error code is generated on the passed node
-   * @see CompileTimeErrorCode#AMBIGUOUS_EXPORT
-   */
-  bool _checkForAmbiguousExport(ExportDirective node, ExportElement exportElement, LibraryElement exportedLibrary) {
-    if (exportedLibrary == null) {
-      return false;
-    }
-    // check exported names
-    Namespace namespace = new NamespaceBuilder().createExportNamespaceForDirective(exportElement);
-    Map<String, Element> definedNames = namespace.definedNames;
-    for (String name in definedNames.keys) {
-      Element element = definedNames[name];
-      Element prevElement = _exportedElements[name];
-      if (element != null && prevElement != null && prevElement != element) {
-        _errorReporter.reportErrorForNode(CompileTimeErrorCode.AMBIGUOUS_EXPORT, node, [
-            name,
-            prevElement.library.definingCompilationUnit.displayName,
-            element.library.definingCompilationUnit.displayName]);
-        return true;
-      } else {
-        _exportedElements[name] = element;
-      }
-    }
-    return false;
-  }
-
-  /**
-   * This verifies that the passed expression can be assigned to its corresponding parameters.
-   *
-   * This method corresponds to BestPracticesVerifier.checkForArgumentTypeNotAssignable.
-   *
-   * @param expression the expression to evaluate
-   * @param expectedStaticType the expected static type of the parameter
-   * @param actualStaticType the actual static type of the argument
-   * @param expectedPropagatedType the expected propagated type of the parameter, may be
-   *          `null`
-   * @param actualPropagatedType the expected propagated type of the parameter, may be `null`
-   * @return `true` if and only if an error code is generated on the passed node
-   * @see StaticWarningCode#ARGUMENT_TYPE_NOT_ASSIGNABLE
-   * @see CompileTimeErrorCode#LIST_ELEMENT_TYPE_NOT_ASSIGNABLE
-   * @see StaticWarningCode#LIST_ELEMENT_TYPE_NOT_ASSIGNABLE
-   * @see CompileTimeErrorCode#MAP_KEY_TYPE_NOT_ASSIGNABLE
-   * @see CompileTimeErrorCode#MAP_VALUE_TYPE_NOT_ASSIGNABLE
-   * @see StaticWarningCode#MAP_KEY_TYPE_NOT_ASSIGNABLE
-   * @see StaticWarningCode#MAP_VALUE_TYPE_NOT_ASSIGNABLE
-   */
-  bool _checkForArgumentTypeNotAssignable(Expression expression, DartType expectedStaticType, DartType actualStaticType, ErrorCode errorCode) {
-    //
-    // Warning case: test static type information
-    //
-    if (actualStaticType != null && expectedStaticType != null) {
-      if (!actualStaticType.isAssignableTo(expectedStaticType)) {
-        _errorReporter.reportTypeErrorForNode(errorCode, expression, [actualStaticType, expectedStaticType]);
-        return true;
-      }
-    }
-    return false;
-  }
-
-  /**
-   * This verifies that the passed argument can be assigned to its corresponding parameter.
-   *
-   * This method corresponds to BestPracticesVerifier.checkForArgumentTypeNotAssignableForArgument.
-   *
-   * @param argument the argument to evaluate
-   * @return `true` if and only if an error code is generated on the passed node
-   * @see StaticWarningCode#ARGUMENT_TYPE_NOT_ASSIGNABLE
-   */
-  bool _checkForArgumentTypeNotAssignableForArgument(Expression argument) {
-    if (argument == null) {
-      return false;
-    }
-    ParameterElement staticParameterElement = argument.staticParameterElement;
-    DartType staticParameterType = staticParameterElement == null ? null : staticParameterElement.type;
-    return _checkForArgumentTypeNotAssignableWithExpectedTypes(argument, staticParameterType, StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE);
-  }
-
-  /**
-   * This verifies that the passed expression can be assigned to its corresponding parameters.
-   *
-   * This method corresponds to
-   * BestPracticesVerifier.checkForArgumentTypeNotAssignableWithExpectedTypes.
-   *
-   * @param expression the expression to evaluate
-   * @param expectedStaticType the expected static type
-   * @param expectedPropagatedType the expected propagated type, may be `null`
-   * @return `true` if and only if an error code is generated on the passed node
-   * @see StaticWarningCode#ARGUMENT_TYPE_NOT_ASSIGNABLE
-   * @see CompileTimeErrorCode#LIST_ELEMENT_TYPE_NOT_ASSIGNABLE
-   * @see StaticWarningCode#LIST_ELEMENT_TYPE_NOT_ASSIGNABLE
-   * @see CompileTimeErrorCode#MAP_KEY_TYPE_NOT_ASSIGNABLE
-   * @see CompileTimeErrorCode#MAP_VALUE_TYPE_NOT_ASSIGNABLE
-   * @see StaticWarningCode#MAP_KEY_TYPE_NOT_ASSIGNABLE
-   * @see StaticWarningCode#MAP_VALUE_TYPE_NOT_ASSIGNABLE
-   */
-  bool _checkForArgumentTypeNotAssignableWithExpectedTypes(Expression expression, DartType expectedStaticType, ErrorCode errorCode) => _checkForArgumentTypeNotAssignable(expression, expectedStaticType, getStaticType(expression), errorCode);
-
-  /**
-   * This verifies that the passed arguments can be assigned to their corresponding parameters.
-   *
-   * This method corresponds to BestPracticesVerifier.checkForArgumentTypesNotAssignableInList.
-   *
-   * @param node the arguments to evaluate
-   * @return `true` if and only if an error code is generated on the passed node
-   * @see StaticWarningCode#ARGUMENT_TYPE_NOT_ASSIGNABLE
-   */
-  bool _checkForArgumentTypesNotAssignableInList(ArgumentList argumentList) {
-    if (argumentList == null) {
-      return false;
-    }
-    bool problemReported = false;
-    for (Expression argument in argumentList.arguments) {
-      if (_checkForArgumentTypeNotAssignableForArgument(argument)) {
-        problemReported = true;
-      }
-    }
-    return problemReported;
-  }
-
-  /**
-   * Check that the static type of the given expression is assignable to the given type. If it
-   * isn't, report an error with the given error code.
-   *
-   * @param expression the expression being tested
-   * @param type the type that the expression must be assignable to
-   * @param errorCode the error code to be reported
-   * @param arguments the arguments to pass in when creating the error
-   * @return `true` if an error was reported
-   */
-  bool _checkForAssignability(Expression expression, InterfaceType type, ErrorCode errorCode, List<Object> arguments) {
-    if (expression == null) {
-      return false;
-    }
-    DartType expressionType = expression.staticType;
-    if (expressionType == null) {
-      return false;
-    }
-    if (expressionType.isAssignableTo(type)) {
-      return false;
-    }
-    _errorReporter.reportErrorForNode(errorCode, expression, arguments);
-    return true;
-  }
-
-  /**
-   * This verifies that the passed expression is not final.
-   *
-   * @param node the expression to evaluate
-   * @return `true` if and only if an error code is generated on the passed node
-   * @see StaticWarningCode#ASSIGNMENT_TO_CONST
-   * @see StaticWarningCode#ASSIGNMENT_TO_FINAL
-   * @see StaticWarningCode#ASSIGNMENT_TO_METHOD
-   */
-  bool _checkForAssignmentToFinal(Expression expression) {
-    // prepare element
-    Element element = null;
-    AstNode highlightedNode = expression;
-    if (expression is Identifier) {
-      element = expression.staticElement;
-      if (expression is PrefixedIdentifier) {
-        highlightedNode = expression.identifier;
-      }
-    } else if (expression is PropertyAccess) {
-      PropertyAccess propertyAccess = expression;
-      element = propertyAccess.propertyName.staticElement;
-      highlightedNode = propertyAccess.propertyName;
-    }
-    // check if element is assignable
-    if (element is PropertyAccessorElement) {
-      PropertyAccessorElement accessor = element as PropertyAccessorElement;
-      element = accessor.variable;
-    }
-    if (element is VariableElement) {
-      VariableElement variable = element as VariableElement;
-      if (variable.isConst) {
-        _errorReporter.reportErrorForNode(StaticWarningCode.ASSIGNMENT_TO_CONST, expression, []);
-        return true;
-      }
-      if (variable.isFinal) {
-        if (variable is FieldElementImpl && variable.setter == null && variable.isSynthetic) {
-          _errorReporter.reportErrorForNode(StaticWarningCode.ASSIGNMENT_TO_FINAL_NO_SETTER, highlightedNode, [variable.name, variable.enclosingElement.displayName]);
-          return true;
-        }
-        _errorReporter.reportErrorForNode(StaticWarningCode.ASSIGNMENT_TO_FINAL, highlightedNode, [variable.name]);
-        return true;
-      }
-      return false;
-    }
-    if (element is FunctionElement) {
-      _errorReporter.reportErrorForNode(StaticWarningCode.ASSIGNMENT_TO_FUNCTION, expression, []);
-      return true;
-    }
-    if (element is MethodElement) {
-      _errorReporter.reportErrorForNode(StaticWarningCode.ASSIGNMENT_TO_METHOD, expression, []);
-      return true;
-    }
-    return false;
-  }
-
-  /**
-   * This verifies that the passed identifier is not a keyword, and generates the passed error code
-   * on the identifier if it is a keyword.
-   *
-   * @param identifier the identifier to check to ensure that it is not a keyword
-   * @param errorCode if the passed identifier is a keyword then this error code is created on the
-   *          identifier, the error code will be one of
-   *          [CompileTimeErrorCode#BUILT_IN_IDENTIFIER_AS_TYPE_NAME],
-   *          [CompileTimeErrorCode#BUILT_IN_IDENTIFIER_AS_TYPE_PARAMETER_NAME] or
-   *          [CompileTimeErrorCode#BUILT_IN_IDENTIFIER_AS_TYPEDEF_NAME]
-   * @return `true` if and only if an error code is generated on the passed node
-   * @see CompileTimeErrorCode#BUILT_IN_IDENTIFIER_AS_TYPE_NAME
-   * @see CompileTimeErrorCode#BUILT_IN_IDENTIFIER_AS_TYPE_PARAMETER_NAME
-   * @see CompileTimeErrorCode#BUILT_IN_IDENTIFIER_AS_TYPEDEF_NAME
-   */
-  bool _checkForBuiltInIdentifierAsName(SimpleIdentifier identifier, ErrorCode errorCode) {
-    sc.Token token = identifier.token;
-    if (token.type == sc.TokenType.KEYWORD) {
-      _errorReporter.reportErrorForNode(errorCode, identifier, [identifier.name]);
-      return true;
-    }
-    return false;
-  }
-
-  /**
-   * This verifies that the given switch case is terminated with 'break', 'continue', 'return' or
-   * 'throw'.
-   *
-   * @param node the switch case to evaluate
-   * @return `true` if and only if an error code is generated on the passed node
-   * @see StaticWarningCode#CASE_BLOCK_NOT_TERMINATED
-   */
-  bool _checkForCaseBlockNotTerminated(SwitchCase node) {
-    NodeList<Statement> statements = node.statements;
-    if (statements.isEmpty) {
-      // fall-through without statements at all
-      AstNode parent = node.parent;
-      if (parent is SwitchStatement) {
-        SwitchStatement switchStatement = parent;
-        NodeList<SwitchMember> members = switchStatement.members;
-        int index = members.indexOf(node);
-        if (index != -1 && index < members.length - 1) {
-          return false;
-        }
-      }
-      // no other switch member after this one
-    } else {
-      Statement statement = statements[statements.length - 1];
-      // terminated with statement
-      if (statement is BreakStatement || statement is ContinueStatement || statement is ReturnStatement) {
-        return false;
-      }
-      // terminated with 'throw' expression
-      if (statement is ExpressionStatement) {
-        Expression expression = statement.expression;
-        if (expression is ThrowExpression) {
-          return false;
-        }
-      }
-    }
-    // report error
-    _errorReporter.reportErrorForToken(StaticWarningCode.CASE_BLOCK_NOT_TERMINATED, node.keyword, []);
-    return true;
-  }
-
-  /**
-   * This verifies that the switch cases in the given switch statement is terminated with 'break',
-   * 'continue', 'return' or 'throw'.
-   *
-   * @param node the switch statement containing the cases to be checked
-   * @return `true` if and only if an error code is generated on the passed node
-   * @see StaticWarningCode#CASE_BLOCK_NOT_TERMINATED
-   */
-  bool _checkForCaseBlocksNotTerminated(SwitchStatement node) {
-    bool foundError = false;
-    NodeList<SwitchMember> members = node.members;
-    int lastMember = members.length - 1;
-    for (int i = 0; i < lastMember; i++) {
-      SwitchMember member = members[i];
-      if (member is SwitchCase && _checkForCaseBlockNotTerminated(member)) {
-        foundError = true;
-      }
-    }
-    return foundError;
-  }
-
-  /**
-   * This verifies that the passed method declaration is abstract only if the enclosing class is
-   * also abstract.
-   *
-   * @param node the method declaration to evaluate
-   * @return `true` if and only if an error code is generated on the passed node
-   * @see StaticWarningCode#CONCRETE_CLASS_WITH_ABSTRACT_MEMBER
-   */
-  bool _checkForConcreteClassWithAbstractMember(MethodDeclaration node) {
-    if (node.isAbstract && _enclosingClass != null && !_enclosingClass.isAbstract) {
-      SimpleIdentifier nameNode = node.name;
-      String memberName = nameNode.name;
-      ExecutableElement overriddenMember;
-      if (node.isGetter) {
-        overriddenMember = _enclosingClass.lookUpInheritedConcreteGetter(memberName, _currentLibrary);
-      } else if (node.isSetter) {
-        overriddenMember = _enclosingClass.lookUpInheritedConcreteSetter(memberName, _currentLibrary);
-      } else {
-        overriddenMember = _enclosingClass.lookUpInheritedConcreteMethod(memberName, _currentLibrary);
-      }
-      if (overriddenMember == null) {
-        _errorReporter.reportErrorForNode(StaticWarningCode.CONCRETE_CLASS_WITH_ABSTRACT_MEMBER, nameNode, [memberName, _enclosingClass.displayName]);
-        return true;
-      }
-    }
-    return false;
-  }
-
-  /**
-   * This verifies all possible conflicts of the constructor name with other constructors and
-   * members of the same class.
-   *
-   * @param node the constructor declaration to evaluate
-   * @param constructorElement the constructor element
-   * @return `true` if and only if an error code is generated on the passed node
-   * @see CompileTimeErrorCode#DUPLICATE_CONSTRUCTOR_DEFAULT
-   * @see CompileTimeErrorCode#DUPLICATE_CONSTRUCTOR_NAME
-   * @see CompileTimeErrorCode#CONFLICTING_CONSTRUCTOR_NAME_AND_FIELD
-   * @see CompileTimeErrorCode#CONFLICTING_CONSTRUCTOR_NAME_AND_METHOD
-   */
-  bool _checkForConflictingConstructorNameAndMember(ConstructorDeclaration node, ConstructorElement constructorElement) {
-    SimpleIdentifier constructorName = node.name;
-    String name = constructorElement.name;
-    ClassElement classElement = constructorElement.enclosingElement;
-    // constructors
-    List<ConstructorElement> constructors = classElement.constructors;
-    for (ConstructorElement otherConstructor in constructors) {
-      if (identical(otherConstructor, constructorElement)) {
-        continue;
-      }
-      if (name == otherConstructor.name) {
-        if (name == null || name.length == 0) {
-          _errorReporter.reportErrorForNode(CompileTimeErrorCode.DUPLICATE_CONSTRUCTOR_DEFAULT, node, []);
-        } else {
-          _errorReporter.reportErrorForNode(CompileTimeErrorCode.DUPLICATE_CONSTRUCTOR_NAME, node, [name]);
-        }
-        return true;
-      }
-    }
-    // conflict with class member
-    if (constructorName != null && constructorElement != null && !constructorName.isSynthetic) {
-      // fields
-      FieldElement field = classElement.getField(name);
-      if (field != null) {
-        _errorReporter.reportErrorForNode(CompileTimeErrorCode.CONFLICTING_CONSTRUCTOR_NAME_AND_FIELD, node, [name]);
-        return true;
-      }
-      // methods
-      MethodElement method = classElement.getMethod(name);
-      if (method != null) {
-        _errorReporter.reportErrorForNode(CompileTimeErrorCode.CONFLICTING_CONSTRUCTOR_NAME_AND_METHOD, node, [name]);
-        return true;
-      }
-    }
-    return false;
-  }
-
-  /**
-   * This verifies that the [enclosingClass] does not have a method and getter pair with the
-   * same name on, via inheritance.
-   *
-   * @return `true` if and only if an error code is generated on the passed node
-   * @see CompileTimeErrorCode#CONFLICTING_GETTER_AND_METHOD
-   * @see CompileTimeErrorCode#CONFLICTING_METHOD_AND_GETTER
-   */
-  bool _checkForConflictingGetterAndMethod() {
-    if (_enclosingClass == null) {
-      return false;
-    }
-    bool hasProblem = false;
-    // method declared in the enclosing class vs. inherited getter
-    for (MethodElement method in _enclosingClass.methods) {
-      String name = method.name;
-      // find inherited property accessor (and can be only getter)
-      ExecutableElement inherited = _inheritanceManager.lookupInheritance(_enclosingClass, name);
-      if (inherited is! PropertyAccessorElement) {
-        continue;
-      }
-      // report problem
-      hasProblem = true;
-      _errorReporter.reportErrorForOffset(CompileTimeErrorCode.CONFLICTING_GETTER_AND_METHOD, method.nameOffset, name.length, [
-          _enclosingClass.displayName,
-          inherited.enclosingElement.displayName,
-          name]);
-    }
-    // getter declared in the enclosing class vs. inherited method
-    for (PropertyAccessorElement accessor in _enclosingClass.accessors) {
-      if (!accessor.isGetter) {
-        continue;
-      }
-      String name = accessor.name;
-      // find inherited method
-      ExecutableElement inherited = _inheritanceManager.lookupInheritance(_enclosingClass, name);
-      if (inherited is! MethodElement) {
-        continue;
-      }
-      // report problem
-      hasProblem = true;
-      _errorReporter.reportErrorForOffset(CompileTimeErrorCode.CONFLICTING_METHOD_AND_GETTER, accessor.nameOffset, name.length, [
-          _enclosingClass.displayName,
-          inherited.enclosingElement.displayName,
-          name]);
-    }
-    // done
-    return hasProblem;
-  }
-
-  /**
-   * This verifies that the superclass of the [enclosingClass] does not declare accessible
-   * static members with the same name as the instance getters/setters declared in
-   * [enclosingClass].
-   *
-   * @param node the method declaration to evaluate
-   * @return `true` if and only if an error code is generated on the passed node
-   * @see StaticWarningCode#CONFLICTING_INSTANCE_GETTER_AND_SUPERCLASS_MEMBER
-   * @see StaticWarningCode#CONFLICTING_INSTANCE_SETTER_AND_SUPERCLASS_MEMBER
-   */
-  bool _checkForConflictingInstanceGetterAndSuperclassMember() {
-    if (_enclosingClass == null) {
-      return false;
-    }
-    InterfaceType enclosingType = _enclosingClass.type;
-    // check every accessor
-    bool hasProblem = false;
-    for (PropertyAccessorElement accessor in _enclosingClass.accessors) {
-      // we analyze instance accessors here
-      if (accessor.isStatic) {
-        continue;
-      }
-      // prepare accessor properties
-      String name = accessor.displayName;
-      bool getter = accessor.isGetter;
-      // if non-final variable, ignore setter - we alreay reported problem for getter
-      if (accessor.isSetter && accessor.isSynthetic) {
-        continue;
-      }
-      // try to find super element
-      ExecutableElement superElement;
-      superElement = enclosingType.lookUpGetterInSuperclass(name, _currentLibrary);
-      if (superElement == null) {
-        superElement = enclosingType.lookUpSetterInSuperclass(name, _currentLibrary);
-      }
-      if (superElement == null) {
-        superElement = enclosingType.lookUpMethodInSuperclass(name, _currentLibrary);
-      }
-      if (superElement == null) {
-        continue;
-      }
-      // OK, not static
-      if (!superElement.isStatic) {
-        continue;
-      }
-      // prepare "super" type to report its name
-      ClassElement superElementClass = superElement.enclosingElement as ClassElement;
-      InterfaceType superElementType = superElementClass.type;
-      // report problem
-      hasProblem = true;
-      if (getter) {
-        _errorReporter.reportErrorForElement(StaticWarningCode.CONFLICTING_INSTANCE_GETTER_AND_SUPERCLASS_MEMBER, accessor, [superElementType.displayName]);
-      } else {
-        _errorReporter.reportErrorForElement(StaticWarningCode.CONFLICTING_INSTANCE_SETTER_AND_SUPERCLASS_MEMBER, accessor, [superElementType.displayName]);
-      }
-    }
-    // done
-    return hasProblem;
-  }
-
-  /**
-   * This verifies that the enclosing class does not have a setter with the same name as the passed
-   * instance method declaration.
-   *
-   * TODO(jwren) add other "conflicting" error codes into algorithm/ data structure
-   *
-   * @param node the method declaration to evaluate
-   * @return `true` if and only if an error code is generated on the passed node
-   * @see StaticWarningCode#CONFLICTING_INSTANCE_METHOD_SETTER
-   */
-  bool _checkForConflictingInstanceMethodSetter(ClassDeclaration node) {
-    // Reference all of the class members in this class.
-    NodeList<ClassMember> classMembers = node.members;
-    if (classMembers.isEmpty) {
-      return false;
-    }
-    // Create a HashMap to track conflicting members, and then loop through members in the class to
-    // construct the HashMap, at the same time, look for violations.  Don't add members if they are
-    // part of a conflict, this prevents multiple warnings for one issue.
-    bool foundError = false;
-    HashMap<String, ClassMember> memberHashMap = new HashMap<String, ClassMember>();
-    for (ClassMember classMember in classMembers) {
-      if (classMember is MethodDeclaration) {
-        MethodDeclaration method = classMember;
-        if (method.isStatic) {
-          continue;
-        }
-        // prepare name
-        SimpleIdentifier name = method.name;
-        if (name == null) {
-          continue;
-        }
-        bool addThisMemberToTheMap = true;
-        bool isGetter = method.isGetter;
-        bool isSetter = method.isSetter;
-        bool isOperator = method.isOperator;
-        bool isMethod = !isGetter && !isSetter && !isOperator;
-        // Do lookups in the enclosing class (and the inherited member) if the member is a method or
-        // a setter for StaticWarningCode.CONFLICTING_INSTANCE_METHOD_SETTER warning.
-        if (isMethod) {
-          String setterName = "${name.name}=";
-          Element enclosingElementOfSetter = null;
-          ClassMember conflictingSetter = memberHashMap[setterName];
-          if (conflictingSetter != null) {
-            enclosingElementOfSetter = conflictingSetter.element.enclosingElement;
-          } else {
-            ExecutableElement elementFromInheritance = _inheritanceManager.lookupInheritance(_enclosingClass, setterName);
-            if (elementFromInheritance != null) {
-              enclosingElementOfSetter = elementFromInheritance.enclosingElement;
-            }
-          }
-          if (enclosingElementOfSetter != null) {
-            // report problem
-            _errorReporter.reportErrorForNode(StaticWarningCode.CONFLICTING_INSTANCE_METHOD_SETTER, name, [
-                _enclosingClass.displayName,
-                name.name,
-                enclosingElementOfSetter.displayName]);
-            foundError = true;
-            addThisMemberToTheMap = false;
-          }
-        } else if (isSetter) {
-          String methodName = name.name;
-          ClassMember conflictingMethod = memberHashMap[methodName];
-          if (conflictingMethod != null && conflictingMethod is MethodDeclaration && !conflictingMethod.isGetter) {
-            // report problem
-            _errorReporter.reportErrorForNode(StaticWarningCode.CONFLICTING_INSTANCE_METHOD_SETTER2, name, [_enclosingClass.displayName, name.name]);
-            foundError = true;
-            addThisMemberToTheMap = false;
-          }
-        }
-        // Finally, add this member into the HashMap.
-        if (addThisMemberToTheMap) {
-          if (method.isSetter) {
-            memberHashMap["${name.name}="] = method;
-          } else {
-            memberHashMap[name.name] = method;
-          }
-        }
-      }
-    }
-    return foundError;
-  }
-
-  /**
-   * This verifies that the enclosing class does not have an instance member with the same name as
-   * the passed static getter method declaration.
-   *
-   * @param node the method declaration to evaluate
-   * @return `true` if and only if an error code is generated on the passed node
-   * @see StaticWarningCode#CONFLICTING_STATIC_GETTER_AND_INSTANCE_SETTER
-   */
-  bool _checkForConflictingStaticGetterAndInstanceSetter(MethodDeclaration node) {
-    if (!node.isStatic) {
-      return false;
-    }
-    // prepare name
-    SimpleIdentifier nameNode = node.name;
-    if (nameNode == null) {
-      return false;
-    }
-    String name = nameNode.name;
-    // prepare enclosing type
-    if (_enclosingClass == null) {
-      return false;
-    }
-    InterfaceType enclosingType = _enclosingClass.type;
-    // try to find setter
-    ExecutableElement setter = enclosingType.lookUpSetter(name, _currentLibrary);
-    if (setter == null) {
-      return false;
-    }
-    // OK, also static
-    if (setter.isStatic) {
-      return false;
-    }
-    // prepare "setter" type to report its name
-    ClassElement setterClass = setter.enclosingElement as ClassElement;
-    InterfaceType setterType = setterClass.type;
-    // report problem
-    _errorReporter.reportErrorForNode(StaticWarningCode.CONFLICTING_STATIC_GETTER_AND_INSTANCE_SETTER, nameNode, [setterType.displayName]);
-    return true;
-  }
-
-  /**
-   * This verifies that the enclosing class does not have an instance member with the same name as
-   * the passed static getter method declaration.
-   *
-   * @param node the method declaration to evaluate
-   * @return `true` if and only if an error code is generated on the passed node
-   * @see StaticWarningCode#CONFLICTING_STATIC_SETTER_AND_INSTANCE_MEMBER
-   */
-  bool _checkForConflictingStaticSetterAndInstanceMember(MethodDeclaration node) {
-    if (!node.isStatic) {
-      return false;
-    }
-    // prepare name
-    SimpleIdentifier nameNode = node.name;
-    if (nameNode == null) {
-      return false;
-    }
-    String name = nameNode.name;
-    // prepare enclosing type
-    if (_enclosingClass == null) {
-      return false;
-    }
-    InterfaceType enclosingType = _enclosingClass.type;
-    // try to find member
-    ExecutableElement member;
-    member = enclosingType.lookUpMethod(name, _currentLibrary);
-    if (member == null) {
-      member = enclosingType.lookUpGetter(name, _currentLibrary);
-    }
-    if (member == null) {
-      member = enclosingType.lookUpSetter(name, _currentLibrary);
-    }
-    if (member == null) {
-      return false;
-    }
-    // OK, also static
-    if (member.isStatic) {
-      return false;
-    }
-    // prepare "member" type to report its name
-    ClassElement memberClass = member.enclosingElement as ClassElement;
-    InterfaceType memberType = memberClass.type;
-    // report problem
-    _errorReporter.reportErrorForNode(StaticWarningCode.CONFLICTING_STATIC_SETTER_AND_INSTANCE_MEMBER, nameNode, [memberType.displayName]);
-    return true;
-  }
-
-  /**
-   * This verifies all conflicts between type variable and enclosing class. TODO(scheglov)
-   *
-   * @param node the class declaration to evaluate
-   * @return `true` if and only if an error code is generated on the passed node
-   * @see CompileTimeErrorCode#CONFLICTING_TYPE_VARIABLE_AND_CLASS
-   * @see CompileTimeErrorCode#CONFLICTING_TYPE_VARIABLE_AND_MEMBER
-   */
-  bool _checkForConflictingTypeVariableErrorCodes(ClassDeclaration node) {
-    bool problemReported = false;
-    for (TypeParameterElement typeParameter in _enclosingClass.typeParameters) {
-      String name = typeParameter.name;
-      // name is same as the name of the enclosing class
-      if (_enclosingClass.name == name) {
-        _errorReporter.reportErrorForOffset(CompileTimeErrorCode.CONFLICTING_TYPE_VARIABLE_AND_CLASS, typeParameter.nameOffset, name.length, [name]);
-        problemReported = true;
-      }
-      // check members
-      if (_enclosingClass.getMethod(name) != null || _enclosingClass.getGetter(name) != null || _enclosingClass.getSetter(name) != null) {
-        _errorReporter.reportErrorForOffset(CompileTimeErrorCode.CONFLICTING_TYPE_VARIABLE_AND_MEMBER, typeParameter.nameOffset, name.length, [name]);
-        problemReported = true;
-      }
-    }
-    return problemReported;
-  }
-
-  /**
-   * This verifies that if the passed constructor declaration is 'const' then there are no
-   * invocations of non-'const' super constructors.
-   *
-   * @param node the constructor declaration to evaluate
-   * @return `true` if and only if an error code is generated on the passed node
-   * @see CompileTimeErrorCode#CONST_CONSTRUCTOR_WITH_NON_CONST_SUPER
-   */
-  bool _checkForConstConstructorWithNonConstSuper(ConstructorDeclaration node) {
-    if (!_isEnclosingConstructorConst) {
-      return false;
-    }
-    // OK, const factory, checked elsewhere
-    if (node.factoryKeyword != null) {
-      return false;
-    }
-    // check for mixins
-    if (_enclosingClass.mixins.length != 0) {
-      _errorReporter.reportErrorForNode(CompileTimeErrorCode.CONST_CONSTRUCTOR_WITH_MIXIN, node.returnType, []);
-      return true;
-    }
-    // try to find and check super constructor invocation
-    for (ConstructorInitializer initializer in node.initializers) {
-      if (initializer is SuperConstructorInvocation) {
-        SuperConstructorInvocation superInvocation = initializer;
-        ConstructorElement element = superInvocation.staticElement;
-        if (element == null || element.isConst) {
-          return false;
-        }
-        _errorReporter.reportErrorForNode(CompileTimeErrorCode.CONST_CONSTRUCTOR_WITH_NON_CONST_SUPER, superInvocation, [element.enclosingElement.displayName]);
-        return true;
-      }
-    }
-    // no explicit super constructor invocation, check default constructor
-    InterfaceType supertype = _enclosingClass.supertype;
-    if (supertype == null) {
-      return false;
-    }
-    if (supertype.isObject) {
-      return false;
-    }
-    ConstructorElement unnamedConstructor = supertype.element.unnamedConstructor;
-    if (unnamedConstructor == null) {
-      return false;
-    }
-    if (unnamedConstructor.isConst) {
-      return false;
-    }
-    // default constructor is not 'const', report problem
-    _errorReporter.reportErrorForNode(CompileTimeErrorCode.CONST_CONSTRUCTOR_WITH_NON_CONST_SUPER, node.returnType, [supertype.displayName]);
-    return true;
-  }
-
-  /**
-   * This verifies that if the passed constructor declaration is 'const' then there are no non-final
-   * instance variable.
-   *
-   * @param node the constructor declaration to evaluate
-   * @param constructorElement the constructor element
-   * @return `true` if and only if an error code is generated on the passed node
-   * @see CompileTimeErrorCode#CONST_CONSTRUCTOR_WITH_NON_FINAL_FIELD
-   */
-  bool _checkForConstConstructorWithNonFinalField(ConstructorDeclaration node, ConstructorElement constructorElement) {
-    if (!_isEnclosingConstructorConst) {
-      return false;
-    }
-    // check if there is non-final field
-    ClassElement classElement = constructorElement.enclosingElement;
-    if (!classElement.hasNonFinalField) {
-      return false;
-    }
-    // report problem
-    _errorReporter.reportErrorForNode(CompileTimeErrorCode.CONST_CONSTRUCTOR_WITH_NON_FINAL_FIELD, node, []);
-    return true;
-  }
-
-  /**
-   * This verifies that the passed 'const' instance creation expression is not creating a deferred
-   * type.
-   *
-   * @param node the instance creation expression to evaluate
-   * @param constructorName the constructor name, always non-`null`
-   * @param typeName the name of the type defining the constructor, always non-`null`
-   * @return `true` if and only if an error code is generated on the passed node
-   * @see CompileTimeErrorCode#CONST_DEFERRED_CLASS
-   */
-  bool _checkForConstDeferredClass(InstanceCreationExpression node, ConstructorName constructorName, TypeName typeName) {
-    if (typeName.isDeferred) {
-      _errorReporter.reportErrorForNode(CompileTimeErrorCode.CONST_DEFERRED_CLASS, constructorName, [typeName.name.name]);
-      return true;
-    }
-    return false;
-  }
-
-  /**
-   * This verifies that the passed throw expression is not enclosed in a 'const' constructor
-   * declaration.
-   *
-   * @param node the throw expression expression to evaluate
-   * @return `true` if and only if an error code is generated on the passed node
-   * @see CompileTimeErrorCode#CONST_CONSTRUCTOR_THROWS_EXCEPTION
-   */
-  bool _checkForConstEvalThrowsException(ThrowExpression node) {
-    if (_isEnclosingConstructorConst) {
-      _errorReporter.reportErrorForNode(CompileTimeErrorCode.CONST_CONSTRUCTOR_THROWS_EXCEPTION, node, []);
-      return true;
-    }
-    return false;
-  }
-
-  /**
-   * This verifies that the passed normal formal parameter is not 'const'.
-   *
-   * @param node the normal formal parameter to evaluate
-   * @return `true` if and only if an error code is generated on the passed node
-   * @see CompileTimeErrorCode#CONST_FORMAL_PARAMETER
-   */
-  bool _checkForConstFormalParameter(NormalFormalParameter node) {
-    if (node.isConst) {
-      _errorReporter.reportErrorForNode(CompileTimeErrorCode.CONST_FORMAL_PARAMETER, node, []);
-      return true;
-    }
-    return false;
-  }
-
-  /**
-   * This verifies that the passed instance creation expression is not being invoked on an abstract
-   * class.
-   *
-   * @param node the instance creation expression to evaluate
-   * @param typeName the [TypeName] of the [ConstructorName] from the
-   *          [InstanceCreationExpression], this is the AST node that the error is attached to
-   * @param type the type being constructed with this [InstanceCreationExpression]
-   * @return `true` if and only if an error code is generated on the passed node
-   * @see StaticWarningCode#CONST_WITH_ABSTRACT_CLASS
-   * @see StaticWarningCode#NEW_WITH_ABSTRACT_CLASS
-   */
-  bool _checkForConstOrNewWithAbstractClass(InstanceCreationExpression node, TypeName typeName, InterfaceType type) {
-    if (type.element.isAbstract) {
-      ConstructorElement element = node.staticElement;
-      if (element != null && !element.isFactory) {
-        if ((node.keyword as sc.KeywordToken).keyword == sc.Keyword.CONST) {
-          _errorReporter.reportErrorForNode(StaticWarningCode.CONST_WITH_ABSTRACT_CLASS, typeName, []);
-        } else {
-          _errorReporter.reportErrorForNode(StaticWarningCode.NEW_WITH_ABSTRACT_CLASS, typeName, []);
-        }
-        return true;
-      }
-    }
-    return false;
-  }
-
-  /**
-   * This verifies that the passed instance creation expression is not being invoked on an enum.
-   *
-   * @param node the instance creation expression to verify
-   * @param typeName the [TypeName] of the [ConstructorName] from the
-   *          [InstanceCreationExpression], this is the AST node that the error is attached to
-   * @param type the type being constructed with this [InstanceCreationExpression]
-   * @return `true` if and only if an error code is generated on the passed node
-   * @see CompileTimeErrorCode#INSTANTIATE_ENUM
-   */
-  bool _checkForConstOrNewWithEnum(InstanceCreationExpression node, TypeName typeName, InterfaceType type) {
-    if (type.element.isEnum) {
-      _errorReporter.reportErrorForNode(CompileTimeErrorCode.INSTANTIATE_ENUM, typeName, []);
-      return true;
-    }
-    return false;
-  }
-
-  /**
-   * This verifies that the passed 'const' instance creation expression is not being invoked on a
-   * constructor that is not 'const'.
-   *
-   * This method assumes that the instance creation was tested to be 'const' before being called.
-   *
-   * @param node the instance creation expression to verify
-   * @return `true` if and only if an error code is generated on the passed node
-   * @see CompileTimeErrorCode#CONST_WITH_NON_CONST
-   */
-  bool _checkForConstWithNonConst(InstanceCreationExpression node) {
-    ConstructorElement constructorElement = node.staticElement;
-    if (constructorElement != null && !constructorElement.isConst) {
-      _errorReporter.reportErrorForNode(CompileTimeErrorCode.CONST_WITH_NON_CONST, node, []);
-      return true;
-    }
-    return false;
-  }
-
-  /**
-   * This verifies that the passed type name does not reference any type parameters.
-   *
-   * @param typeName the type name to evaluate
-   * @return `true` if and only if an error code is generated on the passed node
-   * @see CompileTimeErrorCode#CONST_WITH_TYPE_PARAMETERS
-   */
-  bool _checkForConstWithTypeParameters(TypeName typeName) {
-    // something wrong with AST
-    if (typeName == null) {
-      return false;
-    }
-    Identifier name = typeName.name;
-    if (name == null) {
-      return false;
-    }
-    // should not be a type parameter
-    if (name.staticElement is TypeParameterElement) {
-      _errorReporter.reportErrorForNode(CompileTimeErrorCode.CONST_WITH_TYPE_PARAMETERS, name, []);
-    }
-    // check type arguments
-    TypeArgumentList typeArguments = typeName.typeArguments;
-    if (typeArguments != null) {
-      bool hasError = false;
-      for (TypeName argument in typeArguments.arguments) {
-        if (_checkForConstWithTypeParameters(argument)) {
-          hasError = true;
-        }
-      }
-      return hasError;
-    }
-    // OK
-    return false;
-  }
-
-  /**
-   * This verifies that if the passed 'const' instance creation expression is being invoked on the
-   * resolved constructor.
-   *
-   * This method assumes that the instance creation was tested to be 'const' before being called.
-   *
-   * @param node the instance creation expression to evaluate
-   * @param constructorName the constructor name, always non-`null`
-   * @param typeName the name of the type defining the constructor, always non-`null`
-   * @return `true` if and only if an error code is generated on the passed node
-   * @see CompileTimeErrorCode#CONST_WITH_UNDEFINED_CONSTRUCTOR
-   * @see CompileTimeErrorCode#CONST_WITH_UNDEFINED_CONSTRUCTOR_DEFAULT
-   */
-  bool _checkForConstWithUndefinedConstructor(InstanceCreationExpression node, ConstructorName constructorName, TypeName typeName) {
-    // OK if resolved
-    if (node.staticElement != null) {
-      return false;
-    }
-    DartType type = typeName.type;
-    if (type is InterfaceType) {
-      ClassElement element = type.element;
-      if (element != null && element.isEnum) {
-        // We have already reported the error.
-        return false;
-      }
-    }
-    Identifier className = typeName.name;
-    // report as named or default constructor absence
-    SimpleIdentifier name = constructorName.name;
-    if (name != null) {
-      _errorReporter.reportErrorForNode(CompileTimeErrorCode.CONST_WITH_UNDEFINED_CONSTRUCTOR, name, [className, name]);
-    } else {
-      _errorReporter.reportErrorForNode(CompileTimeErrorCode.CONST_WITH_UNDEFINED_CONSTRUCTOR_DEFAULT, constructorName, [className]);
-    }
-    return true;
-  }
-
-  /**
-   * This verifies that there are no default parameters in the passed function type alias.
-   *
-   * @param node the function type alias to evaluate
-   * @return `true` if and only if an error code is generated on the passed node
-   * @see CompileTimeErrorCode#DEFAULT_VALUE_IN_FUNCTION_TYPE_ALIAS
-   */
-  bool _checkForDefaultValueInFunctionTypeAlias(FunctionTypeAlias node) {
-    bool result = false;
-    FormalParameterList formalParameterList = node.parameters;
-    NodeList<FormalParameter> parameters = formalParameterList.parameters;
-    for (FormalParameter formalParameter in parameters) {
-      if (formalParameter is DefaultFormalParameter) {
-        DefaultFormalParameter defaultFormalParameter = formalParameter;
-        if (defaultFormalParameter.defaultValue != null) {
-          _errorReporter.reportErrorForNode(CompileTimeErrorCode.DEFAULT_VALUE_IN_FUNCTION_TYPE_ALIAS, node, []);
-          result = true;
-        }
-      }
-    }
-    return result;
-  }
-
-  /**
-   * This verifies that the given default formal parameter is not part of a function typed
-   * parameter.
-   *
-   * @param node the default formal parameter to evaluate
-   * @return `true` if and only if an error code is generated on the passed node
-   * @see CompileTimeErrorCode#DEFAULT_VALUE_IN_FUNCTION_TYPED_PARAMETER
-   */
-  bool _checkForDefaultValueInFunctionTypedParameter(DefaultFormalParameter node) {
-    // OK, not in a function typed parameter.
-    if (!_isInFunctionTypedFormalParameter) {
-      return false;
-    }
-    // OK, no default value.
-    if (node.defaultValue == null) {
-      return false;
-    }
-    // Report problem.
-    _errorReporter.reportErrorForNode(CompileTimeErrorCode.DEFAULT_VALUE_IN_FUNCTION_TYPED_PARAMETER, node, []);
-    return true;
-  }
-
-  /**
-   * This verifies that any deferred imports in the given compilation unit have a unique prefix.
-   *
-   * @param node the compilation unit containing the imports to be checked
-   * @return `true` if an error was generated
-   * @see CompileTimeErrorCode#SHARED_DEFERRED_PREFIX
-   */
-  bool _checkForDeferredPrefixCollisions(CompilationUnit node) {
-    bool foundError = false;
-    NodeList<Directive> directives = node.directives;
-    int count = directives.length;
-    if (count > 0) {
-      HashMap<PrefixElement, List<ImportDirective>> prefixToDirectivesMap = new HashMap<PrefixElement, List<ImportDirective>>();
-      for (int i = 0; i < count; i++) {
-        Directive directive = directives[i];
-        if (directive is ImportDirective) {
-          ImportDirective importDirective = directive;
-          SimpleIdentifier prefix = importDirective.prefix;
-          if (prefix != null) {
-            Element element = prefix.staticElement;
-            if (element is PrefixElement) {
-              PrefixElement prefixElement = element;
-              List<ImportDirective> elements = prefixToDirectivesMap[prefixElement];
-              if (elements == null) {
-                elements = new List<ImportDirective>();
-                prefixToDirectivesMap[prefixElement] = elements;
-              }
-              elements.add(importDirective);
-            }
-          }
-        }
-      }
-      for (List<ImportDirective> imports in prefixToDirectivesMap.values) {
-        if (_hasDeferredPrefixCollision(imports)) {
-          foundError = true;
-        }
-      }
-    }
-    return foundError;
-  }
-
-  /**
-   * This verifies that the enclosing class does not have an instance member with the given name of
-   * the static member.
-   *
-   * @return `true` if and only if an error code is generated on the passed node
-   * @see CompileTimeErrorCode#DUPLICATE_DEFINITION_INHERITANCE
-   */
-  bool _checkForDuplicateDefinitionInheritance() {
-    if (_enclosingClass == null) {
-      return false;
-    }
-    bool hasProblem = false;
-    for (ExecutableElement member in _enclosingClass.methods) {
-      if (member.isStatic && _checkForDuplicateDefinitionOfMember(member)) {
-        hasProblem = true;
-      }
-    }
-    for (ExecutableElement member in _enclosingClass.accessors) {
-      if (member.isStatic && _checkForDuplicateDefinitionOfMember(member)) {
-        hasProblem = true;
-      }
-    }
-    return hasProblem;
-  }
-
-  /**
-   * This verifies that the enclosing class does not have an instance member with the given name of
-   * the static member.
-   *
-   * @param staticMember the static member to check conflict for
-   * @return `true` if and only if an error code is generated on the passed node
-   * @see CompileTimeErrorCode#DUPLICATE_DEFINITION_INHERITANCE
-   */
-  bool _checkForDuplicateDefinitionOfMember(ExecutableElement staticMember) {
-    // prepare name
-    String name = staticMember.name;
-    if (name == null) {
-      return false;
-    }
-    // try to find member
-    ExecutableElement inheritedMember = _inheritanceManager.lookupInheritance(_enclosingClass, name);
-    if (inheritedMember == null) {
-      return false;
-    }
-    // OK, also static
-    if (inheritedMember.isStatic) {
-      return false;
-    }
-    // determine the display name, use the extended display name if the enclosing class of the
-    // inherited member is in a different source
-    String displayName;
-    Element enclosingElement = inheritedMember.enclosingElement;
-    if (enclosingElement.source == _enclosingClass.source) {
-      displayName = enclosingElement.displayName;
-    } else {
-      displayName = enclosingElement.getExtendedDisplayName(null);
-    }
-    // report problem
-    _errorReporter.reportErrorForOffset(CompileTimeErrorCode.DUPLICATE_DEFINITION_INHERITANCE, staticMember.nameOffset, name.length, [name, displayName]);
-    return true;
-  }
-
-  /**
-   * This verifies if the passed list literal has type arguments then there is exactly one.
-   *
-   * @param node the list literal to evaluate
-   * @param typeArguments the type arguments, always non-`null`
-   * @return `true` if and only if an error code is generated on the passed node
-   * @see StaticTypeWarningCode#EXPECTED_ONE_LIST_TYPE_ARGUMENTS
-   */
-  bool _checkForExpectedOneListTypeArgument(ListLiteral node, TypeArgumentList typeArguments) {
-    // check number of type arguments
-    int num = typeArguments.arguments.length;
-    if (num == 1) {
-      return false;
-    }
-    // report problem
-    _errorReporter.reportErrorForNode(StaticTypeWarningCode.EXPECTED_ONE_LIST_TYPE_ARGUMENTS, typeArguments, [num]);
-    return true;
-  }
-
-  /**
-   * This verifies the passed import has unique name among other exported libraries.
-   *
-   * @param node the export directive to evaluate
-   * @param exportElement the [ExportElement] retrieved from the node, if the element in the
-   *          node was `null`, then this method is not called
-   * @param exportedLibrary the library element containing the exported element
-   * @return `true` if and only if an error code is generated on the passed node
-   * @see CompileTimeErrorCode#EXPORT_DUPLICATED_LIBRARY_NAME
-   */
-  bool _checkForExportDuplicateLibraryName(ExportDirective node, ExportElement exportElement, LibraryElement exportedLibrary) {
-    if (exportedLibrary == null) {
-      return false;
-    }
-    String name = exportedLibrary.name;
-    // check if there is other exported library with the same name
-    LibraryElement prevLibrary = _nameToExportElement[name];
-    if (prevLibrary != null) {
-      if (prevLibrary != exportedLibrary) {
-        _errorReporter.reportErrorForNode(StaticWarningCode.EXPORT_DUPLICATED_LIBRARY_NAME, node, [
-            prevLibrary.definingCompilationUnit.displayName,
-            exportedLibrary.definingCompilationUnit.displayName,
-            name]);
-        return true;
-      }
-    } else {
-      _nameToExportElement[name] = exportedLibrary;
-    }
-    // OK
-    return false;
-  }
-
-  /**
-   * Check that if the visiting library is not system, then any passed library should not be SDK
-   * internal library.
-   *
-   * @param node the export directive to evaluate
-   * @param exportElement the [ExportElement] retrieved from the node, if the element in the
-   *          node was `null`, then this method is not called
-   * @return `true` if and only if an error code is generated on the passed node
-   * @see CompileTimeErrorCode#EXPORT_INTERNAL_LIBRARY
-   */
-  bool _checkForExportInternalLibrary(ExportDirective node, ExportElement exportElement) {
-    if (_isInSystemLibrary) {
-      return false;
-    }
-    // should be private
-    DartSdk sdk = _currentLibrary.context.sourceFactory.dartSdk;
-    String uri = exportElement.uri;
-    SdkLibrary sdkLibrary = sdk.getSdkLibrary(uri);
-    if (sdkLibrary == null) {
-      return false;
-    }
-    if (!sdkLibrary.isInternal) {
-      return false;
-    }
-    // report problem
-    _errorReporter.reportErrorForNode(CompileTimeErrorCode.EXPORT_INTERNAL_LIBRARY, node, [node.uri]);
-    return true;
-  }
-
-  /**
-   * This verifies that the passed extends clause does not extend a deferred class.
-   *
-   * @param node the extends clause to test
-   * @return `true` if and only if an error code is generated on the passed node
-   * @see CompileTimeErrorCode#EXTENDS_DEFERRED_CLASS
-   */
-  bool _checkForExtendsDeferredClass(ExtendsClause node) {
-    if (node == null) {
-      return false;
-    }
-    return _checkForExtendsOrImplementsDeferredClass(node.superclass, CompileTimeErrorCode.EXTENDS_DEFERRED_CLASS);
-  }
-
-  /**
-   * This verifies that the passed type alias does not extend a deferred class.
-   *
-   * @param node the extends clause to test
-   * @return `true` if and only if an error code is generated on the passed node
-   * @see CompileTimeErrorCode#EXTENDS_DISALLOWED_CLASS
-   */
-  bool _checkForExtendsDeferredClassInTypeAlias(ClassTypeAlias node) {
-    if (node == null) {
-      return false;
-    }
-    return _checkForExtendsOrImplementsDeferredClass(node.superclass, CompileTimeErrorCode.EXTENDS_DEFERRED_CLASS);
-  }
-
-  /**
-   * This verifies that the passed extends clause does not extend classes such as num or String.
-   *
-   * @param node the extends clause to test
-   * @return `true` if and only if an error code is generated on the passed node
-   * @see CompileTimeErrorCode#EXTENDS_DISALLOWED_CLASS
-   */
-  bool _checkForExtendsDisallowedClass(ExtendsClause node) {
-    if (node == null) {
-      return false;
-    }
-    return _checkForExtendsOrImplementsDisallowedClass(node.superclass, CompileTimeErrorCode.EXTENDS_DISALLOWED_CLASS);
-  }
-
-  /**
-   * This verifies that the passed type alias does not extend classes such as num or String.
-   *
-   * @param node the extends clause to test
-   * @return `true` if and only if an error code is generated on the passed node
-   * @see CompileTimeErrorCode#EXTENDS_DISALLOWED_CLASS
-   */
-  bool _checkForExtendsDisallowedClassInTypeAlias(ClassTypeAlias node) {
-    if (node == null) {
-      return false;
-    }
-    return _checkForExtendsOrImplementsDisallowedClass(node.superclass, CompileTimeErrorCode.EXTENDS_DISALLOWED_CLASS);
-  }
-
-  /**
-   * This verifies that the passed type name does not extend, implement or mixin classes that are
-   * deferred.
-   *
-   * @param node the type name to test
-   * @return `true` if and only if an error code is generated on the passed node
-   * @see #checkForExtendsDeferredClass(ExtendsClause)
-   * @see #checkForExtendsDeferredClassInTypeAlias(ClassTypeAlias)
-   * @see #checkForImplementsDeferredClass(ImplementsClause)
-   * @see #checkForAllMixinErrorCodes(WithClause)
-   * @see CompileTimeErrorCode#EXTENDS_DEFERRED_CLASS
-   * @see CompileTimeErrorCode#IMPLEMENTS_DEFERRED_CLASS
-   * @see CompileTimeErrorCode#MIXIN_DEFERRED_CLASS
-   */
-  bool _checkForExtendsOrImplementsDeferredClass(TypeName typeName, ErrorCode errorCode) {
-    if (typeName.isSynthetic) {
-      return false;
-    }
-    if (typeName.isDeferred) {
-      _errorReporter.reportErrorForNode(errorCode, typeName, [typeName.name.name]);
-      return true;
-    }
-    return false;
-  }
-
-  /**
-   * This verifies that the passed type name does not extend, implement or mixin classes such as
-   * 'num' or 'String'.
-   *
-   * @param node the type name to test
-   * @return `true` if and only if an error code is generated on the passed node
-   * @see #checkForExtendsDisallowedClass(ExtendsClause)
-   * @see #checkForExtendsDisallowedClassInTypeAlias(ClassTypeAlias)
-   * @see #checkForImplementsDisallowedClass(ImplementsClause)
-   * @see #checkForAllMixinErrorCodes(WithClause)
-   * @see CompileTimeErrorCode#EXTENDS_DISALLOWED_CLASS
-   * @see CompileTimeErrorCode#IMPLEMENTS_DISALLOWED_CLASS
-   * @see CompileTimeErrorCode#MIXIN_OF_DISALLOWED_CLASS
-   */
-  bool _checkForExtendsOrImplementsDisallowedClass(TypeName typeName, ErrorCode errorCode) {
-    if (typeName.isSynthetic) {
-      return false;
-    }
-    DartType superType = typeName.type;
-    for (InterfaceType disallowedType in _DISALLOWED_TYPES_TO_EXTEND_OR_IMPLEMENT) {
-      if (superType != null && superType == disallowedType) {
-        // if the violating type happens to be 'num', we need to rule out the case where the
-        // enclosing class is 'int' or 'double'
-        if (superType == _typeProvider.numType) {
-          AstNode grandParent = typeName.parent.parent;
-          // Note: this is a corner case that won't happen often, so adding a field currentClass
-          // (see currentFunction) to ErrorVerifier isn't worth if for this case, but if the field
-          // currentClass is added, then this message should become a todo to not lookup the
-          // grandparent node
-          if (grandParent is ClassDeclaration) {
-            ClassElement classElement = grandParent.element;
-            DartType classType = classElement.type;
-            if (classType != null && (classType == _intType || classType == _typeProvider.doubleType)) {
-              return false;
-            }
-          }
-        }
-        // otherwise, report the error
-        _errorReporter.reportErrorForNode(errorCode, typeName, [disallowedType.displayName]);
-        return true;
-      }
-    }
-    return false;
-  }
-
-  /**
-   * This verifies that the passed constructor field initializer has compatible field and
-   * initializer expression types.
-   *
-   * @param node the constructor field initializer to test
-   * @param staticElement the static element from the name in the
-   *          [ConstructorFieldInitializer]
-   * @return `true` if and only if an error code is generated on the passed node
-   * @see CompileTimeErrorCode#CONST_FIELD_INITIALIZER_NOT_ASSIGNABLE
-   * @see StaticWarningCode#FIELD_INITIALIZER_NOT_ASSIGNABLE
-   */
-  bool _checkForFieldInitializerNotAssignable(ConstructorFieldInitializer node, Element staticElement) {
-    // prepare field element
-    if (staticElement is! FieldElement) {
-      return false;
-    }
-    FieldElement fieldElement = staticElement as FieldElement;
-    // prepare field type
-    DartType fieldType = fieldElement.type;
-    // prepare expression type
-    Expression expression = node.expression;
-    if (expression == null) {
-      return false;
-    }
-    // test the static type of the expression
-    DartType staticType = getStaticType(expression);
-    if (staticType == null) {
-      return false;
-    }
-    if (staticType.isAssignableTo(fieldType)) {
-      return false;
-    }
-    // report problem
-    if (_isEnclosingConstructorConst) {
-      // TODO(paulberry): this error should be based on the actual type of the constant, not the
-      // static type.  See dartbug.com/21119.
-      _errorReporter.reportTypeErrorForNode(CheckedModeCompileTimeErrorCode.CONST_FIELD_INITIALIZER_NOT_ASSIGNABLE, expression, [staticType, fieldType]);
-    }
-    _errorReporter.reportTypeErrorForNode(StaticWarningCode.FIELD_INITIALIZER_NOT_ASSIGNABLE, expression, [staticType, fieldType]);
-    return true;
-    // TODO(brianwilkerson) Define a hint corresponding to these errors and report it if appropriate.
-    //    // test the propagated type of the expression
-    //    Type propagatedType = expression.getPropagatedType();
-    //    if (propagatedType != null && propagatedType.isAssignableTo(fieldType)) {
-    //      return false;
-    //    }
-    //    // report problem
-    //    if (isEnclosingConstructorConst) {
-    //      errorReporter.reportTypeErrorForNode(
-    //          CompileTimeErrorCode.CONST_FIELD_INITIALIZER_NOT_ASSIGNABLE,
-    //          expression,
-    //          propagatedType == null ? staticType : propagatedType,
-    //          fieldType);
-    //    } else {
-    //      errorReporter.reportTypeErrorForNode(
-    //          StaticWarningCode.FIELD_INITIALIZER_NOT_ASSIGNABLE,
-    //          expression,
-    //          propagatedType == null ? staticType : propagatedType,
-    //          fieldType);
-    //    }
-    //    return true;
-  }
-
-  /**
-   * This verifies that the passed field formal parameter is in a constructor declaration.
-   *
-   * @param node the field formal parameter to test
-   * @return `true` if and only if an error code is generated on the passed node
-   * @see CompileTimeErrorCode#FIELD_INITIALIZER_OUTSIDE_CONSTRUCTOR
-   */
-  bool _checkForFieldInitializingFormalRedirectingConstructor(FieldFormalParameter node) {
-    ConstructorDeclaration constructor = node.getAncestor((node) => node is ConstructorDeclaration);
-    if (constructor == null) {
-      _errorReporter.reportErrorForNode(CompileTimeErrorCode.FIELD_INITIALIZER_OUTSIDE_CONSTRUCTOR, node, []);
-      return true;
-    }
-    // constructor cannot be a factory
-    if (constructor.factoryKeyword != null) {
-      _errorReporter.reportErrorForNode(CompileTimeErrorCode.FIELD_INITIALIZER_FACTORY_CONSTRUCTOR, node, []);
-      return true;
-    }
-    // constructor cannot have a redirection
-    for (ConstructorInitializer initializer in constructor.initializers) {
-      if (initializer is RedirectingConstructorInvocation) {
-        _errorReporter.reportErrorForNode(CompileTimeErrorCode.FIELD_INITIALIZER_REDIRECTING_CONSTRUCTOR, node, []);
-        return true;
-      }
-    }
-    // OK
-    return false;
-  }
-
-  /**
-   * This verifies that the passed variable declaration list has only initialized variables if the
-   * list is final or const. This method is called by
-   * [checkForFinalNotInitializedInClass],
-   * [visitTopLevelVariableDeclaration] and
-   * [visitVariableDeclarationStatement].
-   *
-   * @param node the class declaration to test
-   * @return `true` if and only if an error code is generated on the passed node
-   * @see CompileTimeErrorCode#CONST_NOT_INITIALIZED
-   * @see StaticWarningCode#FINAL_NOT_INITIALIZED
-   */
-  bool _checkForFinalNotInitialized(VariableDeclarationList node) {
-    if (_isInNativeClass) {
-      return false;
-    }
-    bool foundError = false;
-    if (!node.isSynthetic) {
-      NodeList<VariableDeclaration> variables = node.variables;
-      for (VariableDeclaration variable in variables) {
-        if (variable.initializer == null) {
-          if (node.isConst) {
-            _errorReporter.reportErrorForNode(CompileTimeErrorCode.CONST_NOT_INITIALIZED, variable.name, [variable.name.name]);
-          } else if (node.isFinal) {
-            _errorReporter.reportErrorForNode(StaticWarningCode.FINAL_NOT_INITIALIZED, variable.name, [variable.name.name]);
-          }
-          foundError = true;
-        }
-      }
-    }
-    return foundError;
-  }
-
-  /**
-   * This verifies that final fields that are declared, without any constructors in the enclosing
-   * class, are initialized. Cases in which there is at least one constructor are handled at the end
-   * of [checkForAllFinalInitializedErrorCodes].
-   *
-   * @param node the class declaration to test
-   * @return `true` if and only if an error code is generated on the passed node
-   * @see CompileTimeErrorCode#CONST_NOT_INITIALIZED
-   * @see StaticWarningCode#FINAL_NOT_INITIALIZED
-   */
-  bool _checkForFinalNotInitializedInClass(ClassDeclaration node) {
-    NodeList<ClassMember> classMembers = node.members;
-    for (ClassMember classMember in classMembers) {
-      if (classMember is ConstructorDeclaration) {
-        return false;
-      }
-    }
-    bool foundError = false;
-    for (ClassMember classMember in classMembers) {
-      if (classMember is FieldDeclaration
-          && _checkForFinalNotInitialized(classMember.fields)) {
-        foundError = true;
-      }
-    }
-    return foundError;
-  }
-
-  /**
-   * This verifies that the passed implements clause does not implement classes that are deferred.
-   *
-   * @param node the implements clause to test
-   * @return `true` if and only if an error code is generated on the passed node
-   * @see CompileTimeErrorCode#IMPLEMENTS_DEFERRED_CLASS
-   */
-  bool _checkForImplementsDeferredClass(ImplementsClause node) {
-    if (node == null) {
-      return false;
-    }
-    bool foundError = false;
-    for (TypeName type in node.interfaces) {
-      if (_checkForExtendsOrImplementsDeferredClass(
-          type,
-          CompileTimeErrorCode.IMPLEMENTS_DEFERRED_CLASS)) {
-        foundError = true;
-      }
-    }
-    return foundError;
-  }
-
-  /**
-   * This verifies that the passed implements clause does not implement classes such as 'num' or
-   * 'String'.
-   *
-   * @param node the implements clause to test
-   * @return `true` if and only if an error code is generated on the passed node
-   * @see CompileTimeErrorCode#IMPLEMENTS_DISALLOWED_CLASS
-   */
-  bool _checkForImplementsDisallowedClass(ImplementsClause node) {
-    if (node == null) {
-      return false;
-    }
-    bool foundError = false;
-    for (TypeName type in node.interfaces) {
-      if (_checkForExtendsOrImplementsDisallowedClass(
-          type,
-          CompileTimeErrorCode.IMPLEMENTS_DISALLOWED_CLASS)) {
-        foundError = true;
-      }
-    }
-    return foundError;
-  }
-
-  /**
-   * This verifies that if the passed identifier is part of constructor initializer, then it does
-   * not reference implicitly 'this' expression.
-   *
-   * @param node the simple identifier to test
-   * @return `true` if and only if an error code is generated on the passed node
-   * @see CompileTimeErrorCode#IMPLICIT_THIS_REFERENCE_IN_INITIALIZER
-   * @see CompileTimeErrorCode#INSTANCE_MEMBER_ACCESS_FROM_STATIC TODO(scheglov) rename thid method
-   */
-  bool _checkForImplicitThisReferenceInInitializer(SimpleIdentifier node) {
-    if (!_isInConstructorInitializer && !_isInStaticMethod && !_isInFactory && !_isInInstanceVariableInitializer && !_isInStaticVariableDeclaration) {
-      return false;
-    }
-    // prepare element
-    Element element = node.staticElement;
-    if (!(element is MethodElement || element is PropertyAccessorElement)) {
-      return false;
-    }
-    // static element
-    ExecutableElement executableElement = element as ExecutableElement;
-    if (executableElement.isStatic) {
-      return false;
-    }
-    // not a class member
-    Element enclosingElement = element.enclosingElement;
-    if (enclosingElement is! ClassElement) {
-      return false;
-    }
-    // comment
-    AstNode parent = node.parent;
-    if (parent is CommentReference) {
-      return false;
-    }
-    // qualified method invocation
-    if (parent is MethodInvocation) {
-      MethodInvocation invocation = parent;
-      if (identical(invocation.methodName, node) && invocation.realTarget != null) {
-        return false;
-      }
-    }
-    // qualified property access
-    if (parent is PropertyAccess) {
-      PropertyAccess access = parent;
-      if (identical(access.propertyName, node) && access.realTarget != null) {
-        return false;
-      }
-    }
-    if (parent is PrefixedIdentifier) {
-      PrefixedIdentifier prefixed = parent;
-      if (identical(prefixed.identifier, node)) {
-        return false;
-      }
-    }
-    // report problem
-    if (_isInStaticMethod) {
-      _errorReporter.reportErrorForNode(CompileTimeErrorCode.INSTANCE_MEMBER_ACCESS_FROM_STATIC, node, []);
-    } else if (_isInFactory) {
-      _errorReporter.reportErrorForNode(CompileTimeErrorCode.INSTANCE_MEMBER_ACCESS_FROM_FACTORY, node, []);
-    } else {
-      _errorReporter.reportErrorForNode(CompileTimeErrorCode.IMPLICIT_THIS_REFERENCE_IN_INITIALIZER, node, []);
-    }
-    return true;
-  }
-
-  /**
-   * This verifies the passed import has unique name among other imported libraries.
-   *
-   * @param node the import directive to evaluate
-   * @param importElement the [ImportElement] retrieved from the node, if the element in the
-   *          node was `null`, then this method is not called
-   * @return `true` if and only if an error code is generated on the passed node
-   * @see CompileTimeErrorCode#IMPORT_DUPLICATED_LIBRARY_NAME
-   */
-  bool _checkForImportDuplicateLibraryName(ImportDirective node, ImportElement importElement) {
-    // prepare imported library
-    LibraryElement nodeLibrary = importElement.importedLibrary;
-    if (nodeLibrary == null) {
-      return false;
-    }
-    String name = nodeLibrary.name;
-    // check if there is other imported library with the same name
-    LibraryElement prevLibrary = _nameToImportElement[name];
-    if (prevLibrary != null) {
-      if (prevLibrary != nodeLibrary) {
-        _errorReporter.reportErrorForNode(StaticWarningCode.IMPORT_DUPLICATED_LIBRARY_NAME, node, [
-            prevLibrary.definingCompilationUnit.displayName,
-            nodeLibrary.definingCompilationUnit.displayName,
-            name]);
-        return true;
-      }
-    } else {
-      _nameToImportElement[name] = nodeLibrary;
-    }
-    // OK
-    return false;
-  }
-
-  /**
-   * Check that if the visiting library is not system, then any passed library should not be SDK
-   * internal library.
-   *
-   * @param node the import directive to evaluate
-   * @param importElement the [ImportElement] retrieved from the node, if the element in the
-   *          node was `null`, then this method is not called
-   * @return `true` if and only if an error code is generated on the passed node
-   * @see CompileTimeErrorCode#IMPORT_INTERNAL_LIBRARY
-   */
-  bool _checkForImportInternalLibrary(ImportDirective node, ImportElement importElement) {
-    if (_isInSystemLibrary) {
-      return false;
-    }
-    // should be private
-    DartSdk sdk = _currentLibrary.context.sourceFactory.dartSdk;
-    String uri = importElement.uri;
-    SdkLibrary sdkLibrary = sdk.getSdkLibrary(uri);
-    if (sdkLibrary == null) {
-      return false;
-    }
-    if (!sdkLibrary.isInternal) {
-      return false;
-    }
-    // report problem
-    _errorReporter.reportErrorForNode(CompileTimeErrorCode.IMPORT_INTERNAL_LIBRARY, node, [node.uri]);
-    return true;
-  }
-
-  /**
-   * For each class declaration, this method is called which verifies that all inherited members are
-   * inherited consistently.
-   *
-   * @return `true` if and only if an error code is generated on the passed node
-   * @see StaticTypeWarningCode#INCONSISTENT_METHOD_INHERITANCE
-   */
-  bool _checkForInconsistentMethodInheritance() {
-    // Ensure that the inheritance manager has a chance to generate all errors we may care about,
-    // note that we ensure that the interfaces data since there are no errors.
-    _inheritanceManager.getMapOfMembersInheritedFromInterfaces(_enclosingClass);
-    HashSet<AnalysisError> errors = _inheritanceManager.getErrors(_enclosingClass);
-    if (errors == null || errors.isEmpty) {
-      return false;
-    }
-    for (AnalysisError error in errors) {
-      _errorReporter.reportError(error);
-    }
-    return true;
-  }
-
-  /**
-   * This checks the given "typeReference" is not a type reference and that then the "name" is
-   * reference to an instance member.
-   *
-   * @param typeReference the resolved [ClassElement] of the left hand side of the expression,
-   *          or `null`, aka, the class element of 'C' in 'C.x', see
-   *          [getTypeReference]
-   * @param name the accessed name to evaluate
-   * @return `true` if and only if an error code is generated on the passed node
-   * @see StaticTypeWarningCode#INSTANCE_ACCESS_TO_STATIC_MEMBER
-   */
-  bool _checkForInstanceAccessToStaticMember(ClassElement typeReference, SimpleIdentifier name) {
-    // OK, in comment
-    if (_isInComment) {
-      return false;
-    }
-    // OK, target is a type
-    if (typeReference != null) {
-      return false;
-    }
-    // prepare member Element
-    Element element = name.staticElement;
-    if (element is! ExecutableElement) {
-      return false;
-    }
-    ExecutableElement executableElement = element as ExecutableElement;
-    // OK, top-level element
-    if (executableElement.enclosingElement is! ClassElement) {
-      return false;
-    }
-    // OK, instance member
-    if (!executableElement.isStatic) {
-      return false;
-    }
-    // report problem
-    _errorReporter.reportErrorForNode(StaticTypeWarningCode.INSTANCE_ACCESS_TO_STATIC_MEMBER, name, [name.name]);
-    return true;
-  }
-
-  /**
-   * This checks whether the given [executableElement] collides with the name of a static
-   * method in one of its superclasses, and reports the appropriate warning if it does.
-   *
-   * @param executableElement the method to check.
-   * @param errorNameTarget the node to report problems on.
-   * @return `true` if and only if a warning was generated.
-   * @see StaticTypeWarningCode#INSTANCE_METHOD_NAME_COLLIDES_WITH_SUPERCLASS_STATIC
-   */
-  bool _checkForInstanceMethodNameCollidesWithSuperclassStatic(ExecutableElement executableElement, SimpleIdentifier errorNameTarget) {
-    String executableElementName = executableElement.name;
-    if (executableElement is! PropertyAccessorElement && !executableElement.isOperator) {
-      HashSet<ClassElement> visitedClasses = new HashSet<ClassElement>();
-      InterfaceType superclassType = _enclosingClass.supertype;
-      ClassElement superclassElement = superclassType == null ? null : superclassType.element;
-      bool executableElementPrivate = Identifier.isPrivateName(executableElementName);
-      while (superclassElement != null && !visitedClasses.contains(superclassElement)) {
-        visitedClasses.add(superclassElement);
-        LibraryElement superclassLibrary = superclassElement.library;
-        // Check fields.
-        List<FieldElement> fieldElts = superclassElement.fields;
-        for (FieldElement fieldElt in fieldElts) {
-          // We need the same name.
-          if (fieldElt.name != executableElementName) {
-            continue;
-          }
-          // Ignore if private in a different library - cannot collide.
-          if (executableElementPrivate && _currentLibrary != superclassLibrary) {
-            continue;
-          }
-          // instance vs. static
-          if (fieldElt.isStatic) {
-            _errorReporter.reportErrorForNode(StaticWarningCode.INSTANCE_METHOD_NAME_COLLIDES_WITH_SUPERCLASS_STATIC, errorNameTarget, [
-                executableElementName,
-                fieldElt.enclosingElement.displayName]);
-            return true;
-          }
-        }
-        // Check methods.
-        List<MethodElement> methodElements = superclassElement.methods;
-        for (MethodElement methodElement in methodElements) {
-          // We need the same name.
-          if (methodElement.name != executableElementName) {
-            continue;
-          }
-          // Ignore if private in a different library - cannot collide.
-          if (executableElementPrivate && _currentLibrary != superclassLibrary) {
-            continue;
-          }
-          // instance vs. static
-          if (methodElement.isStatic) {
-            _errorReporter.reportErrorForNode(StaticWarningCode.INSTANCE_METHOD_NAME_COLLIDES_WITH_SUPERCLASS_STATIC, errorNameTarget, [
-                executableElementName,
-                methodElement.enclosingElement.displayName]);
-            return true;
-          }
-        }
-        superclassType = superclassElement.supertype;
-        superclassElement = superclassType == null ? null : superclassType.element;
-      }
-    }
-    return false;
-  }
-
-  /**
-   * This verifies that an 'int' can be assigned to the parameter corresponding to the given
-   * expression. This is used for prefix and postfix expressions where the argument value is
-   * implicit.
-   *
-   * @param argument the expression to which the operator is being applied
-   * @return `true` if and only if an error code is generated on the passed node
-   * @see StaticWarningCode#ARGUMENT_TYPE_NOT_ASSIGNABLE
-   */
-  bool _checkForIntNotAssignable(Expression argument) {
-    if (argument == null) {
-      return false;
-    }
-    ParameterElement staticParameterElement = argument.staticParameterElement;
-    DartType staticParameterType = staticParameterElement == null ? null : staticParameterElement.type;
-    return _checkForArgumentTypeNotAssignable(argument, staticParameterType, _intType, StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE);
-  }
-
-  /**
-   * This verifies that the passed [Annotation] isn't defined in a deferred library.
-   *
-   * @param node the [Annotation]
-   * @return `true` if and only if an error code is generated on the passed node
-   * @see CompileTimeErrorCode.INVALID_ANNOTATION_FROM_DEFERRED_LIBRARY
-   */
-  bool _checkForInvalidAnnotationFromDeferredLibrary(Annotation node) {
-    Identifier nameIdentifier = node.name;
-    if (nameIdentifier is PrefixedIdentifier) {
-      if (nameIdentifier.isDeferred) {
-        _errorReporter.reportErrorForNode(CompileTimeErrorCode.INVALID_ANNOTATION_FROM_DEFERRED_LIBRARY, node.name, []);
-        return true;
-      }
-    }
-    return false;
-  }
-
-  /**
-   * This verifies that the passed left hand side and right hand side represent a valid assignment.
-   *
-   * @param lhs the left hand side expression
-   * @param rhs the right hand side expression
-   * @return `true` if and only if an error code is generated on the passed node
-   * @see StaticTypeWarningCode#INVALID_ASSIGNMENT
-   */
-  bool _checkForInvalidAssignment(Expression lhs, Expression rhs) {
-    if (lhs == null || rhs == null) {
-      return false;
-    }
-    VariableElement leftVariableElement = getVariableElement(lhs);
-    DartType leftType = (leftVariableElement == null) ? getStaticType(lhs) : leftVariableElement.type;
-    DartType staticRightType = getStaticType(rhs);
-    if (!staticRightType.isAssignableTo(leftType)) {
-      _errorReporter.reportTypeErrorForNode(StaticTypeWarningCode.INVALID_ASSIGNMENT, rhs, [staticRightType, leftType]);
-      return true;
-    }
-    return false;
-  }
-
-  /**
-   * Given an assignment using a compound assignment operator, this verifies that the given
-   * assignment is valid.
-   *
-   * @param node the assignment expression being tested
-   * @param lhs the left hand side expression
-   * @param rhs the right hand side expression
-   * @return `true` if and only if an error code is generated on the passed node
-   * @see StaticTypeWarningCode#INVALID_ASSIGNMENT
-   */
-  bool _checkForInvalidCompoundAssignment(AssignmentExpression node, Expression lhs, Expression rhs) {
-    if (lhs == null) {
-      return false;
-    }
-    VariableElement leftVariableElement = getVariableElement(lhs);
-    DartType leftType = (leftVariableElement == null) ? getStaticType(lhs) : leftVariableElement.type;
-    MethodElement invokedMethod = node.staticElement;
-    if (invokedMethod == null) {
-      return false;
-    }
-    DartType rightType = invokedMethod.type.returnType;
-    if (leftType == null || rightType == null) {
-      return false;
-    }
-    if (!rightType.isAssignableTo(leftType)) {
-      _errorReporter.reportTypeErrorForNode(StaticTypeWarningCode.INVALID_ASSIGNMENT, rhs, [rightType, leftType]);
-      return true;
-    }
-    return false;
-  }
-
-  /**
-   * Check the given initializer to ensure that the field being initialized is a valid field.
-   *
-   * @param node the field initializer being checked
-   * @param fieldName the field name from the [ConstructorFieldInitializer]
-   * @param staticElement the static element from the name in the
-   *          [ConstructorFieldInitializer]
-   */
-  void _checkForInvalidField(ConstructorFieldInitializer node, SimpleIdentifier fieldName, Element staticElement) {
-    if (staticElement is FieldElement) {
-      FieldElement fieldElement = staticElement;
-      if (fieldElement.isSynthetic) {
-        _errorReporter.reportErrorForNode(CompileTimeErrorCode.INITIALIZER_FOR_NON_EXISTENT_FIELD, node, [fieldName]);
-      } else if (fieldElement.isStatic) {
-        _errorReporter.reportErrorForNode(CompileTimeErrorCode.INITIALIZER_FOR_STATIC_FIELD, node, [fieldName]);
-      }
-    } else {
-      _errorReporter.reportErrorForNode(CompileTimeErrorCode.INITIALIZER_FOR_NON_EXISTENT_FIELD, node, [fieldName]);
-      return;
-    }
-  }
-
-  /**
-   * Check to see whether the given function body has a modifier associated with it, and report it
-   * as an error if it does.
-   *
-   * @param body the function body being checked
-   * @param errorCode the error code to be reported if a modifier is found
-   * @return `true` if an error was reported
-   */
-  bool _checkForInvalidModifierOnBody(FunctionBody body, CompileTimeErrorCode errorCode) {
-    sc.Token keyword = body.keyword;
-    if (keyword != null) {
-      _errorReporter.reportErrorForToken(errorCode, keyword, [keyword.lexeme]);
-      return true;
-    }
-    return false;
-  }
-
-  /**
-   * This verifies that the usage of the passed 'this' is valid.
-   *
-   * @param node the 'this' expression to evaluate
-   * @return `true` if and only if an error code is generated on the passed node
-   * @see CompileTimeErrorCode#INVALID_REFERENCE_TO_THIS
-   */
-  bool _checkForInvalidReferenceToThis(ThisExpression node) {
-    if (!_isThisInValidContext(node)) {
-      _errorReporter.reportErrorForNode(CompileTimeErrorCode.INVALID_REFERENCE_TO_THIS, node, []);
-      return true;
-    }
-    return false;
-  }
-
-  /**
-   * Checks to ensure that the passed [ListLiteral] or [MapLiteral] does not have a type
-   * parameter as a type argument.
-   *
-   * @param arguments a non-`null`, non-empty [TypeName] node list from the respective
-   *          [ListLiteral] or [MapLiteral]
-   * @param errorCode either [CompileTimeErrorCode#INVALID_TYPE_ARGUMENT_IN_CONST_LIST] or
-   *          [CompileTimeErrorCode#INVALID_TYPE_ARGUMENT_IN_CONST_MAP]
-   * @return `true` if and only if an error code is generated on the passed node
-   */
-  bool _checkForInvalidTypeArgumentInConstTypedLiteral(NodeList<TypeName> arguments, ErrorCode errorCode) {
-    bool foundError = false;
-    for (TypeName typeName in arguments) {
-      if (typeName.type is TypeParameterType) {
-        _errorReporter.reportErrorForNode(errorCode, typeName, [typeName.name]);
-        foundError = true;
-      }
-    }
-    return foundError;
-  }
-
-  /**
-   * This verifies that the elements given [ListLiteral] are subtypes of the specified element
-   * type.
-   *
-   * @param node the list literal to evaluate
-   * @param typeArguments the type arguments, always non-`null`
-   * @return `true` if and only if an error code is generated on the passed node
-   * @see CompileTimeErrorCode#LIST_ELEMENT_TYPE_NOT_ASSIGNABLE
-   * @see StaticWarningCode#LIST_ELEMENT_TYPE_NOT_ASSIGNABLE
-   */
-  bool _checkForListElementTypeNotAssignable(ListLiteral node, TypeArgumentList typeArguments) {
-    NodeList<TypeName> typeNames = typeArguments.arguments;
-    if (typeNames.length < 1) {
-      return false;
-    }
-    DartType listElementType = typeNames[0].type;
-    // Check every list element.
-    bool hasProblems = false;
-    for (Expression element in node.elements) {
-      if (node.constKeyword != null) {
-        // TODO(paulberry): this error should be based on the actual type of the
-        // list element, not the static type.  See dartbug.com/21119.
-        if (_checkForArgumentTypeNotAssignableWithExpectedTypes(
-            element,
-            listElementType,
-            CheckedModeCompileTimeErrorCode.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE)) {
-          hasProblems = true;
-        }
-      }
-      if (_checkForArgumentTypeNotAssignableWithExpectedTypes(
-          element,
-          listElementType,
-          StaticWarningCode.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE)) {
-        hasProblems = true;
-      }
-    }
-    return hasProblems;
-  }
-
-  /**
-   * This verifies that the key/value of entries of the given [MapLiteral] are subtypes of the
-   * key/value types specified in the type arguments.
-   *
-   * @param node the map literal to evaluate
-   * @param typeArguments the type arguments, always non-`null`
-   * @return `true` if and only if an error code is generated on the passed node
-   * @see CompileTimeErrorCode#MAP_KEY_TYPE_NOT_ASSIGNABLE
-   * @see CompileTimeErrorCode#MAP_VALUE_TYPE_NOT_ASSIGNABLE
-   * @see StaticWarningCode#MAP_KEY_TYPE_NOT_ASSIGNABLE
-   * @see StaticWarningCode#MAP_VALUE_TYPE_NOT_ASSIGNABLE
-   */
-  bool _checkForMapTypeNotAssignable(MapLiteral node, TypeArgumentList typeArguments) {
-    // Prepare maps key/value types.
-    NodeList<TypeName> typeNames = typeArguments.arguments;
-    if (typeNames.length < 2) {
-      return false;
-    }
-    DartType keyType = typeNames[0].type;
-    DartType valueType = typeNames[1].type;
-    // Check every map entry.
-    bool hasProblems = false;
-    NodeList<MapLiteralEntry> entries = node.entries;
-    for (MapLiteralEntry entry in entries) {
-      Expression key = entry.key;
-      Expression value = entry.value;
-      if (node.constKeyword != null) {
-        // TODO(paulberry): this error should be based on the actual type of the
-        // list element, not the static type.  See dartbug.com/21119.
-        if (_checkForArgumentTypeNotAssignableWithExpectedTypes(
-            key,
-            keyType,
-            CheckedModeCompileTimeErrorCode.MAP_KEY_TYPE_NOT_ASSIGNABLE)) {
-          hasProblems = true;
-        }
-        if (_checkForArgumentTypeNotAssignableWithExpectedTypes(
-            value,
-            valueType,
-            CheckedModeCompileTimeErrorCode.MAP_VALUE_TYPE_NOT_ASSIGNABLE)) {
-          hasProblems = true;
-        }
-      }
-      if (_checkForArgumentTypeNotAssignableWithExpectedTypes(
-          key,
-          keyType,
-          StaticWarningCode.MAP_KEY_TYPE_NOT_ASSIGNABLE)) {
-        hasProblems = true;
-      }
-      if (_checkForArgumentTypeNotAssignableWithExpectedTypes(
-          value,
-          valueType,
-          StaticWarningCode.MAP_VALUE_TYPE_NOT_ASSIGNABLE)) {
-        hasProblems = true;
-      }
-    }
-    return hasProblems;
-  }
-
-  /**
-   * This verifies that the [enclosingClass] does not define members with the same name as
-   * the enclosing class.
-   *
-   * @return `true` if and only if an error code is generated on the passed node
-   * @see CompileTimeErrorCode#MEMBER_WITH_CLASS_NAME
-   */
-  bool _checkForMemberWithClassName() {
-    if (_enclosingClass == null) {
-      return false;
-    }
-    String className = _enclosingClass.name;
-    if (className == null) {
-      return false;
-    }
-    bool problemReported = false;
-    // check accessors
-    for (PropertyAccessorElement accessor in _enclosingClass.accessors) {
-      if (className == accessor.name) {
-        _errorReporter.reportErrorForOffset(CompileTimeErrorCode.MEMBER_WITH_CLASS_NAME, accessor.nameOffset, className.length, []);
-        problemReported = true;
-      }
-    }
-    // don't check methods, they would be constructors
-    // done
-    return problemReported;
-  }
-
-  /**
-   * Check to make sure that all similarly typed accessors are of the same type (including inherited
-   * accessors).
-   *
-   * @param node the accessor currently being visited
-   * @return `true` if and only if an error code is generated on the passed node
-   * @see StaticWarningCode.MISMATCHED_GETTER_AND_SETTER_TYPES
-   * @see StaticWarningCode.MISMATCHED_GETTER_AND_SETTER_TYPES_FROM_SUPERTYPE
-   */
-  bool _checkForMismatchedAccessorTypes(Declaration accessorDeclaration, String accessorTextName) {
-    ExecutableElement accessorElement = accessorDeclaration.element as ExecutableElement;
-    if (accessorElement is! PropertyAccessorElement) {
-      return false;
-    }
-    PropertyAccessorElement propertyAccessorElement = accessorElement as PropertyAccessorElement;
-    PropertyAccessorElement counterpartAccessor = null;
-    ClassElement enclosingClassForCounterpart = null;
-    if (propertyAccessorElement.isGetter) {
-      counterpartAccessor = propertyAccessorElement.correspondingSetter;
-    } else {
-      counterpartAccessor = propertyAccessorElement.correspondingGetter;
-      // If the setter and getter are in the same enclosing element, return, this prevents having
-      // MISMATCHED_GETTER_AND_SETTER_TYPES reported twice.
-      if (counterpartAccessor != null && identical(counterpartAccessor.enclosingElement, propertyAccessorElement.enclosingElement)) {
-        return false;
-      }
-    }
-    if (counterpartAccessor == null) {
-      // If the accessor is declared in a class, check the superclasses.
-      if (_enclosingClass != null) {
-        // Figure out the correct identifier to lookup in the inheritance graph, if 'x', then 'x=',
-        // or if 'x=', then 'x'.
-        String lookupIdentifier = propertyAccessorElement.name;
-        if (StringUtilities.endsWithChar(lookupIdentifier, 0x3D)) {
-          lookupIdentifier = lookupIdentifier.substring(0, lookupIdentifier.length - 1);
-        } else {
-          lookupIdentifier += "=";
-        }
-        // lookup with the identifier.
-        ExecutableElement elementFromInheritance = _inheritanceManager.lookupInheritance(_enclosingClass, lookupIdentifier);
-        // Verify that we found something, and that it is an accessor
-        if (elementFromInheritance != null && elementFromInheritance is PropertyAccessorElement) {
-          enclosingClassForCounterpart = elementFromInheritance.enclosingElement as ClassElement;
-          counterpartAccessor = elementFromInheritance;
-        }
-      }
-      if (counterpartAccessor == null) {
-        return false;
-      }
-    }
-    // Default of null == no accessor or no type (dynamic)
-    DartType getterType = null;
-    DartType setterType = null;
-    // Get an existing counterpart accessor if any.
-    if (propertyAccessorElement.isGetter) {
-      getterType = _getGetterType(propertyAccessorElement);
-      setterType = _getSetterType(counterpartAccessor);
-    } else if (propertyAccessorElement.isSetter) {
-      setterType = _getSetterType(propertyAccessorElement);
-      getterType = _getGetterType(counterpartAccessor);
-    }
-    // If either types are not assignable to each other, report an error (if the getter is null,
-    // it is dynamic which is assignable to everything).
-    if (setterType != null && getterType != null && !getterType.isAssignableTo(setterType)) {
-      if (enclosingClassForCounterpart == null) {
-        _errorReporter.reportTypeErrorForNode(StaticWarningCode.MISMATCHED_GETTER_AND_SETTER_TYPES, accessorDeclaration, [accessorTextName, setterType, getterType]);
-        return true;
-      } else {
-        _errorReporter.reportTypeErrorForNode(StaticWarningCode.MISMATCHED_GETTER_AND_SETTER_TYPES_FROM_SUPERTYPE, accessorDeclaration, [
-            accessorTextName,
-            setterType,
-            getterType,
-            enclosingClassForCounterpart.displayName]);
-      }
-    }
-    return false;
-  }
-
-  /**
-   * Check to make sure that switch statements whose static type is an enum type either have a
-   * default case or include all of the enum constants.
-   *
-   * @param statement the switch statement to check
-   * @return `true` if and only if an error code is generated on the passed node
-   */
-  bool _checkForMissingEnumConstantInSwitch(SwitchStatement statement) {
-    // TODO(brianwilkerson) This needs to be checked after constant values have been computed.
-    Expression expression = statement.expression;
-    DartType expressionType = getStaticType(expression);
-    if (expressionType == null) {
-      return false;
-    }
-    Element expressionElement = expressionType.element;
-    if (expressionElement is! ClassElement) {
-      return false;
-    }
-    ClassElement classElement = expressionElement as ClassElement;
-    if (!classElement.isEnum) {
-      return false;
-    }
-    List<String> constantNames = new List<String>();
-    List<FieldElement> fields = classElement.fields;
-    int fieldCount = fields.length;
-    for (int i = 0; i < fieldCount; i++) {
-      FieldElement field = fields[i];
-      if (field.isStatic && !field.isSynthetic) {
-        constantNames.add(field.name);
-      }
-    }
-    NodeList<SwitchMember> members = statement.members;
-    int memberCount = members.length;
-    for (int i = 0; i < memberCount; i++) {
-      SwitchMember member = members[i];
-      if (member is SwitchDefault) {
-        return false;
-      }
-      String constantName = _getConstantName((member as SwitchCase).expression);
-      if (constantName != null) {
-        constantNames.remove(constantName);
-      }
-    }
-    int nameCount = constantNames.length;
-    if (nameCount == 0) {
-      return false;
-    }
-    for (int i = 0; i < nameCount; i++) {
-      _errorReporter.reportErrorForNode(CompileTimeErrorCode.MISSING_ENUM_CONSTANT_IN_SWITCH, statement, [constantNames[i]]);
-    }
-    return true;
-  }
-
-  /**
-   * This verifies that the given function body does not contain return statements that both have
-   * and do not have return values.
-   *
-   * @param node the function body being tested
-   * @return `true` if and only if an error code is generated on the passed node
-   * @see StaticWarningCode#MIXED_RETURN_TYPES
-   */
-  bool _checkForMixedReturns(BlockFunctionBody node) {
-    if (_hasReturnWithoutValue) {
-      return false;
-    }
-    int withCount = _returnsWith.length;
-    int withoutCount = _returnsWithout.length;
-    if (withCount > 0 && withoutCount > 0) {
-      for (int i = 0; i < withCount; i++) {
-        _errorReporter.reportErrorForToken(StaticWarningCode.MIXED_RETURN_TYPES, _returnsWith[i].keyword, []);
-      }
-      for (int i = 0; i < withoutCount; i++) {
-        _errorReporter.reportErrorForToken(StaticWarningCode.MIXED_RETURN_TYPES, _returnsWithout[i].keyword, []);
-      }
-      return true;
-    }
-    return false;
-  }
-
-  /**
-   * This verifies that the passed mixin does not have an explicitly declared constructor.
-   *
-   * @param mixinName the node to report problem on
-   * @param mixinElement the mixing to evaluate
-   * @return `true` if and only if an error code is generated on the passed node
-   * @see CompileTimeErrorCode#MIXIN_DECLARES_CONSTRUCTOR
-   */
-  bool _checkForMixinDeclaresConstructor(TypeName mixinName, ClassElement mixinElement) {
-    for (ConstructorElement constructor in mixinElement.constructors) {
-      if (!constructor.isSynthetic && !constructor.isFactory) {
-        _errorReporter.reportErrorForNode(CompileTimeErrorCode.MIXIN_DECLARES_CONSTRUCTOR, mixinName, [mixinElement.name]);
-        return true;
-      }
-    }
-    return false;
-  }
-
-  /**
-   * This verifies that the passed mixin has the 'Object' superclass.
-   *
-   * @param mixinName the node to report problem on
-   * @param mixinElement the mixing to evaluate
-   * @return `true` if and only if an error code is generated on the passed node
-   * @see CompileTimeErrorCode#MIXIN_INHERITS_FROM_NOT_OBJECT
-   */
-  bool _checkForMixinInheritsNotFromObject(TypeName mixinName, ClassElement mixinElement) {
-    InterfaceType mixinSupertype = mixinElement.supertype;
-    if (mixinSupertype != null) {
-      if (!mixinSupertype.isObject || !mixinElement.isTypedef && mixinElement.mixins.length != 0) {
-        _errorReporter.reportErrorForNode(CompileTimeErrorCode.MIXIN_INHERITS_FROM_NOT_OBJECT, mixinName, [mixinElement.name]);
-        return true;
-      }
-    }
-    return false;
-  }
-
-  /**
-   * This verifies that the passed mixin does not reference 'super'.
-   *
-   * @param mixinName the node to report problem on
-   * @param mixinElement the mixing to evaluate
-   * @return `true` if and only if an error code is generated on the passed node
-   * @see CompileTimeErrorCode#MIXIN_REFERENCES_SUPER
-   */
-  bool _checkForMixinReferencesSuper(TypeName mixinName, ClassElement mixinElement) {
-    if (mixinElement.hasReferenceToSuper) {
-      _errorReporter.reportErrorForNode(CompileTimeErrorCode.MIXIN_REFERENCES_SUPER, mixinName, [mixinElement.name]);
-    }
-    return false;
-  }
-
-  /**
-   * This verifies that the passed constructor has at most one 'super' initializer.
-   *
-   * @param node the constructor declaration to evaluate
-   * @return `true` if and only if an error code is generated on the passed node
-   * @see CompileTimeErrorCode#MULTIPLE_SUPER_INITIALIZERS
-   */
-  bool _checkForMultipleSuperInitializers(ConstructorDeclaration node) {
-    int numSuperInitializers = 0;
-    for (ConstructorInitializer initializer in node.initializers) {
-      if (initializer is SuperConstructorInvocation) {
-        numSuperInitializers++;
-        if (numSuperInitializers > 1) {
-          _errorReporter.reportErrorForNode(CompileTimeErrorCode.MULTIPLE_SUPER_INITIALIZERS, initializer, []);
-        }
-      }
-    }
-    return numSuperInitializers > 0;
-  }
-
-  /**
-   * Checks to ensure that native function bodies can only in SDK code.
-   *
-   * @param node the native function body to test
-   * @return `true` if and only if an error code is generated on the passed node
-   * @see ParserErrorCode#NATIVE_FUNCTION_BODY_IN_NON_SDK_CODE
-   */
-  bool _checkForNativeFunctionBodyInNonSDKCode(NativeFunctionBody node) {
-    if (!_isInSystemLibrary && !_hasExtUri) {
-      _errorReporter.reportErrorForNode(ParserErrorCode.NATIVE_FUNCTION_BODY_IN_NON_SDK_CODE, node, []);
-      return true;
-    }
-    return false;
-  }
-
-  /**
-   * This verifies that the passed 'new' instance creation expression invokes existing constructor.
-   *
-   * This method assumes that the instance creation was tested to be 'new' before being called.
-   *
-   * @param node the instance creation expression to evaluate
-   * @param constructorName the constructor name, always non-`null`
-   * @param typeName the name of the type defining the constructor, always non-`null`
-   * @return `true` if and only if an error code is generated on the passed node
-   * @see StaticWarningCode#NEW_WITH_UNDEFINED_CONSTRUCTOR
-   */
-  bool _checkForNewWithUndefinedConstructor(InstanceCreationExpression node, ConstructorName constructorName, TypeName typeName) {
-    // OK if resolved
-    if (node.staticElement != null) {
-      return false;
-    }
-    DartType type = typeName.type;
-    if (type is InterfaceType) {
-      ClassElement element = type.element;
-      if (element != null && element.isEnum) {
-        // We have already reported the error.
-        return false;
-      }
-    }
-    // prepare class name
-    Identifier className = typeName.name;
-    // report as named or default constructor absence
-    SimpleIdentifier name = constructorName.name;
-    if (name != null) {
-      _errorReporter.reportErrorForNode(StaticWarningCode.NEW_WITH_UNDEFINED_CONSTRUCTOR, name, [className, name]);
-    } else {
-      _errorReporter.reportErrorForNode(StaticWarningCode.NEW_WITH_UNDEFINED_CONSTRUCTOR_DEFAULT, constructorName, [className]);
-    }
-    return true;
-  }
-
-  /**
-   * This checks that if the passed class declaration implicitly calls default constructor of its
-   * superclass, there should be such default constructor - implicit or explicit.
-   *
-   * @param node the [ClassDeclaration] to evaluate
-   * @return `true` if and only if an error code is generated on the passed node
-   * @see CompileTimeErrorCode#NO_DEFAULT_SUPER_CONSTRUCTOR_IMPLICIT
-   */
-  bool _checkForNoDefaultSuperConstructorImplicit(ClassDeclaration node) {
-    // do nothing if there is explicit constructor
-    List<ConstructorElement> constructors = _enclosingClass.constructors;
-    if (!constructors[0].isSynthetic) {
-      return false;
-    }
-    // prepare super
-    InterfaceType superType = _enclosingClass.supertype;
-    if (superType == null) {
-      return false;
-    }
-    ClassElement superElement = superType.element;
-    // try to find default generative super constructor
-    ConstructorElement superUnnamedConstructor = superElement.unnamedConstructor;
-    if (superUnnamedConstructor != null) {
-      if (superUnnamedConstructor.isFactory) {
-        _errorReporter.reportErrorForNode(CompileTimeErrorCode.NON_GENERATIVE_CONSTRUCTOR, node.name, [superUnnamedConstructor]);
-        return true;
-      }
-      if (superUnnamedConstructor.isDefaultConstructor) {
-        return true;
-      }
-    }
-    // report problem
-    _errorReporter.reportErrorForNode(CompileTimeErrorCode.NO_DEFAULT_SUPER_CONSTRUCTOR_IMPLICIT, node.name, [superType.displayName]);
-    return true;
-  }
-
-  /**
-   * This checks that passed class declaration overrides all members required by its superclasses
-   * and interfaces.
-   *
-   * @param classNameNode the [SimpleIdentifier] to be used if there is a violation, this is
-   *          either the named from the [ClassDeclaration] or from the [ClassTypeAlias].
-   * @return `true` if and only if an error code is generated on the passed node
-   * @see StaticWarningCode#NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE
-   * @see StaticWarningCode#NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_TWO
-   * @see StaticWarningCode#NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_THREE
-   * @see StaticWarningCode#NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_FOUR
-   * @see StaticWarningCode#NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_FIVE_PLUS
-   */
-  bool _checkForNonAbstractClassInheritsAbstractMember(SimpleIdentifier classNameNode) {
-    if (_enclosingClass.isAbstract) {
-      return false;
-    }
-    //
-    // Store in local sets the set of all method and accessor names
-    //
-    List<MethodElement> methods = _enclosingClass.methods;
-    for (MethodElement method in methods) {
-      String methodName = method.name;
-      // If the enclosing class declares the method noSuchMethod(), then return.
-      // From Spec:  It is a static warning if a concrete class does not have an implementation for
-      // a method in any of its superinterfaces unless it declares its own noSuchMethod
-      // method (7.10).
-      if (methodName == FunctionElement.NO_SUCH_METHOD_METHOD_NAME) {
-        return false;
-      }
-    }
-    HashSet<ExecutableElement> missingOverrides = new HashSet<ExecutableElement>();
-    //
-    // Loop through the set of all executable elements declared in the implicit interface.
-    //
-    MemberMap membersInheritedFromInterfaces = _inheritanceManager.getMapOfMembersInheritedFromInterfaces(_enclosingClass);
-    MemberMap membersInheritedFromSuperclasses = _inheritanceManager.getMapOfMembersInheritedFromClasses(_enclosingClass);
-    for (int i = 0; i < membersInheritedFromInterfaces.size; i++) {
-      String memberName = membersInheritedFromInterfaces.getKey(i);
-      ExecutableElement executableElt = membersInheritedFromInterfaces.getValue(i);
-      if (memberName == null) {
-        break;
-      }
-      // If the element is not synthetic and can be determined to be defined in Object, skip it.
-      if (executableElt.enclosingElement != null && (executableElt.enclosingElement as ClassElement).type.isObject) {
-        continue;
-      }
-      // Check to see if some element is in local enclosing class that matches the name of the
-      // required member.
-      if (_isMemberInClassOrMixin(executableElt, _enclosingClass)) {
-        // We do not have to verify that this implementation of the found method matches the
-        // required function type: the set of StaticWarningCode.INVALID_METHOD_OVERRIDE_* warnings
-        // break out the different specific situations.
-        continue;
-      }
-      // First check to see if this element was declared in the superclass chain, in which case
-      // there is already a concrete implementation.
-      ExecutableElement elt = membersInheritedFromSuperclasses.get(memberName);
-      // Check to see if an element was found in the superclass chain with the correct name.
-      if (elt != null) {
-        // Reference the types, if any are null then continue.
-        InterfaceType enclosingType = _enclosingClass.type;
-        FunctionType concreteType = elt.type;
-        FunctionType requiredMemberType = executableElt.type;
-        if (enclosingType == null || concreteType == null || requiredMemberType == null) {
-          continue;
-        }
-        // Some element was found in the superclass chain that matches the name of the required
-        // member.
-        // If it is not abstract and it is the correct one (types match- the version of this method
-        // that we have has the correct number of parameters, etc), then this class has a valid
-        // implementation of this method, so skip it.
-        if ((elt is MethodElement && !elt.isAbstract) || (elt is PropertyAccessorElement && !elt.isAbstract)) {
-          // Since we are comparing two function types, we need to do the appropriate type
-          // substitutions first ().
-          FunctionType foundConcreteFT = _inheritanceManager.substituteTypeArgumentsInMemberFromInheritance(concreteType, memberName, enclosingType);
-          FunctionType requiredMemberFT = _inheritanceManager.substituteTypeArgumentsInMemberFromInheritance(requiredMemberType, memberName, enclosingType);
-          if (foundConcreteFT.isSubtypeOf(requiredMemberFT)) {
-            continue;
-          }
-        }
-      }
-      // The not qualifying concrete executable element was found, add it to the list.
-      missingOverrides.add(executableElt);
-    }
-    // Now that we have the set of missing overrides, generate a warning on this class
-    int missingOverridesSize = missingOverrides.length;
-    if (missingOverridesSize == 0) {
-      return false;
-    }
-    List<ExecutableElement> missingOverridesArray = new List.from(missingOverrides);
-    List<String> stringMembersArrayListSet = new List<String>();
-    for (int i = 0; i < missingOverridesArray.length; i++) {
-      String newStrMember;
-      Element enclosingElement = missingOverridesArray[i].enclosingElement;
-      String prefix = StringUtilities.EMPTY;
-      if (missingOverridesArray[i] is PropertyAccessorElement) {
-        PropertyAccessorElement propertyAccessorElement = missingOverridesArray[i] as PropertyAccessorElement;
-        if (propertyAccessorElement.isGetter) {
-          prefix = _GETTER_SPACE;
-          // "getter "
-        } else {
-          prefix = _SETTER_SPACE;
-          // "setter "
-        }
-      }
-      if (enclosingElement != null) {
-        newStrMember = "$prefix'${enclosingElement.displayName}.${missingOverridesArray[i].displayName}'";
-      } else {
-        newStrMember = "$prefix'${missingOverridesArray[i].displayName}'";
-      }
-      stringMembersArrayListSet.add(newStrMember);
-    }
-    List<String> stringMembersArray = new List.from(stringMembersArrayListSet);
-    AnalysisErrorWithProperties analysisError;
-    if (stringMembersArray.length == 1) {
-      analysisError = _errorReporter.newErrorWithProperties(StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE, classNameNode, [stringMembersArray[0]]);
-    } else if (stringMembersArray.length == 2) {
-      analysisError = _errorReporter.newErrorWithProperties(StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_TWO, classNameNode, [stringMembersArray[0], stringMembersArray[1]]);
-    } else if (stringMembersArray.length == 3) {
-      analysisError = _errorReporter.newErrorWithProperties(StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_THREE, classNameNode, [
-          stringMembersArray[0],
-          stringMembersArray[1],
-          stringMembersArray[2]]);
-    } else if (stringMembersArray.length == 4) {
-      analysisError = _errorReporter.newErrorWithProperties(StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_FOUR, classNameNode, [
-          stringMembersArray[0],
-          stringMembersArray[1],
-          stringMembersArray[2],
-          stringMembersArray[3]]);
-    } else {
-      analysisError = _errorReporter.newErrorWithProperties(StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_FIVE_PLUS, classNameNode, [
-          stringMembersArray[0],
-          stringMembersArray[1],
-          stringMembersArray[2],
-          stringMembersArray[3],
-          stringMembersArray.length - 4]);
-    }
-    analysisError.setProperty(ErrorProperty.UNIMPLEMENTED_METHODS, missingOverridesArray);
-    _errorReporter.reportError(analysisError);
-    return true;
-  }
-
-  /**
-   * Checks to ensure that the expressions that need to be of type bool, are. Otherwise an error is
-   * reported on the expression.
-   *
-   * @param condition the conditional expression to test
-   * @return `true` if and only if an error code is generated on the passed node
-   * @see StaticTypeWarningCode#NON_BOOL_CONDITION
-   */
-  bool _checkForNonBoolCondition(Expression condition) {
-    DartType conditionType = getStaticType(condition);
-    if (conditionType != null && !conditionType.isAssignableTo(_boolType)) {
-      _errorReporter.reportErrorForNode(StaticTypeWarningCode.NON_BOOL_CONDITION, condition, []);
-      return true;
-    }
-    return false;
-  }
-
-  /**
-   * This verifies that the passed assert statement has either a 'bool' or '() -> bool' input.
-   *
-   * @param node the assert statement to evaluate
-   * @return `true` if and only if an error code is generated on the passed node
-   * @see StaticTypeWarningCode#NON_BOOL_EXPRESSION
-   */
-  bool _checkForNonBoolExpression(AssertStatement node) {
-    Expression expression = node.condition;
-    DartType type = getStaticType(expression);
-    if (type is InterfaceType) {
-      if (!type.isAssignableTo(_boolType)) {
-        _errorReporter.reportErrorForNode(StaticTypeWarningCode.NON_BOOL_EXPRESSION, expression, []);
-        return true;
-      }
-    } else if (type is FunctionType) {
-      FunctionType functionType = type;
-      if (functionType.typeArguments.length == 0 && !functionType.returnType.isAssignableTo(_boolType)) {
-        _errorReporter.reportErrorForNode(StaticTypeWarningCode.NON_BOOL_EXPRESSION, expression, []);
-        return true;
-      }
-    }
-    return false;
-  }
-
-  /**
-   * Checks to ensure that the given expression is assignable to bool.
-   *
-   * @param expression the expression expression to test
-   * @return `true` if and only if an error code is generated on the passed node
-   * @see StaticTypeWarningCode#NON_BOOL_NEGATION_EXPRESSION
-   */
-  bool _checkForNonBoolNegationExpression(Expression expression) {
-    DartType conditionType = getStaticType(expression);
-    if (conditionType != null && !conditionType.isAssignableTo(_boolType)) {
-      _errorReporter.reportErrorForNode(StaticTypeWarningCode.NON_BOOL_NEGATION_EXPRESSION, expression, []);
-      return true;
-    }
-    return false;
-  }
-
-  /**
-   * This verifies the passed map literal either:
-   * * has `const modifier`
-   * * has explicit type arguments
-   * * is not start of the statement
-   *
-   * @param node the map literal to evaluate
-   * @return `true` if and only if an error code is generated on the passed node
-   * @see CompileTimeErrorCode#NON_CONST_MAP_AS_EXPRESSION_STATEMENT
-   */
-  bool _checkForNonConstMapAsExpressionStatement(MapLiteral node) {
-    // "const"
-    if (node.constKeyword != null) {
-      return false;
-    }
-    // has type arguments
-    if (node.typeArguments != null) {
-      return false;
-    }
-    // prepare statement
-    Statement statement = node.getAncestor((node) => node is ExpressionStatement);
-    if (statement == null) {
-      return false;
-    }
-    // OK, statement does not start with map
-    if (!identical(statement.beginToken, node.beginToken)) {
-      return false;
-    }
-    // report problem
-    _errorReporter.reportErrorForNode(CompileTimeErrorCode.NON_CONST_MAP_AS_EXPRESSION_STATEMENT, node, []);
-    return true;
-  }
-
-  /**
-   * This verifies the passed method declaration of operator `[]=`, has `void` return
-   * type.
-   *
-   * @param node the method declaration to evaluate
-   * @return `true` if and only if an error code is generated on the passed node
-   * @see StaticWarningCode#NON_VOID_RETURN_FOR_OPERATOR
-   */
-  bool _checkForNonVoidReturnTypeForOperator(MethodDeclaration node) {
-    // check that []= operator
-    SimpleIdentifier name = node.name;
-    if (name.name != "[]=") {
-      return false;
-    }
-    // check return type
-    TypeName typeName = node.returnType;
-    if (typeName != null) {
-      DartType type = typeName.type;
-      if (type != null && !type.isVoid) {
-        _errorReporter.reportErrorForNode(StaticWarningCode.NON_VOID_RETURN_FOR_OPERATOR, typeName, []);
-      }
-    }
-    // no warning
-    return false;
-  }
-
-  /**
-   * This verifies the passed setter has no return type or the `void` return type.
-   *
-   * @param typeName the type name to evaluate
-   * @return `true` if and only if an error code is generated on the passed node
-   * @see StaticWarningCode#NON_VOID_RETURN_FOR_SETTER
-   */
-  bool _checkForNonVoidReturnTypeForSetter(TypeName typeName) {
-    if (typeName != null) {
-      DartType type = typeName.type;
-      if (type != null && !type.isVoid) {
-        _errorReporter.reportErrorForNode(StaticWarningCode.NON_VOID_RETURN_FOR_SETTER, typeName, []);
-      }
-    }
-    return false;
-  }
-
-  /**
-   * This verifies the passed operator-method declaration, does not have an optional parameter.
-   *
-   * This method assumes that the method declaration was tested to be an operator declaration before
-   * being called.
-   *
-   * @param node the method declaration to evaluate
-   * @return `true` if and only if an error code is generated on the passed node
-   * @see CompileTimeErrorCode#OPTIONAL_PARAMETER_IN_OPERATOR
-   */
-  bool _checkForOptionalParameterInOperator(MethodDeclaration node) {
-    FormalParameterList parameterList = node.parameters;
-    if (parameterList == null) {
-      return false;
-    }
-    bool foundError = false;
-    NodeList<FormalParameter> formalParameters = parameterList.parameters;
-    for (FormalParameter formalParameter in formalParameters) {
-      if (formalParameter.kind.isOptional) {
-        _errorReporter.reportErrorForNode(CompileTimeErrorCode.OPTIONAL_PARAMETER_IN_OPERATOR, formalParameter, []);
-        foundError = true;
-      }
-    }
-    return foundError;
-  }
-
-  /**
-   * This checks for named optional parameters that begin with '_'.
-   *
-   * @param node the default formal parameter to evaluate
-   * @return `true` if and only if an error code is generated on the passed node
-   * @see CompileTimeErrorCode#PRIVATE_OPTIONAL_PARAMETER
-   */
-  bool _checkForPrivateOptionalParameter(FormalParameter node) {
-    // should be named parameter
-    if (node.kind != ParameterKind.NAMED) {
-      return false;
-    }
-    // name should start with '_'
-    SimpleIdentifier name = node.identifier;
-    if (name.isSynthetic || !StringUtilities.startsWithChar(name.name, 0x5F)) {
-      return false;
-    }
-    // report problem
-    _errorReporter.reportErrorForNode(CompileTimeErrorCode.PRIVATE_OPTIONAL_PARAMETER, node, []);
-    return true;
-  }
-
-  /**
-   * This checks if the passed constructor declaration is the redirecting generative constructor and
-   * references itself directly or indirectly.
-   *
-   * @param node the constructor declaration to evaluate
-   * @param constructorElement the constructor element
-   * @return `true` if and only if an error code is generated on the passed node
-   * @see CompileTimeErrorCode#RECURSIVE_CONSTRUCTOR_REDIRECT
-   */
-  bool _checkForRecursiveConstructorRedirect(ConstructorDeclaration node, ConstructorElement constructorElement) {
-    // we check generative constructor here
-    if (node.factoryKeyword != null) {
-      return false;
-    }
-    // try to find redirecting constructor invocation and analyzer it for recursion
-    for (ConstructorInitializer initializer in node.initializers) {
-      if (initializer is RedirectingConstructorInvocation) {
-        // OK if no cycle
-        if (!_hasRedirectingFactoryConstructorCycle(constructorElement)) {
-          return false;
-        }
-        // report error
-        _errorReporter.reportErrorForNode(CompileTimeErrorCode.RECURSIVE_CONSTRUCTOR_REDIRECT, initializer, []);
-        return true;
-      }
-    }
-    // OK, no redirecting constructor invocation
-    return false;
-  }
-
-  /**
-   * This checks if the passed constructor declaration has redirected constructor and references
-   * itself directly or indirectly.
-   *
-   * @param node the constructor declaration to evaluate
-   * @param constructorElement the constructor element
-   * @return `true` if and only if an error code is generated on the passed node
-   * @see CompileTimeErrorCode#RECURSIVE_FACTORY_REDIRECT
-   */
-  bool _checkForRecursiveFactoryRedirect(ConstructorDeclaration node, ConstructorElement constructorElement) {
-    // prepare redirected constructor
-    ConstructorName redirectedConstructorNode = node.redirectedConstructor;
-    if (redirectedConstructorNode == null) {
-      return false;
-    }
-    // OK if no cycle
-    if (!_hasRedirectingFactoryConstructorCycle(constructorElement)) {
-      return false;
-    }
-    // report error
-    _errorReporter.reportErrorForNode(CompileTimeErrorCode.RECURSIVE_FACTORY_REDIRECT, redirectedConstructorNode, []);
-    return true;
-  }
-
-  /**
-   * This checks the class declaration is not a superinterface to itself.
-   *
-   * @param classElt the class element to test
-   * @return `true` if and only if an error code is generated on the passed element
-   * @see CompileTimeErrorCode#RECURSIVE_INTERFACE_INHERITANCE
-   * @see CompileTimeErrorCode#RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_EXTENDS
-   * @see CompileTimeErrorCode#RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_IMPLEMENTS
-   */
-  bool _checkForRecursiveInterfaceInheritance(ClassElement classElt) {
-    if (classElt == null) {
-      return false;
-    }
-    return _safeCheckForRecursiveInterfaceInheritance(classElt, new List<ClassElement>());
-  }
-
-  /**
-   * This checks the passed constructor declaration has a valid combination of redirected
-   * constructor invocation(s), super constructor invocations and field initializers.
-   *
-   * @param node the constructor declaration to evaluate
-   * @return `true` if and only if an error code is generated on the passed node
-   * @see CompileTimeErrorCode#DEFAULT_VALUE_IN_REDIRECTING_FACTORY_CONSTRUCTOR
-   * @see CompileTimeErrorCode#FIELD_INITIALIZER_REDIRECTING_CONSTRUCTOR
-   * @see CompileTimeErrorCode#MULTIPLE_REDIRECTING_CONSTRUCTOR_INVOCATIONS
-   * @see CompileTimeErrorCode#SUPER_IN_REDIRECTING_CONSTRUCTOR
-   * @see CompileTimeErrorCode#REDIRECT_GENERATIVE_TO_NON_GENERATIVE_CONSTRUCTOR
-   */
-  bool _checkForRedirectingConstructorErrorCodes(ConstructorDeclaration node) {
-    bool errorReported = false;
-    //
-    // Check for default values in the parameters
-    //
-    ConstructorName redirectedConstructor = node.redirectedConstructor;
-    if (redirectedConstructor != null) {
-      for (FormalParameter parameter in node.parameters.parameters) {
-        if (parameter is DefaultFormalParameter && parameter.defaultValue != null) {
-          _errorReporter.reportErrorForNode(CompileTimeErrorCode.DEFAULT_VALUE_IN_REDIRECTING_FACTORY_CONSTRUCTOR, parameter.identifier, []);
-          errorReported = true;
-        }
-      }
-    }
-    // check if there are redirected invocations
-    int numRedirections = 0;
-    for (ConstructorInitializer initializer in node.initializers) {
-      if (initializer is RedirectingConstructorInvocation) {
-        if (numRedirections > 0) {
-          _errorReporter.reportErrorForNode(CompileTimeErrorCode.MULTIPLE_REDIRECTING_CONSTRUCTOR_INVOCATIONS, initializer, []);
-          errorReported = true;
-        }
-        if (node.factoryKeyword == null) {
-          RedirectingConstructorInvocation invocation = initializer;
-          ConstructorElement redirectingElement = invocation.staticElement;
-          if (redirectingElement == null) {
-            String enclosingTypeName = _enclosingClass.displayName;
-            String constructorStrName = enclosingTypeName;
-            if (invocation.constructorName != null) {
-              constructorStrName += ".${invocation.constructorName.name}";
-            }
-            _errorReporter.reportErrorForNode(CompileTimeErrorCode.REDIRECT_GENERATIVE_TO_MISSING_CONSTRUCTOR, invocation, [constructorStrName, enclosingTypeName]);
-          } else {
-            if (redirectingElement.isFactory) {
-              _errorReporter.reportErrorForNode(CompileTimeErrorCode.REDIRECT_GENERATIVE_TO_NON_GENERATIVE_CONSTRUCTOR, initializer, []);
-            }
-          }
-        }
-        numRedirections++;
-      }
-    }
-    // check for other initializers
-    if (numRedirections > 0) {
-      for (ConstructorInitializer initializer in node.initializers) {
-        if (initializer is SuperConstructorInvocation) {
-          _errorReporter.reportErrorForNode(CompileTimeErrorCode.SUPER_IN_REDIRECTING_CONSTRUCTOR, initializer, []);
-          errorReported = true;
-        }
-        if (initializer is ConstructorFieldInitializer) {
-          _errorReporter.reportErrorForNode(CompileTimeErrorCode.FIELD_INITIALIZER_REDIRECTING_CONSTRUCTOR, initializer, []);
-          errorReported = true;
-        }
-      }
-    }
-    // done
-    return errorReported;
-  }
-
-  /**
-   * This checks if the passed constructor declaration has redirected constructor and references
-   * itself directly or indirectly.
-   *
-   * @param node the constructor declaration to evaluate
-   * @param constructorElement the constructor element
-   * @return `true` if and only if an error code is generated on the passed node
-   * @see CompileTimeErrorCode#REDIRECT_TO_NON_CONST_CONSTRUCTOR
-   */
-  bool _checkForRedirectToNonConstConstructor(ConstructorDeclaration node, ConstructorElement constructorElement) {
-    // prepare redirected constructor
-    ConstructorName redirectedConstructorNode = node.redirectedConstructor;
-    if (redirectedConstructorNode == null) {
-      return false;
-    }
-    // prepare element
-    if (constructorElement == null) {
-      return false;
-    }
-    // OK, it is not 'const'
-    if (!constructorElement.isConst) {
-      return false;
-    }
-    // prepare redirected constructor
-    ConstructorElement redirectedConstructor = constructorElement.redirectedConstructor;
-    if (redirectedConstructor == null) {
-      return false;
-    }
-    // OK, it is also 'const'
-    if (redirectedConstructor.isConst) {
-      return false;
-    }
-    // report error
-    _errorReporter.reportErrorForNode(CompileTimeErrorCode.REDIRECT_TO_NON_CONST_CONSTRUCTOR, redirectedConstructorNode, []);
-    return true;
-  }
-
-  /**
-   * This checks that the rethrow is inside of a catch clause.
-   *
-   * @param node the rethrow expression to evaluate
-   * @return `true` if and only if an error code is generated on the passed node
-   * @see CompileTimeErrorCode#RETHROW_OUTSIDE_CATCH
-   */
-  bool _checkForRethrowOutsideCatch(RethrowExpression node) {
-    if (!_isInCatchClause) {
-      _errorReporter.reportErrorForNode(CompileTimeErrorCode.RETHROW_OUTSIDE_CATCH, node, []);
-      return true;
-    }
-    return false;
-  }
-
-  /**
-   * This checks that if the the given constructor declaration is generative, then it does not have
-   * an expression function body.
-   *
-   * @param node the constructor to evaluate
-   * @return `true` if and only if an error code is generated on the passed node
-   * @see CompileTimeErrorCode#RETURN_IN_GENERATIVE_CONSTRUCTOR
-   */
-  bool _checkForReturnInGenerativeConstructor(ConstructorDeclaration node) {
-    // ignore factory
-    if (node.factoryKeyword != null) {
-      return false;
-    }
-    // block body (with possible return statement) is checked elsewhere
-    FunctionBody body = node.body;
-    if (body is! ExpressionFunctionBody) {
-      return false;
-    }
-    // report error
-    _errorReporter.reportErrorForNode(CompileTimeErrorCode.RETURN_IN_GENERATIVE_CONSTRUCTOR, body, []);
-    return true;
-  }
-
-  /**
-   * This checks that a type mis-match between the return type and the expressed return type by the
-   * enclosing method or function.
-   *
-   * This method is called both by [checkForAllReturnStatementErrorCodes]
-   * and [visitExpressionFunctionBody].
-   *
-   * @param returnExpression the returned expression to evaluate
-   * @param expectedReturnType the expressed return type by the enclosing method or function
-   * @return `true` if and only if an error code is generated on the passed node
-   * @see StaticTypeWarningCode#RETURN_OF_INVALID_TYPE
-   */
-  bool _checkForReturnOfInvalidType(Expression returnExpression, DartType expectedReturnType) {
-    if (_enclosingFunction == null) {
-      return false;
-    }
-    DartType staticReturnType = getStaticType(returnExpression);
-    if (expectedReturnType.isVoid) {
-      if (staticReturnType.isVoid || staticReturnType.isDynamic || staticReturnType.isBottom) {
-        return false;
-      }
-      _errorReporter.reportTypeErrorForNode(StaticTypeWarningCode.RETURN_OF_INVALID_TYPE, returnExpression, [
-          staticReturnType,
-          expectedReturnType,
-          _enclosingFunction.displayName]);
-      return true;
-    }
-    if (_enclosingFunction.isAsynchronous && !_enclosingFunction.isGenerator) {
-      // TODO(brianwilkerson) Figure out how to get the type "Future" so that we can build the type
-      // we need to test against.
-      //      InterfaceType impliedType = "Future<" + flatten(staticReturnType) + ">"
-      //      if (impliedType.isAssignableTo(expectedReturnType)) {
-      //        return false;
-      //      }
-      //      errorReporter.reportTypeErrorForNode(
-      //          StaticTypeWarningCode.RETURN_OF_INVALID_TYPE,
-      //          returnExpression,
-      //          impliedType,
-      //          expectedReturnType.getDisplayName(),
-      //          enclosingFunction.getDisplayName());
-      //      return true;
-      return false;
-    }
-    if (staticReturnType.isAssignableTo(expectedReturnType)) {
-      return false;
-    }
-    _errorReporter.reportTypeErrorForNode(StaticTypeWarningCode.RETURN_OF_INVALID_TYPE, returnExpression, [
-        staticReturnType,
-        expectedReturnType,
-        _enclosingFunction.displayName]);
-    return true;
-    // TODO(brianwilkerson) Define a hint corresponding to the warning and report it if appropriate.
-    //    Type propagatedReturnType = returnExpression.getPropagatedType();
-    //    boolean isPropagatedAssignable = propagatedReturnType.isAssignableTo(expectedReturnType);
-    //    if (isStaticAssignable || isPropagatedAssignable) {
-    //      return false;
-    //    }
-    //    errorReporter.reportTypeErrorForNode(
-    //        StaticTypeWarningCode.RETURN_OF_INVALID_TYPE,
-    //        returnExpression,
-    //        staticReturnType,
-    //        expectedReturnType,
-    //        enclosingFunction.getDisplayName());
-    //    return true;
-  }
-
-  /**
-   * This checks the given "typeReference" and that the "name" is not the reference to an instance
-   * member.
-   *
-   * @param typeReference the resolved [ClassElement] of the left hand side of the expression,
-   *          or `null`, aka, the class element of 'C' in 'C.x', see
-   *          [getTypeReference]
-   * @param name the accessed name to evaluate
-   * @return `true` if and only if an error code is generated on the passed node
-   * @see StaticWarningCode#STATIC_ACCESS_TO_INSTANCE_MEMBER
-   */
-  bool _checkForStaticAccessToInstanceMember(ClassElement typeReference, SimpleIdentifier name) {
-    // OK, target is not a type
-    if (typeReference == null) {
-      return false;
-    }
-    // prepare member Element
-    Element element = name.staticElement;
-    if (element is! ExecutableElement) {
-      return false;
-    }
-    ExecutableElement memberElement = element as ExecutableElement;
-    // OK, static
-    if (memberElement.isStatic) {
-      return false;
-    }
-    // report problem
-    _errorReporter.reportErrorForNode(StaticWarningCode.STATIC_ACCESS_TO_INSTANCE_MEMBER, name, [name.name]);
-    return true;
-  }
-
-  /**
-   * This checks that the type of the passed 'switch' expression is assignable to the type of the
-   * 'case' members.
-   *
-   * @param node the 'switch' statement to evaluate
-   * @return `true` if and only if an error code is generated on the passed node
-   * @see StaticWarningCode#SWITCH_EXPRESSION_NOT_ASSIGNABLE
-   */
-  bool _checkForSwitchExpressionNotAssignable(SwitchStatement node) {
-    // prepare 'switch' expression type
-    Expression expression = node.expression;
-    DartType expressionType = getStaticType(expression);
-    if (expressionType == null) {
-      return false;
-    }
-    // compare with type of the first 'case'
-    NodeList<SwitchMember> members = node.members;
-    for (SwitchMember switchMember in members) {
-      if (switchMember is! SwitchCase) {
-        continue;
-      }
-      SwitchCase switchCase = switchMember as SwitchCase;
-      // prepare 'case' type
-      Expression caseExpression = switchCase.expression;
-      DartType caseType = getStaticType(caseExpression);
-      // check types
-      if (expressionType.isAssignableTo(caseType)) {
-        return false;
-      }
-      // report problem
-      _errorReporter.reportErrorForNode(StaticWarningCode.SWITCH_EXPRESSION_NOT_ASSIGNABLE, expression, [expressionType, caseType]);
-      return true;
-    }
-    return false;
-  }
-
-  /**
-   * This verifies that the passed function type alias does not reference itself directly.
-   *
-   * @param node the function type alias to evaluate
-   * @return `true` if and only if an error code is generated on the passed node
-   * @see CompileTimeErrorCode#TYPE_ALIAS_CANNOT_REFERENCE_ITSELF
-   */
-  bool _checkForTypeAliasCannotReferenceItself_function(FunctionTypeAlias node) {
-    FunctionTypeAliasElement element = node.element;
-    if (!_hasTypedefSelfReference(element)) {
-      return false;
-    }
-    _errorReporter.reportErrorForNode(CompileTimeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF, node, []);
-    return true;
-  }
-
-  /**
-   * This verifies that the passed type name is not a deferred type.
-   *
-   * @param expression the expression to evaluate
-   * @return `true` if and only if an error code is generated on the passed node
-   * @see StaticWarningCode#TYPE_ANNOTATION_DEFERRED_CLASS
-   */
-  bool _checkForTypeAnnotationDeferredClass(TypeName node) {
-    if (node != null && node.isDeferred) {
-      _errorReporter.reportErrorForNode(StaticWarningCode.TYPE_ANNOTATION_DEFERRED_CLASS, node, [node.name]);
-    }
-    return false;
-  }
-
-  /**
-   * This verifies that the type arguments in the passed type name are all within their bounds.
-   *
-   * @param node the [TypeName] to evaluate
-   * @return `true` if and only if an error code is generated on the passed node
-   * @see StaticTypeWarningCode#TYPE_ARGUMENT_NOT_MATCHING_BOUNDS
-   */
-  bool _checkForTypeArgumentNotMatchingBounds(TypeName node) {
-    if (node.typeArguments == null) {
-      return false;
-    }
-    // prepare Type
-    DartType type = node.type;
-    if (type == null) {
-      return false;
-    }
-    // prepare ClassElement
-    Element element = type.element;
-    if (element is! ClassElement) {
-      return false;
-    }
-    ClassElement classElement = element as ClassElement;
-    // prepare type parameters
-    List<DartType> typeParameters = classElement.type.typeArguments;
-    List<TypeParameterElement> boundingElts = classElement.typeParameters;
-    // iterate over each bounded type parameter and corresponding argument
-    NodeList<TypeName> typeNameArgList = node.typeArguments.arguments;
-    List<DartType> typeArguments = (type as InterfaceType).typeArguments;
-    int loopThroughIndex = math.min(typeNameArgList.length, boundingElts.length);
-    bool foundError = false;
-    for (int i = 0; i < loopThroughIndex; i++) {
-      TypeName argTypeName = typeNameArgList[i];
-      DartType argType = argTypeName.type;
-      DartType boundType = boundingElts[i].bound;
-      if (argType != null && boundType != null) {
-        if (typeArguments.length != 0 && typeArguments.length == typeParameters.length) {
-          boundType = boundType.substitute2(typeArguments, typeParameters);
-        }
-        if (!argType.isSubtypeOf(boundType)) {
-          ErrorCode errorCode;
-          if (_isInConstInstanceCreation) {
-            errorCode = CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS;
-          } else {
-            errorCode = StaticTypeWarningCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS;
-          }
-          _errorReporter.reportTypeErrorForNode(errorCode, argTypeName, [argType, boundType]);
-          foundError = true;
-        }
-      }
-    }
-    return foundError;
-  }
-
-  /**
-   * This checks that if the passed type name is a type parameter being used to define a static
-   * member.
-   *
-   * @param node the type name to evaluate
-   * @return `true` if and only if an error code is generated on the passed node
-   * @see StaticWarningCode#TYPE_PARAMETER_REFERENCED_BY_STATIC
-   */
-  bool _checkForTypeParameterReferencedByStatic(TypeName node) {
-    if (_isInStaticMethod || _isInStaticVariableDeclaration) {
-      DartType type = node.type;
-      if (type is TypeParameterType) {
-        _errorReporter.reportErrorForNode(StaticWarningCode.TYPE_PARAMETER_REFERENCED_BY_STATIC, node, []);
-        return true;
-      }
-    }
-    return false;
-  }
-
-  /**
-   * This checks that if the passed type parameter is a supertype of its bound.
-   *
-   * @param node the type parameter to evaluate
-   * @return `true` if and only if an error code is generated on the passed node
-   * @see StaticTypeWarningCode#TYPE_PARAMETER_SUPERTYPE_OF_ITS_BOUND
-   */
-  bool _checkForTypeParameterSupertypeOfItsBound(TypeParameter node) {
-    TypeParameterElement element = node.element;
-    // prepare bound
-    DartType bound = element.bound;
-    if (bound == null) {
-      return false;
-    }
-    // OK, type parameter is not supertype of its bound
-    if (!bound.isMoreSpecificThan(element.type)) {
-      return false;
-    }
-    // report problem
-    _errorReporter.reportErrorForNode(StaticTypeWarningCode.TYPE_PARAMETER_SUPERTYPE_OF_ITS_BOUND, node, [element.displayName]);
-    return true;
-  }
-
-  /**
-   * This checks that if the passed generative constructor has neither an explicit super constructor
-   * invocation nor a redirecting constructor invocation, that the superclass has a default
-   * generative constructor.
-   *
-   * @param node the constructor declaration to evaluate
-   * @return `true` if and only if an error code is generated on the passed node
-   * @see CompileTimeErrorCode#UNDEFINED_CONSTRUCTOR_IN_INITIALIZER_DEFAULT
-   * @see CompileTimeErrorCode#NON_GENERATIVE_CONSTRUCTOR
-   * @see StaticWarningCode#NO_DEFAULT_SUPER_CONSTRUCTOR_EXPLICIT
-   */
-  bool _checkForUndefinedConstructorInInitializerImplicit(ConstructorDeclaration node) {
-    //
-    // Ignore if the constructor is not generative.
-    //
-    if (node.factoryKeyword != null) {
-      return false;
-    }
-    //
-    // Ignore if the constructor has either an implicit super constructor invocation or a
-    // redirecting constructor invocation.
-    //
-    for (ConstructorInitializer constructorInitializer in node.initializers) {
-      if (constructorInitializer is SuperConstructorInvocation || constructorInitializer is RedirectingConstructorInvocation) {
-        return false;
-      }
-    }
-    //
-    // Check to see whether the superclass has a non-factory unnamed constructor.
-    //
-    if (_enclosingClass == null) {
-      return false;
-    }
-    InterfaceType superType = _enclosingClass.supertype;
-    if (superType == null) {
-      return false;
-    }
-    ClassElement superElement = superType.element;
-    ConstructorElement superUnnamedConstructor = superElement.unnamedConstructor;
-    if (superUnnamedConstructor != null) {
-      if (superUnnamedConstructor.isFactory) {
-        _errorReporter.reportErrorForNode(CompileTimeErrorCode.NON_GENERATIVE_CONSTRUCTOR, node.returnType, [superUnnamedConstructor]);
-        return true;
-      }
-      if (!superUnnamedConstructor.isDefaultConstructor) {
-        int offset;
-        int length;
-        {
-          Identifier returnType = node.returnType;
-          SimpleIdentifier name = node.name;
-          offset = returnType.offset;
-          length = (name != null ? name.end : returnType.end) - offset;
-        }
-        _errorReporter.reportErrorForOffset(CompileTimeErrorCode.NO_DEFAULT_SUPER_CONSTRUCTOR_EXPLICIT, offset, length, [superType.displayName]);
-      }
-      return false;
-    }
-    _errorReporter.reportErrorForNode(CompileTimeErrorCode.UNDEFINED_CONSTRUCTOR_IN_INITIALIZER_DEFAULT, node.returnType, [superElement.name]);
-    return true;
-  }
-
-  /**
-   * This checks that if the given name is a reference to a static member it is defined in the
-   * enclosing class rather than in a superclass.
-   *
-   * @param name the name to be evaluated
-   * @return `true` if and only if an error code is generated on the passed node
-   * @see StaticTypeWarningCode#UNQUALIFIED_REFERENCE_TO_NON_LOCAL_STATIC_MEMBER
-   */
-  bool _checkForUnqualifiedReferenceToNonLocalStaticMember(SimpleIdentifier name) {
-    Element element = name.staticElement;
-    if (element == null || element is TypeParameterElement) {
-      return false;
-    }
-    Element enclosingElement = element.enclosingElement;
-    if (enclosingElement is! ClassElement) {
-      return false;
-    }
-    if ((element is MethodElement && !element.isStatic) || (element is PropertyAccessorElement && !element.isStatic)) {
-      return false;
-    }
-    if (identical(enclosingElement, _enclosingClass)) {
-      return false;
-    }
-    _errorReporter.reportErrorForNode(StaticTypeWarningCode.UNQUALIFIED_REFERENCE_TO_NON_LOCAL_STATIC_MEMBER, name, [name.name]);
-    return true;
-  }
-
-  void _checkForValidField(FieldFormalParameter node) {
-    ParameterElement element = node.element;
-    if (element is FieldFormalParameterElement) {
-      FieldElement fieldElement = element.field;
-      if (fieldElement == null || fieldElement.isSynthetic) {
-        _errorReporter.reportErrorForNode(CompileTimeErrorCode.INITIALIZING_FORMAL_FOR_NON_EXISTENT_FIELD, node, [node.identifier.name]);
-      } else {
-        ParameterElement parameterElement = node.element;
-        if (parameterElement is FieldFormalParameterElementImpl) {
-          FieldFormalParameterElementImpl fieldFormal = parameterElement;
-          DartType declaredType = fieldFormal.type;
-          DartType fieldType = fieldElement.type;
-          if (fieldElement.isSynthetic) {
-            _errorReporter.reportErrorForNode(CompileTimeErrorCode.INITIALIZING_FORMAL_FOR_NON_EXISTENT_FIELD, node, [node.identifier.name]);
-          } else if (fieldElement.isStatic) {
-            _errorReporter.reportErrorForNode(CompileTimeErrorCode.INITIALIZING_FORMAL_FOR_STATIC_FIELD, node, [node.identifier.name]);
-          } else if (declaredType != null && fieldType != null && !declaredType.isAssignableTo(fieldType)) {
-            _errorReporter.reportTypeErrorForNode(StaticWarningCode.FIELD_INITIALIZING_FORMAL_NOT_ASSIGNABLE, node, [declaredType, fieldType]);
-          }
-        } else {
-          if (fieldElement.isSynthetic) {
-            _errorReporter.reportErrorForNode(CompileTimeErrorCode.INITIALIZING_FORMAL_FOR_NON_EXISTENT_FIELD, node, [node.identifier.name]);
-          } else if (fieldElement.isStatic) {
-            _errorReporter.reportErrorForNode(CompileTimeErrorCode.INITIALIZING_FORMAL_FOR_STATIC_FIELD, node, [node.identifier.name]);
-          }
-        }
-      }
-    }
-    //    else {
-    //    // TODO(jwren) Report error, constructor initializer variable is a top level element
-    //    // (Either here or in ErrorVerifier#checkForAllFinalInitializedErrorCodes)
-    //    }
-  }
-
-  /**
-   * This verifies that the given getter does not have a return type of 'void'.
-   *
-   * @param node the method declaration to evaluate
-   * @return `true` if and only if an error code is generated on the passed node
-   * @see StaticWarningCode#VOID_RETURN_FOR_GETTER
-   */
-  bool _checkForVoidReturnType(MethodDeclaration node) {
-    TypeName returnType = node.returnType;
-    if (returnType == null || returnType.name.name != "void") {
-      return false;
-    }
-    _errorReporter.reportErrorForNode(StaticWarningCode.VOID_RETURN_FOR_GETTER, returnType, []);
-    return true;
-  }
-
-  /**
-   * This verifies the passed operator-method declaration, has correct number of parameters.
-   *
-   * This method assumes that the method declaration was tested to be an operator declaration before
-   * being called.
-   *
-   * @param node the method declaration to evaluate
-   * @return `true` if and only if an error code is generated on the passed node
-   * @see CompileTimeErrorCode#WRONG_NUMBER_OF_PARAMETERS_FOR_OPERATOR
-   */
-  bool _checkForWrongNumberOfParametersForOperator(MethodDeclaration node) {
-    // prepare number of parameters
-    FormalParameterList parameterList = node.parameters;
-    if (parameterList == null) {
-      return false;
-    }
-    int numParameters = parameterList.parameters.length;
-    // prepare operator name
-    SimpleIdentifier nameNode = node.name;
-    if (nameNode == null) {
-      return false;
-    }
-    String name = nameNode.name;
-    // check for exact number of parameters
-    int expected = -1;
-    if ("[]=" == name) {
-      expected = 2;
-    } else if ("<" == name || ">" == name || "<=" == name || ">=" == name || "==" == name || "+" == name || "/" == name || "~/" == name || "*" == name || "%" == name || "|" == name || "^" == name || "&" == name || "<<" == name || ">>" == name || "[]" == name) {
-      expected = 1;
-    } else if ("~" == name) {
-      expected = 0;
-    }
-    if (expected != -1 && numParameters != expected) {
-      _errorReporter.reportErrorForNode(CompileTimeErrorCode.WRONG_NUMBER_OF_PARAMETERS_FOR_OPERATOR, nameNode, [name, expected, numParameters]);
-      return true;
-    }
-    // check for operator "-"
-    if ("-" == name && numParameters > 1) {
-      _errorReporter.reportErrorForNode(CompileTimeErrorCode.WRONG_NUMBER_OF_PARAMETERS_FOR_OPERATOR_MINUS, nameNode, [numParameters]);
-      return true;
-    }
-    // OK
-    return false;
-  }
-
-  /**
-   * This verifies if the passed setter parameter list have only one required parameter.
-   *
-   * This method assumes that the method declaration was tested to be a setter before being called.
-   *
-   * @param setterName the name of the setter to report problems on
-   * @param parameterList the parameter list to evaluate
-   * @return `true` if and only if an error code is generated on the passed node
-   * @see CompileTimeErrorCode#WRONG_NUMBER_OF_PARAMETERS_FOR_SETTER
-   */
-  bool _checkForWrongNumberOfParametersForSetter(SimpleIdentifier setterName, FormalParameterList parameterList) {
-    if (setterName == null) {
-      return false;
-    }
-    if (parameterList == null) {
-      return false;
-    }
-    NodeList<FormalParameter> parameters = parameterList.parameters;
-    if (parameters.length != 1 || parameters[0].kind != ParameterKind.REQUIRED) {
-      _errorReporter.reportErrorForNode(CompileTimeErrorCode.WRONG_NUMBER_OF_PARAMETERS_FOR_SETTER, setterName, []);
-      return true;
-    }
-    return false;
-  }
-
-  /**
-   * This verifies that if the given class declaration implements the class Function that it has a
-   * concrete implementation of the call method.
-   *
-   * @return `true` if and only if an error code is generated on the passed node
-   * @see StaticWarningCode#FUNCTION_WITHOUT_CALL
-   */
-  bool _checkImplementsFunctionWithoutCall(ClassDeclaration node) {
-    if (node.isAbstract) {
-      return false;
-    }
-    ClassElement classElement = node.element;
-    if (classElement == null) {
-      return false;
-    }
-    if (!classElement.type.isSubtypeOf(_typeProvider.functionType)) {
-      return false;
-    }
-    // If there is a noSuchMethod method, then don't report the warning, see dartbug.com/16078
-    if (classElement.getMethod(FunctionElement.NO_SUCH_METHOD_METHOD_NAME) != null) {
-      return false;
-    }
-    ExecutableElement callMethod = _inheritanceManager.lookupMember(classElement, "call");
-    if (callMethod == null || callMethod is! MethodElement || (callMethod as MethodElement).isAbstract) {
-      _errorReporter.reportErrorForNode(StaticWarningCode.FUNCTION_WITHOUT_CALL, node.name, []);
-      return true;
-    }
-    return false;
-  }
-
-  /**
-   * This verifies that the given class declaration does not have the same class in the 'extends'
-   * and 'implements' clauses.
-   *
-   * @return `true` if and only if an error code is generated on the passed node
-   * @see CompileTimeErrorCode#IMPLEMENTS_SUPER_CLASS
-   */
-  bool _checkImplementsSuperClass(ClassDeclaration node) {
-    // prepare super type
-    InterfaceType superType = _enclosingClass.supertype;
-    if (superType == null) {
-      return false;
-    }
-    // prepare interfaces
-    ImplementsClause implementsClause = node.implementsClause;
-    if (implementsClause == null) {
-      return false;
-    }
-    // check interfaces
-    bool hasProblem = false;
-    for (TypeName interfaceNode in implementsClause.interfaces) {
-      if (interfaceNode.type == superType) {
-        hasProblem = true;
-        _errorReporter.reportErrorForNode(CompileTimeErrorCode.IMPLEMENTS_SUPER_CLASS, interfaceNode, [superType.displayName]);
-      }
-    }
-    // done
-    return hasProblem;
-  }
-
-  /**
-   * Return the error code that should be used when the given class references itself directly.
-   *
-   * @param classElt the class that references itself
-   * @return the error code that should be used
-   */
-  ErrorCode _getBaseCaseErrorCode(ClassElement classElt) {
-    InterfaceType supertype = classElt.supertype;
-    if (supertype != null && _enclosingClass == supertype.element) {
-      return CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_EXTENDS;
-    }
-    List<InterfaceType> mixins = classElt.mixins;
-    for (int i = 0; i < mixins.length; i++) {
-      if (_enclosingClass == mixins[i].element) {
-        return CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_WITH;
-      }
-    }
-    return CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_IMPLEMENTS;
-  }
-
-  /**
-   * Given an expression in a switch case whose value is expected to be an enum constant, return the
-   * name of the constant.
-   *
-   * @param expression the expression from the switch case
-   * @return the name of the constant referenced by the expression
-   */
-  String _getConstantName(Expression expression) {
-    // TODO(brianwilkerson) Convert this to return the element representing the constant.
-    if (expression is SimpleIdentifier) {
-      return expression.name;
-    } else if (expression is PrefixedIdentifier) {
-      return expression.identifier.name;
-    } else if (expression is PropertyAccess) {
-      return expression.propertyName.name;
-    }
-    return null;
-  }
-
-  /**
-   * Returns the Type (return type) for a given getter.
-   *
-   * @param propertyAccessorElement
-   * @return The type of the given getter.
-   */
-  DartType _getGetterType(PropertyAccessorElement propertyAccessorElement) {
-    FunctionType functionType = propertyAccessorElement.type;
-    if (functionType != null) {
-      return functionType.returnType;
-    } else {
-      return null;
-    }
-  }
-
-  /**
-   * Returns the Type (first and only parameter) for a given setter.
-   *
-   * @param propertyAccessorElement
-   * @return The type of the given setter.
-   */
-  DartType _getSetterType(PropertyAccessorElement propertyAccessorElement) {
-    // Get the parameters for MethodDeclaration or FunctionDeclaration
-    List<ParameterElement> setterParameters = propertyAccessorElement.parameters;
-    // If there are no setter parameters, return no type.
-    if (setterParameters.length == 0) {
-      return null;
-    }
-    return setterParameters[0].type;
-  }
-
-  /**
-   * Given a list of directives that have the same prefix, generate an error if there is more than
-   * one import and any of those imports is deferred.
-   *
-   * @param directives the list of directives that have the same prefix
-   * @return `true` if an error was generated
-   * @see CompileTimeErrorCode#SHARED_DEFERRED_PREFIX
-   */
-  bool _hasDeferredPrefixCollision(List<ImportDirective> directives) {
-    bool foundError = false;
-    int count = directives.length;
-    if (count > 1) {
-      for (int i = 0; i < count; i++) {
-        sc.Token deferredToken = directives[i].deferredToken;
-        if (deferredToken != null) {
-          _errorReporter.reportErrorForToken(CompileTimeErrorCode.SHARED_DEFERRED_PREFIX, deferredToken, []);
-          foundError = true;
-        }
-      }
-    }
-    return foundError;
-  }
-
-  /**
-   * @return `true` if the given constructor redirects to itself, directly or indirectly
-   */
-  bool _hasRedirectingFactoryConstructorCycle(ConstructorElement element) {
-    Set<ConstructorElement> constructors = new HashSet<ConstructorElement>();
-    ConstructorElement current = element;
-    while (current != null) {
-      if (constructors.contains(current)) {
-        return identical(current, element);
-      }
-      constructors.add(current);
-      current = current.redirectedConstructor;
-      if (current is ConstructorMember) {
-        current = (current as ConstructorMember).baseElement;
-      }
-    }
-    return false;
-  }
-
-  /**
-   * @return <code>true</code> if given [Element] has direct or indirect reference to itself
-   *         from anywhere except [ClassElement] or type parameter bounds.
-   */
-  bool _hasTypedefSelfReference(Element target) {
-    Set<Element> checked = new HashSet<Element>();
-    List<Element> toCheck = new List<Element>();
-    toCheck.add(target);
-    bool firstIteration = true;
-    while (true) {
-      Element current;
-      // get next element
-      while (true) {
-        // may be no more elements to check
-        if (toCheck.isEmpty) {
-          return false;
-        }
-        // try to get next element
-        current = toCheck.removeAt(toCheck.length - 1);
-        if (target == current) {
-          if (firstIteration) {
-            firstIteration = false;
-            break;
-          } else {
-            return true;
-          }
-        }
-        if (current != null && !checked.contains(current)) {
-          break;
-        }
-      }
-      // check current element
-      current.accept(new GeneralizingElementVisitor_ErrorVerifier_hasTypedefSelfReference(target, toCheck));
-      checked.add(current);
-    }
-  }
-
-  bool _isFunctionType(DartType type) {
-    if (type.isDynamic || type.isBottom) {
-      return true;
-    } else if (type is FunctionType || type.isDartCoreFunction) {
-      return true;
-    } else if (type is InterfaceType) {
-      MethodElement callMethod = type.lookUpMethod(FunctionElement.CALL_METHOD_NAME, _currentLibrary);
-      return callMethod != null;
-    }
-    return false;
-  }
-
-  /**
-   * Return `true` if the given type represents the class `Future` from the
-   * `dart:async` library.
-   *
-   * @param type the type to be tested
-   * @return `true` if the given type represents the class `Future` from the
-   *         `dart:async` library
-   */
-  bool _isFuture(DartType type) {
-    if (type is InterfaceType) {
-      InterfaceType interfaceType = type;
-      if (interfaceType.name == "Future") {
-        ClassElement element = interfaceType.element;
-        if (element != null) {
-          LibraryElement library = element.library;
-          if (library.name == "dart.async") {
-            return true;
-          }
-        }
-      }
-    }
-    return false;
-  }
-
-  /**
-   * Return `true` iff the passed [ClassElement] has a method, getter or setter that
-   * matches the name of the passed [ExecutableElement] in either the class itself, or one of
-   * its' mixins that is concrete.
-   *
-   * By "match", only the name of the member is tested to match, it does not have to equal or be a
-   * subtype of the passed executable element, this is due to the specific use where this method is
-   * used in [checkForNonAbstractClassInheritsAbstractMember].
-   *
-   * @param executableElt the executable to search for in the passed class element
-   * @param classElt the class method to search through the members of
-   * @return `true` iff the passed member is found in the passed class element
-   */
-  bool _isMemberInClassOrMixin(ExecutableElement executableElt, ClassElement classElt) {
-    ExecutableElement foundElt = null;
-    String executableName = executableElt.name;
-    if (executableElt is MethodElement) {
-      foundElt = classElt.getMethod(executableName);
-      if (foundElt != null && !(foundElt as MethodElement).isAbstract) {
-        return true;
-      }
-      List<InterfaceType> mixins = classElt.mixins;
-      for (int i = 0; i < mixins.length && foundElt == null; i++) {
-        foundElt = mixins[i].getMethod(executableName);
-      }
-      if (foundElt != null && !(foundElt as MethodElement).isAbstract) {
-        return true;
-      }
-    } else if (executableElt is PropertyAccessorElement) {
-      PropertyAccessorElement propertyAccessorElement = executableElt;
-      if (propertyAccessorElement.isGetter) {
-        foundElt = classElt.getGetter(executableName);
-      }
-      if (foundElt == null && propertyAccessorElement.isSetter) {
-        foundElt = classElt.getSetter(executableName);
-      }
-      if (foundElt != null && !(foundElt as PropertyAccessorElement).isAbstract) {
-        return true;
-      }
-      List<InterfaceType> mixins = classElt.mixins;
-      for (int i = 0; i < mixins.length && foundElt == null; i++) {
-        foundElt = mixins[i].getGetter(executableName);
-        if (foundElt == null) {
-          foundElt = mixins[i].getSetter(executableName);
-        }
-      }
-      if (foundElt != null && !(foundElt as PropertyAccessorElement).isAbstract) {
-        return true;
-      }
-    }
-    return false;
-  }
-
-  /**
-   * @param node the 'this' expression to analyze
-   * @return `true` if the given 'this' expression is in the valid context
-   */
-  bool _isThisInValidContext(ThisExpression node) {
-    for (AstNode n = node; n != null; n = n.parent) {
-      if (n is CompilationUnit) {
-        return false;
-      }
-      if (n is ConstructorDeclaration) {
-        ConstructorDeclaration constructor = n as ConstructorDeclaration;
-        return constructor.factoryKeyword == null;
-      }
-      if (n is ConstructorInitializer) {
-        return false;
-      }
-      if (n is MethodDeclaration) {
-        MethodDeclaration method = n as MethodDeclaration;
-        return !method.isStatic;
-      }
-    }
-    return false;
-  }
-
-  /**
-   * Return `true` if the given identifier is in a location where it is allowed to resolve to
-   * a static member of a supertype.
-   *
-   * @param node the node being tested
-   * @return `true` if the given identifier is in a location where it is allowed to resolve to
-   *         a static member of a supertype
-   */
-  bool _isUnqualifiedReferenceToNonLocalStaticMemberAllowed(SimpleIdentifier node) {
-    if (node.inDeclarationContext()) {
-      return true;
-    }
-    AstNode parent = node.parent;
-    if (parent is ConstructorName || parent is MethodInvocation || parent is PropertyAccess || parent is SuperConstructorInvocation) {
-      return true;
-    }
-    if (parent is PrefixedIdentifier && identical(parent.identifier, node)) {
-      return true;
-    }
-    if (parent is Annotation && identical(parent.constructorName, node)) {
-      return true;
-    }
-    if (parent is CommentReference) {
-      CommentReference commentReference = parent;
-      if (commentReference.newKeyword != null) {
-        return true;
-      }
-    }
-    return false;
-  }
-
-  bool _isUserDefinedObject(EvaluationResultImpl result) => result == null || (result.value != null && result.value.isUserDefinedObject);
-
-  /**
-   * This checks the class declaration is not a superinterface to itself.
-   *
-   * @param classElt the class element to test
-   * @param path a list containing the potentially cyclic implements path
-   * @return `true` if and only if an error code is generated on the passed element
-   * @see CompileTimeErrorCode#RECURSIVE_INTERFACE_INHERITANCE
-   * @see CompileTimeErrorCode#RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_EXTENDS
-   * @see CompileTimeErrorCode#RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_IMPLEMENTS
-   * @see CompileTimeErrorCode#RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_WITH
-   */
-  bool _safeCheckForRecursiveInterfaceInheritance(ClassElement classElt, List<ClassElement> path) {
-    // Detect error condition.
-    int size = path.length;
-    // If this is not the base case (size > 0), and the enclosing class is the passed class
-    // element then an error an error.
-    if (size > 0 && _enclosingClass == classElt) {
-      String enclosingClassName = _enclosingClass.displayName;
-      if (size > 1) {
-        // Construct a string showing the cyclic implements path: "A, B, C, D, A"
-        String separator = ", ";
-        StringBuffer buffer = new StringBuffer();
-        for (int i = 0; i < size; i++) {
-          buffer.write(path[i].displayName);
-          buffer.write(separator);
-        }
-        buffer.write(classElt.displayName);
-        _errorReporter.reportErrorForOffset(CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE, _enclosingClass.nameOffset, enclosingClassName.length, [enclosingClassName, buffer.toString()]);
-        return true;
-      } else {
-        // RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_EXTENDS or
-        // RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_IMPLEMENTS or
-        // RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_WITH
-        _errorReporter.reportErrorForOffset(_getBaseCaseErrorCode(classElt), _enclosingClass.nameOffset, enclosingClassName.length, [enclosingClassName]);
-        return true;
-      }
-    }
-    if (path.indexOf(classElt) > 0) {
-      return false;
-    }
-    path.add(classElt);
-    // n-case
-    InterfaceType supertype = classElt.supertype;
-    if (supertype != null && _safeCheckForRecursiveInterfaceInheritance(supertype.element, path)) {
-      return true;
-    }
-    List<InterfaceType> interfaceTypes = classElt.interfaces;
-    for (InterfaceType interfaceType in interfaceTypes) {
-      if (_safeCheckForRecursiveInterfaceInheritance(interfaceType.element, path)) {
-        return true;
-      }
-    }
-    List<InterfaceType> mixinTypes = classElt.mixins;
-    for (InterfaceType mixinType in mixinTypes) {
-      if (_safeCheckForRecursiveInterfaceInheritance(mixinType.element, path)) {
-        return true;
-      }
-    }
-    path.removeAt(path.length - 1);
-    return false;
-  }
-}
-
-/**
  * Instances of the class `ExitDetector` determine whether the visited AST node is guaranteed
  * to terminate by executing a `return` statement, `throw` expression, `rethrow`
  * expression, or simple infinite loop such as `while(true)`.
@@ -12950,7 +4937,7 @@
     bool outerBreakValue = _enclosingBlockContainsBreak;
     _enclosingBlockContainsBreak = false;
     try {
-      return _nodeExits(node.iterator);
+      return _nodeExits(node.iterable);
     } finally {
       _enclosingBlockContainsBreak = outerBreakValue;
     }
@@ -13332,34 +5319,6 @@
   }
 }
 
-class GeneralizingAstVisitor_StaticTypeAnalyzer_computePropagatedReturnTypeOfFunction extends GeneralizingAstVisitor<Object> {
-  DartType result = null;
-
-  GeneralizingAstVisitor_StaticTypeAnalyzer_computePropagatedReturnTypeOfFunction();
-
-  @override
-  Object visitExpression(Expression node) => null;
-
-  @override
-  Object visitReturnStatement(ReturnStatement node) {
-    // prepare this 'return' type
-    DartType type;
-    Expression expression = node.expression;
-    if (expression != null) {
-      type = expression.bestType;
-    } else {
-      type = BottomTypeImpl.instance;
-    }
-    // merge types
-    if (result == null) {
-      result = type;
-    } else {
-      result = result.getLeastUpperBound(type);
-    }
-    return null;
-  }
-}
-
 class GeneralizingElementVisitor_DeclarationMatcher_gatherElements extends GeneralizingElementVisitor<Object> {
   final DeclarationMatcher DeclarationMatcher_this;
 
@@ -13373,83 +5332,6 @@
   }
 }
 
-class GeneralizingElementVisitor_ErrorVerifier_hasTypedefSelfReference extends GeneralizingElementVisitor<Object> {
-  Element target;
-
-  List<Element> toCheck;
-
-  GeneralizingElementVisitor_ErrorVerifier_hasTypedefSelfReference(this.target, this.toCheck) : super();
-
-  bool _inClass = false;
-
-  @override
-  Object visitClassElement(ClassElement element) {
-    _addTypeToCheck(element.supertype);
-    for (InterfaceType mixin in element.mixins) {
-      _addTypeToCheck(mixin);
-    }
-    _inClass = !element.isTypedef;
-    try {
-      return super.visitClassElement(element);
-    } finally {
-      _inClass = false;
-    }
-  }
-
-  @override
-  Object visitExecutableElement(ExecutableElement element) {
-    if (element.isSynthetic) {
-      return null;
-    }
-    _addTypeToCheck(element.returnType);
-    return super.visitExecutableElement(element);
-  }
-
-  @override
-  Object visitFunctionTypeAliasElement(FunctionTypeAliasElement element) {
-    _addTypeToCheck(element.returnType);
-    return super.visitFunctionTypeAliasElement(element);
-  }
-
-  @override
-  Object visitParameterElement(ParameterElement element) {
-    _addTypeToCheck(element.type);
-    return super.visitParameterElement(element);
-  }
-
-  @override
-  Object visitTypeParameterElement(TypeParameterElement element) {
-    _addTypeToCheck(element.bound);
-    return super.visitTypeParameterElement(element);
-  }
-
-  @override
-  Object visitVariableElement(VariableElement element) {
-    _addTypeToCheck(element.type);
-    return super.visitVariableElement(element);
-  }
-
-  void _addTypeToCheck(DartType type) {
-    if (type == null) {
-      return;
-    }
-    Element element = type.element;
-    // it is OK to reference target from class
-    if (_inClass && target == element) {
-      return;
-    }
-    // schedule for checking
-    toCheck.add(element);
-    // type arguments
-    if (type is InterfaceType) {
-      InterfaceType interfaceType = type;
-      for (DartType typeArgument in interfaceType.typeArguments) {
-        _addTypeToCheck(typeArgument);
-      }
-    }
-  }
-}
-
 /**
  * Instances of the class `HintGenerator` traverse a library's worth of dart code at a time to
  * generate hints over the set of sources.
@@ -13626,7 +5508,9 @@
           _errorListener.addAll(resolver.errorListener);
         } on AnalysisException catch (exception, stackTrace) {
           //TODO (danrubel): Handle or forward the exception
-          AnalysisEngine.instance.logger.logError2("Could not resolve script tag", new CaughtException(exception, stackTrace));
+          AnalysisEngine.instance.logger.logError(
+              "Could not resolve script tag",
+              new CaughtException(exception, stackTrace));
         }
         node.scriptElement = script;
         _scripts.add(script);
@@ -15610,7 +7494,9 @@
       try {
         _libraryElement = _analysisContext.computeLibraryElement(librarySource) as LibraryElementImpl;
       } on AnalysisException catch (exception, stackTrace) {
-        AnalysisEngine.instance.logger.logError2("Could not compute library element for ${librarySource.fullName}", new CaughtException(exception, stackTrace));
+        AnalysisEngine.instance.logger.logError(
+            "Could not compute library element for ${librarySource.fullName}",
+            new CaughtException(exception, stackTrace));
       }
     }
     return _libraryElement;
@@ -16917,7 +8803,9 @@
               computer.add(unit);
             }
           } on AnalysisException catch (exception, stackTrace) {
-            AnalysisEngine.instance.logger.logError2("Internal Error: Could not access AST for ${source.fullName} during constant evaluation", new CaughtException(exception, stackTrace));
+            AnalysisEngine.instance.logger.logError(
+                "Internal Error: Could not access AST for ${source.fullName} during constant evaluation",
+                new CaughtException(exception, stackTrace));
           }
         }
       }
@@ -19806,8 +11694,8 @@
     // We visit the iterator before the loop variable because the loop variable cannot be in scope
     // while visiting the iterator.
     //
-    Expression iterator = node.iterator;
-    safelyVisit(iterator);
+    Expression iterable = node.iterable;
+    safelyVisit(iterable);
     DeclaredIdentifier loopVariable = node.loopVariable;
     SimpleIdentifier identifier = node.identifier;
     safelyVisit(loopVariable);
@@ -19816,17 +11704,17 @@
     if (body != null) {
       _overrideManager.enterScope();
       try {
-        if (loopVariable != null && iterator != null) {
+        if (loopVariable != null && iterable != null) {
           LocalVariableElement loopElement = loopVariable.element;
           if (loopElement != null) {
-            DartType iteratorElementType = _getIteratorElementType(iterator);
+            DartType iteratorElementType = _getIteratorElementType(iterable);
             overrideVariable(loopElement, iteratorElementType, true);
             _recordPropagatedType(loopVariable.identifier, iteratorElementType);
           }
-        } else if (identifier != null && iterator != null) {
+        } else if (identifier != null && iterable != null) {
           Element identifierElement = identifier.staticElement;
           if (identifierElement is VariableElement) {
-            DartType iteratorElementType = _getIteratorElementType(iterator);
+            DartType iteratorElementType = _getIteratorElementType(iterable);
             overrideVariable(identifierElement, iteratorElementType, true);
             _recordPropagatedType(identifier, iteratorElementType);
           }
@@ -20707,7 +12595,9 @@
     Scope outerScope = _nameScope;
     try {
       if (classElement == null) {
-        AnalysisEngine.instance.logger.logInformation2("Missing element for class declaration ${node.name.name} in ${definingLibrary.source.fullName}", new JavaException());
+        AnalysisEngine.instance.logger.logInformation(
+            "Missing element for class declaration ${node.name.name} in ${definingLibrary.source.fullName}",
+            new CaughtException(new AnalysisException(), null));
         super.visitClassDeclaration(node);
       } else {
         _nameScope = new TypeParameterScope(_nameScope, classElement);
@@ -20749,7 +12639,9 @@
         }
         buffer.write(" in ");
         buffer.write(definingLibrary.source.fullName);
-        AnalysisEngine.instance.logger.logInformation2(buffer.toString(), new JavaException());
+        AnalysisEngine.instance.logger.logInformation(
+            buffer.toString(),
+            new CaughtException(new AnalysisException(), null));
       } else {
         _nameScope = new FunctionScope(_nameScope, constructorElement);
       }
@@ -20832,7 +12724,9 @@
     Scope outerScope = _nameScope;
     try {
       if (functionElement == null) {
-        AnalysisEngine.instance.logger.logInformation2("Missing element for top-level function ${node.name.name} in ${definingLibrary.source.fullName}", new JavaException());
+        AnalysisEngine.instance.logger.logInformation(
+            "Missing element for top-level function ${node.name.name} in ${definingLibrary.source.fullName}",
+            new CaughtException(new AnalysisException(), null));
       } else {
         _nameScope = new FunctionScope(_nameScope, functionElement);
       }
@@ -20868,7 +12762,9 @@
           }
           buffer.write("in ");
           buffer.write(definingLibrary.source.fullName);
-          AnalysisEngine.instance.logger.logInformation2(buffer.toString(), new JavaException());
+          AnalysisEngine.instance.logger.logInformation(
+              buffer.toString(),
+              new CaughtException(new AnalysisException(), null));
         } else {
           _nameScope = new FunctionScope(_nameScope, functionElement);
         }
@@ -20917,7 +12813,9 @@
     try {
       ExecutableElement methodElement = node.element;
       if (methodElement == null) {
-        AnalysisEngine.instance.logger.logInformation2("Missing element for method ${node.name.name} in ${definingLibrary.source.fullName}", new JavaException());
+        AnalysisEngine.instance.logger.logInformation(
+            "Missing element for method ${node.name.name} in ${definingLibrary.source.fullName}",
+            new CaughtException(new AnalysisException(), null));
       } else {
         _nameScope = new FunctionScope(_nameScope, methodElement);
       }
@@ -21084,7 +12982,7 @@
     // while visiting the iterator.
     //
     safelyVisit(node.identifier);
-    safelyVisit(node.iterator);
+    safelyVisit(node.iterable);
     safelyVisit(node.loopVariable);
     visitStatementInScope(node.body);
   }
@@ -21168,1690 +13066,6 @@
 }
 
 /**
- * Instances of the class `StaticTypeAnalyzer` perform two type-related tasks. First, they
- * compute the static type of every expression. Second, they look for any static type errors or
- * warnings that might need to be generated. The requirements for the type analyzer are:
- * <ol>
- * * Every element that refers to types should be fully populated.
- * * Every node representing an expression should be resolved to the Type of the expression.
- * </ol>
- */
-class StaticTypeAnalyzer extends SimpleAstVisitor<Object> {
-  /**
-   * Create a table mapping HTML tag names to the names of the classes (in 'dart:html') that
-   * implement those tags.
-   *
-   * @return the table that was created
-   */
-  static HashMap<String, String> _createHtmlTagToClassMap() {
-    HashMap<String, String> map = new HashMap<String, String>();
-    map["a"] = "AnchorElement";
-    map["area"] = "AreaElement";
-    map["br"] = "BRElement";
-    map["base"] = "BaseElement";
-    map["body"] = "BodyElement";
-    map["button"] = "ButtonElement";
-    map["canvas"] = "CanvasElement";
-    map["content"] = "ContentElement";
-    map["dl"] = "DListElement";
-    map["datalist"] = "DataListElement";
-    map["details"] = "DetailsElement";
-    map["div"] = "DivElement";
-    map["embed"] = "EmbedElement";
-    map["fieldset"] = "FieldSetElement";
-    map["form"] = "FormElement";
-    map["hr"] = "HRElement";
-    map["head"] = "HeadElement";
-    map["h1"] = "HeadingElement";
-    map["h2"] = "HeadingElement";
-    map["h3"] = "HeadingElement";
-    map["h4"] = "HeadingElement";
-    map["h5"] = "HeadingElement";
-    map["h6"] = "HeadingElement";
-    map["html"] = "HtmlElement";
-    map["iframe"] = "IFrameElement";
-    map["img"] = "ImageElement";
-    map["input"] = "InputElement";
-    map["keygen"] = "KeygenElement";
-    map["li"] = "LIElement";
-    map["label"] = "LabelElement";
-    map["legend"] = "LegendElement";
-    map["link"] = "LinkElement";
-    map["map"] = "MapElement";
-    map["menu"] = "MenuElement";
-    map["meter"] = "MeterElement";
-    map["ol"] = "OListElement";
-    map["object"] = "ObjectElement";
-    map["optgroup"] = "OptGroupElement";
-    map["output"] = "OutputElement";
-    map["p"] = "ParagraphElement";
-    map["param"] = "ParamElement";
-    map["pre"] = "PreElement";
-    map["progress"] = "ProgressElement";
-    map["script"] = "ScriptElement";
-    map["select"] = "SelectElement";
-    map["source"] = "SourceElement";
-    map["span"] = "SpanElement";
-    map["style"] = "StyleElement";
-    map["caption"] = "TableCaptionElement";
-    map["td"] = "TableCellElement";
-    map["col"] = "TableColElement";
-    map["table"] = "TableElement";
-    map["tr"] = "TableRowElement";
-    map["textarea"] = "TextAreaElement";
-    map["title"] = "TitleElement";
-    map["track"] = "TrackElement";
-    map["ul"] = "UListElement";
-    map["video"] = "VideoElement";
-    return map;
-  }
-
-  /**
-   * The resolver driving the resolution and type analysis.
-   */
-  final ResolverVisitor _resolver;
-
-  /**
-   * The object providing access to the types defined by the language.
-   */
-  TypeProvider _typeProvider;
-
-  /**
-   * The type representing the type 'dynamic'.
-   */
-  DartType _dynamicType;
-
-  /**
-   * The type representing the class containing the nodes being analyzed, or `null` if the
-   * nodes are not within a class.
-   */
-  InterfaceType _thisType;
-
-  /**
-   * The object keeping track of which elements have had their types overridden.
-   */
-  TypeOverrideManager _overrideManager;
-
-  /**
-   * The object keeping track of which elements have had their types promoted.
-   */
-  TypePromotionManager _promoteManager;
-
-  /**
-   * A table mapping [ExecutableElement]s to their propagated return types.
-   */
-  HashMap<ExecutableElement, DartType> _propagatedReturnTypes = new HashMap<ExecutableElement, DartType>();
-
-  /**
-   * A table mapping HTML tag names to the names of the classes (in 'dart:html') that implement
-   * those tags.
-   */
-  static HashMap<String, String> _HTML_ELEMENT_TO_CLASS_MAP = _createHtmlTagToClassMap();
-
-  /**
-   * Initialize a newly created type analyzer.
-   *
-   * @param resolver the resolver driving this participant
-   */
-  StaticTypeAnalyzer(this._resolver) {
-    _typeProvider = _resolver.typeProvider;
-    _dynamicType = _typeProvider.dynamicType;
-    _overrideManager = _resolver.overrideManager;
-    _promoteManager = _resolver.promoteManager;
-  }
-
-  /**
-   * Set the type of the class being analyzed to the given type.
-   *
-   * @param thisType the type representing the class containing the nodes being analyzed
-   */
-  void set thisType(InterfaceType thisType) {
-    this._thisType = thisType;
-  }
-
-  /**
-   * The Dart Language Specification, 12.5: <blockquote>The static type of a string literal is
-   * `String`.</blockquote>
-   */
-  @override
-  Object visitAdjacentStrings(AdjacentStrings node) {
-    _recordStaticType(node, _typeProvider.stringType);
-    return null;
-  }
-
-  /**
-   * The Dart Language Specification, 12.32: <blockquote>... the cast expression <i>e as T</i> ...
-   *
-   * It is a static warning if <i>T</i> does not denote a type available in the current lexical
-   * scope.
-   *
-   * The static type of a cast expression <i>e as T</i> is <i>T</i>.</blockquote>
-   */
-  @override
-  Object visitAsExpression(AsExpression node) {
-    _recordStaticType(node, _getType(node.type));
-    return null;
-  }
-
-  /**
-   * The Dart Language Specification, 12.18: <blockquote>... an assignment <i>a</i> of the form <i>v
-   * = e</i> ...
-   *
-   * It is a static type warning if the static type of <i>e</i> may not be assigned to the static
-   * type of <i>v</i>.
-   *
-   * The static type of the expression <i>v = e</i> is the static type of <i>e</i>.
-   *
-   * ... an assignment of the form <i>C.v = e</i> ...
-   *
-   * It is a static type warning if the static type of <i>e</i> may not be assigned to the static
-   * type of <i>C.v</i>.
-   *
-   * The static type of the expression <i>C.v = e</i> is the static type of <i>e</i>.
-   *
-   * ... an assignment of the form <i>e<sub>1</sub>.v = e<sub>2</sub></i> ...
-   *
-   * Let <i>T</i> be the static type of <i>e<sub>1</sub></i>. It is a static type warning if
-   * <i>T</i> does not have an accessible instance setter named <i>v=</i>. It is a static type
-   * warning if the static type of <i>e<sub>2</sub></i> may not be assigned to <i>T</i>.
-   *
-   * The static type of the expression <i>e<sub>1</sub>.v = e<sub>2</sub></i> is the static type of
-   * <i>e<sub>2</sub></i>.
-   *
-   * ... an assignment of the form <i>e<sub>1</sub>[e<sub>2</sub>] = e<sub>3</sub></i> ...
-   *
-   * The static type of the expression <i>e<sub>1</sub>[e<sub>2</sub>] = e<sub>3</sub></i> is the
-   * static type of <i>e<sub>3</sub></i>.
-   *
-   * A compound assignment of the form <i>v op= e</i> is equivalent to <i>v = v op e</i>. A compound
-   * assignment of the form <i>C.v op= e</i> is equivalent to <i>C.v = C.v op e</i>. A compound
-   * assignment of the form <i>e<sub>1</sub>.v op= e<sub>2</sub></i> is equivalent to <i>((x) => x.v
-   * = x.v op e<sub>2</sub>)(e<sub>1</sub>)</i> where <i>x</i> is a variable that is not used in
-   * <i>e<sub>2</sub></i>. A compound assignment of the form <i>e<sub>1</sub>[e<sub>2</sub>] op=
-   * e<sub>3</sub></i> is equivalent to <i>((a, i) => a[i] = a[i] op e<sub>3</sub>)(e<sub>1</sub>,
-   * e<sub>2</sub>)</i> where <i>a</i> and <i>i</i> are a variables that are not used in
-   * <i>e<sub>3</sub></i>.</blockquote>
-   */
-  @override
-  Object visitAssignmentExpression(AssignmentExpression node) {
-    sc.TokenType operator = node.operator.type;
-    if (operator == sc.TokenType.EQ) {
-      Expression rightHandSide = node.rightHandSide;
-      DartType staticType = _getStaticType(rightHandSide);
-      _recordStaticType(node, staticType);
-      DartType overrideType = staticType;
-      DartType propagatedType = rightHandSide.propagatedType;
-      if (propagatedType != null) {
-        if (propagatedType.isMoreSpecificThan(staticType)) {
-          _recordPropagatedType(node, propagatedType);
-        }
-        overrideType = propagatedType;
-      }
-      _resolver.overrideExpression(node.leftHandSide, overrideType, true);
-    } else {
-      ExecutableElement staticMethodElement = node.staticElement;
-      DartType staticType = _computeStaticReturnType(staticMethodElement);
-      _recordStaticType(node, staticType);
-      MethodElement propagatedMethodElement = node.propagatedElement;
-      if (!identical(propagatedMethodElement, staticMethodElement)) {
-        DartType propagatedType = _computeStaticReturnType(propagatedMethodElement);
-        if (propagatedType != null && propagatedType.isMoreSpecificThan(staticType)) {
-          _recordPropagatedType(node, propagatedType);
-        }
-      }
-    }
-    return null;
-  }
-
-  /**
-   * The Dart Language Specification, 12.20: <blockquote>The static type of a logical boolean
-   * expression is `bool`.</blockquote>
-   *
-   * The Dart Language Specification, 12.21:<blockquote>A bitwise expression of the form
-   * <i>e<sub>1</sub> op e<sub>2</sub></i> is equivalent to the method invocation
-   * <i>e<sub>1</sub>.op(e<sub>2</sub>)</i>. A bitwise expression of the form <i>super op
-   * e<sub>2</sub></i> is equivalent to the method invocation
-   * <i>super.op(e<sub>2</sub>)</i>.</blockquote>
-   *
-   * The Dart Language Specification, 12.22: <blockquote>The static type of an equality expression
-   * is `bool`.</blockquote>
-   *
-   * The Dart Language Specification, 12.23: <blockquote>A relational expression of the form
-   * <i>e<sub>1</sub> op e<sub>2</sub></i> is equivalent to the method invocation
-   * <i>e<sub>1</sub>.op(e<sub>2</sub>)</i>. A relational expression of the form <i>super op
-   * e<sub>2</sub></i> is equivalent to the method invocation
-   * <i>super.op(e<sub>2</sub>)</i>.</blockquote>
-   *
-   * The Dart Language Specification, 12.24: <blockquote>A shift expression of the form
-   * <i>e<sub>1</sub> op e<sub>2</sub></i> is equivalent to the method invocation
-   * <i>e<sub>1</sub>.op(e<sub>2</sub>)</i>. A shift expression of the form <i>super op
-   * e<sub>2</sub></i> is equivalent to the method invocation
-   * <i>super.op(e<sub>2</sub>)</i>.</blockquote>
-   *
-   * The Dart Language Specification, 12.25: <blockquote>An additive expression of the form
-   * <i>e<sub>1</sub> op e<sub>2</sub></i> is equivalent to the method invocation
-   * <i>e<sub>1</sub>.op(e<sub>2</sub>)</i>. An additive expression of the form <i>super op
-   * e<sub>2</sub></i> is equivalent to the method invocation
-   * <i>super.op(e<sub>2</sub>)</i>.</blockquote>
-   *
-   * The Dart Language Specification, 12.26: <blockquote>A multiplicative expression of the form
-   * <i>e<sub>1</sub> op e<sub>2</sub></i> is equivalent to the method invocation
-   * <i>e<sub>1</sub>.op(e<sub>2</sub>)</i>. A multiplicative expression of the form <i>super op
-   * e<sub>2</sub></i> is equivalent to the method invocation
-   * <i>super.op(e<sub>2</sub>)</i>.</blockquote>
-   */
-  @override
-  Object visitBinaryExpression(BinaryExpression node) {
-    ExecutableElement staticMethodElement = node.staticElement;
-    DartType staticType = _computeStaticReturnType(staticMethodElement);
-    staticType = _refineBinaryExpressionType(node, staticType);
-    _recordStaticType(node, staticType);
-    MethodElement propagatedMethodElement = node.propagatedElement;
-    if (!identical(propagatedMethodElement, staticMethodElement)) {
-      DartType propagatedType = _computeStaticReturnType(propagatedMethodElement);
-      if (propagatedType != null && propagatedType.isMoreSpecificThan(staticType)) {
-        _recordPropagatedType(node, propagatedType);
-      }
-    }
-    return null;
-  }
-
-  /**
-   * The Dart Language Specification, 12.4: <blockquote>The static type of a boolean literal is
-   * bool.</blockquote>
-   */
-  @override
-  Object visitBooleanLiteral(BooleanLiteral node) {
-    _recordStaticType(node, _typeProvider.boolType);
-    return null;
-  }
-
-  /**
-   * The Dart Language Specification, 12.15.2: <blockquote>A cascaded method invocation expression
-   * of the form <i>e..suffix</i> is equivalent to the expression <i>(t) {t.suffix; return
-   * t;}(e)</i>.</blockquote>
-   */
-  @override
-  Object visitCascadeExpression(CascadeExpression node) {
-    _recordStaticType(node, _getStaticType(node.target));
-    _recordPropagatedType(node, node.target.propagatedType);
-    return null;
-  }
-
-  /**
-   * The Dart Language Specification, 12.19: <blockquote> ... a conditional expression <i>c</i> of
-   * the form <i>e<sub>1</sub> ? e<sub>2</sub> : e<sub>3</sub></i> ...
-   *
-   * It is a static type warning if the type of e<sub>1</sub> may not be assigned to `bool`.
-   *
-   * The static type of <i>c</i> is the least upper bound of the static type of <i>e<sub>2</sub></i>
-   * and the static type of <i>e<sub>3</sub></i>.</blockquote>
-   */
-  @override
-  Object visitConditionalExpression(ConditionalExpression node) {
-    DartType staticThenType = _getStaticType(node.thenExpression);
-    DartType staticElseType = _getStaticType(node.elseExpression);
-    if (staticThenType == null) {
-      // TODO(brianwilkerson) Determine whether this can still happen.
-      staticThenType = _dynamicType;
-    }
-    if (staticElseType == null) {
-      // TODO(brianwilkerson) Determine whether this can still happen.
-      staticElseType = _dynamicType;
-    }
-    DartType staticType = staticThenType.getLeastUpperBound(staticElseType);
-    if (staticType == null) {
-      staticType = _dynamicType;
-    }
-    _recordStaticType(node, staticType);
-    DartType propagatedThenType = node.thenExpression.propagatedType;
-    DartType propagatedElseType = node.elseExpression.propagatedType;
-    if (propagatedThenType != null || propagatedElseType != null) {
-      if (propagatedThenType == null) {
-        propagatedThenType = staticThenType;
-      }
-      if (propagatedElseType == null) {
-        propagatedElseType = staticElseType;
-      }
-      DartType propagatedType = propagatedThenType.getLeastUpperBound(propagatedElseType);
-      if (propagatedType != null && propagatedType.isMoreSpecificThan(staticType)) {
-        _recordPropagatedType(node, propagatedType);
-      }
-    }
-    return null;
-  }
-
-  /**
-   * The Dart Language Specification, 12.3: <blockquote>The static type of a literal double is
-   * double.</blockquote>
-   */
-  @override
-  Object visitDoubleLiteral(DoubleLiteral node) {
-    _recordStaticType(node, _typeProvider.doubleType);
-    return null;
-  }
-
-  @override
-  Object visitFunctionDeclaration(FunctionDeclaration node) {
-    FunctionExpression function = node.functionExpression;
-    ExecutableElementImpl functionElement = node.element as ExecutableElementImpl;
-    functionElement.returnType = _computeStaticReturnTypeOfFunctionDeclaration(node);
-    _recordPropagatedTypeOfFunction(functionElement, function.body);
-    _recordStaticType(function, functionElement.type);
-    return null;
-  }
-
-  /**
-   * The Dart Language Specification, 12.9: <blockquote>The static type of a function literal of the
-   * form <i>(T<sub>1</sub> a<sub>1</sub>, &hellip;, T<sub>n</sub> a<sub>n</sub>, [T<sub>n+1</sub>
-   * x<sub>n+1</sub> = d1, &hellip;, T<sub>n+k</sub> x<sub>n+k</sub> = dk]) => e</i> is
-   * <i>(T<sub>1</sub>, &hellip;, Tn, [T<sub>n+1</sub> x<sub>n+1</sub>, &hellip;, T<sub>n+k</sub>
-   * x<sub>n+k</sub>]) &rarr; T<sub>0</sub></i>, where <i>T<sub>0</sub></i> is the static type of
-   * <i>e</i>. In any case where <i>T<sub>i</sub>, 1 &lt;= i &lt;= n</i>, is not specified, it is
-   * considered to have been specified as dynamic.
-   *
-   * The static type of a function literal of the form <i>(T<sub>1</sub> a<sub>1</sub>, &hellip;,
-   * T<sub>n</sub> a<sub>n</sub>, {T<sub>n+1</sub> x<sub>n+1</sub> : d1, &hellip;, T<sub>n+k</sub>
-   * x<sub>n+k</sub> : dk}) => e</i> is <i>(T<sub>1</sub>, &hellip;, T<sub>n</sub>, {T<sub>n+1</sub>
-   * x<sub>n+1</sub>, &hellip;, T<sub>n+k</sub> x<sub>n+k</sub>}) &rarr; T<sub>0</sub></i>, where
-   * <i>T<sub>0</sub></i> is the static type of <i>e</i>. In any case where <i>T<sub>i</sub>, 1
-   * &lt;= i &lt;= n</i>, is not specified, it is considered to have been specified as dynamic.
-   *
-   * The static type of a function literal of the form <i>(T<sub>1</sub> a<sub>1</sub>, &hellip;,
-   * T<sub>n</sub> a<sub>n</sub>, [T<sub>n+1</sub> x<sub>n+1</sub> = d1, &hellip;, T<sub>n+k</sub>
-   * x<sub>n+k</sub> = dk]) {s}</i> is <i>(T<sub>1</sub>, &hellip;, T<sub>n</sub>, [T<sub>n+1</sub>
-   * x<sub>n+1</sub>, &hellip;, T<sub>n+k</sub> x<sub>n+k</sub>]) &rarr; dynamic</i>. In any case
-   * where <i>T<sub>i</sub>, 1 &lt;= i &lt;= n</i>, is not specified, it is considered to have been
-   * specified as dynamic.
-   *
-   * The static type of a function literal of the form <i>(T<sub>1</sub> a<sub>1</sub>, &hellip;,
-   * T<sub>n</sub> a<sub>n</sub>, {T<sub>n+1</sub> x<sub>n+1</sub> : d1, &hellip;, T<sub>n+k</sub>
-   * x<sub>n+k</sub> : dk}) {s}</i> is <i>(T<sub>1</sub>, &hellip;, T<sub>n</sub>, {T<sub>n+1</sub>
-   * x<sub>n+1</sub>, &hellip;, T<sub>n+k</sub> x<sub>n+k</sub>}) &rarr; dynamic</i>. In any case
-   * where <i>T<sub>i</sub>, 1 &lt;= i &lt;= n</i>, is not specified, it is considered to have been
-   * specified as dynamic.</blockquote>
-   */
-  @override
-  Object visitFunctionExpression(FunctionExpression node) {
-    if (node.parent is FunctionDeclaration) {
-      // The function type will be resolved and set when we visit the parent node.
-      return null;
-    }
-    ExecutableElementImpl functionElement = node.element as ExecutableElementImpl;
-    functionElement.returnType = _computeStaticReturnTypeOfFunctionExpression(node);
-    _recordPropagatedTypeOfFunction(functionElement, node.body);
-    _recordStaticType(node, node.element.type);
-    return null;
-  }
-
-  /**
-   * The Dart Language Specification, 12.14.4: <blockquote>A function expression invocation <i>i</i>
-   * has the form <i>e<sub>f</sub>(a<sub>1</sub>, &hellip;, a<sub>n</sub>, x<sub>n+1</sub>:
-   * a<sub>n+1</sub>, &hellip;, x<sub>n+k</sub>: a<sub>n+k</sub>)</i>, where <i>e<sub>f</sub></i> is
-   * an expression.
-   *
-   * It is a static type warning if the static type <i>F</i> of <i>e<sub>f</sub></i> may not be
-   * assigned to a function type.
-   *
-   * If <i>F</i> is not a function type, the static type of <i>i</i> is dynamic. Otherwise the
-   * static type of <i>i</i> is the declared return type of <i>F</i>.</blockquote>
-   */
-  @override
-  Object visitFunctionExpressionInvocation(FunctionExpressionInvocation node) {
-    ExecutableElement staticMethodElement = node.staticElement;
-    // Record static return type of the static element.
-    DartType staticStaticType = _computeStaticReturnType(staticMethodElement);
-    _recordStaticType(node, staticStaticType);
-    // Record propagated return type of the static element.
-    DartType staticPropagatedType = _computePropagatedReturnType(staticMethodElement);
-    if (staticPropagatedType != null && (staticStaticType == null || staticPropagatedType.isMoreSpecificThan(staticStaticType))) {
-      _recordPropagatedType(node, staticPropagatedType);
-    }
-    ExecutableElement propagatedMethodElement = node.propagatedElement;
-    if (!identical(propagatedMethodElement, staticMethodElement)) {
-      // Record static return type of the propagated element.
-      DartType propagatedStaticType = _computeStaticReturnType(propagatedMethodElement);
-      if (propagatedStaticType != null && (staticStaticType == null || propagatedStaticType.isMoreSpecificThan(staticStaticType)) && (staticPropagatedType == null || propagatedStaticType.isMoreSpecificThan(staticPropagatedType))) {
-        _recordPropagatedType(node, propagatedStaticType);
-      }
-      // Record propagated return type of the propagated element.
-      DartType propagatedPropagatedType = _computePropagatedReturnType(propagatedMethodElement);
-      if (propagatedPropagatedType != null && (staticStaticType == null || propagatedPropagatedType.isMoreSpecificThan(staticStaticType)) && (staticPropagatedType == null || propagatedPropagatedType.isMoreSpecificThan(staticPropagatedType)) && (propagatedStaticType == null || propagatedPropagatedType.isMoreSpecificThan(propagatedStaticType))) {
-        _recordPropagatedType(node, propagatedPropagatedType);
-      }
-    }
-    return null;
-  }
-
-  /**
-   * The Dart Language Specification, 12.29: <blockquote>An assignable expression of the form
-   * <i>e<sub>1</sub>[e<sub>2</sub>]</i> is evaluated as a method invocation of the operator method
-   * <i>[]</i> on <i>e<sub>1</sub></i> with argument <i>e<sub>2</sub></i>.</blockquote>
-   */
-  @override
-  Object visitIndexExpression(IndexExpression node) {
-    if (node.inSetterContext()) {
-      ExecutableElement staticMethodElement = node.staticElement;
-      DartType staticType = _computeArgumentType(staticMethodElement);
-      _recordStaticType(node, staticType);
-      MethodElement propagatedMethodElement = node.propagatedElement;
-      if (!identical(propagatedMethodElement, staticMethodElement)) {
-        DartType propagatedType = _computeArgumentType(propagatedMethodElement);
-        if (propagatedType != null && propagatedType.isMoreSpecificThan(staticType)) {
-          _recordPropagatedType(node, propagatedType);
-        }
-      }
-    } else {
-      ExecutableElement staticMethodElement = node.staticElement;
-      DartType staticType = _computeStaticReturnType(staticMethodElement);
-      _recordStaticType(node, staticType);
-      MethodElement propagatedMethodElement = node.propagatedElement;
-      if (!identical(propagatedMethodElement, staticMethodElement)) {
-        DartType propagatedType = _computeStaticReturnType(propagatedMethodElement);
-        if (propagatedType != null && propagatedType.isMoreSpecificThan(staticType)) {
-          _recordPropagatedType(node, propagatedType);
-        }
-      }
-    }
-    return null;
-  }
-
-  /**
-   * The Dart Language Specification, 12.11.1: <blockquote>The static type of a new expression of
-   * either the form <i>new T.id(a<sub>1</sub>, &hellip;, a<sub>n</sub>)</i> or the form <i>new
-   * T(a<sub>1</sub>, &hellip;, a<sub>n</sub>)</i> is <i>T</i>.</blockquote>
-   *
-   * The Dart Language Specification, 12.11.2: <blockquote>The static type of a constant object
-   * expression of either the form <i>const T.id(a<sub>1</sub>, &hellip;, a<sub>n</sub>)</i> or the
-   * form <i>const T(a<sub>1</sub>, &hellip;, a<sub>n</sub>)</i> is <i>T</i>. </blockquote>
-   */
-  @override
-  Object visitInstanceCreationExpression(InstanceCreationExpression node) {
-    _recordStaticType(node, node.constructorName.type.type);
-    ConstructorElement element = node.staticElement;
-    if (element != null && "Element" == element.enclosingElement.name) {
-      LibraryElement library = element.library;
-      if (_isHtmlLibrary(library)) {
-        String constructorName = element.name;
-        if ("tag" == constructorName) {
-          DartType returnType = _getFirstArgumentAsTypeWithMap(library, node.argumentList, _HTML_ELEMENT_TO_CLASS_MAP);
-          if (returnType != null) {
-            _recordPropagatedType(node, returnType);
-          }
-        } else {
-          DartType returnType = _getElementNameAsType(library, constructorName, _HTML_ELEMENT_TO_CLASS_MAP);
-          if (returnType != null) {
-            _recordPropagatedType(node, returnType);
-          }
-        }
-      }
-    }
-    return null;
-  }
-
-  /**
-   * The Dart Language Specification, 12.3: <blockquote>The static type of an integer literal is
-   * `int`.</blockquote>
-   */
-  @override
-  Object visitIntegerLiteral(IntegerLiteral node) {
-    _recordStaticType(node, _typeProvider.intType);
-    return null;
-  }
-
-  /**
-   * The Dart Language Specification, 12.31: <blockquote>It is a static warning if <i>T</i> does not
-   * denote a type available in the current lexical scope.
-   *
-   * The static type of an is-expression is `bool`.</blockquote>
-   */
-  @override
-  Object visitIsExpression(IsExpression node) {
-    _recordStaticType(node, _typeProvider.boolType);
-    return null;
-  }
-
-  /**
-   * The Dart Language Specification, 12.6: <blockquote>The static type of a list literal of the
-   * form <i><b>const</b> &lt;E&gt;[e<sub>1</sub>, &hellip;, e<sub>n</sub>]</i> or the form
-   * <i>&lt;E&gt;[e<sub>1</sub>, &hellip;, e<sub>n</sub>]</i> is `List&lt;E&gt;`. The static
-   * type a list literal of the form <i><b>const</b> [e<sub>1</sub>, &hellip;, e<sub>n</sub>]</i> or
-   * the form <i>[e<sub>1</sub>, &hellip;, e<sub>n</sub>]</i> is `List&lt;dynamic&gt;`
-   * .</blockquote>
-   */
-  @override
-  Object visitListLiteral(ListLiteral node) {
-    DartType staticType = _dynamicType;
-    TypeArgumentList typeArguments = node.typeArguments;
-    if (typeArguments != null) {
-      NodeList<TypeName> arguments = typeArguments.arguments;
-      if (arguments != null && arguments.length == 1) {
-        TypeName argumentTypeName = arguments[0];
-        DartType argumentType = _getType(argumentTypeName);
-        if (argumentType != null) {
-          staticType = argumentType;
-        }
-      }
-    }
-    _recordStaticType(node, _typeProvider.listType.substitute4(<DartType> [staticType]));
-    return null;
-  }
-
-  /**
-   * The Dart Language Specification, 12.7: <blockquote>The static type of a map literal of the form
-   * <i><b>const</b> &lt;K, V&gt; {k<sub>1</sub>:e<sub>1</sub>, &hellip;,
-   * k<sub>n</sub>:e<sub>n</sub>}</i> or the form <i>&lt;K, V&gt; {k<sub>1</sub>:e<sub>1</sub>,
-   * &hellip;, k<sub>n</sub>:e<sub>n</sub>}</i> is `Map&lt;K, V&gt;`. The static type a map
-   * literal of the form <i><b>const</b> {k<sub>1</sub>:e<sub>1</sub>, &hellip;,
-   * k<sub>n</sub>:e<sub>n</sub>}</i> or the form <i>{k<sub>1</sub>:e<sub>1</sub>, &hellip;,
-   * k<sub>n</sub>:e<sub>n</sub>}</i> is `Map&lt;dynamic, dynamic&gt;`.
-   *
-   * It is a compile-time error if the first type argument to a map literal is not
-   * <i>String</i>.</blockquote>
-   */
-  @override
-  Object visitMapLiteral(MapLiteral node) {
-    DartType staticKeyType = _dynamicType;
-    DartType staticValueType = _dynamicType;
-    TypeArgumentList typeArguments = node.typeArguments;
-    if (typeArguments != null) {
-      NodeList<TypeName> arguments = typeArguments.arguments;
-      if (arguments != null && arguments.length == 2) {
-        TypeName entryKeyTypeName = arguments[0];
-        DartType entryKeyType = _getType(entryKeyTypeName);
-        if (entryKeyType != null) {
-          staticKeyType = entryKeyType;
-        }
-        TypeName entryValueTypeName = arguments[1];
-        DartType entryValueType = _getType(entryValueTypeName);
-        if (entryValueType != null) {
-          staticValueType = entryValueType;
-        }
-      }
-    }
-    _recordStaticType(node, _typeProvider.mapType.substitute4(<DartType> [staticKeyType, staticValueType]));
-    return null;
-  }
-
-  /**
-   * The Dart Language Specification, 12.15.1: <blockquote>An ordinary method invocation <i>i</i>
-   * has the form <i>o.m(a<sub>1</sub>, &hellip;, a<sub>n</sub>, x<sub>n+1</sub>: a<sub>n+1</sub>,
-   * &hellip;, x<sub>n+k</sub>: a<sub>n+k</sub>)</i>.
-   *
-   * Let <i>T</i> be the static type of <i>o</i>. It is a static type warning if <i>T</i> does not
-   * have an accessible instance member named <i>m</i>. If <i>T.m</i> exists, it is a static warning
-   * if the type <i>F</i> of <i>T.m</i> may not be assigned to a function type.
-   *
-   * If <i>T.m</i> does not exist, or if <i>F</i> is not a function type, the static type of
-   * <i>i</i> is dynamic. Otherwise the static type of <i>i</i> is the declared return type of
-   * <i>F</i>.</blockquote>
-   *
-   * The Dart Language Specification, 11.15.3: <blockquote>A static method invocation <i>i</i> has
-   * the form <i>C.m(a<sub>1</sub>, &hellip;, a<sub>n</sub>, x<sub>n+1</sub>: a<sub>n+1</sub>,
-   * &hellip;, x<sub>n+k</sub>: a<sub>n+k</sub>)</i>.
-   *
-   * It is a static type warning if the type <i>F</i> of <i>C.m</i> may not be assigned to a
-   * function type.
-   *
-   * If <i>F</i> is not a function type, or if <i>C.m</i> does not exist, the static type of i is
-   * dynamic. Otherwise the static type of <i>i</i> is the declared return type of
-   * <i>F</i>.</blockquote>
-   *
-   * The Dart Language Specification, 11.15.4: <blockquote>A super method invocation <i>i</i> has
-   * the form <i>super.m(a<sub>1</sub>, &hellip;, a<sub>n</sub>, x<sub>n+1</sub>: a<sub>n+1</sub>,
-   * &hellip;, x<sub>n+k</sub>: a<sub>n+k</sub>)</i>.
-   *
-   * It is a static type warning if <i>S</i> does not have an accessible instance member named m. If
-   * <i>S.m</i> exists, it is a static warning if the type <i>F</i> of <i>S.m</i> may not be
-   * assigned to a function type.
-   *
-   * If <i>S.m</i> does not exist, or if <i>F</i> is not a function type, the static type of
-   * <i>i</i> is dynamic. Otherwise the static type of <i>i</i> is the declared return type of
-   * <i>F</i>.</blockquote>
-   */
-  @override
-  Object visitMethodInvocation(MethodInvocation node) {
-    SimpleIdentifier methodNameNode = node.methodName;
-    Element staticMethodElement = methodNameNode.staticElement;
-    // Record types of the variable invoked as a function.
-    if (staticMethodElement is VariableElement) {
-      VariableElement variable = staticMethodElement;
-      DartType staticType = variable.type;
-      _recordStaticType(methodNameNode, staticType);
-      DartType propagatedType = _overrideManager.getType(variable);
-      if (propagatedType != null && propagatedType.isMoreSpecificThan(staticType)) {
-        _recordPropagatedType(methodNameNode, propagatedType);
-      }
-    }
-    // Record static return type of the static element.
-    DartType staticStaticType = _computeStaticReturnType(staticMethodElement);
-    _recordStaticType(node, staticStaticType);
-    // Record propagated return type of the static element.
-    DartType staticPropagatedType = _computePropagatedReturnType(staticMethodElement);
-    if (staticPropagatedType != null && (staticStaticType == null || staticPropagatedType.isMoreSpecificThan(staticStaticType))) {
-      _recordPropagatedType(node, staticPropagatedType);
-    }
-    bool needPropagatedType = true;
-    String methodName = methodNameNode.name;
-    if (methodName == "then") {
-      Expression target = node.realTarget;
-      if (target != null) {
-        DartType targetType = target.bestType;
-        if (_isAsyncFutureType(targetType)) {
-          // Future.then(closure) return type is:
-          // 1) the returned Future type, if the closure returns a Future;
-          // 2) Future<valueType>, if the closure returns a value.
-          NodeList<Expression> arguments = node.argumentList.arguments;
-          if (arguments.length == 1) {
-            // TODO(brianwilkerson) Handle the case where both arguments are provided.
-            Expression closureArg = arguments[0];
-            if (closureArg is FunctionExpression) {
-              FunctionExpression closureExpr = closureArg;
-              DartType returnType = _computePropagatedReturnType(closureExpr.element);
-              if (returnType != null) {
-                // prepare the type of the returned Future
-                InterfaceTypeImpl newFutureType;
-                if (_isAsyncFutureType(returnType)) {
-                  newFutureType = returnType as InterfaceTypeImpl;
-                } else {
-                  InterfaceType futureType = targetType as InterfaceType;
-                  newFutureType = new InterfaceTypeImpl.con1(futureType.element);
-                  newFutureType.typeArguments = <DartType> [returnType];
-                }
-                // set the 'then' invocation type
-                _recordPropagatedType(node, newFutureType);
-                needPropagatedType = false;
-                return null;
-              }
-            }
-          }
-        }
-      }
-    } else if (methodName == "\$dom_createEvent") {
-      Expression target = node.realTarget;
-      if (target != null) {
-        DartType targetType = target.bestType;
-        if (targetType is InterfaceType && (targetType.name == "HtmlDocument" || targetType.name == "Document")) {
-          LibraryElement library = targetType.element.library;
-          if (_isHtmlLibrary(library)) {
-            DartType returnType = _getFirstArgumentAsType(library, node.argumentList);
-            if (returnType != null) {
-              _recordPropagatedType(node, returnType);
-              needPropagatedType = false;
-            }
-          }
-        }
-      }
-    } else if (methodName == "query") {
-      Expression target = node.realTarget;
-      if (target == null) {
-        Element methodElement = methodNameNode.bestElement;
-        if (methodElement != null) {
-          LibraryElement library = methodElement.library;
-          if (_isHtmlLibrary(library)) {
-            DartType returnType = _getFirstArgumentAsQuery(library, node.argumentList);
-            if (returnType != null) {
-              _recordPropagatedType(node, returnType);
-              needPropagatedType = false;
-            }
-          }
-        }
-      } else {
-        DartType targetType = target.bestType;
-        if (targetType is InterfaceType && (targetType.name == "HtmlDocument" || targetType.name == "Document")) {
-          LibraryElement library = targetType.element.library;
-          if (_isHtmlLibrary(library)) {
-            DartType returnType = _getFirstArgumentAsQuery(library, node.argumentList);
-            if (returnType != null) {
-              _recordPropagatedType(node, returnType);
-              needPropagatedType = false;
-            }
-          }
-        }
-      }
-    } else if (methodName == "\$dom_createElement") {
-      Expression target = node.realTarget;
-      if (target != null) {
-        DartType targetType = target.bestType;
-        if (targetType is InterfaceType && (targetType.name == "HtmlDocument" || targetType.name == "Document")) {
-          LibraryElement library = targetType.element.library;
-          if (_isHtmlLibrary(library)) {
-            DartType returnType = _getFirstArgumentAsQuery(library, node.argumentList);
-            if (returnType != null) {
-              _recordPropagatedType(node, returnType);
-              needPropagatedType = false;
-            }
-          }
-        }
-      }
-    } else if (methodName == "JS") {
-      DartType returnType = _getFirstArgumentAsType(_typeProvider.objectType.element.library, node.argumentList);
-      if (returnType != null) {
-        _recordPropagatedType(node, returnType);
-        needPropagatedType = false;
-      }
-    } else if (methodName == "getContext") {
-      Expression target = node.realTarget;
-      if (target != null) {
-        DartType targetType = target.bestType;
-        if (targetType is InterfaceType && (targetType.name == "CanvasElement")) {
-          NodeList<Expression> arguments = node.argumentList.arguments;
-          if (arguments.length == 1) {
-            Expression argument = arguments[0];
-            if (argument is StringLiteral) {
-              String value = argument.stringValue;
-              if ("2d" == value) {
-                PropertyAccessorElement getter = targetType.element.getGetter("context2D");
-                if (getter != null) {
-                  DartType returnType = getter.returnType;
-                  if (returnType != null) {
-                    _recordPropagatedType(node, returnType);
-                    needPropagatedType = false;
-                  }
-                }
-              }
-            }
-          }
-        }
-      }
-    }
-    if (needPropagatedType) {
-      Element propagatedElement = methodNameNode.propagatedElement;
-      // HACK: special case for object methods ([toString]) on dynamic expressions.
-      // More special cases in [visitPrefixedIdentfier].
-      if (propagatedElement == null) {
-        propagatedElement = _typeProvider.objectType.getMethod(methodNameNode.name);
-      }
-      if (!identical(propagatedElement, staticMethodElement)) {
-        // Record static return type of the propagated element.
-        DartType propagatedStaticType = _computeStaticReturnType(propagatedElement);
-        if (propagatedStaticType != null && (staticStaticType == null || propagatedStaticType.isMoreSpecificThan(staticStaticType)) && (staticPropagatedType == null || propagatedStaticType.isMoreSpecificThan(staticPropagatedType))) {
-          _recordPropagatedType(node, propagatedStaticType);
-        }
-        // Record propagated return type of the propagated element.
-        DartType propagatedPropagatedType = _computePropagatedReturnType(propagatedElement);
-        if (propagatedPropagatedType != null && (staticStaticType == null || propagatedPropagatedType.isMoreSpecificThan(staticStaticType)) && (staticPropagatedType == null || propagatedPropagatedType.isMoreSpecificThan(staticPropagatedType)) && (propagatedStaticType == null || propagatedPropagatedType.isMoreSpecificThan(propagatedStaticType))) {
-          _recordPropagatedType(node, propagatedPropagatedType);
-        }
-      }
-    }
-    return null;
-  }
-
-  @override
-  Object visitNamedExpression(NamedExpression node) {
-    Expression expression = node.expression;
-    _recordStaticType(node, _getStaticType(expression));
-    _recordPropagatedType(node, expression.propagatedType);
-    return null;
-  }
-
-  /**
-   * The Dart Language Specification, 12.2: <blockquote>The static type of `null` is bottom.
-   * </blockquote>
-   */
-  @override
-  Object visitNullLiteral(NullLiteral node) {
-    _recordStaticType(node, _typeProvider.bottomType);
-    return null;
-  }
-
-  @override
-  Object visitParenthesizedExpression(ParenthesizedExpression node) {
-    Expression expression = node.expression;
-    _recordStaticType(node, _getStaticType(expression));
-    _recordPropagatedType(node, expression.propagatedType);
-    return null;
-  }
-
-  /**
-   * The Dart Language Specification, 12.28: <blockquote>A postfix expression of the form
-   * <i>v++</i>, where <i>v</i> is an identifier, is equivalent to <i>(){var r = v; v = r + 1;
-   * return r}()</i>.
-   *
-   * A postfix expression of the form <i>C.v++</i> is equivalent to <i>(){var r = C.v; C.v = r + 1;
-   * return r}()</i>.
-   *
-   * A postfix expression of the form <i>e1.v++</i> is equivalent to <i>(x){var r = x.v; x.v = r +
-   * 1; return r}(e1)</i>.
-   *
-   * A postfix expression of the form <i>e1[e2]++</i> is equivalent to <i>(a, i){var r = a[i]; a[i]
-   * = r + 1; return r}(e1, e2)</i>
-   *
-   * A postfix expression of the form <i>v--</i>, where <i>v</i> is an identifier, is equivalent to
-   * <i>(){var r = v; v = r - 1; return r}()</i>.
-   *
-   * A postfix expression of the form <i>C.v--</i> is equivalent to <i>(){var r = C.v; C.v = r - 1;
-   * return r}()</i>.
-   *
-   * A postfix expression of the form <i>e1.v--</i> is equivalent to <i>(x){var r = x.v; x.v = r -
-   * 1; return r}(e1)</i>.
-   *
-   * A postfix expression of the form <i>e1[e2]--</i> is equivalent to <i>(a, i){var r = a[i]; a[i]
-   * = r - 1; return r}(e1, e2)</i></blockquote>
-   */
-  @override
-  Object visitPostfixExpression(PostfixExpression node) {
-    Expression operand = node.operand;
-    DartType staticType = _getStaticType(operand);
-    sc.TokenType operator = node.operator.type;
-    if (operator == sc.TokenType.MINUS_MINUS || operator == sc.TokenType.PLUS_PLUS) {
-      DartType intType = _typeProvider.intType;
-      if (identical(_getStaticType(node.operand), intType)) {
-        staticType = intType;
-      }
-    }
-    _recordStaticType(node, staticType);
-    _recordPropagatedType(node, operand.propagatedType);
-    return null;
-  }
-
-  /**
-   * See [visitSimpleIdentifier].
-   */
-  @override
-  Object visitPrefixedIdentifier(PrefixedIdentifier node) {
-    SimpleIdentifier prefixedIdentifier = node.identifier;
-    Element staticElement = prefixedIdentifier.staticElement;
-    DartType staticType = _dynamicType;
-    DartType propagatedType = null;
-    if (staticElement is ClassElement) {
-      if (_isNotTypeLiteral(node)) {
-        staticType = staticElement.type;
-      } else {
-        staticType = _typeProvider.typeType;
-      }
-    } else if (staticElement is FunctionTypeAliasElement) {
-      if (_isNotTypeLiteral(node)) {
-        staticType = staticElement.type;
-      } else {
-        staticType = _typeProvider.typeType;
-      }
-    } else if (staticElement is MethodElement) {
-      staticType = staticElement.type;
-    } else if (staticElement is PropertyAccessorElement) {
-      staticType = _getTypeOfProperty(staticElement, node.prefix.staticType);
-      propagatedType = _getPropertyPropagatedType(staticElement, propagatedType);
-    } else if (staticElement is ExecutableElement) {
-      staticType = staticElement.type;
-    } else if (staticElement is TypeParameterElement) {
-      staticType = staticElement.type;
-    } else if (staticElement is VariableElement) {
-      staticType = staticElement.type;
-    }
-    _recordStaticType(prefixedIdentifier, staticType);
-    _recordStaticType(node, staticType);
-    Element propagatedElement = prefixedIdentifier.propagatedElement;
-    // HACK: special case for object getters ([hashCode] and [runtimeType]) on dynamic expressions.
-    // More special cases in [visitMethodInvocation].
-    if (propagatedElement == null) {
-      propagatedElement = _typeProvider.objectType.getGetter(prefixedIdentifier.name);
-    }
-    if (propagatedElement is ClassElement) {
-      if (_isNotTypeLiteral(node)) {
-        propagatedType = (propagatedElement as ClassElement).type;
-      } else {
-        propagatedType = _typeProvider.typeType;
-      }
-    } else if (propagatedElement is FunctionTypeAliasElement) {
-      propagatedType = (propagatedElement as FunctionTypeAliasElement).type;
-    } else if (propagatedElement is MethodElement) {
-      propagatedType = (propagatedElement as MethodElement).type;
-    } else if (propagatedElement is PropertyAccessorElement) {
-      propagatedType = _getTypeOfProperty(propagatedElement as PropertyAccessorElement, node.prefix.staticType);
-      propagatedType = _getPropertyPropagatedType(propagatedElement, propagatedType);
-    } else if (propagatedElement is ExecutableElement) {
-      propagatedType = (propagatedElement as ExecutableElement).type;
-    } else if (propagatedElement is TypeParameterElement) {
-      propagatedType = (propagatedElement as TypeParameterElement).type;
-    } else if (propagatedElement is VariableElement) {
-      propagatedType = (propagatedElement as VariableElement).type;
-    }
-    DartType overriddenType = _overrideManager.getType(propagatedElement);
-    if (propagatedType == null || (overriddenType != null && overriddenType.isMoreSpecificThan(propagatedType))) {
-      propagatedType = overriddenType;
-    }
-    if (propagatedType != null && propagatedType.isMoreSpecificThan(staticType)) {
-      _recordPropagatedType(prefixedIdentifier, propagatedType);
-      _recordPropagatedType(node, propagatedType);
-    }
-    return null;
-  }
-
-  /**
-   * The Dart Language Specification, 12.27: <blockquote>A unary expression <i>u</i> of the form
-   * <i>op e</i> is equivalent to a method invocation <i>expression e.op()</i>. An expression of the
-   * form <i>op super</i> is equivalent to the method invocation <i>super.op()<i>.</blockquote>
-   */
-  @override
-  Object visitPrefixExpression(PrefixExpression node) {
-    sc.TokenType operator = node.operator.type;
-    if (operator == sc.TokenType.BANG) {
-      _recordStaticType(node, _typeProvider.boolType);
-    } else {
-      // The other cases are equivalent to invoking a method.
-      ExecutableElement staticMethodElement = node.staticElement;
-      DartType staticType = _computeStaticReturnType(staticMethodElement);
-      if (operator == sc.TokenType.MINUS_MINUS || operator == sc.TokenType.PLUS_PLUS) {
-        DartType intType = _typeProvider.intType;
-        if (identical(_getStaticType(node.operand), intType)) {
-          staticType = intType;
-        }
-      }
-      _recordStaticType(node, staticType);
-      MethodElement propagatedMethodElement = node.propagatedElement;
-      if (!identical(propagatedMethodElement, staticMethodElement)) {
-        DartType propagatedType = _computeStaticReturnType(propagatedMethodElement);
-        if (propagatedType != null && propagatedType.isMoreSpecificThan(staticType)) {
-          _recordPropagatedType(node, propagatedType);
-        }
-      }
-    }
-    return null;
-  }
-
-  /**
-   * The Dart Language Specification, 12.13: <blockquote> Property extraction allows for a member of
-   * an object to be concisely extracted from the object. If <i>o</i> is an object, and if <i>m</i>
-   * is the name of a method member of <i>o</i>, then
-   * * <i>o.m</i> is defined to be equivalent to: <i>(r<sub>1</sub>, &hellip;, r<sub>n</sub>,
-   * {p<sub>1</sub> : d<sub>1</sub>, &hellip;, p<sub>k</sub> : d<sub>k</sub>}){return
-   * o.m(r<sub>1</sub>, &hellip;, r<sub>n</sub>, p<sub>1</sub>: p<sub>1</sub>, &hellip;,
-   * p<sub>k</sub>: p<sub>k</sub>);}</i> if <i>m</i> has required parameters <i>r<sub>1</sub>,
-   * &hellip;, r<sub>n</sub></i>, and named parameters <i>p<sub>1</sub> &hellip; p<sub>k</sub></i>
-   * with defaults <i>d<sub>1</sub>, &hellip;, d<sub>k</sub></i>.
-   * * <i>(r<sub>1</sub>, &hellip;, r<sub>n</sub>, [p<sub>1</sub> = d<sub>1</sub>, &hellip;,
-   * p<sub>k</sub> = d<sub>k</sub>]){return o.m(r<sub>1</sub>, &hellip;, r<sub>n</sub>,
-   * p<sub>1</sub>, &hellip;, p<sub>k</sub>);}</i> if <i>m</i> has required parameters
-   * <i>r<sub>1</sub>, &hellip;, r<sub>n</sub></i>, and optional positional parameters
-   * <i>p<sub>1</sub> &hellip; p<sub>k</sub></i> with defaults <i>d<sub>1</sub>, &hellip;,
-   * d<sub>k</sub></i>.
-   * Otherwise, if <i>m</i> is the name of a getter member of <i>o</i> (declared implicitly or
-   * explicitly) then <i>o.m</i> evaluates to the result of invoking the getter. </blockquote>
-   *
-   * The Dart Language Specification, 12.17: <blockquote> ... a getter invocation <i>i</i> of the
-   * form <i>e.m</i> ...
-   *
-   * Let <i>T</i> be the static type of <i>e</i>. It is a static type warning if <i>T</i> does not
-   * have a getter named <i>m</i>.
-   *
-   * The static type of <i>i</i> is the declared return type of <i>T.m</i>, if <i>T.m</i> exists;
-   * otherwise the static type of <i>i</i> is dynamic.
-   *
-   * ... a getter invocation <i>i</i> of the form <i>C.m</i> ...
-   *
-   * It is a static warning if there is no class <i>C</i> in the enclosing lexical scope of
-   * <i>i</i>, or if <i>C</i> does not declare, implicitly or explicitly, a getter named <i>m</i>.
-   *
-   * The static type of <i>i</i> is the declared return type of <i>C.m</i> if it exists or dynamic
-   * otherwise.
-   *
-   * ... a top-level getter invocation <i>i</i> of the form <i>m</i>, where <i>m</i> is an
-   * identifier ...
-   *
-   * The static type of <i>i</i> is the declared return type of <i>m</i>.</blockquote>
-   */
-  @override
-  Object visitPropertyAccess(PropertyAccess node) {
-    SimpleIdentifier propertyName = node.propertyName;
-    Element staticElement = propertyName.staticElement;
-    DartType staticType = _dynamicType;
-    if (staticElement is MethodElement) {
-      staticType = staticElement.type;
-    } else if (staticElement is PropertyAccessorElement) {
-      Expression realTarget = node.realTarget;
-      staticType = _getTypeOfProperty(staticElement, realTarget != null ? _getStaticType(realTarget) : null);
-    } else {
-      // TODO(brianwilkerson) Report this internal error.
-    }
-    _recordStaticType(propertyName, staticType);
-    _recordStaticType(node, staticType);
-    Element propagatedElement = propertyName.propagatedElement;
-    DartType propagatedType = _overrideManager.getType(propagatedElement);
-    if (propagatedElement is MethodElement) {
-      propagatedType = propagatedElement.type;
-    } else if (propagatedElement is PropertyAccessorElement) {
-      Expression realTarget = node.realTarget;
-      propagatedType = _getTypeOfProperty(propagatedElement, realTarget != null ? realTarget.bestType : null);
-    } else {
-      // TODO(brianwilkerson) Report this internal error.
-    }
-    if (propagatedType != null && propagatedType.isMoreSpecificThan(staticType)) {
-      _recordPropagatedType(propertyName, propagatedType);
-      _recordPropagatedType(node, propagatedType);
-    }
-    return null;
-  }
-
-  /**
-   * The Dart Language Specification, 12.9: <blockquote>The static type of a rethrow expression is
-   * bottom.</blockquote>
-   */
-  @override
-  Object visitRethrowExpression(RethrowExpression node) {
-    _recordStaticType(node, _typeProvider.bottomType);
-    return null;
-  }
-
-  /**
-   * The Dart Language Specification, 12.30: <blockquote>Evaluation of an identifier expression
-   * <i>e</i> of the form <i>id</i> proceeds as follows:
-   *
-   * Let <i>d</i> be the innermost declaration in the enclosing lexical scope whose name is
-   * <i>id</i>. If no such declaration exists in the lexical scope, let <i>d</i> be the declaration
-   * of the inherited member named <i>id</i> if it exists.
-   * * If <i>d</i> is a class or type alias <i>T</i>, the value of <i>e</i> is the unique instance
-   * of class `Type` reifying <i>T</i>.
-   * * If <i>d</i> is a type parameter <i>T</i>, then the value of <i>e</i> is the value of the
-   * actual type argument corresponding to <i>T</i> that was passed to the generative constructor
-   * that created the current binding of this. We are assured that this is well defined, because if
-   * we were in a static member the reference to <i>T</i> would be a compile-time error.
-   * * If <i>d</i> is a library variable then:
-   * * If <i>d</i> is of one of the forms <i>var v = e<sub>i</sub>;</i>, <i>T v =
-   * e<sub>i</sub>;</i>, <i>final v = e<sub>i</sub>;</i>, <i>final T v = e<sub>i</sub>;</i>, and no
-   * value has yet been stored into <i>v</i> then the initializer expression <i>e<sub>i</sub></i> is
-   * evaluated. If, during the evaluation of <i>e<sub>i</sub></i>, the getter for <i>v</i> is
-   * referenced, a CyclicInitializationError is thrown. If the evaluation succeeded yielding an
-   * object <i>o</i>, let <i>r = o</i>, otherwise let <i>r = null</i>. In any case, <i>r</i> is
-   * stored into <i>v</i>. The value of <i>e</i> is <i>r</i>.
-   * * If <i>d</i> is of one of the forms <i>const v = e;</i> or <i>const T v = e;</i> the result
-   * of the getter is the value of the compile time constant <i>e</i>. Otherwise
-   * * <i>e</i> evaluates to the current binding of <i>id</i>.
-   * * If <i>d</i> is a local variable or formal parameter then <i>e</i> evaluates to the current
-   * binding of <i>id</i>.
-   * * If <i>d</i> is a static method, top level function or local function then <i>e</i>
-   * evaluates to the function defined by <i>d</i>.
-   * * If <i>d</i> is the declaration of a static variable or static getter declared in class
-   * <i>C</i>, then <i>e</i> is equivalent to the getter invocation <i>C.id</i>.
-   * * If <i>d</i> is the declaration of a top level getter, then <i>e</i> is equivalent to the
-   * getter invocation <i>id</i>.
-   * * Otherwise, if <i>e</i> occurs inside a top level or static function (be it function,
-   * method, getter, or setter) or variable initializer, evaluation of e causes a NoSuchMethodError
-   * to be thrown.
-   * * Otherwise <i>e</i> is equivalent to the property extraction <i>this.id</i>.
-   * </blockquote>
-   */
-  @override
-  Object visitSimpleIdentifier(SimpleIdentifier node) {
-    Element element = node.staticElement;
-    DartType staticType = _dynamicType;
-    if (element is ClassElement) {
-      if (_isNotTypeLiteral(node)) {
-        staticType = element.type;
-      } else {
-        staticType = _typeProvider.typeType;
-      }
-    } else if (element is FunctionTypeAliasElement) {
-      if (_isNotTypeLiteral(node)) {
-        staticType = element.type;
-      } else {
-        staticType = _typeProvider.typeType;
-      }
-    } else if (element is MethodElement) {
-      staticType = element.type;
-    } else if (element is PropertyAccessorElement) {
-      staticType = _getTypeOfProperty(element, null);
-    } else if (element is ExecutableElement) {
-      staticType = element.type;
-    } else if (element is TypeParameterElement) {
-      staticType = _typeProvider.typeType;
-    } else if (element is VariableElement) {
-      VariableElement variable = element;
-      staticType = _promoteManager.getStaticType(variable);
-    } else if (element is PrefixElement) {
-      return null;
-    } else {
-      staticType = _dynamicType;
-    }
-    _recordStaticType(node, staticType);
-    // TODO(brianwilkerson) I think we want to repeat the logic above using the propagated element
-    // to get another candidate for the propagated type.
-    DartType propagatedType = _getPropertyPropagatedType(element, null);
-    if (propagatedType == null) {
-      DartType overriddenType = _overrideManager.getType(element);
-      if (propagatedType == null || overriddenType != null && overriddenType.isMoreSpecificThan(propagatedType)) {
-        propagatedType = overriddenType;
-      }
-    }
-    if (propagatedType != null && propagatedType.isMoreSpecificThan(staticType)) {
-      _recordPropagatedType(node, propagatedType);
-    }
-    return null;
-  }
-
-  /**
-   * The Dart Language Specification, 12.5: <blockquote>The static type of a string literal is
-   * `String`.</blockquote>
-   */
-  @override
-  Object visitSimpleStringLiteral(SimpleStringLiteral node) {
-    _recordStaticType(node, _typeProvider.stringType);
-    return null;
-  }
-
-  /**
-   * The Dart Language Specification, 12.5: <blockquote>The static type of a string literal is
-   * `String`.</blockquote>
-   */
-  @override
-  Object visitStringInterpolation(StringInterpolation node) {
-    _recordStaticType(node, _typeProvider.stringType);
-    return null;
-  }
-
-  @override
-  Object visitSuperExpression(SuperExpression node) {
-    if (_thisType == null) {
-      // TODO(brianwilkerson) Report this error if it hasn't already been reported
-      _recordStaticType(node, _dynamicType);
-    } else {
-      _recordStaticType(node, _thisType);
-    }
-    return null;
-  }
-
-  @override
-  Object visitSymbolLiteral(SymbolLiteral node) {
-    _recordStaticType(node, _typeProvider.symbolType);
-    return null;
-  }
-
-  /**
-   * The Dart Language Specification, 12.10: <blockquote>The static type of `this` is the
-   * interface of the immediately enclosing class.</blockquote>
-   */
-  @override
-  Object visitThisExpression(ThisExpression node) {
-    if (_thisType == null) {
-      // TODO(brianwilkerson) Report this error if it hasn't already been reported
-      _recordStaticType(node, _dynamicType);
-    } else {
-      _recordStaticType(node, _thisType);
-    }
-    return null;
-  }
-
-  /**
-   * The Dart Language Specification, 12.8: <blockquote>The static type of a throw expression is
-   * bottom.</blockquote>
-   */
-  @override
-  Object visitThrowExpression(ThrowExpression node) {
-    _recordStaticType(node, _typeProvider.bottomType);
-    return null;
-  }
-
-  @override
-  Object visitVariableDeclaration(VariableDeclaration node) {
-    Expression initializer = node.initializer;
-    if (initializer != null) {
-      DartType rightType = initializer.bestType;
-      SimpleIdentifier name = node.name;
-      _recordPropagatedType(name, rightType);
-      VariableElement element = name.staticElement as VariableElement;
-      if (element != null) {
-        _resolver.overrideVariable(element, rightType, true);
-      }
-    }
-    return null;
-  }
-
-  /**
-   * Record that the static type of the given node is the type of the second argument to the method
-   * represented by the given element.
-   *
-   * @param element the element representing the method invoked by the given node
-   */
-  DartType _computeArgumentType(ExecutableElement element) {
-    if (element != null) {
-      List<ParameterElement> parameters = element.parameters;
-      if (parameters != null && parameters.length == 2) {
-        return parameters[1].type;
-      }
-    }
-    return _dynamicType;
-  }
-
-  /**
-   * Compute the propagated return type of the method or function represented by the given element.
-   *
-   * @param element the element representing the method or function invoked by the given node
-   * @return the propagated return type that was computed
-   */
-  DartType _computePropagatedReturnType(Element element) {
-    if (element is ExecutableElement) {
-      return _propagatedReturnTypes[element];
-    }
-    return null;
-  }
-
-  /**
-   * Given a function body, compute the propagated return type of the function. The propagated
-   * return type of functions with a block body is the least upper bound of all
-   * [ReturnStatement] expressions, with an expression body it is the type of the expression.
-   *
-   * @param body the boy of the function whose propagated return type is to be computed
-   * @return the propagated return type that was computed
-   */
-  DartType _computePropagatedReturnTypeOfFunction(FunctionBody body) {
-    if (body is ExpressionFunctionBody) {
-      ExpressionFunctionBody expressionBody = body;
-      return expressionBody.expression.bestType;
-    }
-    if (body is BlockFunctionBody) {
-      GeneralizingAstVisitor_StaticTypeAnalyzer_computePropagatedReturnTypeOfFunction visitor
-          = new GeneralizingAstVisitor_StaticTypeAnalyzer_computePropagatedReturnTypeOfFunction();
-      body.accept(visitor);
-      return visitor.result;
-    }
-    return null;
-  }
-
-  /**
-   * Compute the static return type of the method or function represented by the given element.
-   *
-   * @param element the element representing the method or function invoked by the given node
-   * @return the static return type that was computed
-   */
-  DartType _computeStaticReturnType(Element element) {
-    if (element is PropertyAccessorElement) {
-      //
-      // This is a function invocation expression disguised as something else. We are invoking a
-      // getter and then invoking the returned function.
-      //
-      FunctionType propertyType = element.type;
-      if (propertyType != null) {
-        DartType returnType = propertyType.returnType;
-        if (returnType.isDartCoreFunction) {
-          return _dynamicType;
-        } else if (returnType is InterfaceType) {
-          MethodElement callMethod = returnType.lookUpMethod(FunctionElement.CALL_METHOD_NAME, _resolver.definingLibrary);
-          if (callMethod != null) {
-            return callMethod.type.returnType;
-          }
-        } else if (returnType is FunctionType) {
-          DartType innerReturnType = returnType.returnType;
-          if (innerReturnType != null) {
-            return innerReturnType;
-          }
-        }
-        if (returnType != null) {
-          return returnType;
-        }
-      }
-    } else if (element is ExecutableElement) {
-      FunctionType type = element.type;
-      if (type != null) {
-        // TODO(brianwilkerson) Figure out the conditions under which the type is null.
-        return type.returnType;
-      }
-    } else if (element is VariableElement) {
-      VariableElement variable = element;
-      DartType variableType = _promoteManager.getStaticType(variable);
-      if (variableType is FunctionType) {
-        return variableType.returnType;
-      }
-    }
-    return _dynamicType;
-  }
-
-  /**
-   * Given a function declaration, compute the return static type of the function. The return type
-   * of functions with a block body is `dynamicType`, with an expression body it is the type
-   * of the expression.
-   *
-   * @param node the function expression whose static return type is to be computed
-   * @return the static return type that was computed
-   */
-  DartType _computeStaticReturnTypeOfFunctionDeclaration(FunctionDeclaration node) {
-    TypeName returnType = node.returnType;
-    if (returnType == null) {
-      return _dynamicType;
-    }
-    return returnType.type;
-  }
-
-  /**
-   * Given a function expression, compute the return type of the function. The return type of
-   * functions with a block body is `dynamicType`, with an expression body it is the type of
-   * the expression.
-   *
-   * @param node the function expression whose return type is to be computed
-   * @return the return type that was computed
-   */
-  DartType _computeStaticReturnTypeOfFunctionExpression(FunctionExpression node) {
-    FunctionBody body = node.body;
-    if (body is ExpressionFunctionBody) {
-      return _getStaticType(body.expression);
-    }
-    return _dynamicType;
-  }
-
-  /**
-   * If the given element name can be mapped to the name of a class defined within the given
-   * library, return the type specified by the argument.
-   *
-   * @param library the library in which the specified type would be defined
-   * @param elementName the name of the element for which a type is being sought
-   * @param nameMap an optional map used to map the element name to a type name
-   * @return the type specified by the first argument in the argument list
-   */
-  DartType _getElementNameAsType(LibraryElement library, String elementName, HashMap<String, String> nameMap) {
-    if (elementName != null) {
-      if (nameMap != null) {
-        elementName = nameMap[elementName.toLowerCase()];
-      }
-      ClassElement returnType = library.getType(elementName);
-      if (returnType != null) {
-        return returnType.type;
-      }
-    }
-    return null;
-  }
-
-  /**
-   * If the given argument list contains at least one argument, and if the argument is a simple
-   * string literal, then parse that argument as a query string and return the type specified by the
-   * argument.
-   *
-   * @param library the library in which the specified type would be defined
-   * @param argumentList the list of arguments from which a type is to be extracted
-   * @return the type specified by the first argument in the argument list
-   */
-  DartType _getFirstArgumentAsQuery(LibraryElement library, ArgumentList argumentList) {
-    String argumentValue = _getFirstArgumentAsString(argumentList);
-    if (argumentValue != null) {
-      //
-      // If the query has spaces, full parsing is required because it might be:
-      //   E[text='warning text']
-      //
-      if (StringUtilities.indexOf1(argumentValue, 0, 0x20) >= 0) {
-        return null;
-      }
-      //
-      // Otherwise, try to extract the tag based on http://www.w3.org/TR/CSS2/selector.html.
-      //
-      String tag = argumentValue;
-      tag = StringUtilities.substringBeforeChar(tag, 0x3A);
-      tag = StringUtilities.substringBeforeChar(tag, 0x5B);
-      tag = StringUtilities.substringBeforeChar(tag, 0x2E);
-      tag = StringUtilities.substringBeforeChar(tag, 0x23);
-      tag = _HTML_ELEMENT_TO_CLASS_MAP[tag.toLowerCase()];
-      ClassElement returnType = library.getType(tag);
-      if (returnType != null) {
-        return returnType.type;
-      }
-    }
-    return null;
-  }
-
-  /**
-   * If the given argument list contains at least one argument, and if the argument is a simple
-   * string literal, return the String value of the argument.
-   *
-   * @param argumentList the list of arguments from which a string value is to be extracted
-   * @return the string specified by the first argument in the argument list
-   */
-  String _getFirstArgumentAsString(ArgumentList argumentList) {
-    NodeList<Expression> arguments = argumentList.arguments;
-    if (arguments.length > 0) {
-      Expression argument = arguments[0];
-      if (argument is SimpleStringLiteral) {
-        return argument.value;
-      }
-    }
-    return null;
-  }
-
-  /**
-   * If the given argument list contains at least one argument, and if the argument is a simple
-   * string literal, and if the value of the argument is the name of a class defined within the
-   * given library, return the type specified by the argument.
-   *
-   * @param library the library in which the specified type would be defined
-   * @param argumentList the list of arguments from which a type is to be extracted
-   * @return the type specified by the first argument in the argument list
-   */
-  DartType _getFirstArgumentAsType(LibraryElement library, ArgumentList argumentList) => _getFirstArgumentAsTypeWithMap(library, argumentList, null);
-
-  /**
-   * If the given argument list contains at least one argument, and if the argument is a simple
-   * string literal, and if the value of the argument is the name of a class defined within the
-   * given library, return the type specified by the argument.
-   *
-   * @param library the library in which the specified type would be defined
-   * @param argumentList the list of arguments from which a type is to be extracted
-   * @param nameMap an optional map used to map the element name to a type name
-   * @return the type specified by the first argument in the argument list
-   */
-  DartType _getFirstArgumentAsTypeWithMap(LibraryElement library, ArgumentList argumentList, HashMap<String, String> nameMap) => _getElementNameAsType(library, _getFirstArgumentAsString(argumentList), nameMap);
-
-  /**
-   * Return the propagated type of the given [Element], or `null`.
-   */
-  DartType _getPropertyPropagatedType(Element element, DartType currentType) {
-    if (element is PropertyAccessorElement) {
-      PropertyAccessorElement accessor = element;
-      if (accessor.isGetter) {
-        PropertyInducingElement variable = accessor.variable;
-        DartType propagatedType = variable.propagatedType;
-        if (currentType == null || propagatedType != null && propagatedType.isMoreSpecificThan(currentType)) {
-          return propagatedType;
-        }
-      }
-    }
-    return currentType;
-  }
-
-  /**
-   * Return the static type of the given expression.
-   *
-   * @param expression the expression whose type is to be returned
-   * @return the static type of the given expression
-   */
-  DartType _getStaticType(Expression expression) {
-    DartType type = expression.staticType;
-    if (type == null) {
-      // TODO(brianwilkerson) Determine the conditions for which the static type is null.
-      return _dynamicType;
-    }
-    return type;
-  }
-
-  /**
-   * Return the type represented by the given type name.
-   *
-   * @param typeName the type name representing the type to be returned
-   * @return the type represented by the type name
-   */
-  DartType _getType(TypeName typeName) {
-    DartType type = typeName.type;
-    if (type == null) {
-      //TODO(brianwilkerson) Determine the conditions for which the type is null.
-      return _dynamicType;
-    }
-    return type;
-  }
-
-  /**
-   * Return the type that should be recorded for a node that resolved to the given accessor.
-   *
-   * @param accessor the accessor that the node resolved to
-   * @param context if the accessor element has context [by being the RHS of a
-   *          [PrefixedIdentifier] or [PropertyAccess]], and the return type of the
-   *          accessor is a parameter type, then the type of the LHS can be used to get more
-   *          specific type information
-   * @return the type that should be recorded for a node that resolved to the given accessor
-   */
-  DartType _getTypeOfProperty(PropertyAccessorElement accessor, DartType context) {
-    FunctionType functionType = accessor.type;
-    if (functionType == null) {
-      // TODO(brianwilkerson) Report this internal error. This happens when we are analyzing a
-      // reference to a property before we have analyzed the declaration of the property or when
-      // the property does not have a defined type.
-      return _dynamicType;
-    }
-    if (accessor.isSetter) {
-      List<DartType> parameterTypes = functionType.normalParameterTypes;
-      if (parameterTypes != null && parameterTypes.length > 0) {
-        return parameterTypes[0];
-      }
-      PropertyAccessorElement getter = accessor.variable.getter;
-      if (getter != null) {
-        functionType = getter.type;
-        if (functionType != null) {
-          return functionType.returnType;
-        }
-      }
-      return _dynamicType;
-    }
-    DartType returnType = functionType.returnType;
-    if (returnType is TypeParameterType && context is InterfaceType) {
-      // if the return type is a TypeParameter, we try to use the context [that the function is being
-      // called on] to get a more accurate returnType type
-      InterfaceType interfaceTypeContext = context;
-      //      Type[] argumentTypes = interfaceTypeContext.getTypeArguments();
-      List<TypeParameterElement> typeParameterElements = interfaceTypeContext.element != null ? interfaceTypeContext.element.typeParameters : null;
-      if (typeParameterElements != null) {
-        for (int i = 0; i < typeParameterElements.length; i++) {
-          TypeParameterElement typeParameterElement = typeParameterElements[i];
-          if (returnType.name == typeParameterElement.name) {
-            return interfaceTypeContext.typeArguments[i];
-          }
-        }
-        // TODO(jwren) troubleshoot why call to substitute doesn't work
-        //        Type[] parameterTypes = TypeParameterTypeImpl.getTypes(parameterElements);
-        //        return returnType.substitute(argumentTypes, parameterTypes);
-      }
-    }
-    return returnType;
-  }
-
-  /**
-   * Return `true` if the given [Type] is the `Future` form the 'dart:async'
-   * library.
-   */
-  bool _isAsyncFutureType(DartType type) => type is InterfaceType && type.name == "Future" && _isAsyncLibrary(type.element.library);
-
-  /**
-   * Return `true` if the given library is the 'dart:async' library.
-   *
-   * @param library the library being tested
-   * @return `true` if the library is 'dart:async'
-   */
-  bool _isAsyncLibrary(LibraryElement library) => library.name == "dart.async";
-
-  /**
-   * Return `true` if the given library is the 'dart:html' library.
-   *
-   * @param library the library being tested
-   * @return `true` if the library is 'dart:html'
-   */
-  bool _isHtmlLibrary(LibraryElement library) => library != null && "dart.dom.html" == library.name;
-
-  /**
-   * Return `true` if the given node is not a type literal.
-   *
-   * @param node the node being tested
-   * @return `true` if the given node is not a type literal
-   */
-  bool _isNotTypeLiteral(Identifier node) {
-    AstNode parent = node.parent;
-    return parent is TypeName || (parent is PrefixedIdentifier && (parent.parent is TypeName || identical(parent.prefix, node))) || (parent is PropertyAccess && identical(parent.target, node)) || (parent is MethodInvocation && identical(node, parent.target));
-  }
-
-  /**
-   * Record that the propagated type of the given node is the given type.
-   *
-   * @param expression the node whose type is to be recorded
-   * @param type the propagated type of the node
-   */
-  void _recordPropagatedType(Expression expression, DartType type) {
-    if (type != null && !type.isDynamic && !type.isBottom) {
-      expression.propagatedType = type;
-    }
-  }
-
-  /**
-   * Given a function element and its body, compute and record the propagated return type of the
-   * function.
-   *
-   * @param functionElement the function element to record propagated return type for
-   * @param body the boy of the function whose propagated return type is to be computed
-   * @return the propagated return type that was computed, may be `null` if it is not more
-   *         specific than the static return type.
-   */
-  void _recordPropagatedTypeOfFunction(ExecutableElement functionElement, FunctionBody body) {
-    DartType propagatedReturnType = _computePropagatedReturnTypeOfFunction(body);
-    if (propagatedReturnType == null) {
-      return;
-    }
-    // Ignore 'bottom' type.
-    if (propagatedReturnType.isBottom) {
-      return;
-    }
-    // Record only if we inferred more specific type.
-    DartType staticReturnType = functionElement.returnType;
-    if (!propagatedReturnType.isMoreSpecificThan(staticReturnType)) {
-      return;
-    }
-    // OK, do record.
-    _propagatedReturnTypes[functionElement] = propagatedReturnType;
-  }
-
-  /**
-   * Record that the static type of the given node is the given type.
-   *
-   * @param expression the node whose type is to be recorded
-   * @param type the static type of the node
-   */
-  void _recordStaticType(Expression expression, DartType type) {
-    if (type == null) {
-      expression.staticType = _dynamicType;
-    } else {
-      expression.staticType = type;
-    }
-  }
-
-  /**
-   * Attempts to make a better guess for the static type of the given binary expression.
-   *
-   * @param node the binary expression to analyze
-   * @param staticType the static type of the expression as resolved
-   * @return the better type guess, or the same static type as given
-   */
-  DartType _refineBinaryExpressionType(BinaryExpression node, DartType staticType) {
-    sc.TokenType operator = node.operator.type;
-    // bool
-    if (operator == sc.TokenType.AMPERSAND_AMPERSAND || operator == sc.TokenType.BAR_BAR || operator == sc.TokenType.EQ_EQ || operator == sc.TokenType.BANG_EQ) {
-      return _typeProvider.boolType;
-    }
-    DartType intType = _typeProvider.intType;
-    if (_getStaticType(node.leftOperand) == intType) {
-      // int op double
-      if (operator == sc.TokenType.MINUS || operator == sc.TokenType.PERCENT || operator == sc.TokenType.PLUS || operator == sc.TokenType.STAR) {
-        DartType doubleType = _typeProvider.doubleType;
-        if (_getStaticType(node.rightOperand) == doubleType) {
-          return doubleType;
-        }
-      }
-      // int op int
-      if (operator == sc.TokenType.MINUS || operator == sc.TokenType.PERCENT || operator == sc.TokenType.PLUS || operator == sc.TokenType.STAR || operator == sc.TokenType.TILDE_SLASH) {
-        if (_getStaticType(node.rightOperand) == intType) {
-          staticType = intType;
-        }
-      }
-    }
-    // default
-    return staticType;
-  }
-
-  get thisType_J2DAccessor => _thisType;
-
-  set thisType_J2DAccessor(__v) => _thisType = __v;
-}
-
-/**
  * Instances of this class manage the knowledge of what the set of subtypes are for a given type.
  */
 class SubtypeManager {
@@ -24033,7 +14247,9 @@
       buffer.write(" in ");
       buffer.write(source.fullName);
       buffer.write(" was not set while trying to resolve types.");
-      AnalysisEngine.instance.logger.logError2(buffer.toString(), new CaughtException(new AnalysisException(), null));
+      AnalysisEngine.instance.logger.logError(
+          buffer.toString(),
+          new CaughtException(new AnalysisException(), null));
     } else {
       ClassElement definingClass = element.enclosingElement as ClassElement;
       element.returnType = definingClass.type;
@@ -24101,7 +14317,9 @@
       buffer.write(" in ");
       buffer.write(source.fullName);
       buffer.write(" was not set while trying to resolve types.");
-      AnalysisEngine.instance.logger.logError2(buffer.toString(), new CaughtException(new AnalysisException(), null));
+      AnalysisEngine.instance.logger.logError(
+          buffer.toString(),
+          new CaughtException(new AnalysisException(), null));
     }
     element.returnType = _computeReturnType(node.returnType);
     FunctionTypeImpl type = new FunctionTypeImpl.con1(element);
@@ -24154,7 +14372,9 @@
       buffer.write(" in ");
       buffer.write(source.fullName);
       buffer.write(" was not set while trying to resolve types.");
-      AnalysisEngine.instance.logger.logError2(buffer.toString(), new CaughtException(new AnalysisException(), null));
+      AnalysisEngine.instance.logger.logError(
+          buffer.toString(),
+          new CaughtException(new AnalysisException(), null));
     }
     element.returnType = _computeReturnType(node.returnType);
     FunctionTypeImpl type = new FunctionTypeImpl.con1(element);
diff --git a/pkg/analyzer/lib/src/generated/sdk_io.dart b/pkg/analyzer/lib/src/generated/sdk_io.dart
index 920dccc..565f080 100644
--- a/pkg/analyzer/lib/src/generated/sdk_io.dart
+++ b/pkg/analyzer/lib/src/generated/sdk_io.dart
@@ -7,6 +7,8 @@
 
 library engine.sdk.io;
 
+import 'package:analyzer/src/generated/java_engine.dart';
+
 import 'java_core.dart';
 import 'java_io.dart';
 import 'java_engine_io.dart';
@@ -253,8 +255,10 @@
         String path = library.shortName;
         try {
           return new FileBasedSource.con2(parseUriWithException(path), file);
-        } on URISyntaxException catch (exception) {
-          AnalysisEngine.instance.logger.logInformation2("Failed to create URI: $path", exception);
+        } on URISyntaxException catch (exception, stackTrace) {
+          AnalysisEngine.instance.logger.logInformation(
+              "Failed to create URI: $path",
+              new CaughtException(exception, stackTrace));
           return null;
         }
       }
@@ -263,8 +267,10 @@
         String path = "${library.shortName}/${filePath.substring(libraryPath.length + 1)}";
         try {
           return new FileBasedSource.con2(parseUriWithException(path), file);
-        } on URISyntaxException catch (exception) {
-          AnalysisEngine.instance.logger.logInformation2("Failed to create URI: $path", exception);
+        } on URISyntaxException catch (exception, stackTrace) {
+          AnalysisEngine.instance.logger.logInformation(
+              "Failed to create URI: $path",
+              new CaughtException(exception, stackTrace));
           return null;
         }
       }
@@ -497,8 +503,10 @@
     try {
       String contents = librariesFile.readAsStringSync();
       return new SdkLibrariesReader(useDart2jsPaths).readFromFile(librariesFile, contents);
-    } catch (exception) {
-      AnalysisEngine.instance.logger.logError2("Could not initialize the library map from ${librariesFile.getAbsolutePath()}", exception);
+    } catch (exception, stackTrace) {
+      AnalysisEngine.instance.logger.logError(
+          "Could not initialize the library map from ${librariesFile.getAbsolutePath()}",
+          new CaughtException(exception, stackTrace));
       return new LibraryMap();
     }
   }
diff --git a/pkg/analyzer/lib/src/generated/source.dart b/pkg/analyzer/lib/src/generated/source.dart
index 3b3d79b..47bb620 100644
--- a/pkg/analyzer/lib/src/generated/source.dart
+++ b/pkg/analyzer/lib/src/generated/source.dart
@@ -156,6 +156,12 @@
   final List<int> _lineStarts;
 
   /**
+   * The zero-based [_lineStarts] index resulting from the last call to
+   * [getLocation].
+   */
+  int _previousLine = 0;
+
+  /**
    * Initialize a newly created set of line information to represent the data encoded in the given
    * array.
    *
@@ -176,13 +182,37 @@
    * @return the location information for the character at the given offset
    */
   LineInfo_Location getLocation(int offset) {
-    int lineCount = _lineStarts.length;
-    for (int i = 1; i < lineCount; i++) {
-      if (offset < _lineStarts[i]) {
-        return new LineInfo_Location(i, offset - _lineStarts[i - 1] + 1);
+    var min = 0;
+    var max = _lineStarts.length - 1;
+
+    // Subsequent calls to [getLocation] are often for offsets near each other.
+    // To take advantage of that, we cache the index of the line start we found
+    // when this was last called. If the current offset is on that line or
+    // later, we'll skip those early indices completely when searching.
+    if (offset >= _lineStarts[_previousLine]) {
+      min = _previousLine;
+
+      // Before kicking off a full binary search, do a quick check here to see
+      // if the new offset is on that exact line.
+      if (min == _lineStarts.length - 1 || offset < _lineStarts[min + 1]) {
+        return new LineInfo_Location(min + 1, offset - _lineStarts[min] + 1);
       }
     }
-    return new LineInfo_Location(lineCount, offset - _lineStarts[lineCount - 1] + 1);
+
+    // Binary search to fine the line containing this offset.
+    while (min < max) {
+      var midpoint = (max - min + 1) ~/ 2 + min;
+
+      if (_lineStarts[midpoint] > offset) {
+        max = midpoint - 1;
+      } else {
+        min = midpoint;
+      }
+    }
+
+    _previousLine = min;
+
+    return new LineInfo_Location(min + 1, offset - _lineStarts[min] + 1);
   }
 }
 
@@ -521,8 +551,10 @@
       if (uri.isAbsolute) {
         return _internalResolveUri(null, uri);
       }
-    } catch (exception) {
-      AnalysisEngine.instance.logger.logError2("Could not resolve URI: $absoluteUri", exception);
+    } catch (exception, stackTrace) {
+      AnalysisEngine.instance.logger.logError(
+          "Could not resolve URI: $absoluteUri",
+          new CaughtException(exception, stackTrace));
     }
     return null;
   }
@@ -539,7 +571,9 @@
       try {
         return _internalResolveUri(null, absoluteUri);
       } on AnalysisException catch (exception, stackTrace) {
-        AnalysisEngine.instance.logger.logError2("Could not resolve URI: $absoluteUri", new CaughtException(exception, stackTrace));
+        AnalysisEngine.instance.logger.logError(
+            "Could not resolve URI: $absoluteUri",
+            new CaughtException(exception, stackTrace));
       }
     }
     return null;
@@ -603,8 +637,10 @@
     try {
       // Force the creation of an escaped URI to deal with spaces, etc.
       return _internalResolveUri(containingSource, parseUriWithException(containedUri));
-    } catch (exception) {
-      AnalysisEngine.instance.logger.logError2("Could not resolve URI ($containedUri) relative to source (${containingSource.fullName})", exception);
+    } catch (exception, stackTrace) {
+      AnalysisEngine.instance.logger.logError(
+          "Could not resolve URI ($containedUri) relative to source (${containingSource.fullName})",
+          new CaughtException(exception, stackTrace));
       return null;
     }
   }
diff --git a/pkg/analyzer/lib/src/generated/source_io.dart b/pkg/analyzer/lib/src/generated/source_io.dart
index 60740c1..9fa796a 100644
--- a/pkg/analyzer/lib/src/generated/source_io.dart
+++ b/pkg/analyzer/lib/src/generated/source_io.dart
@@ -399,20 +399,18 @@
 
   @override
   Uri restoreAbsolute(Source source) {
-    if (source is FileBasedSource) {
-      String sourcePath = source.file.getPath();
-      for (JavaFile packagesDirectory in _packagesDirectories) {
-        List<JavaFile> pkgFolders = packagesDirectory.listFiles();
-        if (pkgFolders != null) {
-          for (JavaFile pkgFolder in pkgFolders) {
-            try {
-              String pkgCanonicalPath = pkgFolder.getCanonicalPath();
-              if (sourcePath.startsWith(pkgCanonicalPath)) {
-                String relPath = sourcePath.substring(pkgCanonicalPath.length);
-                return parseUriWithException("$PACKAGE_SCHEME:${pkgFolder.getName()}$relPath");
-              }
-            } catch (e) {
+    String sourcePath = source.fullName;
+    for (JavaFile packagesDirectory in _packagesDirectories) {
+      List<JavaFile> pkgFolders = packagesDirectory.listFiles();
+      if (pkgFolders != null) {
+        for (JavaFile pkgFolder in pkgFolders) {
+          try {
+            String pkgCanonicalPath = pkgFolder.getCanonicalPath();
+            if (sourcePath.startsWith(pkgCanonicalPath)) {
+              String relPath = sourcePath.substring(pkgCanonicalPath.length);
+              return parseUriWithException("$PACKAGE_SCHEME:${pkgFolder.getName()}$relPath");
             }
+          } catch (e) {
           }
         }
       }
@@ -433,12 +431,16 @@
     JavaFile pkgDir = new JavaFile.relative(packagesDirectory, pkgName);
     try {
       pkgDir = pkgDir.getCanonicalFile();
-    } on JavaIOException catch (e) {
-      if (!e.toString().contains("Required key not available")) {
-        AnalysisEngine.instance.logger.logError2("Canonical failed: $pkgDir", e);
+    } on JavaIOException catch (exception, stackTrace) {
+      if (!exception.toString().contains("Required key not available")) {
+        AnalysisEngine.instance.logger.logError(
+            "Canonical failed: $pkgDir",
+            new CaughtException(exception, stackTrace));
       } else if (_CanLogRequiredKeyIoException) {
         _CanLogRequiredKeyIoException = false;
-        AnalysisEngine.instance.logger.logError2("Canonical failed: $pkgDir", e);
+        AnalysisEngine.instance.logger.logError(
+            "Canonical failed: $pkgDir",
+            new CaughtException(exception, stackTrace));
       }
     }
     return new JavaFile.relative(pkgDir, relPath.replaceAll('/', new String.fromCharCode(JavaFile.separatorChar)));
diff --git a/pkg/analyzer/lib/src/generated/static_type_analyzer.dart b/pkg/analyzer/lib/src/generated/static_type_analyzer.dart
new file mode 100644
index 0000000..4744470
--- /dev/null
+++ b/pkg/analyzer/lib/src/generated/static_type_analyzer.dart
@@ -0,0 +1,1727 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for 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 engine.resolver.static_type_analyzer;
+
+import 'dart:collection';
+
+import 'java_engine.dart';
+import 'scanner.dart' as sc;
+import 'ast.dart';
+import 'element.dart';
+import 'resolver.dart';
+
+class GeneralizingAstVisitor_StaticTypeAnalyzer_computePropagatedReturnTypeOfFunction extends GeneralizingAstVisitor<Object> {
+  DartType result = null;
+
+  GeneralizingAstVisitor_StaticTypeAnalyzer_computePropagatedReturnTypeOfFunction();
+
+  @override
+  Object visitExpression(Expression node) => null;
+
+  @override
+  Object visitReturnStatement(ReturnStatement node) {
+    // prepare this 'return' type
+    DartType type;
+    Expression expression = node.expression;
+    if (expression != null) {
+      type = expression.bestType;
+    } else {
+      type = BottomTypeImpl.instance;
+    }
+    // merge types
+    if (result == null) {
+      result = type;
+    } else {
+      result = result.getLeastUpperBound(type);
+    }
+    return null;
+  }
+}
+
+/**
+ * Instances of the class `StaticTypeAnalyzer` perform two type-related tasks. First, they
+ * compute the static type of every expression. Second, they look for any static type errors or
+ * warnings that might need to be generated. The requirements for the type analyzer are:
+ * <ol>
+ * * Every element that refers to types should be fully populated.
+ * * Every node representing an expression should be resolved to the Type of the expression.
+ * </ol>
+ */
+class StaticTypeAnalyzer extends SimpleAstVisitor<Object> {
+  /**
+   * Create a table mapping HTML tag names to the names of the classes (in 'dart:html') that
+   * implement those tags.
+   *
+   * @return the table that was created
+   */
+  static HashMap<String, String> _createHtmlTagToClassMap() {
+    HashMap<String, String> map = new HashMap<String, String>();
+    map["a"] = "AnchorElement";
+    map["area"] = "AreaElement";
+    map["br"] = "BRElement";
+    map["base"] = "BaseElement";
+    map["body"] = "BodyElement";
+    map["button"] = "ButtonElement";
+    map["canvas"] = "CanvasElement";
+    map["content"] = "ContentElement";
+    map["dl"] = "DListElement";
+    map["datalist"] = "DataListElement";
+    map["details"] = "DetailsElement";
+    map["div"] = "DivElement";
+    map["embed"] = "EmbedElement";
+    map["fieldset"] = "FieldSetElement";
+    map["form"] = "FormElement";
+    map["hr"] = "HRElement";
+    map["head"] = "HeadElement";
+    map["h1"] = "HeadingElement";
+    map["h2"] = "HeadingElement";
+    map["h3"] = "HeadingElement";
+    map["h4"] = "HeadingElement";
+    map["h5"] = "HeadingElement";
+    map["h6"] = "HeadingElement";
+    map["html"] = "HtmlElement";
+    map["iframe"] = "IFrameElement";
+    map["img"] = "ImageElement";
+    map["input"] = "InputElement";
+    map["keygen"] = "KeygenElement";
+    map["li"] = "LIElement";
+    map["label"] = "LabelElement";
+    map["legend"] = "LegendElement";
+    map["link"] = "LinkElement";
+    map["map"] = "MapElement";
+    map["menu"] = "MenuElement";
+    map["meter"] = "MeterElement";
+    map["ol"] = "OListElement";
+    map["object"] = "ObjectElement";
+    map["optgroup"] = "OptGroupElement";
+    map["output"] = "OutputElement";
+    map["p"] = "ParagraphElement";
+    map["param"] = "ParamElement";
+    map["pre"] = "PreElement";
+    map["progress"] = "ProgressElement";
+    map["script"] = "ScriptElement";
+    map["select"] = "SelectElement";
+    map["source"] = "SourceElement";
+    map["span"] = "SpanElement";
+    map["style"] = "StyleElement";
+    map["caption"] = "TableCaptionElement";
+    map["td"] = "TableCellElement";
+    map["col"] = "TableColElement";
+    map["table"] = "TableElement";
+    map["tr"] = "TableRowElement";
+    map["textarea"] = "TextAreaElement";
+    map["title"] = "TitleElement";
+    map["track"] = "TrackElement";
+    map["ul"] = "UListElement";
+    map["video"] = "VideoElement";
+    return map;
+  }
+
+  /**
+   * The resolver driving the resolution and type analysis.
+   */
+  final ResolverVisitor _resolver;
+
+  /**
+   * The object providing access to the types defined by the language.
+   */
+  TypeProvider _typeProvider;
+
+  /**
+   * The type representing the type 'dynamic'.
+   */
+  DartType _dynamicType;
+
+  /**
+   * The type representing the class containing the nodes being analyzed, or `null` if the
+   * nodes are not within a class.
+   */
+  InterfaceType _thisType;
+
+  /**
+   * The object keeping track of which elements have had their types overridden.
+   */
+  TypeOverrideManager _overrideManager;
+
+  /**
+   * The object keeping track of which elements have had their types promoted.
+   */
+  TypePromotionManager _promoteManager;
+
+  /**
+   * A table mapping [ExecutableElement]s to their propagated return types.
+   */
+  HashMap<ExecutableElement, DartType> _propagatedReturnTypes = new HashMap<ExecutableElement, DartType>();
+
+  /**
+   * A table mapping HTML tag names to the names of the classes (in 'dart:html') that implement
+   * those tags.
+   */
+  static HashMap<String, String> _HTML_ELEMENT_TO_CLASS_MAP = _createHtmlTagToClassMap();
+
+  /**
+   * Initialize a newly created type analyzer.
+   *
+   * @param resolver the resolver driving this participant
+   */
+  StaticTypeAnalyzer(this._resolver) {
+    _typeProvider = _resolver.typeProvider;
+    _dynamicType = _typeProvider.dynamicType;
+    _overrideManager = _resolver.overrideManager;
+    _promoteManager = _resolver.promoteManager;
+  }
+
+  /**
+   * Set the type of the class being analyzed to the given type.
+   *
+   * @param thisType the type representing the class containing the nodes being analyzed
+   */
+  void set thisType(InterfaceType thisType) {
+    this._thisType = thisType;
+  }
+
+  /**
+   * The Dart Language Specification, 12.5: <blockquote>The static type of a string literal is
+   * `String`.</blockquote>
+   */
+  @override
+  Object visitAdjacentStrings(AdjacentStrings node) {
+    _recordStaticType(node, _typeProvider.stringType);
+    return null;
+  }
+
+  /**
+   * The Dart Language Specification, 12.32: <blockquote>... the cast expression <i>e as T</i> ...
+   *
+   * It is a static warning if <i>T</i> does not denote a type available in the current lexical
+   * scope.
+   *
+   * The static type of a cast expression <i>e as T</i> is <i>T</i>.</blockquote>
+   */
+  @override
+  Object visitAsExpression(AsExpression node) {
+    _recordStaticType(node, _getType(node.type));
+    return null;
+  }
+
+  /**
+   * The Dart Language Specification, 12.18: <blockquote>... an assignment <i>a</i> of the form <i>v
+   * = e</i> ...
+   *
+   * It is a static type warning if the static type of <i>e</i> may not be assigned to the static
+   * type of <i>v</i>.
+   *
+   * The static type of the expression <i>v = e</i> is the static type of <i>e</i>.
+   *
+   * ... an assignment of the form <i>C.v = e</i> ...
+   *
+   * It is a static type warning if the static type of <i>e</i> may not be assigned to the static
+   * type of <i>C.v</i>.
+   *
+   * The static type of the expression <i>C.v = e</i> is the static type of <i>e</i>.
+   *
+   * ... an assignment of the form <i>e<sub>1</sub>.v = e<sub>2</sub></i> ...
+   *
+   * Let <i>T</i> be the static type of <i>e<sub>1</sub></i>. It is a static type warning if
+   * <i>T</i> does not have an accessible instance setter named <i>v=</i>. It is a static type
+   * warning if the static type of <i>e<sub>2</sub></i> may not be assigned to <i>T</i>.
+   *
+   * The static type of the expression <i>e<sub>1</sub>.v = e<sub>2</sub></i> is the static type of
+   * <i>e<sub>2</sub></i>.
+   *
+   * ... an assignment of the form <i>e<sub>1</sub>[e<sub>2</sub>] = e<sub>3</sub></i> ...
+   *
+   * The static type of the expression <i>e<sub>1</sub>[e<sub>2</sub>] = e<sub>3</sub></i> is the
+   * static type of <i>e<sub>3</sub></i>.
+   *
+   * A compound assignment of the form <i>v op= e</i> is equivalent to <i>v = v op e</i>. A compound
+   * assignment of the form <i>C.v op= e</i> is equivalent to <i>C.v = C.v op e</i>. A compound
+   * assignment of the form <i>e<sub>1</sub>.v op= e<sub>2</sub></i> is equivalent to <i>((x) => x.v
+   * = x.v op e<sub>2</sub>)(e<sub>1</sub>)</i> where <i>x</i> is a variable that is not used in
+   * <i>e<sub>2</sub></i>. A compound assignment of the form <i>e<sub>1</sub>[e<sub>2</sub>] op=
+   * e<sub>3</sub></i> is equivalent to <i>((a, i) => a[i] = a[i] op e<sub>3</sub>)(e<sub>1</sub>,
+   * e<sub>2</sub>)</i> where <i>a</i> and <i>i</i> are a variables that are not used in
+   * <i>e<sub>3</sub></i>.</blockquote>
+   */
+  @override
+  Object visitAssignmentExpression(AssignmentExpression node) {
+    sc.TokenType operator = node.operator.type;
+    if (operator == sc.TokenType.EQ) {
+      Expression rightHandSide = node.rightHandSide;
+      DartType staticType = _getStaticType(rightHandSide);
+      _recordStaticType(node, staticType);
+      DartType overrideType = staticType;
+      DartType propagatedType = rightHandSide.propagatedType;
+      if (propagatedType != null) {
+        if (propagatedType.isMoreSpecificThan(staticType)) {
+          _recordPropagatedType(node, propagatedType);
+        }
+        overrideType = propagatedType;
+      }
+      _resolver.overrideExpression(node.leftHandSide, overrideType, true);
+    } else {
+      ExecutableElement staticMethodElement = node.staticElement;
+      DartType staticType = _computeStaticReturnType(staticMethodElement);
+      _recordStaticType(node, staticType);
+      MethodElement propagatedMethodElement = node.propagatedElement;
+      if (!identical(propagatedMethodElement, staticMethodElement)) {
+        DartType propagatedType = _computeStaticReturnType(propagatedMethodElement);
+        if (propagatedType != null && propagatedType.isMoreSpecificThan(staticType)) {
+          _recordPropagatedType(node, propagatedType);
+        }
+      }
+    }
+    return null;
+  }
+
+  /**
+   * The Dart Language Specification, 12.20: <blockquote>The static type of a logical boolean
+   * expression is `bool`.</blockquote>
+   *
+   * The Dart Language Specification, 12.21:<blockquote>A bitwise expression of the form
+   * <i>e<sub>1</sub> op e<sub>2</sub></i> is equivalent to the method invocation
+   * <i>e<sub>1</sub>.op(e<sub>2</sub>)</i>. A bitwise expression of the form <i>super op
+   * e<sub>2</sub></i> is equivalent to the method invocation
+   * <i>super.op(e<sub>2</sub>)</i>.</blockquote>
+   *
+   * The Dart Language Specification, 12.22: <blockquote>The static type of an equality expression
+   * is `bool`.</blockquote>
+   *
+   * The Dart Language Specification, 12.23: <blockquote>A relational expression of the form
+   * <i>e<sub>1</sub> op e<sub>2</sub></i> is equivalent to the method invocation
+   * <i>e<sub>1</sub>.op(e<sub>2</sub>)</i>. A relational expression of the form <i>super op
+   * e<sub>2</sub></i> is equivalent to the method invocation
+   * <i>super.op(e<sub>2</sub>)</i>.</blockquote>
+   *
+   * The Dart Language Specification, 12.24: <blockquote>A shift expression of the form
+   * <i>e<sub>1</sub> op e<sub>2</sub></i> is equivalent to the method invocation
+   * <i>e<sub>1</sub>.op(e<sub>2</sub>)</i>. A shift expression of the form <i>super op
+   * e<sub>2</sub></i> is equivalent to the method invocation
+   * <i>super.op(e<sub>2</sub>)</i>.</blockquote>
+   *
+   * The Dart Language Specification, 12.25: <blockquote>An additive expression of the form
+   * <i>e<sub>1</sub> op e<sub>2</sub></i> is equivalent to the method invocation
+   * <i>e<sub>1</sub>.op(e<sub>2</sub>)</i>. An additive expression of the form <i>super op
+   * e<sub>2</sub></i> is equivalent to the method invocation
+   * <i>super.op(e<sub>2</sub>)</i>.</blockquote>
+   *
+   * The Dart Language Specification, 12.26: <blockquote>A multiplicative expression of the form
+   * <i>e<sub>1</sub> op e<sub>2</sub></i> is equivalent to the method invocation
+   * <i>e<sub>1</sub>.op(e<sub>2</sub>)</i>. A multiplicative expression of the form <i>super op
+   * e<sub>2</sub></i> is equivalent to the method invocation
+   * <i>super.op(e<sub>2</sub>)</i>.</blockquote>
+   */
+  @override
+  Object visitBinaryExpression(BinaryExpression node) {
+    ExecutableElement staticMethodElement = node.staticElement;
+    DartType staticType = _computeStaticReturnType(staticMethodElement);
+    staticType = _refineBinaryExpressionType(node, staticType);
+    _recordStaticType(node, staticType);
+    MethodElement propagatedMethodElement = node.propagatedElement;
+    if (!identical(propagatedMethodElement, staticMethodElement)) {
+      DartType propagatedType = _computeStaticReturnType(propagatedMethodElement);
+      if (propagatedType != null && propagatedType.isMoreSpecificThan(staticType)) {
+        _recordPropagatedType(node, propagatedType);
+      }
+    }
+    return null;
+  }
+
+  /**
+   * The Dart Language Specification, 12.4: <blockquote>The static type of a boolean literal is
+   * bool.</blockquote>
+   */
+  @override
+  Object visitBooleanLiteral(BooleanLiteral node) {
+    _recordStaticType(node, _typeProvider.boolType);
+    return null;
+  }
+
+  /**
+   * The Dart Language Specification, 12.15.2: <blockquote>A cascaded method invocation expression
+   * of the form <i>e..suffix</i> is equivalent to the expression <i>(t) {t.suffix; return
+   * t;}(e)</i>.</blockquote>
+   */
+  @override
+  Object visitCascadeExpression(CascadeExpression node) {
+    _recordStaticType(node, _getStaticType(node.target));
+    _recordPropagatedType(node, node.target.propagatedType);
+    return null;
+  }
+
+  /**
+   * The Dart Language Specification, 12.19: <blockquote> ... a conditional expression <i>c</i> of
+   * the form <i>e<sub>1</sub> ? e<sub>2</sub> : e<sub>3</sub></i> ...
+   *
+   * It is a static type warning if the type of e<sub>1</sub> may not be assigned to `bool`.
+   *
+   * The static type of <i>c</i> is the least upper bound of the static type of <i>e<sub>2</sub></i>
+   * and the static type of <i>e<sub>3</sub></i>.</blockquote>
+   */
+  @override
+  Object visitConditionalExpression(ConditionalExpression node) {
+    DartType staticThenType = _getStaticType(node.thenExpression);
+    DartType staticElseType = _getStaticType(node.elseExpression);
+    if (staticThenType == null) {
+      // TODO(brianwilkerson) Determine whether this can still happen.
+      staticThenType = _dynamicType;
+    }
+    if (staticElseType == null) {
+      // TODO(brianwilkerson) Determine whether this can still happen.
+      staticElseType = _dynamicType;
+    }
+    DartType staticType = staticThenType.getLeastUpperBound(staticElseType);
+    if (staticType == null) {
+      staticType = _dynamicType;
+    }
+    _recordStaticType(node, staticType);
+    DartType propagatedThenType = node.thenExpression.propagatedType;
+    DartType propagatedElseType = node.elseExpression.propagatedType;
+    if (propagatedThenType != null || propagatedElseType != null) {
+      if (propagatedThenType == null) {
+        propagatedThenType = staticThenType;
+      }
+      if (propagatedElseType == null) {
+        propagatedElseType = staticElseType;
+      }
+      DartType propagatedType = propagatedThenType.getLeastUpperBound(propagatedElseType);
+      if (propagatedType != null && propagatedType.isMoreSpecificThan(staticType)) {
+        _recordPropagatedType(node, propagatedType);
+      }
+    }
+    return null;
+  }
+
+  /**
+   * The Dart Language Specification, 12.3: <blockquote>The static type of a literal double is
+   * double.</blockquote>
+   */
+  @override
+  Object visitDoubleLiteral(DoubleLiteral node) {
+    _recordStaticType(node, _typeProvider.doubleType);
+    return null;
+  }
+
+  @override
+  Object visitFunctionDeclaration(FunctionDeclaration node) {
+    FunctionExpression function = node.functionExpression;
+    ExecutableElementImpl functionElement = node.element as ExecutableElementImpl;
+    functionElement.returnType = _computeStaticReturnTypeOfFunctionDeclaration(node);
+    _recordPropagatedTypeOfFunction(functionElement, function.body);
+    _recordStaticType(function, functionElement.type);
+    return null;
+  }
+
+  /**
+   * The Dart Language Specification, 12.9: <blockquote>The static type of a function literal of the
+   * form <i>(T<sub>1</sub> a<sub>1</sub>, &hellip;, T<sub>n</sub> a<sub>n</sub>, [T<sub>n+1</sub>
+   * x<sub>n+1</sub> = d1, &hellip;, T<sub>n+k</sub> x<sub>n+k</sub> = dk]) => e</i> is
+   * <i>(T<sub>1</sub>, &hellip;, Tn, [T<sub>n+1</sub> x<sub>n+1</sub>, &hellip;, T<sub>n+k</sub>
+   * x<sub>n+k</sub>]) &rarr; T<sub>0</sub></i>, where <i>T<sub>0</sub></i> is the static type of
+   * <i>e</i>. In any case where <i>T<sub>i</sub>, 1 &lt;= i &lt;= n</i>, is not specified, it is
+   * considered to have been specified as dynamic.
+   *
+   * The static type of a function literal of the form <i>(T<sub>1</sub> a<sub>1</sub>, &hellip;,
+   * T<sub>n</sub> a<sub>n</sub>, {T<sub>n+1</sub> x<sub>n+1</sub> : d1, &hellip;, T<sub>n+k</sub>
+   * x<sub>n+k</sub> : dk}) => e</i> is <i>(T<sub>1</sub>, &hellip;, T<sub>n</sub>, {T<sub>n+1</sub>
+   * x<sub>n+1</sub>, &hellip;, T<sub>n+k</sub> x<sub>n+k</sub>}) &rarr; T<sub>0</sub></i>, where
+   * <i>T<sub>0</sub></i> is the static type of <i>e</i>. In any case where <i>T<sub>i</sub>, 1
+   * &lt;= i &lt;= n</i>, is not specified, it is considered to have been specified as dynamic.
+   *
+   * The static type of a function literal of the form <i>(T<sub>1</sub> a<sub>1</sub>, &hellip;,
+   * T<sub>n</sub> a<sub>n</sub>, [T<sub>n+1</sub> x<sub>n+1</sub> = d1, &hellip;, T<sub>n+k</sub>
+   * x<sub>n+k</sub> = dk]) {s}</i> is <i>(T<sub>1</sub>, &hellip;, T<sub>n</sub>, [T<sub>n+1</sub>
+   * x<sub>n+1</sub>, &hellip;, T<sub>n+k</sub> x<sub>n+k</sub>]) &rarr; dynamic</i>. In any case
+   * where <i>T<sub>i</sub>, 1 &lt;= i &lt;= n</i>, is not specified, it is considered to have been
+   * specified as dynamic.
+   *
+   * The static type of a function literal of the form <i>(T<sub>1</sub> a<sub>1</sub>, &hellip;,
+   * T<sub>n</sub> a<sub>n</sub>, {T<sub>n+1</sub> x<sub>n+1</sub> : d1, &hellip;, T<sub>n+k</sub>
+   * x<sub>n+k</sub> : dk}) {s}</i> is <i>(T<sub>1</sub>, &hellip;, T<sub>n</sub>, {T<sub>n+1</sub>
+   * x<sub>n+1</sub>, &hellip;, T<sub>n+k</sub> x<sub>n+k</sub>}) &rarr; dynamic</i>. In any case
+   * where <i>T<sub>i</sub>, 1 &lt;= i &lt;= n</i>, is not specified, it is considered to have been
+   * specified as dynamic.</blockquote>
+   */
+  @override
+  Object visitFunctionExpression(FunctionExpression node) {
+    if (node.parent is FunctionDeclaration) {
+      // The function type will be resolved and set when we visit the parent node.
+      return null;
+    }
+    ExecutableElementImpl functionElement = node.element as ExecutableElementImpl;
+    functionElement.returnType = _computeStaticReturnTypeOfFunctionExpression(node);
+    _recordPropagatedTypeOfFunction(functionElement, node.body);
+    _recordStaticType(node, node.element.type);
+    return null;
+  }
+
+  /**
+   * The Dart Language Specification, 12.14.4: <blockquote>A function expression invocation <i>i</i>
+   * has the form <i>e<sub>f</sub>(a<sub>1</sub>, &hellip;, a<sub>n</sub>, x<sub>n+1</sub>:
+   * a<sub>n+1</sub>, &hellip;, x<sub>n+k</sub>: a<sub>n+k</sub>)</i>, where <i>e<sub>f</sub></i> is
+   * an expression.
+   *
+   * It is a static type warning if the static type <i>F</i> of <i>e<sub>f</sub></i> may not be
+   * assigned to a function type.
+   *
+   * If <i>F</i> is not a function type, the static type of <i>i</i> is dynamic. Otherwise the
+   * static type of <i>i</i> is the declared return type of <i>F</i>.</blockquote>
+   */
+  @override
+  Object visitFunctionExpressionInvocation(FunctionExpressionInvocation node) {
+    ExecutableElement staticMethodElement = node.staticElement;
+    // Record static return type of the static element.
+    DartType staticStaticType = _computeStaticReturnType(staticMethodElement);
+    _recordStaticType(node, staticStaticType);
+    // Record propagated return type of the static element.
+    DartType staticPropagatedType = _computePropagatedReturnType(staticMethodElement);
+    if (staticPropagatedType != null && (staticStaticType == null || staticPropagatedType.isMoreSpecificThan(staticStaticType))) {
+      _recordPropagatedType(node, staticPropagatedType);
+    }
+    ExecutableElement propagatedMethodElement = node.propagatedElement;
+    if (!identical(propagatedMethodElement, staticMethodElement)) {
+      // Record static return type of the propagated element.
+      DartType propagatedStaticType = _computeStaticReturnType(propagatedMethodElement);
+      if (propagatedStaticType != null && (staticStaticType == null || propagatedStaticType.isMoreSpecificThan(staticStaticType)) && (staticPropagatedType == null || propagatedStaticType.isMoreSpecificThan(staticPropagatedType))) {
+        _recordPropagatedType(node, propagatedStaticType);
+      }
+      // Record propagated return type of the propagated element.
+      DartType propagatedPropagatedType = _computePropagatedReturnType(propagatedMethodElement);
+      if (propagatedPropagatedType != null && (staticStaticType == null || propagatedPropagatedType.isMoreSpecificThan(staticStaticType)) && (staticPropagatedType == null || propagatedPropagatedType.isMoreSpecificThan(staticPropagatedType)) && (propagatedStaticType == null || propagatedPropagatedType.isMoreSpecificThan(propagatedStaticType))) {
+        _recordPropagatedType(node, propagatedPropagatedType);
+      }
+    }
+    return null;
+  }
+
+  /**
+   * The Dart Language Specification, 12.29: <blockquote>An assignable expression of the form
+   * <i>e<sub>1</sub>[e<sub>2</sub>]</i> is evaluated as a method invocation of the operator method
+   * <i>[]</i> on <i>e<sub>1</sub></i> with argument <i>e<sub>2</sub></i>.</blockquote>
+   */
+  @override
+  Object visitIndexExpression(IndexExpression node) {
+    if (node.inSetterContext()) {
+      ExecutableElement staticMethodElement = node.staticElement;
+      DartType staticType = _computeArgumentType(staticMethodElement);
+      _recordStaticType(node, staticType);
+      MethodElement propagatedMethodElement = node.propagatedElement;
+      if (!identical(propagatedMethodElement, staticMethodElement)) {
+        DartType propagatedType = _computeArgumentType(propagatedMethodElement);
+        if (propagatedType != null && propagatedType.isMoreSpecificThan(staticType)) {
+          _recordPropagatedType(node, propagatedType);
+        }
+      }
+    } else {
+      ExecutableElement staticMethodElement = node.staticElement;
+      DartType staticType = _computeStaticReturnType(staticMethodElement);
+      _recordStaticType(node, staticType);
+      MethodElement propagatedMethodElement = node.propagatedElement;
+      if (!identical(propagatedMethodElement, staticMethodElement)) {
+        DartType propagatedType = _computeStaticReturnType(propagatedMethodElement);
+        if (propagatedType != null && propagatedType.isMoreSpecificThan(staticType)) {
+          _recordPropagatedType(node, propagatedType);
+        }
+      }
+    }
+    return null;
+  }
+
+  /**
+   * The Dart Language Specification, 12.11.1: <blockquote>The static type of a new expression of
+   * either the form <i>new T.id(a<sub>1</sub>, &hellip;, a<sub>n</sub>)</i> or the form <i>new
+   * T(a<sub>1</sub>, &hellip;, a<sub>n</sub>)</i> is <i>T</i>.</blockquote>
+   *
+   * The Dart Language Specification, 12.11.2: <blockquote>The static type of a constant object
+   * expression of either the form <i>const T.id(a<sub>1</sub>, &hellip;, a<sub>n</sub>)</i> or the
+   * form <i>const T(a<sub>1</sub>, &hellip;, a<sub>n</sub>)</i> is <i>T</i>. </blockquote>
+   */
+  @override
+  Object visitInstanceCreationExpression(InstanceCreationExpression node) {
+    _recordStaticType(node, node.constructorName.type.type);
+    ConstructorElement element = node.staticElement;
+    if (element != null && "Element" == element.enclosingElement.name) {
+      LibraryElement library = element.library;
+      if (_isHtmlLibrary(library)) {
+        String constructorName = element.name;
+        if ("tag" == constructorName) {
+          DartType returnType = _getFirstArgumentAsTypeWithMap(library, node.argumentList, _HTML_ELEMENT_TO_CLASS_MAP);
+          if (returnType != null) {
+            _recordPropagatedType(node, returnType);
+          }
+        } else {
+          DartType returnType = _getElementNameAsType(library, constructorName, _HTML_ELEMENT_TO_CLASS_MAP);
+          if (returnType != null) {
+            _recordPropagatedType(node, returnType);
+          }
+        }
+      }
+    }
+    return null;
+  }
+
+  /**
+   * The Dart Language Specification, 12.3: <blockquote>The static type of an integer literal is
+   * `int`.</blockquote>
+   */
+  @override
+  Object visitIntegerLiteral(IntegerLiteral node) {
+    _recordStaticType(node, _typeProvider.intType);
+    return null;
+  }
+
+  /**
+   * The Dart Language Specification, 12.31: <blockquote>It is a static warning if <i>T</i> does not
+   * denote a type available in the current lexical scope.
+   *
+   * The static type of an is-expression is `bool`.</blockquote>
+   */
+  @override
+  Object visitIsExpression(IsExpression node) {
+    _recordStaticType(node, _typeProvider.boolType);
+    return null;
+  }
+
+  /**
+   * The Dart Language Specification, 12.6: <blockquote>The static type of a list literal of the
+   * form <i><b>const</b> &lt;E&gt;[e<sub>1</sub>, &hellip;, e<sub>n</sub>]</i> or the form
+   * <i>&lt;E&gt;[e<sub>1</sub>, &hellip;, e<sub>n</sub>]</i> is `List&lt;E&gt;`. The static
+   * type a list literal of the form <i><b>const</b> [e<sub>1</sub>, &hellip;, e<sub>n</sub>]</i> or
+   * the form <i>[e<sub>1</sub>, &hellip;, e<sub>n</sub>]</i> is `List&lt;dynamic&gt;`
+   * .</blockquote>
+   */
+  @override
+  Object visitListLiteral(ListLiteral node) {
+    DartType staticType = _dynamicType;
+    TypeArgumentList typeArguments = node.typeArguments;
+    if (typeArguments != null) {
+      NodeList<TypeName> arguments = typeArguments.arguments;
+      if (arguments != null && arguments.length == 1) {
+        TypeName argumentTypeName = arguments[0];
+        DartType argumentType = _getType(argumentTypeName);
+        if (argumentType != null) {
+          staticType = argumentType;
+        }
+      }
+    }
+    _recordStaticType(node, _typeProvider.listType.substitute4(<DartType> [staticType]));
+    return null;
+  }
+
+  /**
+   * The Dart Language Specification, 12.7: <blockquote>The static type of a map literal of the form
+   * <i><b>const</b> &lt;K, V&gt; {k<sub>1</sub>:e<sub>1</sub>, &hellip;,
+   * k<sub>n</sub>:e<sub>n</sub>}</i> or the form <i>&lt;K, V&gt; {k<sub>1</sub>:e<sub>1</sub>,
+   * &hellip;, k<sub>n</sub>:e<sub>n</sub>}</i> is `Map&lt;K, V&gt;`. The static type a map
+   * literal of the form <i><b>const</b> {k<sub>1</sub>:e<sub>1</sub>, &hellip;,
+   * k<sub>n</sub>:e<sub>n</sub>}</i> or the form <i>{k<sub>1</sub>:e<sub>1</sub>, &hellip;,
+   * k<sub>n</sub>:e<sub>n</sub>}</i> is `Map&lt;dynamic, dynamic&gt;`.
+   *
+   * It is a compile-time error if the first type argument to a map literal is not
+   * <i>String</i>.</blockquote>
+   */
+  @override
+  Object visitMapLiteral(MapLiteral node) {
+    DartType staticKeyType = _dynamicType;
+    DartType staticValueType = _dynamicType;
+    TypeArgumentList typeArguments = node.typeArguments;
+    if (typeArguments != null) {
+      NodeList<TypeName> arguments = typeArguments.arguments;
+      if (arguments != null && arguments.length == 2) {
+        TypeName entryKeyTypeName = arguments[0];
+        DartType entryKeyType = _getType(entryKeyTypeName);
+        if (entryKeyType != null) {
+          staticKeyType = entryKeyType;
+        }
+        TypeName entryValueTypeName = arguments[1];
+        DartType entryValueType = _getType(entryValueTypeName);
+        if (entryValueType != null) {
+          staticValueType = entryValueType;
+        }
+      }
+    }
+    _recordStaticType(node, _typeProvider.mapType.substitute4(<DartType> [staticKeyType, staticValueType]));
+    return null;
+  }
+
+  /**
+   * The Dart Language Specification, 12.15.1: <blockquote>An ordinary method invocation <i>i</i>
+   * has the form <i>o.m(a<sub>1</sub>, &hellip;, a<sub>n</sub>, x<sub>n+1</sub>: a<sub>n+1</sub>,
+   * &hellip;, x<sub>n+k</sub>: a<sub>n+k</sub>)</i>.
+   *
+   * Let <i>T</i> be the static type of <i>o</i>. It is a static type warning if <i>T</i> does not
+   * have an accessible instance member named <i>m</i>. If <i>T.m</i> exists, it is a static warning
+   * if the type <i>F</i> of <i>T.m</i> may not be assigned to a function type.
+   *
+   * If <i>T.m</i> does not exist, or if <i>F</i> is not a function type, the static type of
+   * <i>i</i> is dynamic. Otherwise the static type of <i>i</i> is the declared return type of
+   * <i>F</i>.</blockquote>
+   *
+   * The Dart Language Specification, 11.15.3: <blockquote>A static method invocation <i>i</i> has
+   * the form <i>C.m(a<sub>1</sub>, &hellip;, a<sub>n</sub>, x<sub>n+1</sub>: a<sub>n+1</sub>,
+   * &hellip;, x<sub>n+k</sub>: a<sub>n+k</sub>)</i>.
+   *
+   * It is a static type warning if the type <i>F</i> of <i>C.m</i> may not be assigned to a
+   * function type.
+   *
+   * If <i>F</i> is not a function type, or if <i>C.m</i> does not exist, the static type of i is
+   * dynamic. Otherwise the static type of <i>i</i> is the declared return type of
+   * <i>F</i>.</blockquote>
+   *
+   * The Dart Language Specification, 11.15.4: <blockquote>A super method invocation <i>i</i> has
+   * the form <i>super.m(a<sub>1</sub>, &hellip;, a<sub>n</sub>, x<sub>n+1</sub>: a<sub>n+1</sub>,
+   * &hellip;, x<sub>n+k</sub>: a<sub>n+k</sub>)</i>.
+   *
+   * It is a static type warning if <i>S</i> does not have an accessible instance member named m. If
+   * <i>S.m</i> exists, it is a static warning if the type <i>F</i> of <i>S.m</i> may not be
+   * assigned to a function type.
+   *
+   * If <i>S.m</i> does not exist, or if <i>F</i> is not a function type, the static type of
+   * <i>i</i> is dynamic. Otherwise the static type of <i>i</i> is the declared return type of
+   * <i>F</i>.</blockquote>
+   */
+  @override
+  Object visitMethodInvocation(MethodInvocation node) {
+    SimpleIdentifier methodNameNode = node.methodName;
+    Element staticMethodElement = methodNameNode.staticElement;
+    // Record types of the variable invoked as a function.
+    if (staticMethodElement is VariableElement) {
+      VariableElement variable = staticMethodElement;
+      DartType staticType = variable.type;
+      _recordStaticType(methodNameNode, staticType);
+      DartType propagatedType = _overrideManager.getType(variable);
+      if (propagatedType != null && propagatedType.isMoreSpecificThan(staticType)) {
+        _recordPropagatedType(methodNameNode, propagatedType);
+      }
+    }
+    // Record static return type of the static element.
+    DartType staticStaticType = _computeStaticReturnType(staticMethodElement);
+    _recordStaticType(node, staticStaticType);
+    // Record propagated return type of the static element.
+    DartType staticPropagatedType = _computePropagatedReturnType(staticMethodElement);
+    if (staticPropagatedType != null && (staticStaticType == null || staticPropagatedType.isMoreSpecificThan(staticStaticType))) {
+      _recordPropagatedType(node, staticPropagatedType);
+    }
+    bool needPropagatedType = true;
+    String methodName = methodNameNode.name;
+    if (methodName == "then") {
+      Expression target = node.realTarget;
+      if (target != null) {
+        DartType targetType = target.bestType;
+        if (_isAsyncFutureType(targetType)) {
+          // Future.then(closure) return type is:
+          // 1) the returned Future type, if the closure returns a Future;
+          // 2) Future<valueType>, if the closure returns a value.
+          NodeList<Expression> arguments = node.argumentList.arguments;
+          if (arguments.length == 1) {
+            // TODO(brianwilkerson) Handle the case where both arguments are provided.
+            Expression closureArg = arguments[0];
+            if (closureArg is FunctionExpression) {
+              FunctionExpression closureExpr = closureArg;
+              DartType returnType = _computePropagatedReturnType(closureExpr.element);
+              if (returnType != null) {
+                // prepare the type of the returned Future
+                InterfaceTypeImpl newFutureType;
+                if (_isAsyncFutureType(returnType)) {
+                  newFutureType = returnType as InterfaceTypeImpl;
+                } else {
+                  InterfaceType futureType = targetType as InterfaceType;
+                  newFutureType = new InterfaceTypeImpl.con1(futureType.element);
+                  newFutureType.typeArguments = <DartType> [returnType];
+                }
+                // set the 'then' invocation type
+                _recordPropagatedType(node, newFutureType);
+                needPropagatedType = false;
+                return null;
+              }
+            }
+          }
+        }
+      }
+    } else if (methodName == "\$dom_createEvent") {
+      Expression target = node.realTarget;
+      if (target != null) {
+        DartType targetType = target.bestType;
+        if (targetType is InterfaceType && (targetType.name == "HtmlDocument" || targetType.name == "Document")) {
+          LibraryElement library = targetType.element.library;
+          if (_isHtmlLibrary(library)) {
+            DartType returnType = _getFirstArgumentAsType(library, node.argumentList);
+            if (returnType != null) {
+              _recordPropagatedType(node, returnType);
+              needPropagatedType = false;
+            }
+          }
+        }
+      }
+    } else if (methodName == "query") {
+      Expression target = node.realTarget;
+      if (target == null) {
+        Element methodElement = methodNameNode.bestElement;
+        if (methodElement != null) {
+          LibraryElement library = methodElement.library;
+          if (_isHtmlLibrary(library)) {
+            DartType returnType = _getFirstArgumentAsQuery(library, node.argumentList);
+            if (returnType != null) {
+              _recordPropagatedType(node, returnType);
+              needPropagatedType = false;
+            }
+          }
+        }
+      } else {
+        DartType targetType = target.bestType;
+        if (targetType is InterfaceType && (targetType.name == "HtmlDocument" || targetType.name == "Document")) {
+          LibraryElement library = targetType.element.library;
+          if (_isHtmlLibrary(library)) {
+            DartType returnType = _getFirstArgumentAsQuery(library, node.argumentList);
+            if (returnType != null) {
+              _recordPropagatedType(node, returnType);
+              needPropagatedType = false;
+            }
+          }
+        }
+      }
+    } else if (methodName == "\$dom_createElement") {
+      Expression target = node.realTarget;
+      if (target != null) {
+        DartType targetType = target.bestType;
+        if (targetType is InterfaceType && (targetType.name == "HtmlDocument" || targetType.name == "Document")) {
+          LibraryElement library = targetType.element.library;
+          if (_isHtmlLibrary(library)) {
+            DartType returnType = _getFirstArgumentAsQuery(library, node.argumentList);
+            if (returnType != null) {
+              _recordPropagatedType(node, returnType);
+              needPropagatedType = false;
+            }
+          }
+        }
+      }
+    } else if (methodName == "JS") {
+      DartType returnType = _getFirstArgumentAsType(_typeProvider.objectType.element.library, node.argumentList);
+      if (returnType != null) {
+        _recordPropagatedType(node, returnType);
+        needPropagatedType = false;
+      }
+    } else if (methodName == "getContext") {
+      Expression target = node.realTarget;
+      if (target != null) {
+        DartType targetType = target.bestType;
+        if (targetType is InterfaceType && (targetType.name == "CanvasElement")) {
+          NodeList<Expression> arguments = node.argumentList.arguments;
+          if (arguments.length == 1) {
+            Expression argument = arguments[0];
+            if (argument is StringLiteral) {
+              String value = argument.stringValue;
+              if ("2d" == value) {
+                PropertyAccessorElement getter = targetType.element.getGetter("context2D");
+                if (getter != null) {
+                  DartType returnType = getter.returnType;
+                  if (returnType != null) {
+                    _recordPropagatedType(node, returnType);
+                    needPropagatedType = false;
+                  }
+                }
+              }
+            }
+          }
+        }
+      }
+    }
+    if (needPropagatedType) {
+      Element propagatedElement = methodNameNode.propagatedElement;
+      // HACK: special case for object methods ([toString]) on dynamic expressions.
+      // More special cases in [visitPrefixedIdentfier].
+      if (propagatedElement == null) {
+        propagatedElement = _typeProvider.objectType.getMethod(methodNameNode.name);
+      }
+      if (!identical(propagatedElement, staticMethodElement)) {
+        // Record static return type of the propagated element.
+        DartType propagatedStaticType = _computeStaticReturnType(propagatedElement);
+        if (propagatedStaticType != null && (staticStaticType == null || propagatedStaticType.isMoreSpecificThan(staticStaticType)) && (staticPropagatedType == null || propagatedStaticType.isMoreSpecificThan(staticPropagatedType))) {
+          _recordPropagatedType(node, propagatedStaticType);
+        }
+        // Record propagated return type of the propagated element.
+        DartType propagatedPropagatedType = _computePropagatedReturnType(propagatedElement);
+        if (propagatedPropagatedType != null && (staticStaticType == null || propagatedPropagatedType.isMoreSpecificThan(staticStaticType)) && (staticPropagatedType == null || propagatedPropagatedType.isMoreSpecificThan(staticPropagatedType)) && (propagatedStaticType == null || propagatedPropagatedType.isMoreSpecificThan(propagatedStaticType))) {
+          _recordPropagatedType(node, propagatedPropagatedType);
+        }
+      }
+    }
+    return null;
+  }
+
+  @override
+  Object visitNamedExpression(NamedExpression node) {
+    Expression expression = node.expression;
+    _recordStaticType(node, _getStaticType(expression));
+    _recordPropagatedType(node, expression.propagatedType);
+    return null;
+  }
+
+  /**
+   * The Dart Language Specification, 12.2: <blockquote>The static type of `null` is bottom.
+   * </blockquote>
+   */
+  @override
+  Object visitNullLiteral(NullLiteral node) {
+    _recordStaticType(node, _typeProvider.bottomType);
+    return null;
+  }
+
+  @override
+  Object visitParenthesizedExpression(ParenthesizedExpression node) {
+    Expression expression = node.expression;
+    _recordStaticType(node, _getStaticType(expression));
+    _recordPropagatedType(node, expression.propagatedType);
+    return null;
+  }
+
+  /**
+   * The Dart Language Specification, 12.28: <blockquote>A postfix expression of the form
+   * <i>v++</i>, where <i>v</i> is an identifier, is equivalent to <i>(){var r = v; v = r + 1;
+   * return r}()</i>.
+   *
+   * A postfix expression of the form <i>C.v++</i> is equivalent to <i>(){var r = C.v; C.v = r + 1;
+   * return r}()</i>.
+   *
+   * A postfix expression of the form <i>e1.v++</i> is equivalent to <i>(x){var r = x.v; x.v = r +
+   * 1; return r}(e1)</i>.
+   *
+   * A postfix expression of the form <i>e1[e2]++</i> is equivalent to <i>(a, i){var r = a[i]; a[i]
+   * = r + 1; return r}(e1, e2)</i>
+   *
+   * A postfix expression of the form <i>v--</i>, where <i>v</i> is an identifier, is equivalent to
+   * <i>(){var r = v; v = r - 1; return r}()</i>.
+   *
+   * A postfix expression of the form <i>C.v--</i> is equivalent to <i>(){var r = C.v; C.v = r - 1;
+   * return r}()</i>.
+   *
+   * A postfix expression of the form <i>e1.v--</i> is equivalent to <i>(x){var r = x.v; x.v = r -
+   * 1; return r}(e1)</i>.
+   *
+   * A postfix expression of the form <i>e1[e2]--</i> is equivalent to <i>(a, i){var r = a[i]; a[i]
+   * = r - 1; return r}(e1, e2)</i></blockquote>
+   */
+  @override
+  Object visitPostfixExpression(PostfixExpression node) {
+    Expression operand = node.operand;
+    DartType staticType = _getStaticType(operand);
+    sc.TokenType operator = node.operator.type;
+    if (operator == sc.TokenType.MINUS_MINUS || operator == sc.TokenType.PLUS_PLUS) {
+      DartType intType = _typeProvider.intType;
+      if (identical(_getStaticType(node.operand), intType)) {
+        staticType = intType;
+      }
+    }
+    _recordStaticType(node, staticType);
+    _recordPropagatedType(node, operand.propagatedType);
+    return null;
+  }
+
+  /**
+   * See [visitSimpleIdentifier].
+   */
+  @override
+  Object visitPrefixedIdentifier(PrefixedIdentifier node) {
+    SimpleIdentifier prefixedIdentifier = node.identifier;
+    Element staticElement = prefixedIdentifier.staticElement;
+    DartType staticType = _dynamicType;
+    DartType propagatedType = null;
+    if (staticElement is ClassElement) {
+      if (_isNotTypeLiteral(node)) {
+        staticType = staticElement.type;
+      } else {
+        staticType = _typeProvider.typeType;
+      }
+    } else if (staticElement is FunctionTypeAliasElement) {
+      if (_isNotTypeLiteral(node)) {
+        staticType = staticElement.type;
+      } else {
+        staticType = _typeProvider.typeType;
+      }
+    } else if (staticElement is MethodElement) {
+      staticType = staticElement.type;
+    } else if (staticElement is PropertyAccessorElement) {
+      staticType = _getTypeOfProperty(staticElement, node.prefix.staticType);
+      propagatedType = _getPropertyPropagatedType(staticElement, propagatedType);
+    } else if (staticElement is ExecutableElement) {
+      staticType = staticElement.type;
+    } else if (staticElement is TypeParameterElement) {
+      staticType = staticElement.type;
+    } else if (staticElement is VariableElement) {
+      staticType = staticElement.type;
+    }
+    _recordStaticType(prefixedIdentifier, staticType);
+    _recordStaticType(node, staticType);
+    Element propagatedElement = prefixedIdentifier.propagatedElement;
+    // HACK: special case for object getters ([hashCode] and [runtimeType]) on dynamic expressions.
+    // More special cases in [visitMethodInvocation].
+    if (propagatedElement == null) {
+      propagatedElement = _typeProvider.objectType.getGetter(prefixedIdentifier.name);
+    }
+    if (propagatedElement is ClassElement) {
+      if (_isNotTypeLiteral(node)) {
+        propagatedType = (propagatedElement as ClassElement).type;
+      } else {
+        propagatedType = _typeProvider.typeType;
+      }
+    } else if (propagatedElement is FunctionTypeAliasElement) {
+      propagatedType = (propagatedElement as FunctionTypeAliasElement).type;
+    } else if (propagatedElement is MethodElement) {
+      propagatedType = (propagatedElement as MethodElement).type;
+    } else if (propagatedElement is PropertyAccessorElement) {
+      propagatedType = _getTypeOfProperty(propagatedElement as PropertyAccessorElement, node.prefix.staticType);
+      propagatedType = _getPropertyPropagatedType(propagatedElement, propagatedType);
+    } else if (propagatedElement is ExecutableElement) {
+      propagatedType = (propagatedElement as ExecutableElement).type;
+    } else if (propagatedElement is TypeParameterElement) {
+      propagatedType = (propagatedElement as TypeParameterElement).type;
+    } else if (propagatedElement is VariableElement) {
+      propagatedType = (propagatedElement as VariableElement).type;
+    }
+    DartType overriddenType = _overrideManager.getType(propagatedElement);
+    if (propagatedType == null || (overriddenType != null && overriddenType.isMoreSpecificThan(propagatedType))) {
+      propagatedType = overriddenType;
+    }
+    if (propagatedType != null && propagatedType.isMoreSpecificThan(staticType)) {
+      _recordPropagatedType(prefixedIdentifier, propagatedType);
+      _recordPropagatedType(node, propagatedType);
+    }
+    return null;
+  }
+
+  /**
+   * The Dart Language Specification, 12.27: <blockquote>A unary expression <i>u</i> of the form
+   * <i>op e</i> is equivalent to a method invocation <i>expression e.op()</i>. An expression of the
+   * form <i>op super</i> is equivalent to the method invocation <i>super.op()<i>.</blockquote>
+   */
+  @override
+  Object visitPrefixExpression(PrefixExpression node) {
+    sc.TokenType operator = node.operator.type;
+    if (operator == sc.TokenType.BANG) {
+      _recordStaticType(node, _typeProvider.boolType);
+    } else {
+      // The other cases are equivalent to invoking a method.
+      ExecutableElement staticMethodElement = node.staticElement;
+      DartType staticType = _computeStaticReturnType(staticMethodElement);
+      if (operator == sc.TokenType.MINUS_MINUS || operator == sc.TokenType.PLUS_PLUS) {
+        DartType intType = _typeProvider.intType;
+        if (identical(_getStaticType(node.operand), intType)) {
+          staticType = intType;
+        }
+      }
+      _recordStaticType(node, staticType);
+      MethodElement propagatedMethodElement = node.propagatedElement;
+      if (!identical(propagatedMethodElement, staticMethodElement)) {
+        DartType propagatedType = _computeStaticReturnType(propagatedMethodElement);
+        if (propagatedType != null && propagatedType.isMoreSpecificThan(staticType)) {
+          _recordPropagatedType(node, propagatedType);
+        }
+      }
+    }
+    return null;
+  }
+
+  /**
+   * The Dart Language Specification, 12.13: <blockquote> Property extraction allows for a member of
+   * an object to be concisely extracted from the object. If <i>o</i> is an object, and if <i>m</i>
+   * is the name of a method member of <i>o</i>, then
+   * * <i>o.m</i> is defined to be equivalent to: <i>(r<sub>1</sub>, &hellip;, r<sub>n</sub>,
+   * {p<sub>1</sub> : d<sub>1</sub>, &hellip;, p<sub>k</sub> : d<sub>k</sub>}){return
+   * o.m(r<sub>1</sub>, &hellip;, r<sub>n</sub>, p<sub>1</sub>: p<sub>1</sub>, &hellip;,
+   * p<sub>k</sub>: p<sub>k</sub>);}</i> if <i>m</i> has required parameters <i>r<sub>1</sub>,
+   * &hellip;, r<sub>n</sub></i>, and named parameters <i>p<sub>1</sub> &hellip; p<sub>k</sub></i>
+   * with defaults <i>d<sub>1</sub>, &hellip;, d<sub>k</sub></i>.
+   * * <i>(r<sub>1</sub>, &hellip;, r<sub>n</sub>, [p<sub>1</sub> = d<sub>1</sub>, &hellip;,
+   * p<sub>k</sub> = d<sub>k</sub>]){return o.m(r<sub>1</sub>, &hellip;, r<sub>n</sub>,
+   * p<sub>1</sub>, &hellip;, p<sub>k</sub>);}</i> if <i>m</i> has required parameters
+   * <i>r<sub>1</sub>, &hellip;, r<sub>n</sub></i>, and optional positional parameters
+   * <i>p<sub>1</sub> &hellip; p<sub>k</sub></i> with defaults <i>d<sub>1</sub>, &hellip;,
+   * d<sub>k</sub></i>.
+   * Otherwise, if <i>m</i> is the name of a getter member of <i>o</i> (declared implicitly or
+   * explicitly) then <i>o.m</i> evaluates to the result of invoking the getter. </blockquote>
+   *
+   * The Dart Language Specification, 12.17: <blockquote> ... a getter invocation <i>i</i> of the
+   * form <i>e.m</i> ...
+   *
+   * Let <i>T</i> be the static type of <i>e</i>. It is a static type warning if <i>T</i> does not
+   * have a getter named <i>m</i>.
+   *
+   * The static type of <i>i</i> is the declared return type of <i>T.m</i>, if <i>T.m</i> exists;
+   * otherwise the static type of <i>i</i> is dynamic.
+   *
+   * ... a getter invocation <i>i</i> of the form <i>C.m</i> ...
+   *
+   * It is a static warning if there is no class <i>C</i> in the enclosing lexical scope of
+   * <i>i</i>, or if <i>C</i> does not declare, implicitly or explicitly, a getter named <i>m</i>.
+   *
+   * The static type of <i>i</i> is the declared return type of <i>C.m</i> if it exists or dynamic
+   * otherwise.
+   *
+   * ... a top-level getter invocation <i>i</i> of the form <i>m</i>, where <i>m</i> is an
+   * identifier ...
+   *
+   * The static type of <i>i</i> is the declared return type of <i>m</i>.</blockquote>
+   */
+  @override
+  Object visitPropertyAccess(PropertyAccess node) {
+    SimpleIdentifier propertyName = node.propertyName;
+    Element staticElement = propertyName.staticElement;
+    DartType staticType = _dynamicType;
+    if (staticElement is MethodElement) {
+      staticType = staticElement.type;
+    } else if (staticElement is PropertyAccessorElement) {
+      Expression realTarget = node.realTarget;
+      staticType = _getTypeOfProperty(staticElement, realTarget != null ? _getStaticType(realTarget) : null);
+    } else {
+      // TODO(brianwilkerson) Report this internal error.
+    }
+    _recordStaticType(propertyName, staticType);
+    _recordStaticType(node, staticType);
+    Element propagatedElement = propertyName.propagatedElement;
+    DartType propagatedType = _overrideManager.getType(propagatedElement);
+    if (propagatedElement is MethodElement) {
+      propagatedType = propagatedElement.type;
+    } else if (propagatedElement is PropertyAccessorElement) {
+      Expression realTarget = node.realTarget;
+      propagatedType = _getTypeOfProperty(propagatedElement, realTarget != null ? realTarget.bestType : null);
+    } else {
+      // TODO(brianwilkerson) Report this internal error.
+    }
+    if (propagatedType != null && propagatedType.isMoreSpecificThan(staticType)) {
+      _recordPropagatedType(propertyName, propagatedType);
+      _recordPropagatedType(node, propagatedType);
+    }
+    return null;
+  }
+
+  /**
+   * The Dart Language Specification, 12.9: <blockquote>The static type of a rethrow expression is
+   * bottom.</blockquote>
+   */
+  @override
+  Object visitRethrowExpression(RethrowExpression node) {
+    _recordStaticType(node, _typeProvider.bottomType);
+    return null;
+  }
+
+  /**
+   * The Dart Language Specification, 12.30: <blockquote>Evaluation of an identifier expression
+   * <i>e</i> of the form <i>id</i> proceeds as follows:
+   *
+   * Let <i>d</i> be the innermost declaration in the enclosing lexical scope whose name is
+   * <i>id</i>. If no such declaration exists in the lexical scope, let <i>d</i> be the declaration
+   * of the inherited member named <i>id</i> if it exists.
+   * * If <i>d</i> is a class or type alias <i>T</i>, the value of <i>e</i> is the unique instance
+   * of class `Type` reifying <i>T</i>.
+   * * If <i>d</i> is a type parameter <i>T</i>, then the value of <i>e</i> is the value of the
+   * actual type argument corresponding to <i>T</i> that was passed to the generative constructor
+   * that created the current binding of this. We are assured that this is well defined, because if
+   * we were in a static member the reference to <i>T</i> would be a compile-time error.
+   * * If <i>d</i> is a library variable then:
+   * * If <i>d</i> is of one of the forms <i>var v = e<sub>i</sub>;</i>, <i>T v =
+   * e<sub>i</sub>;</i>, <i>final v = e<sub>i</sub>;</i>, <i>final T v = e<sub>i</sub>;</i>, and no
+   * value has yet been stored into <i>v</i> then the initializer expression <i>e<sub>i</sub></i> is
+   * evaluated. If, during the evaluation of <i>e<sub>i</sub></i>, the getter for <i>v</i> is
+   * referenced, a CyclicInitializationError is thrown. If the evaluation succeeded yielding an
+   * object <i>o</i>, let <i>r = o</i>, otherwise let <i>r = null</i>. In any case, <i>r</i> is
+   * stored into <i>v</i>. The value of <i>e</i> is <i>r</i>.
+   * * If <i>d</i> is of one of the forms <i>const v = e;</i> or <i>const T v = e;</i> the result
+   * of the getter is the value of the compile time constant <i>e</i>. Otherwise
+   * * <i>e</i> evaluates to the current binding of <i>id</i>.
+   * * If <i>d</i> is a local variable or formal parameter then <i>e</i> evaluates to the current
+   * binding of <i>id</i>.
+   * * If <i>d</i> is a static method, top level function or local function then <i>e</i>
+   * evaluates to the function defined by <i>d</i>.
+   * * If <i>d</i> is the declaration of a static variable or static getter declared in class
+   * <i>C</i>, then <i>e</i> is equivalent to the getter invocation <i>C.id</i>.
+   * * If <i>d</i> is the declaration of a top level getter, then <i>e</i> is equivalent to the
+   * getter invocation <i>id</i>.
+   * * Otherwise, if <i>e</i> occurs inside a top level or static function (be it function,
+   * method, getter, or setter) or variable initializer, evaluation of e causes a NoSuchMethodError
+   * to be thrown.
+   * * Otherwise <i>e</i> is equivalent to the property extraction <i>this.id</i>.
+   * </blockquote>
+   */
+  @override
+  Object visitSimpleIdentifier(SimpleIdentifier node) {
+    Element element = node.staticElement;
+    DartType staticType = _dynamicType;
+    if (element is ClassElement) {
+      if (_isNotTypeLiteral(node)) {
+        staticType = element.type;
+      } else {
+        staticType = _typeProvider.typeType;
+      }
+    } else if (element is FunctionTypeAliasElement) {
+      if (_isNotTypeLiteral(node)) {
+        staticType = element.type;
+      } else {
+        staticType = _typeProvider.typeType;
+      }
+    } else if (element is MethodElement) {
+      staticType = element.type;
+    } else if (element is PropertyAccessorElement) {
+      staticType = _getTypeOfProperty(element, null);
+    } else if (element is ExecutableElement) {
+      staticType = element.type;
+    } else if (element is TypeParameterElement) {
+      staticType = _typeProvider.typeType;
+    } else if (element is VariableElement) {
+      VariableElement variable = element;
+      staticType = _promoteManager.getStaticType(variable);
+    } else if (element is PrefixElement) {
+      return null;
+    } else if (element is DynamicElementImpl) {
+      staticType = _typeProvider.typeType;
+    } else {
+      staticType = _dynamicType;
+    }
+    _recordStaticType(node, staticType);
+    // TODO(brianwilkerson) I think we want to repeat the logic above using the propagated element
+    // to get another candidate for the propagated type.
+    DartType propagatedType = _getPropertyPropagatedType(element, null);
+    if (propagatedType == null) {
+      DartType overriddenType = _overrideManager.getType(element);
+      if (propagatedType == null || overriddenType != null && overriddenType.isMoreSpecificThan(propagatedType)) {
+        propagatedType = overriddenType;
+      }
+    }
+    if (propagatedType != null && propagatedType.isMoreSpecificThan(staticType)) {
+      _recordPropagatedType(node, propagatedType);
+    }
+    return null;
+  }
+
+  /**
+   * The Dart Language Specification, 12.5: <blockquote>The static type of a string literal is
+   * `String`.</blockquote>
+   */
+  @override
+  Object visitSimpleStringLiteral(SimpleStringLiteral node) {
+    _recordStaticType(node, _typeProvider.stringType);
+    return null;
+  }
+
+  /**
+   * The Dart Language Specification, 12.5: <blockquote>The static type of a string literal is
+   * `String`.</blockquote>
+   */
+  @override
+  Object visitStringInterpolation(StringInterpolation node) {
+    _recordStaticType(node, _typeProvider.stringType);
+    return null;
+  }
+
+  @override
+  Object visitSuperExpression(SuperExpression node) {
+    if (_thisType == null) {
+      // TODO(brianwilkerson) Report this error if it hasn't already been reported
+      _recordStaticType(node, _dynamicType);
+    } else {
+      _recordStaticType(node, _thisType);
+    }
+    return null;
+  }
+
+  @override
+  Object visitSymbolLiteral(SymbolLiteral node) {
+    _recordStaticType(node, _typeProvider.symbolType);
+    return null;
+  }
+
+  /**
+   * The Dart Language Specification, 12.10: <blockquote>The static type of `this` is the
+   * interface of the immediately enclosing class.</blockquote>
+   */
+  @override
+  Object visitThisExpression(ThisExpression node) {
+    if (_thisType == null) {
+      // TODO(brianwilkerson) Report this error if it hasn't already been reported
+      _recordStaticType(node, _dynamicType);
+    } else {
+      _recordStaticType(node, _thisType);
+    }
+    return null;
+  }
+
+  /**
+   * The Dart Language Specification, 12.8: <blockquote>The static type of a throw expression is
+   * bottom.</blockquote>
+   */
+  @override
+  Object visitThrowExpression(ThrowExpression node) {
+    _recordStaticType(node, _typeProvider.bottomType);
+    return null;
+  }
+
+  @override
+  Object visitVariableDeclaration(VariableDeclaration node) {
+    Expression initializer = node.initializer;
+    if (initializer != null) {
+      DartType rightType = initializer.bestType;
+      SimpleIdentifier name = node.name;
+      _recordPropagatedType(name, rightType);
+      VariableElement element = name.staticElement as VariableElement;
+      if (element != null) {
+        _resolver.overrideVariable(element, rightType, true);
+      }
+    }
+    return null;
+  }
+
+  /**
+   * Record that the static type of the given node is the type of the second argument to the method
+   * represented by the given element.
+   *
+   * @param element the element representing the method invoked by the given node
+   */
+  DartType _computeArgumentType(ExecutableElement element) {
+    if (element != null) {
+      List<ParameterElement> parameters = element.parameters;
+      if (parameters != null && parameters.length == 2) {
+        return parameters[1].type;
+      }
+    }
+    return _dynamicType;
+  }
+
+  /**
+   * Compute the propagated return type of the method or function represented by the given element.
+   *
+   * @param element the element representing the method or function invoked by the given node
+   * @return the propagated return type that was computed
+   */
+  DartType _computePropagatedReturnType(Element element) {
+    if (element is ExecutableElement) {
+      return _propagatedReturnTypes[element];
+    }
+    return null;
+  }
+
+  /**
+   * Given a function body, compute the propagated return type of the function. The propagated
+   * return type of functions with a block body is the least upper bound of all
+   * [ReturnStatement] expressions, with an expression body it is the type of the expression.
+   *
+   * @param body the boy of the function whose propagated return type is to be computed
+   * @return the propagated return type that was computed
+   */
+  DartType _computePropagatedReturnTypeOfFunction(FunctionBody body) {
+    if (body is ExpressionFunctionBody) {
+      ExpressionFunctionBody expressionBody = body;
+      return expressionBody.expression.bestType;
+    }
+    if (body is BlockFunctionBody) {
+      GeneralizingAstVisitor_StaticTypeAnalyzer_computePropagatedReturnTypeOfFunction visitor
+          = new GeneralizingAstVisitor_StaticTypeAnalyzer_computePropagatedReturnTypeOfFunction();
+      body.accept(visitor);
+      return visitor.result;
+    }
+    return null;
+  }
+
+  /**
+   * Compute the static return type of the method or function represented by the given element.
+   *
+   * @param element the element representing the method or function invoked by the given node
+   * @return the static return type that was computed
+   */
+  DartType _computeStaticReturnType(Element element) {
+    if (element is PropertyAccessorElement) {
+      //
+      // This is a function invocation expression disguised as something else. We are invoking a
+      // getter and then invoking the returned function.
+      //
+      FunctionType propertyType = element.type;
+      if (propertyType != null) {
+        DartType returnType = propertyType.returnType;
+        if (returnType.isDartCoreFunction) {
+          return _dynamicType;
+        } else if (returnType is InterfaceType) {
+          MethodElement callMethod = returnType.lookUpMethod(FunctionElement.CALL_METHOD_NAME, _resolver.definingLibrary);
+          if (callMethod != null) {
+            return callMethod.type.returnType;
+          }
+        } else if (returnType is FunctionType) {
+          DartType innerReturnType = returnType.returnType;
+          if (innerReturnType != null) {
+            return innerReturnType;
+          }
+        }
+        if (returnType != null) {
+          return returnType;
+        }
+      }
+    } else if (element is ExecutableElement) {
+      FunctionType type = element.type;
+      if (type != null) {
+        // TODO(brianwilkerson) Figure out the conditions under which the type is null.
+        return type.returnType;
+      }
+    } else if (element is VariableElement) {
+      VariableElement variable = element;
+      DartType variableType = _promoteManager.getStaticType(variable);
+      if (variableType is FunctionType) {
+        return variableType.returnType;
+      }
+    }
+    return _dynamicType;
+  }
+
+  /**
+   * Given a function declaration, compute the return static type of the function. The return type
+   * of functions with a block body is `dynamicType`, with an expression body it is the type
+   * of the expression.
+   *
+   * @param node the function expression whose static return type is to be computed
+   * @return the static return type that was computed
+   */
+  DartType _computeStaticReturnTypeOfFunctionDeclaration(FunctionDeclaration node) {
+    TypeName returnType = node.returnType;
+    if (returnType == null) {
+      return _dynamicType;
+    }
+    return returnType.type;
+  }
+
+  /**
+   * Given a function expression, compute the return type of the function. The return type of
+   * functions with a block body is `dynamicType`, with an expression body it is the type of
+   * the expression.
+   *
+   * @param node the function expression whose return type is to be computed
+   * @return the return type that was computed
+   */
+  DartType _computeStaticReturnTypeOfFunctionExpression(FunctionExpression node) {
+    FunctionBody body = node.body;
+    if (body is ExpressionFunctionBody) {
+      return _getStaticType(body.expression);
+    }
+    return _dynamicType;
+  }
+
+  /**
+   * If the given element name can be mapped to the name of a class defined within the given
+   * library, return the type specified by the argument.
+   *
+   * @param library the library in which the specified type would be defined
+   * @param elementName the name of the element for which a type is being sought
+   * @param nameMap an optional map used to map the element name to a type name
+   * @return the type specified by the first argument in the argument list
+   */
+  DartType _getElementNameAsType(LibraryElement library, String elementName, HashMap<String, String> nameMap) {
+    if (elementName != null) {
+      if (nameMap != null) {
+        elementName = nameMap[elementName.toLowerCase()];
+      }
+      ClassElement returnType = library.getType(elementName);
+      if (returnType != null) {
+        return returnType.type;
+      }
+    }
+    return null;
+  }
+
+  /**
+   * If the given argument list contains at least one argument, and if the argument is a simple
+   * string literal, then parse that argument as a query string and return the type specified by the
+   * argument.
+   *
+   * @param library the library in which the specified type would be defined
+   * @param argumentList the list of arguments from which a type is to be extracted
+   * @return the type specified by the first argument in the argument list
+   */
+  DartType _getFirstArgumentAsQuery(LibraryElement library, ArgumentList argumentList) {
+    String argumentValue = _getFirstArgumentAsString(argumentList);
+    if (argumentValue != null) {
+      //
+      // If the query has spaces, full parsing is required because it might be:
+      //   E[text='warning text']
+      //
+      if (StringUtilities.indexOf1(argumentValue, 0, 0x20) >= 0) {
+        return null;
+      }
+      //
+      // Otherwise, try to extract the tag based on http://www.w3.org/TR/CSS2/selector.html.
+      //
+      String tag = argumentValue;
+      tag = StringUtilities.substringBeforeChar(tag, 0x3A);
+      tag = StringUtilities.substringBeforeChar(tag, 0x5B);
+      tag = StringUtilities.substringBeforeChar(tag, 0x2E);
+      tag = StringUtilities.substringBeforeChar(tag, 0x23);
+      tag = _HTML_ELEMENT_TO_CLASS_MAP[tag.toLowerCase()];
+      ClassElement returnType = library.getType(tag);
+      if (returnType != null) {
+        return returnType.type;
+      }
+    }
+    return null;
+  }
+
+  /**
+   * If the given argument list contains at least one argument, and if the argument is a simple
+   * string literal, return the String value of the argument.
+   *
+   * @param argumentList the list of arguments from which a string value is to be extracted
+   * @return the string specified by the first argument in the argument list
+   */
+  String _getFirstArgumentAsString(ArgumentList argumentList) {
+    NodeList<Expression> arguments = argumentList.arguments;
+    if (arguments.length > 0) {
+      Expression argument = arguments[0];
+      if (argument is SimpleStringLiteral) {
+        return argument.value;
+      }
+    }
+    return null;
+  }
+
+  /**
+   * If the given argument list contains at least one argument, and if the argument is a simple
+   * string literal, and if the value of the argument is the name of a class defined within the
+   * given library, return the type specified by the argument.
+   *
+   * @param library the library in which the specified type would be defined
+   * @param argumentList the list of arguments from which a type is to be extracted
+   * @return the type specified by the first argument in the argument list
+   */
+  DartType _getFirstArgumentAsType(LibraryElement library, ArgumentList argumentList) => _getFirstArgumentAsTypeWithMap(library, argumentList, null);
+
+  /**
+   * If the given argument list contains at least one argument, and if the argument is a simple
+   * string literal, and if the value of the argument is the name of a class defined within the
+   * given library, return the type specified by the argument.
+   *
+   * @param library the library in which the specified type would be defined
+   * @param argumentList the list of arguments from which a type is to be extracted
+   * @param nameMap an optional map used to map the element name to a type name
+   * @return the type specified by the first argument in the argument list
+   */
+  DartType _getFirstArgumentAsTypeWithMap(LibraryElement library, ArgumentList argumentList, HashMap<String, String> nameMap) => _getElementNameAsType(library, _getFirstArgumentAsString(argumentList), nameMap);
+
+  /**
+   * Return the propagated type of the given [Element], or `null`.
+   */
+  DartType _getPropertyPropagatedType(Element element, DartType currentType) {
+    if (element is PropertyAccessorElement) {
+      PropertyAccessorElement accessor = element;
+      if (accessor.isGetter) {
+        PropertyInducingElement variable = accessor.variable;
+        DartType propagatedType = variable.propagatedType;
+        if (currentType == null || propagatedType != null && propagatedType.isMoreSpecificThan(currentType)) {
+          return propagatedType;
+        }
+      }
+    }
+    return currentType;
+  }
+
+  /**
+   * Return the static type of the given expression.
+   *
+   * @param expression the expression whose type is to be returned
+   * @return the static type of the given expression
+   */
+  DartType _getStaticType(Expression expression) {
+    DartType type = expression.staticType;
+    if (type == null) {
+      // TODO(brianwilkerson) Determine the conditions for which the static type is null.
+      return _dynamicType;
+    }
+    return type;
+  }
+
+  /**
+   * Return the type represented by the given type name.
+   *
+   * @param typeName the type name representing the type to be returned
+   * @return the type represented by the type name
+   */
+  DartType _getType(TypeName typeName) {
+    DartType type = typeName.type;
+    if (type == null) {
+      //TODO(brianwilkerson) Determine the conditions for which the type is null.
+      return _dynamicType;
+    }
+    return type;
+  }
+
+  /**
+   * Return the type that should be recorded for a node that resolved to the given accessor.
+   *
+   * @param accessor the accessor that the node resolved to
+   * @param context if the accessor element has context [by being the RHS of a
+   *          [PrefixedIdentifier] or [PropertyAccess]], and the return type of the
+   *          accessor is a parameter type, then the type of the LHS can be used to get more
+   *          specific type information
+   * @return the type that should be recorded for a node that resolved to the given accessor
+   */
+  DartType _getTypeOfProperty(PropertyAccessorElement accessor, DartType context) {
+    FunctionType functionType = accessor.type;
+    if (functionType == null) {
+      // TODO(brianwilkerson) Report this internal error. This happens when we are analyzing a
+      // reference to a property before we have analyzed the declaration of the property or when
+      // the property does not have a defined type.
+      return _dynamicType;
+    }
+    if (accessor.isSetter) {
+      List<DartType> parameterTypes = functionType.normalParameterTypes;
+      if (parameterTypes != null && parameterTypes.length > 0) {
+        return parameterTypes[0];
+      }
+      PropertyAccessorElement getter = accessor.variable.getter;
+      if (getter != null) {
+        functionType = getter.type;
+        if (functionType != null) {
+          return functionType.returnType;
+        }
+      }
+      return _dynamicType;
+    }
+    DartType returnType = functionType.returnType;
+    if (returnType is TypeParameterType && context is InterfaceType) {
+      // if the return type is a TypeParameter, we try to use the context [that the function is being
+      // called on] to get a more accurate returnType type
+      InterfaceType interfaceTypeContext = context;
+      //      Type[] argumentTypes = interfaceTypeContext.getTypeArguments();
+      List<TypeParameterElement> typeParameterElements = interfaceTypeContext.element != null ? interfaceTypeContext.element.typeParameters : null;
+      if (typeParameterElements != null) {
+        for (int i = 0; i < typeParameterElements.length; i++) {
+          TypeParameterElement typeParameterElement = typeParameterElements[i];
+          if (returnType.name == typeParameterElement.name) {
+            return interfaceTypeContext.typeArguments[i];
+          }
+        }
+        // TODO(jwren) troubleshoot why call to substitute doesn't work
+        //        Type[] parameterTypes = TypeParameterTypeImpl.getTypes(parameterElements);
+        //        return returnType.substitute(argumentTypes, parameterTypes);
+      }
+    }
+    return returnType;
+  }
+
+  /**
+   * Return `true` if the given [Type] is the `Future` form the 'dart:async'
+   * library.
+   */
+  bool _isAsyncFutureType(DartType type) => type is InterfaceType && type.name == "Future" && _isAsyncLibrary(type.element.library);
+
+  /**
+   * Return `true` if the given library is the 'dart:async' library.
+   *
+   * @param library the library being tested
+   * @return `true` if the library is 'dart:async'
+   */
+  bool _isAsyncLibrary(LibraryElement library) => library.name == "dart.async";
+
+  /**
+   * Return `true` if the given library is the 'dart:html' library.
+   *
+   * @param library the library being tested
+   * @return `true` if the library is 'dart:html'
+   */
+  bool _isHtmlLibrary(LibraryElement library) => library != null && "dart.dom.html" == library.name;
+
+  /**
+   * Return `true` if the given node is not a type literal.
+   *
+   * @param node the node being tested
+   * @return `true` if the given node is not a type literal
+   */
+  bool _isNotTypeLiteral(Identifier node) {
+    AstNode parent = node.parent;
+    return parent is TypeName || (parent is PrefixedIdentifier && (parent.parent is TypeName || identical(parent.prefix, node))) || (parent is PropertyAccess && identical(parent.target, node)) || (parent is MethodInvocation && identical(node, parent.target));
+  }
+
+  /**
+   * Record that the propagated type of the given node is the given type.
+   *
+   * @param expression the node whose type is to be recorded
+   * @param type the propagated type of the node
+   */
+  void _recordPropagatedType(Expression expression, DartType type) {
+    if (type != null && !type.isDynamic && !type.isBottom) {
+      expression.propagatedType = type;
+    }
+  }
+
+  /**
+   * Given a function element and its body, compute and record the propagated return type of the
+   * function.
+   *
+   * @param functionElement the function element to record propagated return type for
+   * @param body the boy of the function whose propagated return type is to be computed
+   * @return the propagated return type that was computed, may be `null` if it is not more
+   *         specific than the static return type.
+   */
+  void _recordPropagatedTypeOfFunction(ExecutableElement functionElement, FunctionBody body) {
+    DartType propagatedReturnType = _computePropagatedReturnTypeOfFunction(body);
+    if (propagatedReturnType == null) {
+      return;
+    }
+    // Ignore 'bottom' type.
+    if (propagatedReturnType.isBottom) {
+      return;
+    }
+    // Record only if we inferred more specific type.
+    DartType staticReturnType = functionElement.returnType;
+    if (!propagatedReturnType.isMoreSpecificThan(staticReturnType)) {
+      return;
+    }
+    // OK, do record.
+    _propagatedReturnTypes[functionElement] = propagatedReturnType;
+  }
+
+  /**
+   * Record that the static type of the given node is the given type.
+   *
+   * @param expression the node whose type is to be recorded
+   * @param type the static type of the node
+   */
+  void _recordStaticType(Expression expression, DartType type) {
+    if (type == null) {
+      expression.staticType = _dynamicType;
+    } else {
+      expression.staticType = type;
+    }
+  }
+
+  /**
+   * Attempts to make a better guess for the static type of the given binary expression.
+   *
+   * @param node the binary expression to analyze
+   * @param staticType the static type of the expression as resolved
+   * @return the better type guess, or the same static type as given
+   */
+  DartType _refineBinaryExpressionType(BinaryExpression node, DartType staticType) {
+    sc.TokenType operator = node.operator.type;
+    // bool
+    if (operator == sc.TokenType.AMPERSAND_AMPERSAND || operator == sc.TokenType.BAR_BAR || operator == sc.TokenType.EQ_EQ || operator == sc.TokenType.BANG_EQ) {
+      return _typeProvider.boolType;
+    }
+    DartType intType = _typeProvider.intType;
+    if (_getStaticType(node.leftOperand) == intType) {
+      // int op double
+      if (operator == sc.TokenType.MINUS || operator == sc.TokenType.PERCENT || operator == sc.TokenType.PLUS || operator == sc.TokenType.STAR) {
+        DartType doubleType = _typeProvider.doubleType;
+        if (_getStaticType(node.rightOperand) == doubleType) {
+          return doubleType;
+        }
+      }
+      // int op int
+      if (operator == sc.TokenType.MINUS || operator == sc.TokenType.PERCENT || operator == sc.TokenType.PLUS || operator == sc.TokenType.STAR || operator == sc.TokenType.TILDE_SLASH) {
+        if (_getStaticType(node.rightOperand) == intType) {
+          staticType = intType;
+        }
+      }
+    }
+    // default
+    return staticType;
+  }
+
+  get thisType_J2DAccessor => _thisType;
+
+  set thisType_J2DAccessor(__v) => _thisType = __v;
+}
diff --git a/pkg/analyzer/lib/src/services/formatter_impl.dart b/pkg/analyzer/lib/src/services/formatter_impl.dart
index d35bd2b..68725e7 100644
--- a/pkg/analyzer/lib/src/services/formatter_impl.dart
+++ b/pkg/analyzer/lib/src/services/formatter_impl.dart
@@ -828,7 +828,7 @@
     space();
     token(node.inKeyword);
     space();
-    visit(node.iterator);
+    visit(node.iterable);
     token(node.rightParenthesis);
     space();
     visit(node.body);
diff --git a/pkg/analyzer/pubspec.yaml b/pkg/analyzer/pubspec.yaml
index 54c3359..4bb0356 100644
--- a/pkg/analyzer/pubspec.yaml
+++ b/pkg/analyzer/pubspec.yaml
@@ -6,7 +6,7 @@
 environment:
   sdk: '>=0.8.10+6 <2.0.0'
 dependencies:
-  args: '>=0.10.0 <0.13.0'
+  args: '>=0.12.1 <0.13.0'
   logging: '>=0.9.0 <0.10.0'
   path: '>=0.9.0 <2.0.0'
   watcher: '>=0.9.0 <0.10.0'
diff --git a/pkg/analyzer/test/generated/all_the_rest.dart b/pkg/analyzer/test/generated/all_the_rest.dart
index 7aa42b0..4e86f49 100644
--- a/pkg/analyzer/test/generated/all_the_rest.dart
+++ b/pkg/analyzer/test/generated/all_the_rest.dart
@@ -5394,6 +5394,85 @@
     expect(_stringValue(null).hasExactValue, isTrue);
   }
 
+  void test_identical_bool_false() {
+    _assertIdentical(_boolValue(false), _boolValue(false), _boolValue(true));
+  }
+
+  void test_identical_bool_true() {
+    _assertIdentical(_boolValue(true), _boolValue(true), _boolValue(true));
+  }
+
+  void test_identical_bool_unknown() {
+    _assertIdentical(_boolValue(null), _boolValue(null), _boolValue(false));
+  }
+
+  void test_identical_double_false() {
+    _assertIdentical(_boolValue(false), _doubleValue(2.0), _doubleValue(4.0));
+  }
+
+  void test_identical_double_true() {
+    _assertIdentical(_boolValue(true), _doubleValue(2.0), _doubleValue(2.0));
+  }
+
+  void test_identical_double_unknown() {
+    _assertIdentical(_boolValue(null), _doubleValue(1.0), _doubleValue(null));
+  }
+
+  void test_identical_int_false() {
+    _assertIdentical(_boolValue(false), _intValue(-5), _intValue(5));
+  }
+
+  void test_identical_int_true() {
+    _assertIdentical(_boolValue(true), _intValue(5), _intValue(5));
+  }
+
+  void test_identical_int_unknown() {
+    _assertIdentical(_boolValue(null), _intValue(null), _intValue(3));
+  }
+
+  void test_identical_list_empty() {
+    _assertIdentical(_boolValue(true), _listValue([]), _listValue([]));
+  }
+
+  void test_identical_list_false() {
+    _assertIdentical(_boolValue(false), _listValue([]),
+        _listValue([_intValue(3)]));
+  }
+
+  void test_identical_map_empty() {
+    _assertIdentical(_boolValue(true), _mapValue([]), _mapValue([]));
+  }
+
+  void test_identical_map_false() {
+    _assertIdentical(_boolValue(false), _mapValue([]),
+        _mapValue([_intValue(1), _intValue(2)]));
+  }
+
+  void test_identical_null() {
+    _assertIdentical(_boolValue(true), _nullValue(), _nullValue());
+  }
+
+  void test_identical_string_false() {
+    _assertIdentical(
+        _boolValue(false),
+        _stringValue("abc"),
+        _stringValue("def"));
+  }
+
+  void test_identical_string_true() {
+    _assertIdentical(
+        _boolValue(true),
+        _stringValue("abc"),
+        _stringValue("abc"));
+  }
+
+  void test_identical_string_unknown() {
+    _assertIdentical(
+        _boolValue(null),
+        _stringValue(null),
+        _stringValue("def"));
+  }
+
   void test_integerDivide_knownDouble_knownDouble() {
     _assertIntegerDivide(_intValue(3), _doubleValue(6.0), _doubleValue(2.0));
   }
@@ -6441,6 +6520,22 @@
     }
   }
 
+  /**
+   * Assert that the result of comparing the left and right operands using
+   * identical() is the expected value.
+   *
+   * @param expected the expected result of the operation
+   * @param leftOperand the left operand to the operation
+   * @param rightOperand the left operand to the operation
+   */
+  void _assertIdentical(DartObjectImpl expected, DartObjectImpl leftOperand,
+      DartObjectImpl rightOperand) {
+    DartObjectImpl result =
+        leftOperand.isIdentical(_typeProvider, rightOperand);
+    expect(result, isNotNull);
+    expect(result, expected);
+  }
+
   void _assertInstanceOfObjectArray(Object result) {
     // TODO(scheglov) implement
   }
diff --git a/pkg/analyzer/test/generated/ast_test.dart b/pkg/analyzer/test/generated/ast_test.dart
index 3a13b38..58ea86f 100644
--- a/pkg/analyzer/test/generated/ast_test.dart
+++ b/pkg/analyzer/test/generated/ast_test.dart
@@ -953,6 +953,15 @@
     }
   }
 
+  void test_inGetterContext_forEachLoop() {
+    SimpleIdentifier identifier = AstFactory.identifier3("a");
+    Expression iterator = AstFactory.listLiteral([]);
+    Statement body = AstFactory.block([]);
+    ForEachStatement forEachStatement =
+        AstFactory.forEachStatement2(identifier, iterator, body);
+    expect(identifier.inGetterContext(), isFalse);
+  }
+
   void test_inReferenceContext() {
     SimpleIdentifier identifier = AstFactory.identifier3("id");
     AstFactory.namedExpression(AstFactory.label(identifier), AstFactory.identifier3("_"));
@@ -977,6 +986,15 @@
     }
   }
 
+  void test_inSetterContext_forEachLoop() {
+    SimpleIdentifier identifier = AstFactory.identifier3("a");
+    Expression iterator = AstFactory.listLiteral([]);
+    Statement body = AstFactory.block([]);
+    ForEachStatement forEachStatement =
+        AstFactory.forEachStatement2(identifier, iterator, body);
+    expect(identifier.inSetterContext(), isTrue);
+  }
+
   void test_isQualified_inMethodInvocation_noTarget() {
     MethodInvocation invocation = AstFactory.methodInvocation2("test", [AstFactory.identifier3("arg0")]);
     SimpleIdentifier identifier = invocation.methodName;
diff --git a/pkg/analyzer/test/generated/compile_time_error_code_test.dart b/pkg/analyzer/test/generated/compile_time_error_code_test.dart
index c72aea8..a3193bc 100644
--- a/pkg/analyzer/test/generated/compile_time_error_code_test.dart
+++ b/pkg/analyzer/test/generated/compile_time_error_code_test.dart
@@ -2721,6 +2721,43 @@
     assertErrors(source, [CompileTimeErrorCode.INVALID_URI]);
   }
 
+  void test_isInConstInstanceCreation_restored() {
+    // If ErrorVerifier._isInConstInstanceCreation is not properly restored on
+    // exit from visitInstanceCreationExpression, the error at (1) will be
+    // treated as a warning rather than an error.
+    Source source = addSource(r'''
+class Foo<T extends num> {
+  const Foo(x, y);
+}
+const x = const Foo<int>(const Foo<int>(0, 1),
+    const <Foo<String>>[]); // (1)
+''');
+    resolve(source);
+    assertErrors(source, [CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS]);
+    verify([source]);
+  }
+
+  void test_isInInstanceVariableInitializer_restored() {
+    // If ErrorVerifier._isInInstanceVariableInitializer is not properly
+    // restored on exit from visitVariableDeclaration, the error at (1)
+    // won't be detected.
+    Source source = addSource(r'''
+class Foo {
+  var bar;
+  Map foo = {
+    'bar': () {
+        var _bar;
+    },
+    'bop': _foo // (1)
+  };
+  _foo() {
+  }
+}''');
+    resolve(source);
+    assertErrors(source, [CompileTimeErrorCode.IMPLICIT_THIS_REFERENCE_IN_INITIALIZER]);
+    verify([source]);
+  }
+
   void test_labelInOuterScope() {
     Source source = addSource(r'''
 class A {
diff --git a/pkg/analyzer/test/generated/engine_test.dart b/pkg/analyzer/test/generated/engine_test.dart
index fdbf762..7fa5e6e 100644
--- a/pkg/analyzer/test/generated/engine_test.dart
+++ b/pkg/analyzer/test/generated/engine_test.dart
@@ -1999,45 +1999,7 @@
 
 
 class DartEntryTest extends EngineTestCase {
-  void set state2(DataDescriptor descriptor) {
-    DartEntry entry = new DartEntry();
-    expect(entry.getState(descriptor), isNot(same(CacheState.FLUSHED)));
-    entry.setState(descriptor, CacheState.FLUSHED);
-    expect(entry.getState(descriptor), same(CacheState.FLUSHED));
-  }
-
-  void set state3(DataDescriptor descriptor) {
-    Source source = new TestSource();
-    DartEntry entry = new DartEntry();
-    expect(entry.getStateInLibrary(descriptor, source), isNot(same(CacheState.FLUSHED)));
-    entry.setStateInLibrary(descriptor, source, CacheState.FLUSHED);
-    expect(entry.getStateInLibrary(descriptor, source), same(CacheState.FLUSHED));
-  }
-
-  void test_creation() {
-    Source librarySource = new TestSource();
-    DartEntry entry = new DartEntry();
-    expect(entry.getState(SourceEntry.CONTENT), same(CacheState.INVALID));
-    expect(entry.getState(DartEntry.ELEMENT), same(CacheState.INVALID));
-    expect(entry.getState(DartEntry.EXPORTED_LIBRARIES), same(CacheState.INVALID));
-    expect(entry.getState(DartEntry.IMPORTED_LIBRARIES), same(CacheState.INVALID));
-    expect(entry.getState(DartEntry.INCLUDED_PARTS), same(CacheState.INVALID));
-    expect(entry.getState(DartEntry.IS_CLIENT), same(CacheState.INVALID));
-    expect(entry.getState(DartEntry.IS_LAUNCHABLE), same(CacheState.INVALID));
-    expect(entry.getState(SourceEntry.LINE_INFO), same(CacheState.INVALID));
-    expect(entry.getState(DartEntry.PARSE_ERRORS), same(CacheState.INVALID));
-    expect(entry.getState(DartEntry.PARSED_UNIT), same(CacheState.INVALID));
-    expect(entry.getState(DartEntry.PUBLIC_NAMESPACE), same(CacheState.INVALID));
-    expect(entry.getState(DartEntry.SCAN_ERRORS), same(CacheState.INVALID));
-    expect(entry.getState(DartEntry.SOURCE_KIND), same(CacheState.INVALID));
-    expect(entry.getState(DartEntry.TOKEN_STREAM), same(CacheState.INVALID));
-    expect(entry.getStateInLibrary(DartEntry.HINTS, librarySource), same(CacheState.INVALID));
-    expect(entry.getStateInLibrary(DartEntry.RESOLUTION_ERRORS, librarySource), same(CacheState.INVALID));
-    expect(entry.getStateInLibrary(DartEntry.RESOLVED_UNIT, librarySource), same(CacheState.INVALID));
-    expect(entry.getStateInLibrary(DartEntry.VERIFICATION_ERRORS, librarySource), same(CacheState.INVALID));
-  }
-
-  void test_getAllErrors() {
+  void test_allErrors() {
     Source source = new TestSource();
     DartEntry entry = new DartEntry();
     expect(entry.allErrors, hasLength(0));
@@ -2069,12 +2031,44 @@
                 StaticWarningCode.CASE_BLOCK_NOT_TERMINATED,
                 [])]);
     entry.setValueInLibrary(
+        DartEntry.ANGULAR_ERRORS,
+        source,
+        <AnalysisError>[new AnalysisError.con1(source, AngularCode.MISSING_NAME, [])]);
+    entry.setValueInLibrary(
         DartEntry.HINTS,
         source,
         <AnalysisError>[new AnalysisError.con1(source, HintCode.DEAD_CODE, [])]);
     expect(entry.allErrors, hasLength(5));
   }
 
+  void test_creation() {
+    Source librarySource = new TestSource();
+    DartEntry entry = new DartEntry();
+    expect(entry.getState(SourceEntry.CONTENT), same(CacheState.INVALID));
+    expect(entry.getState(SourceEntry.LINE_INFO), same(CacheState.INVALID));
+    expect(entry.getState(DartEntry.CONTAINING_LIBRARIES), same(CacheState.INVALID));
+    expect(entry.getState(DartEntry.ELEMENT), same(CacheState.INVALID));
+    expect(entry.getState(DartEntry.EXPORTED_LIBRARIES), same(CacheState.INVALID));
+    expect(entry.getState(DartEntry.IMPORTED_LIBRARIES), same(CacheState.INVALID));
+    expect(entry.getState(DartEntry.INCLUDED_PARTS), same(CacheState.INVALID));
+    expect(entry.getState(DartEntry.IS_CLIENT), same(CacheState.INVALID));
+    expect(entry.getState(DartEntry.IS_LAUNCHABLE), same(CacheState.INVALID));
+    expect(entry.getState(DartEntry.PARSE_ERRORS), same(CacheState.INVALID));
+    expect(entry.getState(DartEntry.PARSED_UNIT), same(CacheState.INVALID));
+    expect(entry.getState(DartEntry.PUBLIC_NAMESPACE), same(CacheState.INVALID));
+    expect(entry.getState(DartEntry.SCAN_ERRORS), same(CacheState.INVALID));
+    expect(entry.getState(DartEntry.SOURCE_KIND), same(CacheState.INVALID));
+    expect(entry.getState(DartEntry.TOKEN_STREAM), same(CacheState.INVALID));
+
+    expect(entry.getStateInLibrary(DartEntry.ANGULAR_ERRORS, librarySource), same(CacheState.INVALID));
+    expect(entry.getStateInLibrary(DartEntry.BUILT_ELEMENT, librarySource), same(CacheState.INVALID));
+    expect(entry.getStateInLibrary(DartEntry.BUILT_UNIT, librarySource), same(CacheState.INVALID));
+    expect(entry.getStateInLibrary(DartEntry.HINTS, librarySource), same(CacheState.INVALID));
+    expect(entry.getStateInLibrary(DartEntry.RESOLUTION_ERRORS, librarySource), same(CacheState.INVALID));
+    expect(entry.getStateInLibrary(DartEntry.RESOLVED_UNIT, librarySource), same(CacheState.INVALID));
+    expect(entry.getStateInLibrary(DartEntry.VERIFICATION_ERRORS, librarySource), same(CacheState.INVALID));
+  }
+
   void test_getResolvableCompilationUnit_none() {
     DartEntry entry = new DartEntry();
     expect(entry.resolvableCompilationUnit, isNull);
@@ -2305,50 +2299,90 @@
   }
 
   void test_invalidateAllInformation() {
-    DartEntry entry = _entryWithValidState();
+    Source librarySource = new TestSource();
+    DartEntry entry = _entryWithValidState(librarySource);
     entry.invalidateAllInformation();
+    expect(entry.getState(SourceEntry.CONTENT), same(CacheState.INVALID));
+    expect(entry.getState(SourceEntry.LINE_INFO), same(CacheState.INVALID));
+    expect(entry.getState(DartEntry.CONTAINING_LIBRARIES), same(CacheState.VALID));
     expect(entry.getState(DartEntry.ELEMENT), same(CacheState.INVALID));
     expect(entry.getState(DartEntry.EXPORTED_LIBRARIES), same(CacheState.INVALID));
     expect(entry.getState(DartEntry.IMPORTED_LIBRARIES), same(CacheState.INVALID));
     expect(entry.getState(DartEntry.INCLUDED_PARTS), same(CacheState.INVALID));
     expect(entry.getState(DartEntry.IS_CLIENT), same(CacheState.INVALID));
     expect(entry.getState(DartEntry.IS_LAUNCHABLE), same(CacheState.INVALID));
-    expect(entry.getState(SourceEntry.LINE_INFO), same(CacheState.INVALID));
     expect(entry.getState(DartEntry.PARSE_ERRORS), same(CacheState.INVALID));
     expect(entry.getState(DartEntry.PARSED_UNIT), same(CacheState.INVALID));
     expect(entry.getState(DartEntry.PUBLIC_NAMESPACE), same(CacheState.INVALID));
     expect(entry.getState(DartEntry.SCAN_ERRORS), same(CacheState.INVALID));
+    expect(entry.getState(DartEntry.SOURCE_KIND), same(CacheState.INVALID));
     expect(entry.getState(DartEntry.TOKEN_STREAM), same(CacheState.INVALID));
+
+    expect(entry.getStateInLibrary(DartEntry.ANGULAR_ERRORS, librarySource), same(CacheState.INVALID));
+    expect(entry.getStateInLibrary(DartEntry.BUILT_ELEMENT, librarySource), same(CacheState.INVALID));
+    expect(entry.getStateInLibrary(DartEntry.BUILT_UNIT, librarySource), same(CacheState.INVALID));
+    expect(entry.getStateInLibrary(DartEntry.HINTS, librarySource), same(CacheState.INVALID));
+    expect(entry.getStateInLibrary(DartEntry.RESOLUTION_ERRORS, librarySource), same(CacheState.INVALID));
+    expect(entry.getStateInLibrary(DartEntry.RESOLVED_UNIT, librarySource), same(CacheState.INVALID));
+    expect(entry.getStateInLibrary(DartEntry.VERIFICATION_ERRORS, librarySource), same(CacheState.INVALID));
   }
 
   void test_invalidateAllResolutionInformation() {
-    DartEntry entry = _entryWithValidState();
+    Source librarySource = new TestSource();
+    DartEntry entry = _entryWithValidState(librarySource);
     entry.invalidateAllResolutionInformation(false);
-    expect(entry.getState(DartEntry.ELEMENT), same(CacheState.INVALID));
-    expect(entry.getState(DartEntry.IS_CLIENT), same(CacheState.INVALID));
-    expect(entry.getState(DartEntry.IS_LAUNCHABLE), same(CacheState.INVALID));
+    expect(entry.getState(SourceEntry.CONTENT), same(CacheState.VALID));
     expect(entry.getState(SourceEntry.LINE_INFO), same(CacheState.VALID));
-    expect(entry.getState(DartEntry.PARSE_ERRORS), same(CacheState.VALID));
-    expect(entry.getState(DartEntry.PARSED_UNIT), same(CacheState.VALID));
-    expect(entry.getState(DartEntry.PUBLIC_NAMESPACE), same(CacheState.INVALID));
+    expect(entry.getState(DartEntry.CONTAINING_LIBRARIES), same(CacheState.VALID));
+    expect(entry.getState(DartEntry.ELEMENT), same(CacheState.INVALID));
     expect(entry.getState(DartEntry.EXPORTED_LIBRARIES), same(CacheState.VALID));
     expect(entry.getState(DartEntry.IMPORTED_LIBRARIES), same(CacheState.VALID));
     expect(entry.getState(DartEntry.INCLUDED_PARTS), same(CacheState.VALID));
-  }
-
-  void test_invalidateAllResolutionInformation_includingUris() {
-    DartEntry entry = _entryWithValidState();
-    entry.invalidateAllResolutionInformation(true);
-    expect(entry.getState(DartEntry.ELEMENT), same(CacheState.INVALID));
     expect(entry.getState(DartEntry.IS_CLIENT), same(CacheState.INVALID));
     expect(entry.getState(DartEntry.IS_LAUNCHABLE), same(CacheState.INVALID));
-    expect(entry.getState(SourceEntry.LINE_INFO), same(CacheState.VALID));
     expect(entry.getState(DartEntry.PARSE_ERRORS), same(CacheState.VALID));
     expect(entry.getState(DartEntry.PARSED_UNIT), same(CacheState.VALID));
     expect(entry.getState(DartEntry.PUBLIC_NAMESPACE), same(CacheState.INVALID));
+    expect(entry.getState(DartEntry.SCAN_ERRORS), same(CacheState.VALID));
+    expect(entry.getState(DartEntry.SOURCE_KIND), same(CacheState.VALID));
+    expect(entry.getState(DartEntry.TOKEN_STREAM), same(CacheState.VALID));
+
+    expect(entry.getStateInLibrary(DartEntry.ANGULAR_ERRORS, librarySource), same(CacheState.INVALID));
+    expect(entry.getStateInLibrary(DartEntry.BUILT_ELEMENT, librarySource), same(CacheState.INVALID));
+    expect(entry.getStateInLibrary(DartEntry.BUILT_UNIT, librarySource), same(CacheState.INVALID));
+    expect(entry.getStateInLibrary(DartEntry.HINTS, librarySource), same(CacheState.INVALID));
+    expect(entry.getStateInLibrary(DartEntry.RESOLUTION_ERRORS, librarySource), same(CacheState.INVALID));
+    expect(entry.getStateInLibrary(DartEntry.RESOLVED_UNIT, librarySource), same(CacheState.INVALID));
+    expect(entry.getStateInLibrary(DartEntry.VERIFICATION_ERRORS, librarySource), same(CacheState.INVALID));
+  }
+
+  void test_invalidateAllResolutionInformation_includingUris() {
+    Source librarySource = new TestSource();
+    DartEntry entry = _entryWithValidState(librarySource);
+    entry.invalidateAllResolutionInformation(true);
+    expect(entry.getState(SourceEntry.CONTENT), same(CacheState.VALID));
+    expect(entry.getState(SourceEntry.LINE_INFO), same(CacheState.VALID));
+    expect(entry.getState(DartEntry.CONTAINING_LIBRARIES), same(CacheState.VALID));
+    expect(entry.getState(DartEntry.ELEMENT), same(CacheState.INVALID));
     expect(entry.getState(DartEntry.EXPORTED_LIBRARIES), same(CacheState.INVALID));
     expect(entry.getState(DartEntry.IMPORTED_LIBRARIES), same(CacheState.INVALID));
     expect(entry.getState(DartEntry.INCLUDED_PARTS), same(CacheState.INVALID));
+    expect(entry.getState(DartEntry.IS_CLIENT), same(CacheState.INVALID));
+    expect(entry.getState(DartEntry.IS_LAUNCHABLE), same(CacheState.INVALID));
+    expect(entry.getState(DartEntry.PARSE_ERRORS), same(CacheState.VALID));
+    expect(entry.getState(DartEntry.PARSED_UNIT), same(CacheState.VALID));
+    expect(entry.getState(DartEntry.PUBLIC_NAMESPACE), same(CacheState.INVALID));
+    expect(entry.getState(DartEntry.SCAN_ERRORS), same(CacheState.VALID));
+    expect(entry.getState(DartEntry.SOURCE_KIND), same(CacheState.VALID));
+    expect(entry.getState(DartEntry.TOKEN_STREAM), same(CacheState.VALID));
+
+    expect(entry.getStateInLibrary(DartEntry.ANGULAR_ERRORS, librarySource), same(CacheState.INVALID));
+    expect(entry.getStateInLibrary(DartEntry.BUILT_ELEMENT, librarySource), same(CacheState.INVALID));
+    expect(entry.getStateInLibrary(DartEntry.BUILT_UNIT, librarySource), same(CacheState.INVALID));
+    expect(entry.getStateInLibrary(DartEntry.HINTS, librarySource), same(CacheState.INVALID));
+    expect(entry.getStateInLibrary(DartEntry.RESOLUTION_ERRORS, librarySource), same(CacheState.INVALID));
+    expect(entry.getStateInLibrary(DartEntry.RESOLVED_UNIT, librarySource), same(CacheState.INVALID));
+    expect(entry.getStateInLibrary(DartEntry.VERIFICATION_ERRORS, librarySource), same(CacheState.INVALID));
   }
 
   void test_isClient() {
@@ -2382,243 +2416,335 @@
   }
 
   void test_recordBuildElementError() {
-    // TODO(brianwilkerson) This test should set the state for two libraries,
-    // record an error in one library, then verify that the data for the other
-    // library is still valid.
-    Source source = new TestSource();
-    DartEntry entry = new DartEntry();
+    Source firstLibrary = new TestSource('first.dart');
+    Source secondLibrary = new TestSource('second.dart');
+    DartEntry entry = _entryWithValidState(firstLibrary, secondLibrary);
     entry.recordBuildElementErrorInLibrary(
-        source,
+        firstLibrary,
         new CaughtException(new AnalysisException(), null));
-    expect(entry.getState(SourceEntry.CONTENT), same(CacheState.INVALID));
-    expect(entry.getStateInLibrary(DartEntry.BUILT_ELEMENT, source), same(CacheState.ERROR));
-    expect(entry.getStateInLibrary(DartEntry.BUILT_UNIT, source), same(CacheState.ERROR));
+    expect(entry.getState(SourceEntry.CONTENT), same(CacheState.VALID));
+    expect(entry.getState(SourceEntry.LINE_INFO), same(CacheState.VALID));
+    expect(entry.getState(DartEntry.CONTAINING_LIBRARIES), same(CacheState.VALID));
     expect(entry.getState(DartEntry.ELEMENT), same(CacheState.ERROR));
-    expect(entry.getState(DartEntry.EXPORTED_LIBRARIES), same(CacheState.INVALID));
-    expect(entry.getState(DartEntry.IMPORTED_LIBRARIES), same(CacheState.INVALID));
-    expect(entry.getState(DartEntry.INCLUDED_PARTS), same(CacheState.INVALID));
+    expect(entry.getState(DartEntry.EXPORTED_LIBRARIES), same(CacheState.VALID));
+    expect(entry.getState(DartEntry.IMPORTED_LIBRARIES), same(CacheState.VALID));
+    expect(entry.getState(DartEntry.INCLUDED_PARTS), same(CacheState.VALID));
     expect(entry.getState(DartEntry.IS_CLIENT), same(CacheState.ERROR));
     expect(entry.getState(DartEntry.IS_LAUNCHABLE), same(CacheState.ERROR));
-    expect(entry.getState(SourceEntry.LINE_INFO), same(CacheState.INVALID));
-    expect(entry.getState(DartEntry.PARSE_ERRORS), same(CacheState.INVALID));
-    expect(entry.getState(DartEntry.PARSED_UNIT), same(CacheState.INVALID));
+    expect(entry.getState(DartEntry.PARSE_ERRORS), same(CacheState.VALID));
+    expect(entry.getState(DartEntry.PARSED_UNIT), same(CacheState.VALID));
     expect(entry.getState(DartEntry.PUBLIC_NAMESPACE), same(CacheState.ERROR));
-    expect(entry.getState(DartEntry.SCAN_ERRORS), same(CacheState.INVALID));
-    expect(entry.getState(DartEntry.SOURCE_KIND), same(CacheState.INVALID));
-    expect(entry.getState(DartEntry.TOKEN_STREAM), same(CacheState.INVALID));
-    expect(entry.getStateInLibrary(DartEntry.HINTS, source), same(CacheState.ERROR));
-    expect(entry.getStateInLibrary(DartEntry.RESOLUTION_ERRORS, source), same(CacheState.ERROR));
-    expect(entry.getStateInLibrary(DartEntry.RESOLVED_UNIT, source), same(CacheState.ERROR));
-    expect(entry.getStateInLibrary(DartEntry.VERIFICATION_ERRORS, source), same(CacheState.ERROR));
+    expect(entry.getState(DartEntry.SCAN_ERRORS), same(CacheState.VALID));
+    expect(entry.getState(DartEntry.SOURCE_KIND), same(CacheState.VALID));
+    expect(entry.getState(DartEntry.TOKEN_STREAM), same(CacheState.VALID));
+
+    expect(entry.getStateInLibrary(DartEntry.ANGULAR_ERRORS, firstLibrary), same(CacheState.ERROR));
+    expect(entry.getStateInLibrary(DartEntry.BUILT_ELEMENT, firstLibrary), same(CacheState.ERROR));
+    expect(entry.getStateInLibrary(DartEntry.BUILT_UNIT, firstLibrary), same(CacheState.ERROR));
+    expect(entry.getStateInLibrary(DartEntry.HINTS, firstLibrary), same(CacheState.ERROR));
+    expect(entry.getStateInLibrary(DartEntry.RESOLUTION_ERRORS, firstLibrary), same(CacheState.ERROR));
+    expect(entry.getStateInLibrary(DartEntry.RESOLVED_UNIT, firstLibrary), same(CacheState.ERROR));
+    expect(entry.getStateInLibrary(DartEntry.VERIFICATION_ERRORS, firstLibrary), same(CacheState.ERROR));
+
+    expect(entry.getStateInLibrary(DartEntry.ANGULAR_ERRORS, secondLibrary), same(CacheState.VALID));
+    expect(entry.getStateInLibrary(DartEntry.BUILT_ELEMENT, secondLibrary), same(CacheState.VALID));
+    expect(entry.getStateInLibrary(DartEntry.BUILT_UNIT, secondLibrary), same(CacheState.VALID));
+    expect(entry.getStateInLibrary(DartEntry.HINTS, secondLibrary), same(CacheState.VALID));
+    expect(entry.getStateInLibrary(DartEntry.RESOLUTION_ERRORS, secondLibrary), same(CacheState.VALID));
+    expect(entry.getStateInLibrary(DartEntry.RESOLVED_UNIT, secondLibrary), same(CacheState.VALID));
+    expect(entry.getStateInLibrary(DartEntry.VERIFICATION_ERRORS, secondLibrary), same(CacheState.VALID));
   }
 
   void test_recordContentError() {
-    DartEntry entry = new DartEntry();
+    Source firstLibrary = new TestSource('first.dart');
+//    Source secondLibrary = new TestSource('second.dart');
+    DartEntry entry = _entryWithValidState(firstLibrary);
     entry.recordContentError(
         new CaughtException(new AnalysisException(), null));
     expect(entry.getState(SourceEntry.CONTENT), same(CacheState.ERROR));
+    expect(entry.getState(SourceEntry.LINE_INFO), same(CacheState.ERROR));
+    expect(entry.getState(DartEntry.CONTAINING_LIBRARIES), same(CacheState.VALID));
     expect(entry.getState(DartEntry.ELEMENT), same(CacheState.ERROR));
     expect(entry.getState(DartEntry.EXPORTED_LIBRARIES), same(CacheState.ERROR));
     expect(entry.getState(DartEntry.IMPORTED_LIBRARIES), same(CacheState.ERROR));
     expect(entry.getState(DartEntry.INCLUDED_PARTS), same(CacheState.ERROR));
     expect(entry.getState(DartEntry.IS_CLIENT), same(CacheState.ERROR));
     expect(entry.getState(DartEntry.IS_LAUNCHABLE), same(CacheState.ERROR));
-    expect(entry.getState(SourceEntry.LINE_INFO), same(CacheState.ERROR));
     expect(entry.getState(DartEntry.PARSE_ERRORS), same(CacheState.ERROR));
     expect(entry.getState(DartEntry.PARSED_UNIT), same(CacheState.ERROR));
     expect(entry.getState(DartEntry.PUBLIC_NAMESPACE), same(CacheState.ERROR));
     expect(entry.getState(DartEntry.SCAN_ERRORS), same(CacheState.ERROR));
     expect(entry.getState(DartEntry.SOURCE_KIND), same(CacheState.ERROR));
     expect(entry.getState(DartEntry.TOKEN_STREAM), same(CacheState.ERROR));
+
+    expect(entry.getStateInLibrary(DartEntry.ANGULAR_ERRORS, firstLibrary), same(CacheState.ERROR));
+    expect(entry.getStateInLibrary(DartEntry.BUILT_ELEMENT, firstLibrary), same(CacheState.ERROR));
+    expect(entry.getStateInLibrary(DartEntry.BUILT_UNIT, firstLibrary), same(CacheState.ERROR));
+    expect(entry.getStateInLibrary(DartEntry.HINTS, firstLibrary), same(CacheState.ERROR));
+    expect(entry.getStateInLibrary(DartEntry.RESOLUTION_ERRORS, firstLibrary), same(CacheState.ERROR));
+    expect(entry.getStateInLibrary(DartEntry.RESOLVED_UNIT, firstLibrary), same(CacheState.ERROR));
+    expect(entry.getStateInLibrary(DartEntry.VERIFICATION_ERRORS, firstLibrary), same(CacheState.ERROR));
+
     // The following lines are commented out because we don't currently have
     // any way of setting the state for data associated with a library we
     // don't know anything about.
-//    assertSame(CacheState.ERROR, entry.getStateInLibrary(DartEntry.BUILD_ELEMENT_ERRORS, source));
-//    assertSame(CacheState.ERROR, entry.getStateInLibrary(DartEntry.BUILT_UNIT, source));
-//    assertSame(CacheState.ERROR, entry.getStateInLibrary(DartEntry.HINTS, source));
-//    assertSame(CacheState.ERROR, entry.getStateInLibrary(DartEntry.RESOLUTION_ERRORS, source));
-//    assertSame(CacheState.ERROR, entry.getStateInLibrary(DartEntry.RESOLVED_UNIT, source));
-//    assertSame(CacheState.ERROR, entry.getStateInLibrary(DartEntry.VERIFICATION_ERRORS, source));
+//    expect(entry.getStateInLibrary(DartEntry.ANGULAR_ERRORS, secondLibrary), same(CacheState.ERROR));
+//    expect(entry.getStateInLibrary(DartEntry.BUILT_ELEMENT, secondLibrary), same(CacheState.ERROR));
+//    expect(entry.getStateInLibrary(DartEntry.BUILT_UNIT, secondLibrary), same(CacheState.ERROR));
+//    expect(entry.getStateInLibrary(DartEntry.HINTS, secondLibrary), same(CacheState.ERROR));
+//    expect(entry.getStateInLibrary(DartEntry.RESOLUTION_ERRORS, secondLibrary), same(CacheState.ERROR));
+//    expect(entry.getStateInLibrary(DartEntry.RESOLVED_UNIT, secondLibrary), same(CacheState.ERROR));
+//    expect(entry.getStateInLibrary(DartEntry.VERIFICATION_ERRORS, secondLibrary), same(CacheState.ERROR));
   }
 
   void test_recordHintErrorInLibrary() {
-    // TODO(brianwilkerson) This test should set the state for two libraries,
-    // record an error in one library, then verify that the data for the other
-    // library is still valid.
-    Source source = new TestSource();
-    DartEntry entry = new DartEntry();
+    Source firstLibrary = new TestSource('first.dart');
+    Source secondLibrary = new TestSource('second.dart');
+    DartEntry entry = _entryWithValidState(firstLibrary, secondLibrary);
     entry.recordHintErrorInLibrary(
-        source,
+        firstLibrary,
         new CaughtException(new AnalysisException(), null));
-    expect(entry.getState(SourceEntry.CONTENT), same(CacheState.INVALID));
-    expect(entry.getState(DartEntry.ELEMENT), same(CacheState.INVALID));
-    expect(entry.getState(DartEntry.EXPORTED_LIBRARIES), same(CacheState.INVALID));
-    expect(entry.getState(DartEntry.IMPORTED_LIBRARIES), same(CacheState.INVALID));
-    expect(entry.getState(DartEntry.INCLUDED_PARTS), same(CacheState.INVALID));
-    expect(entry.getState(DartEntry.IS_CLIENT), same(CacheState.INVALID));
-    expect(entry.getState(DartEntry.IS_LAUNCHABLE), same(CacheState.INVALID));
-    expect(entry.getState(SourceEntry.LINE_INFO), same(CacheState.INVALID));
-    expect(entry.getState(DartEntry.PARSE_ERRORS), same(CacheState.INVALID));
-    expect(entry.getState(DartEntry.PARSED_UNIT), same(CacheState.INVALID));
-    expect(entry.getState(DartEntry.PUBLIC_NAMESPACE), same(CacheState.INVALID));
-    expect(entry.getState(DartEntry.SCAN_ERRORS), same(CacheState.INVALID));
-    expect(entry.getState(DartEntry.SOURCE_KIND), same(CacheState.INVALID));
-    expect(entry.getState(DartEntry.TOKEN_STREAM), same(CacheState.INVALID));
-    expect(entry.getStateInLibrary(DartEntry.HINTS, source), same(CacheState.ERROR));
-    expect(entry.getStateInLibrary(DartEntry.RESOLUTION_ERRORS, source), same(CacheState.INVALID));
-    expect(entry.getStateInLibrary(DartEntry.RESOLVED_UNIT, source), same(CacheState.INVALID));
-    expect(entry.getStateInLibrary(DartEntry.VERIFICATION_ERRORS, source), same(CacheState.INVALID));
+    expect(entry.getState(SourceEntry.CONTENT), same(CacheState.VALID));
+    expect(entry.getState(SourceEntry.LINE_INFO), same(CacheState.VALID));
+    expect(entry.getState(DartEntry.CONTAINING_LIBRARIES), same(CacheState.VALID));
+    expect(entry.getState(DartEntry.ELEMENT), same(CacheState.VALID));
+    expect(entry.getState(DartEntry.EXPORTED_LIBRARIES), same(CacheState.VALID));
+    expect(entry.getState(DartEntry.IMPORTED_LIBRARIES), same(CacheState.VALID));
+    expect(entry.getState(DartEntry.INCLUDED_PARTS), same(CacheState.VALID));
+    expect(entry.getState(DartEntry.IS_CLIENT), same(CacheState.VALID));
+    expect(entry.getState(DartEntry.IS_LAUNCHABLE), same(CacheState.VALID));
+    expect(entry.getState(DartEntry.PARSE_ERRORS), same(CacheState.VALID));
+    expect(entry.getState(DartEntry.PARSED_UNIT), same(CacheState.VALID));
+    expect(entry.getState(DartEntry.PUBLIC_NAMESPACE), same(CacheState.VALID));
+    expect(entry.getState(DartEntry.SCAN_ERRORS), same(CacheState.VALID));
+    expect(entry.getState(DartEntry.SOURCE_KIND), same(CacheState.VALID));
+    expect(entry.getState(DartEntry.TOKEN_STREAM), same(CacheState.VALID));
+
+    expect(entry.getStateInLibrary(DartEntry.ANGULAR_ERRORS, firstLibrary), same(CacheState.VALID));
+    expect(entry.getStateInLibrary(DartEntry.BUILT_ELEMENT, firstLibrary), same(CacheState.VALID));
+    expect(entry.getStateInLibrary(DartEntry.BUILT_UNIT, firstLibrary), same(CacheState.VALID));
+    expect(entry.getStateInLibrary(DartEntry.HINTS, firstLibrary), same(CacheState.ERROR));
+    expect(entry.getStateInLibrary(DartEntry.RESOLUTION_ERRORS, firstLibrary), same(CacheState.VALID));
+    expect(entry.getStateInLibrary(DartEntry.RESOLVED_UNIT, firstLibrary), same(CacheState.VALID));
+    expect(entry.getStateInLibrary(DartEntry.VERIFICATION_ERRORS, firstLibrary), same(CacheState.VALID));
+
+    expect(entry.getStateInLibrary(DartEntry.ANGULAR_ERRORS, secondLibrary), same(CacheState.VALID));
+    expect(entry.getStateInLibrary(DartEntry.BUILT_ELEMENT, secondLibrary), same(CacheState.VALID));
+    expect(entry.getStateInLibrary(DartEntry.BUILT_UNIT, secondLibrary), same(CacheState.VALID));
+    expect(entry.getStateInLibrary(DartEntry.HINTS, secondLibrary), same(CacheState.VALID));
+    expect(entry.getStateInLibrary(DartEntry.RESOLUTION_ERRORS, secondLibrary), same(CacheState.VALID));
+    expect(entry.getStateInLibrary(DartEntry.RESOLVED_UNIT, secondLibrary), same(CacheState.VALID));
+    expect(entry.getStateInLibrary(DartEntry.VERIFICATION_ERRORS, secondLibrary), same(CacheState.VALID));
   }
 
   void test_recordParseError() {
-    DartEntry entry = new DartEntry();
+    Source firstLibrary = new TestSource('first.dart');
+//    Source secondLibrary = new TestSource('second.dart');
+    DartEntry entry = _entryWithValidState(firstLibrary);
     entry.recordParseError(new CaughtException(new AnalysisException(), null));
-    expect(entry.getState(SourceEntry.CONTENT), same(CacheState.INVALID));
+    expect(entry.getState(SourceEntry.CONTENT), same(CacheState.VALID));
+    expect(entry.getState(SourceEntry.LINE_INFO), same(CacheState.VALID));
+    expect(entry.getState(DartEntry.CONTAINING_LIBRARIES), same(CacheState.VALID));
     expect(entry.getState(DartEntry.ELEMENT), same(CacheState.ERROR));
     expect(entry.getState(DartEntry.EXPORTED_LIBRARIES), same(CacheState.ERROR));
     expect(entry.getState(DartEntry.IMPORTED_LIBRARIES), same(CacheState.ERROR));
     expect(entry.getState(DartEntry.INCLUDED_PARTS), same(CacheState.ERROR));
     expect(entry.getState(DartEntry.IS_CLIENT), same(CacheState.ERROR));
     expect(entry.getState(DartEntry.IS_LAUNCHABLE), same(CacheState.ERROR));
-    expect(entry.getState(SourceEntry.LINE_INFO), same(CacheState.INVALID));
     expect(entry.getState(DartEntry.PARSE_ERRORS), same(CacheState.ERROR));
     expect(entry.getState(DartEntry.PARSED_UNIT), same(CacheState.ERROR));
     expect(entry.getState(DartEntry.PUBLIC_NAMESPACE), same(CacheState.ERROR));
-    expect(entry.getState(DartEntry.SCAN_ERRORS), same(CacheState.INVALID));
+    expect(entry.getState(DartEntry.SCAN_ERRORS), same(CacheState.VALID));
     expect(entry.getState(DartEntry.SOURCE_KIND), same(CacheState.ERROR));
-    expect(entry.getState(DartEntry.TOKEN_STREAM), same(CacheState.INVALID));
+    expect(entry.getState(DartEntry.TOKEN_STREAM), same(CacheState.VALID));
+
+    expect(entry.getStateInLibrary(DartEntry.ANGULAR_ERRORS, firstLibrary), same(CacheState.ERROR));
+    expect(entry.getStateInLibrary(DartEntry.BUILT_ELEMENT, firstLibrary), same(CacheState.ERROR));
+    expect(entry.getStateInLibrary(DartEntry.BUILT_UNIT, firstLibrary), same(CacheState.ERROR));
+    expect(entry.getStateInLibrary(DartEntry.HINTS, firstLibrary), same(CacheState.ERROR));
+    expect(entry.getStateInLibrary(DartEntry.RESOLUTION_ERRORS, firstLibrary), same(CacheState.ERROR));
+    expect(entry.getStateInLibrary(DartEntry.RESOLVED_UNIT, firstLibrary), same(CacheState.ERROR));
+    expect(entry.getStateInLibrary(DartEntry.VERIFICATION_ERRORS, firstLibrary), same(CacheState.ERROR));
+
     // The following lines are commented out because we don't currently have
     // any way of setting the state for data associated with a library we
     // don't know anything about.
-//    assertSame(CacheState.ERROR, entry.getStateInLibrary(DartEntry.BUILD_ELEMENT_ERRORS, source));
-//    assertSame(CacheState.ERROR, entry.getStateInLibrary(DartEntry.BUILT_UNIT, source));
-//    assertSame(CacheState.ERROR, entry.getStateInLibrary(DartEntry.HINTS, source));
-//    assertSame(CacheState.ERROR, entry.getStateInLibrary(DartEntry.RESOLUTION_ERRORS, source));
-//    assertSame(CacheState.ERROR, entry.getStateInLibrary(DartEntry.RESOLVED_UNIT, source));
-//    assertSame(CacheState.ERROR, entry.getStateInLibrary(DartEntry.VERIFICATION_ERRORS, source));
+//    expect(entry.getStateInLibrary(DartEntry.ANGULAR_ERRORS, secondLibrary), same(CacheState.ERROR));
+//    expect(entry.getStateInLibrary(DartEntry.BUILT_ELEMENT, secondLibrary), same(CacheState.ERROR));
+//    expect(entry.getStateInLibrary(DartEntry.BUILT_UNIT, secondLibrary), same(CacheState.ERROR));
+//    expect(entry.getStateInLibrary(DartEntry.HINTS, secondLibrary), same(CacheState.ERROR));
+//    expect(entry.getStateInLibrary(DartEntry.RESOLUTION_ERRORS, secondLibrary), same(CacheState.ERROR));
+//    expect(entry.getStateInLibrary(DartEntry.RESOLVED_UNIT, secondLibrary), same(CacheState.ERROR));
+//    expect(entry.getStateInLibrary(DartEntry.VERIFICATION_ERRORS, secondLibrary), same(CacheState.ERROR));
   }
 
   void test_recordResolutionError() {
-    //    Source source = new TestSource();
-    DartEntry entry = new DartEntry();
+    Source firstLibrary = new TestSource('first.dart');
+//    Source secondLibrary = new TestSource('second.dart');
+    DartEntry entry = _entryWithValidState(firstLibrary);
     entry.recordResolutionError(
         new CaughtException(new AnalysisException(), null));
-    expect(entry.getState(SourceEntry.CONTENT), same(CacheState.INVALID));
+    expect(entry.getState(SourceEntry.CONTENT), same(CacheState.VALID));
+    expect(entry.getState(SourceEntry.LINE_INFO), same(CacheState.VALID));
+    expect(entry.getState(DartEntry.CONTAINING_LIBRARIES), same(CacheState.VALID));
     expect(entry.getState(DartEntry.ELEMENT), same(CacheState.ERROR));
-    expect(entry.getState(DartEntry.EXPORTED_LIBRARIES), same(CacheState.INVALID));
-    expect(entry.getState(DartEntry.IMPORTED_LIBRARIES), same(CacheState.INVALID));
-    expect(entry.getState(DartEntry.INCLUDED_PARTS), same(CacheState.INVALID));
+    expect(entry.getState(DartEntry.EXPORTED_LIBRARIES), same(CacheState.VALID));
+    expect(entry.getState(DartEntry.IMPORTED_LIBRARIES), same(CacheState.VALID));
+    expect(entry.getState(DartEntry.INCLUDED_PARTS), same(CacheState.VALID));
     expect(entry.getState(DartEntry.IS_CLIENT), same(CacheState.ERROR));
     expect(entry.getState(DartEntry.IS_LAUNCHABLE), same(CacheState.ERROR));
-    expect(entry.getState(SourceEntry.LINE_INFO), same(CacheState.INVALID));
-    expect(entry.getState(DartEntry.PARSE_ERRORS), same(CacheState.INVALID));
-    expect(entry.getState(DartEntry.PARSED_UNIT), same(CacheState.INVALID));
+    expect(entry.getState(DartEntry.PARSE_ERRORS), same(CacheState.VALID));
+    expect(entry.getState(DartEntry.PARSED_UNIT), same(CacheState.VALID));
     expect(entry.getState(DartEntry.PUBLIC_NAMESPACE), same(CacheState.ERROR));
-    expect(entry.getState(DartEntry.SCAN_ERRORS), same(CacheState.INVALID));
-    expect(entry.getState(DartEntry.SOURCE_KIND), same(CacheState.INVALID));
-    expect(entry.getState(DartEntry.TOKEN_STREAM), same(CacheState.INVALID));
+    expect(entry.getState(DartEntry.SCAN_ERRORS), same(CacheState.VALID));
+    expect(entry.getState(DartEntry.SOURCE_KIND), same(CacheState.VALID));
+    expect(entry.getState(DartEntry.TOKEN_STREAM), same(CacheState.VALID));
+
+    expect(entry.getStateInLibrary(DartEntry.ANGULAR_ERRORS, firstLibrary), same(CacheState.ERROR));
+    expect(entry.getStateInLibrary(DartEntry.BUILT_ELEMENT, firstLibrary), same(CacheState.ERROR));
+    expect(entry.getStateInLibrary(DartEntry.BUILT_UNIT, firstLibrary), same(CacheState.ERROR));
+    expect(entry.getStateInLibrary(DartEntry.HINTS, firstLibrary), same(CacheState.ERROR));
+    expect(entry.getStateInLibrary(DartEntry.RESOLUTION_ERRORS, firstLibrary), same(CacheState.ERROR));
+    expect(entry.getStateInLibrary(DartEntry.RESOLVED_UNIT, firstLibrary), same(CacheState.ERROR));
+    expect(entry.getStateInLibrary(DartEntry.VERIFICATION_ERRORS, firstLibrary), same(CacheState.ERROR));
+
     // The following lines are commented out because we don't currently have
     // any way of setting the state for data associated with a library we
     // don't know anything about.
-//    assertSame(CacheState.ERROR, entry.getStateInLibrary(DartEntry.BUILD_ELEMENT_ERRORS, source));
-//    assertSame(CacheState.ERROR, entry.getStateInLibrary(DartEntry.BUILT_UNIT, source));
-//    assertSame(CacheState.ERROR, entry.getStateInLibrary(DartEntry.HINTS, source));
-//    assertSame(CacheState.ERROR, entry.getStateInLibrary(DartEntry.RESOLUTION_ERRORS, source));
-//    assertSame(CacheState.ERROR, entry.getStateInLibrary(DartEntry.RESOLVED_UNIT, source));
-//    assertSame(CacheState.ERROR, entry.getStateInLibrary(DartEntry.VERIFICATION_ERRORS, source));
+//    expect(entry.getStateInLibrary(DartEntry.ANGULAR_ERRORS, secondLibrary), same(CacheState.ERROR));
+//    expect(entry.getStateInLibrary(DartEntry.BUILT_ELEMENT, secondLibrary), same(CacheState.ERROR));
+//    expect(entry.getStateInLibrary(DartEntry.BUILT_UNIT, secondLibrary), same(CacheState.ERROR));
+//    expect(entry.getStateInLibrary(DartEntry.HINTS, secondLibrary), same(CacheState.ERROR));
+//    expect(entry.getStateInLibrary(DartEntry.RESOLUTION_ERRORS, secondLibrary), same(CacheState.ERROR));
+//    expect(entry.getStateInLibrary(DartEntry.RESOLVED_UNIT, secondLibrary), same(CacheState.ERROR));
+//    expect(entry.getStateInLibrary(DartEntry.VERIFICATION_ERRORS, secondLibrary), same(CacheState.ERROR));
   }
 
   void test_recordResolutionErrorInLibrary() {
-    // TODO(brianwilkerson) This test should set the state for two libraries,
-    // record an error in one library, then verify that the data for the other
-    // library is still valid.
-    Source source = new TestSource();
-    DartEntry entry = new DartEntry();
+    Source firstLibrary = new TestSource('first.dart');
+    Source secondLibrary = new TestSource('second.dart');
+    DartEntry entry = _entryWithValidState(firstLibrary, secondLibrary);
     entry.recordResolutionErrorInLibrary(
-        source,
+        firstLibrary,
         new CaughtException(new AnalysisException(), null));
-    expect(entry.getState(SourceEntry.CONTENT), same(CacheState.INVALID));
+    expect(entry.getState(SourceEntry.CONTENT), same(CacheState.VALID));
+    expect(entry.getState(SourceEntry.LINE_INFO), same(CacheState.VALID));
+    expect(entry.getState(DartEntry.CONTAINING_LIBRARIES), same(CacheState.VALID));
     expect(entry.getState(DartEntry.ELEMENT), same(CacheState.ERROR));
-    expect(entry.getState(DartEntry.EXPORTED_LIBRARIES), same(CacheState.INVALID));
-    expect(entry.getState(DartEntry.IMPORTED_LIBRARIES), same(CacheState.INVALID));
-    expect(entry.getState(DartEntry.INCLUDED_PARTS), same(CacheState.INVALID));
+    expect(entry.getState(DartEntry.EXPORTED_LIBRARIES), same(CacheState.VALID));
+    expect(entry.getState(DartEntry.IMPORTED_LIBRARIES), same(CacheState.VALID));
+    expect(entry.getState(DartEntry.INCLUDED_PARTS), same(CacheState.VALID));
     expect(entry.getState(DartEntry.IS_CLIENT), same(CacheState.ERROR));
     expect(entry.getState(DartEntry.IS_LAUNCHABLE), same(CacheState.ERROR));
-    expect(entry.getState(SourceEntry.LINE_INFO), same(CacheState.INVALID));
-    expect(entry.getState(DartEntry.PARSE_ERRORS), same(CacheState.INVALID));
-    expect(entry.getState(DartEntry.PARSED_UNIT), same(CacheState.INVALID));
+    expect(entry.getState(DartEntry.PARSE_ERRORS), same(CacheState.VALID));
+    expect(entry.getState(DartEntry.PARSED_UNIT), same(CacheState.VALID));
     expect(entry.getState(DartEntry.PUBLIC_NAMESPACE), same(CacheState.ERROR));
-    expect(entry.getState(DartEntry.SCAN_ERRORS), same(CacheState.INVALID));
-    expect(entry.getState(DartEntry.SOURCE_KIND), same(CacheState.INVALID));
-    expect(entry.getState(DartEntry.TOKEN_STREAM), same(CacheState.INVALID));
-    expect(entry.getStateInLibrary(DartEntry.HINTS, source), same(CacheState.ERROR));
-    expect(entry.getStateInLibrary(DartEntry.RESOLUTION_ERRORS, source), same(CacheState.ERROR));
-    expect(entry.getStateInLibrary(DartEntry.RESOLVED_UNIT, source), same(CacheState.ERROR));
-    expect(entry.getStateInLibrary(DartEntry.VERIFICATION_ERRORS, source), same(CacheState.ERROR));
+    expect(entry.getState(DartEntry.SCAN_ERRORS), same(CacheState.VALID));
+    expect(entry.getState(DartEntry.SOURCE_KIND), same(CacheState.VALID));
+    expect(entry.getState(DartEntry.TOKEN_STREAM), same(CacheState.VALID));
+
+    expect(entry.getStateInLibrary(DartEntry.ANGULAR_ERRORS, firstLibrary), same(CacheState.ERROR));
+    expect(entry.getStateInLibrary(DartEntry.BUILT_ELEMENT, firstLibrary), same(CacheState.VALID));
+    expect(entry.getStateInLibrary(DartEntry.BUILT_UNIT, firstLibrary), same(CacheState.VALID));
+    expect(entry.getStateInLibrary(DartEntry.HINTS, firstLibrary), same(CacheState.ERROR));
+    expect(entry.getStateInLibrary(DartEntry.RESOLUTION_ERRORS, firstLibrary), same(CacheState.ERROR));
+    expect(entry.getStateInLibrary(DartEntry.RESOLVED_UNIT, firstLibrary), same(CacheState.ERROR));
+    expect(entry.getStateInLibrary(DartEntry.VERIFICATION_ERRORS, firstLibrary), same(CacheState.ERROR));
+
+    expect(entry.getStateInLibrary(DartEntry.ANGULAR_ERRORS, secondLibrary), same(CacheState.VALID));
+    expect(entry.getStateInLibrary(DartEntry.BUILT_ELEMENT, secondLibrary), same(CacheState.VALID));
+    expect(entry.getStateInLibrary(DartEntry.BUILT_UNIT, secondLibrary), same(CacheState.VALID));
+    expect(entry.getStateInLibrary(DartEntry.HINTS, secondLibrary), same(CacheState.VALID));
+    expect(entry.getStateInLibrary(DartEntry.RESOLUTION_ERRORS, secondLibrary), same(CacheState.VALID));
+    expect(entry.getStateInLibrary(DartEntry.RESOLVED_UNIT, secondLibrary), same(CacheState.VALID));
+    expect(entry.getStateInLibrary(DartEntry.VERIFICATION_ERRORS, secondLibrary), same(CacheState.VALID));
   }
 
   void test_recordScanError() {
-//    Source source = new TestSource();
-    DartEntry entry = new DartEntry();
+    Source firstLibrary = new TestSource('first.dart');
+//    Source secondLibrary = new TestSource('second.dart');
+    DartEntry entry = _entryWithValidState(firstLibrary);
     entry.recordScanError(new CaughtException(new AnalysisException(), null));
-    expect(entry.getState(SourceEntry.CONTENT), same(CacheState.INVALID));
+    expect(entry.getState(SourceEntry.CONTENT), same(CacheState.VALID));
+    expect(entry.getState(SourceEntry.LINE_INFO), same(CacheState.ERROR));
+    expect(entry.getState(DartEntry.CONTAINING_LIBRARIES), same(CacheState.VALID));
     expect(entry.getState(DartEntry.ELEMENT), same(CacheState.ERROR));
     expect(entry.getState(DartEntry.EXPORTED_LIBRARIES), same(CacheState.ERROR));
     expect(entry.getState(DartEntry.IMPORTED_LIBRARIES), same(CacheState.ERROR));
     expect(entry.getState(DartEntry.INCLUDED_PARTS), same(CacheState.ERROR));
     expect(entry.getState(DartEntry.IS_CLIENT), same(CacheState.ERROR));
     expect(entry.getState(DartEntry.IS_LAUNCHABLE), same(CacheState.ERROR));
-    expect(entry.getState(SourceEntry.LINE_INFO), same(CacheState.ERROR));
     expect(entry.getState(DartEntry.PARSE_ERRORS), same(CacheState.ERROR));
     expect(entry.getState(DartEntry.PARSED_UNIT), same(CacheState.ERROR));
     expect(entry.getState(DartEntry.PUBLIC_NAMESPACE), same(CacheState.ERROR));
     expect(entry.getState(DartEntry.SCAN_ERRORS), same(CacheState.ERROR));
     expect(entry.getState(DartEntry.SOURCE_KIND), same(CacheState.ERROR));
     expect(entry.getState(DartEntry.TOKEN_STREAM), same(CacheState.ERROR));
+
+    expect(entry.getStateInLibrary(DartEntry.ANGULAR_ERRORS, firstLibrary), same(CacheState.ERROR));
+    expect(entry.getStateInLibrary(DartEntry.BUILT_ELEMENT, firstLibrary), same(CacheState.ERROR));
+    expect(entry.getStateInLibrary(DartEntry.BUILT_UNIT, firstLibrary), same(CacheState.ERROR));
+    expect(entry.getStateInLibrary(DartEntry.HINTS, firstLibrary), same(CacheState.ERROR));
+    expect(entry.getStateInLibrary(DartEntry.RESOLUTION_ERRORS, firstLibrary), same(CacheState.ERROR));
+    expect(entry.getStateInLibrary(DartEntry.RESOLVED_UNIT, firstLibrary), same(CacheState.ERROR));
+    expect(entry.getStateInLibrary(DartEntry.VERIFICATION_ERRORS, firstLibrary), same(CacheState.ERROR));
+
     // The following lines are commented out because we don't currently have
     // any way of setting the state for data associated with a library we
     // don't know anything about.
-//    JUnitTestCase.assertSame(CacheState.ERROR, entry.getStateInLibrary(DartEntry.BUILT_ELEMENT, source));
-//    JUnitTestCase.assertSame(CacheState.ERROR, entry.getStateInLibrary(DartEntry.BUILT_UNIT, source));
-//    JUnitTestCase.assertSame(CacheState.ERROR, entry.getStateInLibrary(DartEntry.HINTS, source));
-//    JUnitTestCase.assertSame(CacheState.ERROR, entry.getStateInLibrary(DartEntry.RESOLUTION_ERRORS, source));
-//    JUnitTestCase.assertSame(CacheState.ERROR, entry.getStateInLibrary(DartEntry.RESOLVED_UNIT, source));
-//    JUnitTestCase.assertSame(CacheState.ERROR, entry.getStateInLibrary(DartEntry.VERIFICATION_ERRORS, source));
+//    expect(entry.getStateInLibrary(DartEntry.ANGULAR_ERRORS, secondLibrary), same(CacheState.ERROR));
+//    expect(entry.getStateInLibrary(DartEntry.BUILT_ELEMENT, secondLibrary), same(CacheState.ERROR));
+//    expect(entry.getStateInLibrary(DartEntry.BUILT_UNIT, secondLibrary), same(CacheState.ERROR));
+//    expect(entry.getStateInLibrary(DartEntry.HINTS, secondLibrary), same(CacheState.ERROR));
+//    expect(entry.getStateInLibrary(DartEntry.RESOLUTION_ERRORS, secondLibrary), same(CacheState.ERROR));
+//    expect(entry.getStateInLibrary(DartEntry.RESOLVED_UNIT, secondLibrary), same(CacheState.ERROR));
+//    expect(entry.getStateInLibrary(DartEntry.VERIFICATION_ERRORS, secondLibrary), same(CacheState.ERROR));
   }
 
   void test_recordVerificationErrorInLibrary() {
-    // TODO(brianwilkerson) This test should set the state for two libraries,
-    // record an error in one library, then verify that the data for the other
-    // library is still valid.
-    Source source = new TestSource();
-    DartEntry entry = new DartEntry();
+    Source firstLibrary = new TestSource('first.dart');
+    Source secondLibrary = new TestSource('second.dart');
+    DartEntry entry = _entryWithValidState(firstLibrary, secondLibrary);
     entry.recordVerificationErrorInLibrary(
-        source,
+        firstLibrary,
         new CaughtException(new AnalysisException(), null));
-    expect(entry.getState(SourceEntry.CONTENT), same(CacheState.INVALID));
-    expect(entry.getState(DartEntry.ELEMENT), same(CacheState.INVALID));
-    expect(entry.getState(DartEntry.EXPORTED_LIBRARIES), same(CacheState.INVALID));
-    expect(entry.getState(DartEntry.IMPORTED_LIBRARIES), same(CacheState.INVALID));
-    expect(entry.getState(DartEntry.INCLUDED_PARTS), same(CacheState.INVALID));
-    expect(entry.getState(DartEntry.IS_CLIENT), same(CacheState.INVALID));
-    expect(entry.getState(DartEntry.IS_LAUNCHABLE), same(CacheState.INVALID));
-    expect(entry.getState(SourceEntry.LINE_INFO), same(CacheState.INVALID));
-    expect(entry.getState(DartEntry.PARSE_ERRORS), same(CacheState.INVALID));
-    expect(entry.getState(DartEntry.PARSED_UNIT), same(CacheState.INVALID));
-    expect(entry.getState(DartEntry.PUBLIC_NAMESPACE), same(CacheState.INVALID));
-    expect(entry.getState(DartEntry.SCAN_ERRORS), same(CacheState.INVALID));
-    expect(entry.getState(DartEntry.SOURCE_KIND), same(CacheState.INVALID));
-    expect(entry.getState(DartEntry.TOKEN_STREAM), same(CacheState.INVALID));
-    expect(entry.getStateInLibrary(DartEntry.HINTS, source), same(CacheState.ERROR));
-    expect(entry.getStateInLibrary(DartEntry.RESOLUTION_ERRORS, source), same(CacheState.INVALID));
-    expect(entry.getStateInLibrary(DartEntry.RESOLVED_UNIT, source), same(CacheState.INVALID));
-    expect(entry.getStateInLibrary(DartEntry.VERIFICATION_ERRORS, source), same(CacheState.ERROR));
+    expect(entry.getState(SourceEntry.CONTENT), same(CacheState.VALID));
+    expect(entry.getState(SourceEntry.LINE_INFO), same(CacheState.VALID));
+    expect(entry.getState(DartEntry.CONTAINING_LIBRARIES), same(CacheState.VALID));
+    expect(entry.getState(DartEntry.ELEMENT), same(CacheState.VALID));
+    expect(entry.getState(DartEntry.EXPORTED_LIBRARIES), same(CacheState.VALID));
+    expect(entry.getState(DartEntry.IMPORTED_LIBRARIES), same(CacheState.VALID));
+    expect(entry.getState(DartEntry.INCLUDED_PARTS), same(CacheState.VALID));
+    expect(entry.getState(DartEntry.IS_CLIENT), same(CacheState.VALID));
+    expect(entry.getState(DartEntry.IS_LAUNCHABLE), same(CacheState.VALID));
+    expect(entry.getState(DartEntry.PARSE_ERRORS), same(CacheState.VALID));
+    expect(entry.getState(DartEntry.PARSED_UNIT), same(CacheState.VALID));
+    expect(entry.getState(DartEntry.PUBLIC_NAMESPACE), same(CacheState.VALID));
+    expect(entry.getState(DartEntry.SCAN_ERRORS), same(CacheState.VALID));
+    expect(entry.getState(DartEntry.SOURCE_KIND), same(CacheState.VALID));
+    expect(entry.getState(DartEntry.TOKEN_STREAM), same(CacheState.VALID));
+
+    expect(entry.getStateInLibrary(DartEntry.ANGULAR_ERRORS, firstLibrary), same(CacheState.VALID));
+    expect(entry.getStateInLibrary(DartEntry.BUILT_ELEMENT, firstLibrary), same(CacheState.VALID));
+    expect(entry.getStateInLibrary(DartEntry.BUILT_UNIT, firstLibrary), same(CacheState.VALID));
+    expect(entry.getStateInLibrary(DartEntry.HINTS, firstLibrary), same(CacheState.ERROR));
+    expect(entry.getStateInLibrary(DartEntry.RESOLUTION_ERRORS, firstLibrary), same(CacheState.VALID));
+    expect(entry.getStateInLibrary(DartEntry.RESOLVED_UNIT, firstLibrary), same(CacheState.VALID));
+    expect(entry.getStateInLibrary(DartEntry.VERIFICATION_ERRORS, firstLibrary), same(CacheState.ERROR));
+
+    expect(entry.getStateInLibrary(DartEntry.ANGULAR_ERRORS, secondLibrary), same(CacheState.VALID));
+    expect(entry.getStateInLibrary(DartEntry.BUILT_ELEMENT, secondLibrary), same(CacheState.VALID));
+    expect(entry.getStateInLibrary(DartEntry.BUILT_UNIT, secondLibrary), same(CacheState.VALID));
+    expect(entry.getStateInLibrary(DartEntry.HINTS, secondLibrary), same(CacheState.VALID));
+    expect(entry.getStateInLibrary(DartEntry.RESOLUTION_ERRORS, secondLibrary), same(CacheState.VALID));
+    expect(entry.getStateInLibrary(DartEntry.RESOLVED_UNIT, secondLibrary), same(CacheState.VALID));
+    expect(entry.getStateInLibrary(DartEntry.VERIFICATION_ERRORS, secondLibrary), same(CacheState.VALID));
   }
 
   void test_removeResolution_multiple_first() {
-    Source source1 = new TestSource();
-    Source source2 = new TestSource();
-    Source source3 = new TestSource();
+    Source source1 = new TestSource('first.dart');
+    Source source2 = new TestSource('second.dart');
+    Source source3 = new TestSource('third.dart');
     DartEntry entry = new DartEntry();
     entry.setValueInLibrary(
         DartEntry.RESOLVED_UNIT,
@@ -2636,9 +2762,9 @@
   }
 
   void test_removeResolution_multiple_last() {
-    Source source1 = new TestSource();
-    Source source2 = new TestSource();
-    Source source3 = new TestSource();
+    Source source1 = new TestSource('first.dart');
+    Source source2 = new TestSource('second.dart');
+    Source source3 = new TestSource('third.dart');
     DartEntry entry = new DartEntry();
     entry.setValueInLibrary(
         DartEntry.RESOLVED_UNIT,
@@ -2656,9 +2782,9 @@
   }
 
   void test_removeResolution_multiple_middle() {
-    Source source1 = new TestSource();
-    Source source2 = new TestSource();
-    Source source3 = new TestSource();
+    Source source1 = new TestSource('first.dart');
+    Source source2 = new TestSource('second.dart');
+    Source source3 = new TestSource('third.dart');
     DartEntry entry = new DartEntry();
     entry.setValueInLibrary(
         DartEntry.RESOLVED_UNIT,
@@ -2685,24 +2811,67 @@
     entry.removeResolution(source1);
   }
 
+  void test_resolvableCompilationUnit_builtUnit() {
+    Source librarySource = new TestSource('/lib.dart');
+    CompilationUnit unit = AstFactory.compilationUnit();
+    CompilationUnitElement element = ElementFactory.compilationUnit('test.dart');
+    unit.element = element;
+    DartEntry entry = new DartEntry();
+    entry.setState(DartEntry.PARSED_UNIT, CacheState.FLUSHED);
+    entry.setValueInLibrary(DartEntry.BUILT_UNIT, librarySource, unit);
+    entry.invalidateAllResolutionInformation(false);
+    CompilationUnit resolvableUnit = entry.resolvableCompilationUnit;
+    expect(resolvableUnit, isNotNull);
+    expect(resolvableUnit.element, isNull);
+    expect(entry.resolvableCompilationUnit, isNull);
+  }
+
+  void test_resolvableCompilationUnit_none() {
+    DartEntry entry = new DartEntry();
+    expect(entry.resolvableCompilationUnit, isNull);
+  }
+
+  void test_resolvableCompilationUnit_parsed() {
+    CompilationUnit unit = AstFactory.compilationUnit();
+    DartEntry entry = new DartEntry();
+    entry.setValue(DartEntry.PARSED_UNIT, unit);
+    expect(entry.resolvableCompilationUnit, unit);
+    expect(entry.resolvableCompilationUnit, isNull);
+  }
+
+  void test_resolvableCompilationUnit_resolved() {
+    Source librarySource = new TestSource('/lib.dart');
+    CompilationUnit unit = AstFactory.compilationUnit();
+    CompilationUnitElement element = ElementFactory.compilationUnit('test.dart');
+    unit.element = element;
+    DartEntry entry = new DartEntry();
+    entry.setState(DartEntry.PARSED_UNIT, CacheState.FLUSHED);
+    entry.setValueInLibrary(DartEntry.RESOLVED_UNIT, librarySource, unit);
+    entry.invalidateAllResolutionInformation(false);
+    CompilationUnit resolvableUnit = entry.resolvableCompilationUnit;
+    expect(resolvableUnit, isNotNull);
+    expect(resolvableUnit.element, isNull);
+    expect(entry.resolvableCompilationUnit, isNull);
+  }
+
   void test_setState_element() {
-    state2 = DartEntry.ELEMENT;
+    _setState(DartEntry.ELEMENT);
   }
 
   void test_setState_exportedLibraries() {
-    state2 = DartEntry.EXPORTED_LIBRARIES;
+    _setState(DartEntry.EXPORTED_LIBRARIES);
   }
 
   void test_setState_hints() {
-    state3 = DartEntry.HINTS;
+    _setStateInLibrary(DartEntry.HINTS);
   }
 
   void test_setState_importedLibraries() {
-    state2 = DartEntry.IMPORTED_LIBRARIES;
+    _setState(DartEntry.IMPORTED_LIBRARIES);
   }
 
   void test_setState_includedParts() {
-    state2 = DartEntry.INCLUDED_PARTS;
+    _setState(DartEntry.INCLUDED_PARTS);
   }
 
   void test_setState_invalid_element() {
@@ -2745,108 +2914,108 @@
    }
 
   void test_setState_isClient() {
-    state2 = DartEntry.IS_CLIENT;
+    _setState(DartEntry.IS_CLIENT);
   }
 
   void test_setState_isLaunchable() {
-    state2 = DartEntry.IS_LAUNCHABLE;
+    _setState(DartEntry.IS_LAUNCHABLE);
   }
 
   void test_setState_lineInfo() {
-    state2 = SourceEntry.LINE_INFO;
+    _setState(SourceEntry.LINE_INFO);
   }
 
   void test_setState_parseErrors() {
-    state2 = DartEntry.PARSE_ERRORS;
+    _setState(DartEntry.PARSE_ERRORS);
   }
 
   void test_setState_parsedUnit() {
-    state2 = DartEntry.PARSED_UNIT;
+    _setState(DartEntry.PARSED_UNIT);
   }
 
   void test_setState_publicNamespace() {
-    state2 = DartEntry.PUBLIC_NAMESPACE;
+    _setState(DartEntry.PUBLIC_NAMESPACE);
   }
 
   void test_setState_resolutionErrors() {
-    state3 = DartEntry.RESOLUTION_ERRORS;
+    _setStateInLibrary(DartEntry.RESOLUTION_ERRORS);
   }
 
   void test_setState_resolvedUnit() {
-    state3 = DartEntry.RESOLVED_UNIT;
+    _setStateInLibrary(DartEntry.RESOLVED_UNIT);
   }
 
   void test_setState_scanErrors() {
-    state2 = DartEntry.SCAN_ERRORS;
+    _setState(DartEntry.SCAN_ERRORS);
   }
 
   void test_setState_sourceKind() {
-    state2 = DartEntry.SOURCE_KIND;
+    _setState(DartEntry.SOURCE_KIND);
   }
 
   void test_setState_tokenStream() {
-    state2 = DartEntry.TOKEN_STREAM;
+    _setState(DartEntry.TOKEN_STREAM);
   }
 
   void test_setState_verificationErrors() {
-    state3 = DartEntry.VERIFICATION_ERRORS;
+    _setStateInLibrary(DartEntry.VERIFICATION_ERRORS);
   }
 
   void test_setValue_element() {
-    _setValue2(
+    _setValue(
         DartEntry.ELEMENT,
         new LibraryElementImpl.forNode(null, AstFactory.libraryIdentifier2(["lib"])));
   }
 
   void test_setValue_exportedLibraries() {
-    _setValue2(DartEntry.EXPORTED_LIBRARIES, <Source>[new TestSource()]);
+    _setValue(DartEntry.EXPORTED_LIBRARIES, <Source>[new TestSource()]);
   }
 
   void test_setValue_hints() {
-    _setValue3(
+    _setValueInLibrary(
         DartEntry.HINTS,
         <AnalysisError>[new AnalysisError.con1(null, HintCode.DEAD_CODE, [])]);
   }
 
   void test_setValue_importedLibraries() {
-    _setValue2(DartEntry.IMPORTED_LIBRARIES, <Source>[new TestSource()]);
+    _setValue(DartEntry.IMPORTED_LIBRARIES, <Source>[new TestSource()]);
   }
 
   void test_setValue_includedParts() {
-    _setValue2(DartEntry.INCLUDED_PARTS, <Source>[new TestSource()]);
+    _setValue(DartEntry.INCLUDED_PARTS, <Source>[new TestSource()]);
   }
 
   void test_setValue_isClient() {
-    _setValue2(DartEntry.IS_CLIENT, true);
+    _setValue(DartEntry.IS_CLIENT, true);
   }
 
   void test_setValue_isLaunchable() {
-    _setValue2(DartEntry.IS_LAUNCHABLE, true);
+    _setValue(DartEntry.IS_LAUNCHABLE, true);
   }
 
   void test_setValue_lineInfo() {
-    _setValue2(SourceEntry.LINE_INFO, new LineInfo(<int>[0]));
+    _setValue(SourceEntry.LINE_INFO, new LineInfo(<int>[0]));
   }
 
   void test_setValue_parseErrors() {
-    _setValue2(
+    _setValue(
         DartEntry.PARSE_ERRORS,
         <AnalysisError>[
             new AnalysisError.con1(null, ParserErrorCode.ABSTRACT_CLASS_MEMBER, [])]);
   }
 
   void test_setValue_parsedUnit() {
-    _setValue2(DartEntry.PARSED_UNIT, AstFactory.compilationUnit());
+    _setValue(DartEntry.PARSED_UNIT, AstFactory.compilationUnit());
   }
 
   void test_setValue_publicNamespace() {
-    _setValue2(
+    _setValue(
         DartEntry.PUBLIC_NAMESPACE,
         new Namespace(new HashMap<String, Element>()));
   }
 
   void test_setValue_resolutionErrors() {
-    _setValue3(
+    _setValueInLibrary(
         DartEntry.RESOLUTION_ERRORS,
         <AnalysisError>[
             new AnalysisError.con1(
@@ -2856,11 +3025,11 @@
   }
 
   void test_setValue_resolvedUnit() {
-    _setValue3(DartEntry.RESOLVED_UNIT, AstFactory.compilationUnit());
+    _setValueInLibrary(DartEntry.RESOLVED_UNIT, AstFactory.compilationUnit());
   }
 
   void test_setValue_scanErrors() {
-    _setValue2(
+    _setValue(
         DartEntry.SCAN_ERRORS,
         <AnalysisError>[
             new AnalysisError.con1(
@@ -2870,46 +3039,110 @@
   }
 
   void test_setValue_sourceKind() {
-    _setValue2(DartEntry.SOURCE_KIND, SourceKind.LIBRARY);
+    _setValue(DartEntry.SOURCE_KIND, SourceKind.LIBRARY);
   }
 
   void test_setValue_tokenStream() {
-    _setValue2(DartEntry.TOKEN_STREAM, new Token(TokenType.LT, 5));
+    _setValue(DartEntry.TOKEN_STREAM, new Token(TokenType.LT, 5));
   }
 
   void test_setValue_verificationErrors() {
-    _setValue3(
+    _setValueInLibrary(
         DartEntry.VERIFICATION_ERRORS,
         <AnalysisError>[
             new AnalysisError.con1(null, StaticWarningCode.CASE_BLOCK_NOT_TERMINATED, [])]);
   }
 
-  DartEntry _entryWithValidState() {
+  DartEntry _entryWithValidState([Source firstLibrary, Source secondLibrary]) {
     DartEntry entry = new DartEntry();
+    entry.setValue(SourceEntry.CONTENT, null);
+    entry.setValue(SourceEntry.LINE_INFO, null);
+    entry.setValue(DartEntry.CONTAINING_LIBRARIES, null);
     entry.setValue(DartEntry.ELEMENT, null);
     entry.setValue(DartEntry.EXPORTED_LIBRARIES, null);
     entry.setValue(DartEntry.IMPORTED_LIBRARIES, null);
     entry.setValue(DartEntry.INCLUDED_PARTS, null);
-    entry.setValue(DartEntry.IS_CLIENT, true);
-    entry.setValue(DartEntry.IS_LAUNCHABLE, true);
-    entry.setValue(SourceEntry.LINE_INFO, null);
+    entry.setValue(DartEntry.IS_CLIENT, null);
+    entry.setValue(DartEntry.IS_LAUNCHABLE, null);
     entry.setValue(DartEntry.PARSE_ERRORS, null);
     entry.setValue(DartEntry.PARSED_UNIT, null);
     entry.setValue(DartEntry.PUBLIC_NAMESPACE, null);
+    entry.setValue(DartEntry.SCAN_ERRORS, null);
+    entry.setValue(DartEntry.SOURCE_KIND, null);
+    entry.setValue(DartEntry.TOKEN_STREAM, null);
+    if (firstLibrary != null) {
+      entry.setValueInLibrary(DartEntry.ANGULAR_ERRORS, firstLibrary, null);
+      entry.setValueInLibrary(DartEntry.BUILT_ELEMENT, firstLibrary, null);
+      entry.setValueInLibrary(DartEntry.BUILT_UNIT, firstLibrary, null);
+      entry.setValueInLibrary(DartEntry.HINTS, firstLibrary, null);
+      entry.setValueInLibrary(DartEntry.RESOLUTION_ERRORS, firstLibrary, null);
+      entry.setValueInLibrary(DartEntry.RESOLVED_UNIT, firstLibrary, null);
+      entry.setValueInLibrary(DartEntry.VERIFICATION_ERRORS, firstLibrary, null);
+    }
+    if (secondLibrary != null) {
+      entry.setValueInLibrary(DartEntry.ANGULAR_ERRORS, secondLibrary, null);
+      entry.setValueInLibrary(DartEntry.BUILT_ELEMENT, secondLibrary, null);
+      entry.setValueInLibrary(DartEntry.BUILT_UNIT, secondLibrary, null);
+      entry.setValueInLibrary(DartEntry.HINTS, secondLibrary, null);
+      entry.setValueInLibrary(DartEntry.RESOLUTION_ERRORS, secondLibrary, null);
+      entry.setValueInLibrary(DartEntry.RESOLVED_UNIT, secondLibrary, null);
+      entry.setValueInLibrary(DartEntry.VERIFICATION_ERRORS, secondLibrary, null);
+    }
+    //
+    // Validate that the state was set correctly.
+    //
+    expect(entry.getState(SourceEntry.CONTENT), same(CacheState.VALID));
+    expect(entry.getState(SourceEntry.LINE_INFO), same(CacheState.VALID));
+    expect(entry.getState(DartEntry.CONTAINING_LIBRARIES), same(CacheState.VALID));
     expect(entry.getState(DartEntry.ELEMENT), same(CacheState.VALID));
     expect(entry.getState(DartEntry.EXPORTED_LIBRARIES), same(CacheState.VALID));
     expect(entry.getState(DartEntry.IMPORTED_LIBRARIES), same(CacheState.VALID));
     expect(entry.getState(DartEntry.INCLUDED_PARTS), same(CacheState.VALID));
     expect(entry.getState(DartEntry.IS_CLIENT), same(CacheState.VALID));
     expect(entry.getState(DartEntry.IS_LAUNCHABLE), same(CacheState.VALID));
-    expect(entry.getState(SourceEntry.LINE_INFO), same(CacheState.VALID));
     expect(entry.getState(DartEntry.PARSE_ERRORS), same(CacheState.VALID));
     expect(entry.getState(DartEntry.PARSED_UNIT), same(CacheState.VALID));
     expect(entry.getState(DartEntry.PUBLIC_NAMESPACE), same(CacheState.VALID));
+    expect(entry.getState(DartEntry.SCAN_ERRORS), same(CacheState.VALID));
+    expect(entry.getState(DartEntry.SOURCE_KIND), same(CacheState.VALID));
+    expect(entry.getState(DartEntry.TOKEN_STREAM), same(CacheState.VALID));
+    if (firstLibrary != null) {
+      expect(entry.getStateInLibrary(DartEntry.ANGULAR_ERRORS, firstLibrary), same(CacheState.VALID));
+      expect(entry.getStateInLibrary(DartEntry.BUILT_ELEMENT, firstLibrary), same(CacheState.VALID));
+      expect(entry.getStateInLibrary(DartEntry.BUILT_UNIT, firstLibrary), same(CacheState.VALID));
+      expect(entry.getStateInLibrary(DartEntry.HINTS, firstLibrary), same(CacheState.VALID));
+      expect(entry.getStateInLibrary(DartEntry.RESOLUTION_ERRORS, firstLibrary), same(CacheState.VALID));
+      expect(entry.getStateInLibrary(DartEntry.RESOLVED_UNIT, firstLibrary), same(CacheState.VALID));
+      expect(entry.getStateInLibrary(DartEntry.VERIFICATION_ERRORS, firstLibrary), same(CacheState.VALID));
+    }
+    if (secondLibrary != null) {
+      expect(entry.getStateInLibrary(DartEntry.ANGULAR_ERRORS, secondLibrary), same(CacheState.VALID));
+      expect(entry.getStateInLibrary(DartEntry.BUILT_ELEMENT, secondLibrary), same(CacheState.VALID));
+      expect(entry.getStateInLibrary(DartEntry.BUILT_UNIT, secondLibrary), same(CacheState.VALID));
+      expect(entry.getStateInLibrary(DartEntry.HINTS, secondLibrary), same(CacheState.VALID));
+      expect(entry.getStateInLibrary(DartEntry.RESOLUTION_ERRORS, secondLibrary), same(CacheState.VALID));
+      expect(entry.getStateInLibrary(DartEntry.RESOLVED_UNIT, secondLibrary), same(CacheState.VALID));
+      expect(entry.getStateInLibrary(DartEntry.VERIFICATION_ERRORS, secondLibrary), same(CacheState.VALID));
+    }
     return entry;
   }
 
-  void _setValue2(DataDescriptor descriptor, Object newValue) {
+  void _setState(DataDescriptor descriptor) {
+    DartEntry entry = new DartEntry();
+    expect(entry.getState(descriptor), isNot(same(CacheState.FLUSHED)));
+    entry.setState(descriptor, CacheState.FLUSHED);
+    expect(entry.getState(descriptor), same(CacheState.FLUSHED));
+  }
+
+  void _setStateInLibrary(DataDescriptor descriptor) {
+    Source source = new TestSource();
+    DartEntry entry = new DartEntry();
+    expect(entry.getStateInLibrary(descriptor, source), isNot(same(CacheState.FLUSHED)));
+    entry.setStateInLibrary(descriptor, source, CacheState.FLUSHED);
+    expect(entry.getStateInLibrary(descriptor, source), same(CacheState.FLUSHED));
+  }
+
+  void _setValue(DataDescriptor descriptor, Object newValue) {
     DartEntry entry = new DartEntry();
     Object value = entry.getValue(descriptor);
     expect(newValue, isNot(same(value)));
@@ -2918,7 +3151,7 @@
     expect(entry.getValue(descriptor), same(newValue));
   }
 
-  void _setValue3(DataDescriptor descriptor, Object newValue) {
+  void _setValueInLibrary(DataDescriptor descriptor, Object newValue) {
     Source source = new TestSource();
     DartEntry entry = new DartEntry();
     Object value = entry.getValueInLibrary(descriptor, source);
@@ -5600,6 +5833,12 @@
   void setContents(Source source, String contents) {
     fail("Unexpected invocation of setContents");
   }
+  @override
+  void visitCacheItems(void callback(Source source, SourceEntry dartEntry,
+                                     DataDescriptor rowDesc,
+                                     CacheState state)) {
+    fail("Unexpected invocation of visitCacheItems");
+  }
 }
 
 
diff --git a/pkg/analyzer/test/generated/parser_test.dart b/pkg/analyzer/test/generated/parser_test.dart
index 501b539..fc1eeb8 100644
--- a/pkg/analyzer/test/generated/parser_test.dart
+++ b/pkg/analyzer/test/generated/parser_test.dart
@@ -5898,7 +5898,7 @@
     expect(statement.loopVariable, isNull);
     expect(statement.identifier, isNotNull);
     expect(statement.inKeyword, isNotNull);
-    expect(statement.iterator, isNotNull);
+    expect(statement.iterable, isNotNull);
     expect(statement.rightParenthesis, isNotNull);
     expect(statement.body, isNotNull);
   }
@@ -5911,7 +5911,7 @@
     expect(statement.loopVariable, isNull);
     expect(statement.identifier, isNotNull);
     expect(statement.inKeyword, isNotNull);
-    expect(statement.iterator, isNotNull);
+    expect(statement.iterable, isNotNull);
     expect(statement.rightParenthesis, isNotNull);
     expect(statement.body, isNotNull);
   }
@@ -5925,7 +5925,7 @@
     expect(statement.loopVariable.metadata, hasLength(1));
     expect(statement.identifier, isNull);
     expect(statement.inKeyword, isNotNull);
-    expect(statement.iterator, isNotNull);
+    expect(statement.iterable, isNotNull);
     expect(statement.rightParenthesis, isNotNull);
     expect(statement.body, isNotNull);
   }
@@ -5938,7 +5938,7 @@
     expect(statement.loopVariable, isNotNull);
     expect(statement.identifier, isNull);
     expect(statement.inKeyword, isNotNull);
-    expect(statement.iterator, isNotNull);
+    expect(statement.iterable, isNotNull);
     expect(statement.rightParenthesis, isNotNull);
     expect(statement.body, isNotNull);
   }
@@ -5951,7 +5951,7 @@
     expect(statement.loopVariable, isNotNull);
     expect(statement.identifier, isNull);
     expect(statement.inKeyword, isNotNull);
-    expect(statement.iterator, isNotNull);
+    expect(statement.iterable, isNotNull);
     expect(statement.rightParenthesis, isNotNull);
     expect(statement.body, isNotNull);
   }
diff --git a/pkg/analyzer/test/generated/resolver_test.dart b/pkg/analyzer/test/generated/resolver_test.dart
index f8089e9..e05c4d0 100644
--- a/pkg/analyzer/test/generated/resolver_test.dart
+++ b/pkg/analyzer/test/generated/resolver_test.dart
@@ -14,7 +14,9 @@
 import 'package:analyzer/src/generated/ast.dart';
 import 'package:analyzer/src/generated/parser.dart' show ParserErrorCode;
 import 'package:analyzer/src/generated/element.dart';
+import 'package:analyzer/src/generated/element_resolver.dart';
 import 'package:analyzer/src/generated/resolver.dart';
+import 'package:analyzer/src/generated/static_type_analyzer.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/utilities_dart.dart';
 import 'package:analyzer/src/generated/sdk.dart';
@@ -25,6 +27,7 @@
 import 'package:analyzer/src/generated/testing/element_factory.dart';
 import 'package:analyzer/src/generated/java_io.dart';
 import '../reflective_tests.dart';
+import 'parser_test.dart';
 
 
 /**
@@ -977,7 +980,7 @@
 const int ZERO = 0;
 class C {
   int m(int p) {
-    return (p * p) + (p * p) + ZERO;
+    return p + p;
   }
 }''');
   }
@@ -1063,9 +1066,7 @@
     Source source = addSource(oldContent);
     LibraryElement library = resolve(source);
     CompilationUnit oldUnit = resolveCompilationUnit(source, library);
-    AnalysisContext context = analysisContext;
-    context.setContents(source, newContent);
-    CompilationUnit newUnit = context.parseCompilationUnit(source);
+    CompilationUnit newUnit = ParserTestCase.parseCompilationUnit(newContent, []);
     DeclarationMatcher matcher = new DeclarationMatcher();
     expect(matcher.matches(newUnit, oldUnit.element), expectMatch);
   }
@@ -8415,6 +8416,16 @@
     _listener.assertNoErrors();
   }
 
+  void test_visitSimpleIdentifier_dynamic() {
+    // "dynamic"
+    SimpleIdentifier identifier = AstFactory.identifier3('dynamic');
+    DynamicElementImpl element = DynamicElementImpl.instance;
+    identifier.staticElement = element;
+    identifier.staticType = _typeProvider.typeType;
+    expect(_analyze(identifier), same(_typeProvider.typeType));
+    _listener.assertNoErrors();
+  }
+
   void test_visitSimpleStringLiteral() {
     // "a"
     Expression node = _resolvedString("a");
diff --git a/pkg/analyzer/test/generated/static_type_warning_code_test.dart b/pkg/analyzer/test/generated/static_type_warning_code_test.dart
index 67ec5de..02c588b 100644
--- a/pkg/analyzer/test/generated/static_type_warning_code_test.dart
+++ b/pkg/analyzer/test/generated/static_type_warning_code_test.dart
@@ -220,6 +220,17 @@
     verify([source]);
   }
 
+  void test_invalidAssignment_dynamic() {
+    Source source = addSource(r'''
+main() {
+  dynamic = 1;
+}
+''');
+    resolve(source);
+    assertErrors(source, [StaticTypeWarningCode.INVALID_ASSIGNMENT]);
+    verify([source]);
+  }
+
   void test_invalidAssignment_instanceVariable() {
     Source source = addSource(r'''
 class A {
diff --git a/pkg/analyzer/test/generated/static_warning_code_test.dart b/pkg/analyzer/test/generated/static_warning_code_test.dart
index f8b0893..2c779c5 100644
--- a/pkg/analyzer/test/generated/static_warning_code_test.dart
+++ b/pkg/analyzer/test/generated/static_warning_code_test.dart
@@ -9,7 +9,6 @@
 import 'package:analyzer/src/generated/parser.dart' show ParserErrorCode;
 import 'package:unittest/unittest.dart';
 import 'resolver_test.dart';
-import 'test_support.dart';
 import '../reflective_tests.dart';
 
 
diff --git a/pkg/analyzer/test/generated/test_support.dart b/pkg/analyzer/test/generated/test_support.dart
index 60c3ce6..20f04a8 100644
--- a/pkg/analyzer/test/generated/test_support.dart
+++ b/pkg/analyzer/test/generated/test_support.dart
@@ -557,22 +557,22 @@
   int infoCount = 0;
 
   @override
-  void logError(String message) {
+  void logError(String message, [CaughtException exception]) {
     errorCount++;
   }
 
   @override
-  void logError2(String message, Exception exception) {
+  void logError2(String message, Object exception) {
     errorCount++;
   }
 
   @override
-  void logInformation(String message) {
+  void logInformation(String message, [CaughtException exception]) {
     infoCount++;
   }
 
   @override
-  void logInformation2(String message, Exception exception) {
+  void logInformation2(String message, Object exception) {
     infoCount++;
   }
 }
diff --git a/pkg/analyzer/test/generated/utilities_test.dart b/pkg/analyzer/test/generated/utilities_test.dart
index 5aea6b7..27ebefd 100644
--- a/pkg/analyzer/test/generated/utilities_test.dart
+++ b/pkg/analyzer/test/generated/utilities_test.dart
@@ -10,7 +10,6 @@
 import 'dart:collection';
 
 import 'package:analyzer/src/generated/ast.dart';
-import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/java_core.dart';
 import 'package:analyzer/src/generated/java_engine.dart';
 import 'package:analyzer/src/generated/scanner.dart';
@@ -2795,13 +2794,13 @@
 class Getter_NodeReplacerTest_test_forEachStatement_withIdentifier_3 implements
     NodeReplacerTest_Getter {
   @override
-  Expression get(ForEachStatement node) => node.iterator;
+  Expression get(ForEachStatement node) => node.iterable;
 }
 
 class Getter_NodeReplacerTest_test_forEachStatement_withLoopVariable implements
     NodeReplacerTest_Getter {
   @override
-  Expression get(ForEachStatement node) => node.iterator;
+  Expression get(ForEachStatement node) => node.iterable;
 }
 
 class Getter_NodeReplacerTest_test_forEachStatement_withLoopVariable_2
@@ -5238,55 +5237,6 @@
   }
 }
 
-/**
- * Instances of the class `TestLogger` implement a logger that can be used by tests.
- */
-class TestLogger implements Logger {
-  /**
-   * The number of error messages that were logged.
-   */
-  int _errorCount = 0;
-
-  /**
-   * The number of informational messages that were logged.
-   */
-  int _infoCount = 0;
-
-  /**
-   * Return the number of error messages that were logged.
-   *
-   * @return the number of error messages that were logged
-   */
-  int get errorCount => _errorCount;
-
-  /**
-   * Return the number of informational messages that were logged.
-   *
-   * @return the number of informational messages that were logged
-   */
-  int get infoCount => _infoCount;
-
-  @override
-  void logError(String message) {
-    _errorCount++;
-  }
-
-  @override
-  void logError2(String message, Exception exception) {
-    _errorCount++;
-  }
-
-  @override
-  void logInformation(String message) {
-    _infoCount++;
-  }
-
-  @override
-  void logInformation2(String message, Exception exception) {
-    _infoCount++;
-  }
-}
-
 
 class TokenMapTest {
   void test_creation() {
diff --git a/pkg/analyzer/test/task/task_dart_test.dart b/pkg/analyzer/test/task/task_dart_test.dart
index 9a44b7d..1d0da10 100644
--- a/pkg/analyzer/test/task/task_dart_test.dart
+++ b/pkg/analyzer/test/task/task_dart_test.dart
@@ -15,7 +15,6 @@
 import '../generated/engine_test.dart';
 import '../generated/resolver_test.dart';
 import '../generated/test_support.dart';
-import '../reflective_tests.dart';
 
 main() {
   groupSep = ' | ';
diff --git a/pkg/analyzer2dart/lib/src/cps_generator.dart b/pkg/analyzer2dart/lib/src/cps_generator.dart
index a8c7698..ffeea64 100644
--- a/pkg/analyzer2dart/lib/src/cps_generator.dart
+++ b/pkg/analyzer2dart/lib/src/cps_generator.dart
@@ -31,6 +31,8 @@
 

   Source get currentSource => element.source;

 

+  analyzer.LibraryElement get currentLibrary => element.library;

+

   ir.Node visit(AstNode node) => node.accept(this);

 

   @override

@@ -304,6 +306,25 @@
   }

 

   @override

+  ir.Node visitListLiteral(ListLiteral node) {

+    dart2js.InterfaceType type = converter.convertType(node.staticType);

+    // TODO(johnniwinther): Use `build` instead of `(e) => build(e)` when issue

+    // 18630 has been resolved.

+    Iterable<ir.Primitive> values = node.elements.map((e) => build(e));

+    return irBuilder.buildListLiteral(type, values);

+  }

+

+  @override

+  ir.Node visitMapLiteral(MapLiteral node) {

+    dart2js.InterfaceType type = converter.convertType(node.staticType);

+    return irBuilder.buildMapLiteral(

+        type,

+        node.entries.map((e) => e.key),

+        node.entries.map((e) => e.value),

+        build);

+  }

+

+  @override
   visitForStatement(ForStatement node) {

     // TODO(johnniwinther): Support `for` as a jump target.

     SubbuildFunction buildInitializer;

@@ -317,4 +338,68 @@
                        buildBody: subbuild(node.body),

                        buildUpdate: subbuildSequence(node.updaters));

   }

+

+  @override

+  visitWhileStatement(WhileStatement node) {

+    // TODO(johnniwinther): Support `while` as a jump target.

+    irBuilder.buildWhile(buildCondition: subbuild(node.condition),

+                         buildBody: subbuild(node.body));

+  }

+

+  @override

+  visitDeclaredIdentifier(DeclaredIdentifier node) {

+    giveUp(node, "Unexpected node: DeclaredIdentifier");

+  }

+

+  @override

+  visitForEachStatement(ForEachStatement node) {

+    SubbuildFunction buildVariableDeclaration;

+    dart2js.Element variableElement;

+    Selector variableSelector;

+    if (node.identifier != null) {

+       AccessSemantics accessSemantics =

+           node.identifier.accept(ACCESS_SEMANTICS_VISITOR);

+       if (accessSemantics.kind == AccessKind.DYNAMIC) {

+         variableSelector = new Selector.setter(

+             node.identifier.name, converter.convertElement(currentLibrary));

+       } else if (accessSemantics.element != null) {

+         variableElement = converter.convertElement(accessSemantics.element);

+         variableSelector = new Selector.setter(

+             variableElement.name,

+             converter.convertElement(accessSemantics.element.library));

+       } else {

+         giveUp(node, 'For-in of unresolved variable: $accessSemantics');

+       }

+    } else {

+      assert(invariant(

+          node, node.loopVariable != null, "Loop variable expected"));

+      variableElement = converter.convertElement(node.loopVariable.element);

+      buildVariableDeclaration = (IrBuilder builder) {

+        builder.declareLocalVariable(variableElement);

+      };

+    }

+    // TODO(johnniwinther): Support `for-in` as a jump target.

+    irBuilder.buildForIn(

+        buildExpression: subbuild(node.iterable),

+        buildVariableDeclaration: buildVariableDeclaration,

+        variableElement: variableElement,

+        variableSelector: variableSelector,

+        buildBody: subbuild(node.body));

+  }

+  @override

+  ir.Primitive visitIsExpression(IsExpression node) {

+    return irBuilder.buildTypeOperator(

+        visit(node.expression),

+        converter.convertType(node.type.type),

+        isTypeTest: true,

+        isNotCheck: node.notOperator != null);

+  }

+

+  @override

+  ir.Primitive visitAsExpression(AsExpression node) {

+    return irBuilder.buildTypeOperator(

+        visit(node.expression),

+        converter.convertType(node.type.type),

+        isTypeTest: false);

+  }

 }

diff --git a/pkg/analyzer2dart/lib/src/modely.dart b/pkg/analyzer2dart/lib/src/modely.dart
index 390ea7c..4f89848 100644
--- a/pkg/analyzer2dart/lib/src/modely.dart
+++ b/pkg/analyzer2dart/lib/src/modely.dart
@@ -361,6 +361,9 @@
 

   @override

   bool get hasFunctionSignature => unsupported('hasFunctionSignature');

+

+  @override

+  get asyncMarker => unsupported('asyncMarker');

 }

 

 class TopLevelFunctionElementY extends ElementY

diff --git a/pkg/analyzer2dart/lib/src/tree_shaker.dart b/pkg/analyzer2dart/lib/src/tree_shaker.dart
index 47a653f..bc69438 100644
--- a/pkg/analyzer2dart/lib/src/tree_shaker.dart
+++ b/pkg/analyzer2dart/lib/src/tree_shaker.dart
@@ -44,6 +44,9 @@
   /**
    * The classes that are instantiated by the method.
    */
+  // TODO(johnniwinther,paulberry): Register instantiated types.
+  // TODO(johnniwinther,paulberry): Register checked types from is/as checks,
+  // catch clauses and (checked) type annotations.
   final List<ClassElement> instantiates = <ClassElement>[];
 
   MethodAnalysis(this.declaration);
diff --git a/pkg/analyzer2dart/test/end2end_data.dart b/pkg/analyzer2dart/test/end2end_data.dart
index 455f790..6237402 100644
--- a/pkg/analyzer2dart/test/end2end_data.dart
+++ b/pkg/analyzer2dart/test/end2end_data.dart
@@ -501,6 +501,38 @@
 '''),
   ]),
 
+  const Group('List literal', const <TestSpec>[
+    const TestSpec('''
+main() {
+  return [];
+}
+'''),
+
+    const TestSpec('''
+main() {
+  return <int>[];
+}
+'''),
+
+    const TestSpec('''
+main() {
+  return <int>[0];
+}
+'''),
+
+    const TestSpec('''
+main(a) {
+  return <int>[0, 1, a];
+}
+'''),
+
+    const TestSpec('''
+main(a) {
+  return [0, [1], [a, <int>[3]]];
+}
+'''),
+  ]),
+
   const Group('Constructor invocation', const <TestSpec>[
     const TestSpec('''
 main(a) {
@@ -515,6 +547,37 @@
 '''),
   ]),
 
+  const Group('Map literal', const <TestSpec>[
+    const TestSpec('''
+main() {
+  return {};
+}
+'''),
+
+    const TestSpec('''
+main() {
+  return <int, String>{};
+}
+'''),
+
+    const TestSpec('''
+main() {
+  return <String, int>{"a": 0};
+}
+'''),
+
+    const TestSpec('''
+main(a) {
+  return <String, int>{"a": 0, "b": 1, "c": a};
+}
+'''),
+
+    const TestSpec('''
+main(a) {
+  return {0: "a", 1: {2: "b"}, a: {3: "c"}};
+}
+'''),
+  ]),
   const Group('For loop', const <TestSpec>[
     const TestSpec('''
 main() {
@@ -528,7 +591,7 @@
 
 const TestSpec('''
 main() {
-  for (int i = 0; i < 10; i = i + 1) {
+  for (var i = 0; i < 10; i = i + 1) {
     print(i);
   }
 }
@@ -558,4 +621,119 @@
 }
 '''),
   ]),
+
+  const Group('While loop', const <TestSpec>[
+    const TestSpec('''
+main() {
+  while (true) {}
+}
+'''),
+
+const TestSpec('''
+main() {
+  var i = 0;
+  while (i < 10) {
+    print(i);
+    i = i + 1;
+  }
+}''', '''
+main() {
+  var i = 0;
+  while (i < 10) {
+    print(i);
+    ++i;
+  }
+}'''),
+  ]),
+
+  const Group('Type operators', const <TestSpec>[
+    const TestSpec('''
+main(a) {
+  return a is String;
+}
+'''),
+
+    const TestSpec('''
+main(a) {
+  return a is List<String>;
+}
+'''),
+
+    const TestSpec('''
+main(a) {
+  return a is Comparator<String>;
+}
+'''),
+
+  const TestSpec('''
+main(a) {
+  return a is! String;
+}
+''', '''
+main(a) {
+  return !(a is String);
+}
+'''),
+
+const TestSpec('''
+main(a) {
+  return a as String;
+}
+'''),
+  ]),
+
+  const Group('For in loop', const <TestSpec>[
+// TODO(johnniwinther): Add tests for `i` as top-level, static and instance
+// fields.
+    const TestSpec('''
+main(a) {
+  for (var i in a) {
+    print(i);
+  }
+}
+''', '''
+main(a) {
+  var v0 = a.iterator;
+  while (v0.moveNext()) {
+    print(v0.current);
+  }
+}'''),
+
+    const TestSpec('''
+main(a) {
+  for (var i in a) {
+    print(i);
+    i = 0;
+    print(i);
+  }
+}
+''', '''
+main(a) {
+  var v0 = a.iterator, i;
+  while (v0.moveNext()) {
+    i = v0.current;
+    print(i);
+    i = 0;
+    print(i);
+  }
+}
+'''),
+
+    const TestSpec('''
+main(a) {
+  var i;
+  for (i in a) {
+    print(i);
+  }
+}
+''', '''
+main(a) {
+  var i, v0 = a.iterator;
+  while (v0.moveNext()) {
+    i = v0.current;
+    print(i);
+  }
+}
+'''),
+  ]),
 ];
diff --git a/pkg/analyzer2dart/test/end2end_test.dart b/pkg/analyzer2dart/test/end2end_test.dart
index 3cfde57..6cc500c0 100644
--- a/pkg/analyzer2dart/test/end2end_test.dart
+++ b/pkg/analyzer2dart/test/end2end_test.dart
@@ -27,7 +27,7 @@
 
 checkResult(TestSpec result) {
   String input = result.input;
-  String expectedOutput = result.output;
+  String expectedOutput = result.output.trim();
 
   CollectingOutputProvider outputProvider = new CollectingOutputProvider();
   MemoryResourceProvider provider = new MemoryResourceProvider();
@@ -40,6 +40,6 @@
   ClosedWorld world = driver.computeWorld(entryPoint);
   ConvertedWorld convertedWorld = convertWorld(world);
   compileToDart(driver, convertedWorld);
-  String output = outputProvider.output.text;
+  String output = outputProvider.output.text.trim();
   expect(output, equals(expectedOutput));
 }
diff --git a/pkg/analyzer2dart/test/identifier_semantics_test.dart b/pkg/analyzer2dart/test/identifier_semantics_test.dart
index 3ccc46f..b9a3044 100644
--- a/pkg/analyzer2dart/test/identifier_semantics_test.dart
+++ b/pkg/analyzer2dart/test/identifier_semantics_test.dart
@@ -1103,6 +1103,17 @@
     helper.checkStaticField('x', null, 'x', isWrite: true);
   });
 
+  test('Set variable defined at top level in foreach loop', () {
+    Helper helper = new Helper('''
+var x;
+
+f() {
+  for (x in []) {}
+}
+''');
+    helper.checkStaticField('x', null, 'x', isWrite: true);
+  });
+
   test('Set variable defined at top level via prefix', () {
     Helper helper = new Helper('''
 import 'lib.dart' as l;
@@ -1132,6 +1143,20 @@
     helper.checkStaticField('x', 'A', 'x', isWrite: true);
   });
 
+  test('Set field defined statically in class from inside class in foreach' +
+      ' loop', () {
+    Helper helper = new Helper('''
+class A {
+  static var x;
+
+  f() {
+    for (x in []) {}
+  }
+}
+''');
+    helper.checkStaticField('x', 'A', 'x', isWrite: true);
+  });
+
   test('Set field defined statically in class from outside class', () {
     Helper helper = new Helper('''
 class A {
@@ -1178,6 +1203,20 @@
     helper.checkDynamic('x', null, 'x', isWrite: true);
   });
 
+  test('Set field defined dynamically in class from inside class in foreach' +
+      ' loop', () {
+    Helper helper = new Helper('''
+class A {
+  var x;
+
+  f() {
+    for (x in []) {}
+  }
+}
+''');
+    helper.checkDynamic('x', null, 'x', isWrite: true);
+  });
+
   test(
       'Set field defined dynamically in class from outside class via typed var',
       () {
@@ -1220,6 +1259,16 @@
     helper.checkLocalVariable('x', 'x', isWrite: true);
   });
 
+  test('Set variable defined locally in foreach loop', () {
+    Helper helper = new Helper('''
+f() {
+  var x;
+  for (x in []) {}
+}
+''');
+    helper.checkLocalVariable('x', 'x', isWrite: true);
+  });
+
   test('Set variable defined in parameter', () {
     Helper helper = new Helper('''
 f(x) {
@@ -1229,6 +1278,15 @@
     helper.checkParameter('x', 'x', isWrite: true);
   });
 
+  test('Set variable defined in parameter in foreach loop', () {
+    Helper helper = new Helper('''
+f(x) {
+  for (x in []) {}
+}
+''');
+    helper.checkParameter('x', 'x', isWrite: true);
+  });
+
   test('Set accessor defined at top level', () {
     Helper helper = new Helper('''
 set x(value) {};
@@ -1240,6 +1298,17 @@
     helper.checkStaticProperty('x', null, 'x', true, isWrite: true);
   });
 
+  test('Set accessor defined at top level in foreach loop', () {
+    Helper helper = new Helper('''
+set x(value) {};
+
+f() {
+  for (x in []) {}
+}
+''');
+    helper.checkStaticProperty('x', null, 'x', true, isWrite: true);
+  });
+
   test('Set accessor defined at top level via prefix', () {
     Helper helper = new Helper('''
 import 'lib.dart' as l;
@@ -1269,6 +1338,20 @@
     helper.checkStaticProperty('x', 'A', 'x', true, isWrite: true);
   });
 
+  test('Set accessor defined statically in class from inside class in' +
+      ' foreach loop', () {
+    Helper helper = new Helper('''
+class A {
+  static set x(value) {}
+
+  f() {
+    for (x in []) {}
+  }
+}
+''');
+    helper.checkStaticProperty('x', 'A', 'x', true, isWrite: true);
+  });
+
   test('Set accessor defined statically in class from outside class', () {
     Helper helper = new Helper('''
 class A {
@@ -1315,6 +1398,20 @@
     helper.checkDynamic('x', null, 'x', isWrite: true);
   });
 
+  test('Set accessor defined dynamically in class from inside class in' +
+      ' foreach loop', () {
+    Helper helper = new Helper('''
+class A {
+  set x(value) {}
+
+  f() {
+    for (x in []) {}
+  }
+}
+''');
+    helper.checkDynamic('x', null, 'x', isWrite: true);
+  });
+
   test(
       'Set accessor defined dynamically in class from outside class via typed var',
       () {
@@ -1380,6 +1477,15 @@
     helper.checkDynamic('x', null, 'x', isWrite: true);
   });
 
+  test('Set accessor undefined at top level in foreach loop', () {
+    Helper helper = new Helper('''
+f() {
+  for (x in []) {}
+}
+''');
+    helper.checkDynamic('x', null, 'x', isWrite: true);
+  });
+
   test('Set accessor undefined at top level via prefix', () {
     Helper helper = new Helper('''
 import 'lib.dart' as l;
@@ -1434,6 +1540,18 @@
     helper.checkDynamic('x', null, 'x', isWrite: true);
   });
 
+  test('Set accessor undefined dynamically in class from inside class in' +
+      ' foreach loop', () {
+    Helper helper = new Helper('''
+class A {
+  f() {
+    for (x in []) {}
+  }
+}
+''');
+    helper.checkDynamic('x', null, 'x', isWrite: true);
+  });
+
   test(
       'Set accessor undefined dynamically in class from outside class via typed var',
       () {
diff --git a/pkg/analyzer2dart/test/sexpr_data.dart b/pkg/analyzer2dart/test/sexpr_data.dart
index bf1f08a..049760f 100644
--- a/pkg/analyzer2dart/test/sexpr_data.dart
+++ b/pkg/analyzer2dart/test/sexpr_data.dart
@@ -816,6 +816,115 @@
 '''),
   ]),
 
+  const Group('List literal', const <TestSpec>[
+    const TestSpec('''
+main() {
+  return [];
+}
+''', '''
+(FunctionDefinition main ( return)
+  (LetPrim v0 (LiteralList ()))
+  (InvokeContinuation return v0))
+'''),
+
+    const TestSpec('''
+main() {
+  return [0];
+}
+''', '''
+(FunctionDefinition main ( return)
+  (LetPrim v0 (Constant IntConstant(0)))
+  (LetPrim v1 (LiteralList (v0)))
+  (InvokeContinuation return v1))
+'''),
+
+    const TestSpec('''
+main(a) {
+  return [0, 1, a];
+}
+''', '''
+(FunctionDefinition main (a return)
+  (LetPrim v0 (Constant IntConstant(0)))
+  (LetPrim v1 (Constant IntConstant(1)))
+  (LetPrim v2 (LiteralList (v0 v1 a)))
+  (InvokeContinuation return v2))
+'''),
+
+    const TestSpec('''
+main(a) {
+  return [0, [1], [a, [3]]];
+}
+''', '''
+(FunctionDefinition main (a return)
+  (LetPrim v0 (Constant IntConstant(0)))
+  (LetPrim v1 (Constant IntConstant(1)))
+  (LetPrim v2 (LiteralList (v1)))
+  (LetPrim v3 (Constant IntConstant(3)))
+  (LetPrim v4 (LiteralList (v3)))
+  (LetPrim v5 (LiteralList (a v4)))
+  (LetPrim v6 (LiteralList (v0 v2 v5)))
+  (InvokeContinuation return v6))
+'''),
+  ]),
+
+  const Group('Map literal', const <TestSpec>[
+    const TestSpec('''
+main() {
+  return {};
+}
+''', '''
+(FunctionDefinition main ( return)
+  (LetPrim v0 (LiteralMap () ()))
+  (InvokeContinuation return v0))
+'''),
+
+    const TestSpec('''
+main() {
+  return {"a": 0};
+}
+''', '''
+(FunctionDefinition main ( return)
+  (LetPrim v0 (Constant StringConstant("a")))
+  (LetPrim v1 (Constant IntConstant(0)))
+  (LetPrim v2 (LiteralMap (v0) (v1)))
+  (InvokeContinuation return v2))
+'''),
+
+    const TestSpec('''
+main(a) {
+  return {"a": 0, "b": 1, "c": a};
+}
+''', '''
+(FunctionDefinition main (a return)
+  (LetPrim v0 (Constant StringConstant("a")))
+  (LetPrim v1 (Constant IntConstant(0)))
+  (LetPrim v2 (Constant StringConstant("b")))
+  (LetPrim v3 (Constant IntConstant(1)))
+  (LetPrim v4 (Constant StringConstant("c")))
+  (LetPrim v5 (LiteralMap (v0 v2 v4) (v1 v3 a)))
+  (InvokeContinuation return v5))
+'''),
+
+    const TestSpec('''
+main(a) {
+  return {0: "a", 1: {2: "b"}, a: {3: "c"}};
+}
+''', '''
+(FunctionDefinition main (a return)
+  (LetPrim v0 (Constant IntConstant(0)))
+  (LetPrim v1 (Constant StringConstant("a")))
+  (LetPrim v2 (Constant IntConstant(1)))
+  (LetPrim v3 (Constant IntConstant(2)))
+  (LetPrim v4 (Constant StringConstant("b")))
+  (LetPrim v5 (LiteralMap (v3) (v4)))
+  (LetPrim v6 (Constant IntConstant(3)))
+  (LetPrim v7 (Constant StringConstant("c")))
+  (LetPrim v8 (LiteralMap (v6) (v7)))
+  (LetPrim v9 (LiteralMap (v0 v2 a) (v1 v5 v8)))
+  (InvokeContinuation return v9))
+'''),
+  ]),
+
   const Group('For loop', const <TestSpec>[
     const TestSpec('''
 main() {
@@ -836,7 +945,7 @@
 
 const TestSpec('''
 main() {
-  for (int i = 0; i < 10; i = i + 1) {
+  for (var i = 0; i < 10; i = i + 1) {
     print(i);
   }
 }
@@ -888,4 +997,208 @@
   (InvokeContinuation k0 v0))
 '''),
   ]),
+
+  const Group('While loop', const <TestSpec>[
+    const TestSpec('''
+main() {
+  while (true) {}
+}
+''', '''
+(FunctionDefinition main ( return)
+  (LetCont* (k0)
+    (LetPrim v0 (Constant BoolConstant(true)))
+    (LetCont (k1)
+      (LetPrim v1 (Constant NullConstant))
+      (InvokeContinuation return v1))
+    (LetCont (k2)
+      (InvokeContinuation* k0 ))
+    (Branch (IsTrue v0) k2 k1))
+  (InvokeContinuation k0 ))
+'''),
+
+const TestSpec('''
+main() {
+  var i = 0;
+  while (i < 10) {
+    print(i);
+    i = i + 1;
+  }
+}
+''', '''
+(FunctionDefinition main ( return)
+  (LetPrim v0 (Constant IntConstant(0)))
+  (LetCont* (k0 v1)
+    (LetPrim v2 (Constant IntConstant(10)))
+    (LetCont (k1 v3)
+      (LetCont (k2)
+        (LetPrim v4 (Constant NullConstant))
+        (InvokeContinuation return v4))
+      (LetCont (k3)
+        (LetCont (k4 v5)
+          (LetPrim v6 (Constant IntConstant(1)))
+          (LetCont (k5 v7)
+            (InvokeContinuation* k0 v7))
+          (InvokeMethod v1 + v6 k5))
+        (InvokeStatic print v1 k4))
+      (Branch (IsTrue v3) k3 k2))
+    (InvokeMethod v1 < v2 k1))
+  (InvokeContinuation k0 v0))
+'''),
+  ]),
+
+  const Group('Type operators', const <TestSpec>[
+    const TestSpec('''
+main(a) {
+  return a is String;
+}
+''', '''
+(FunctionDefinition main (a return)
+  (LetCont (k0 v0)
+    (InvokeContinuation return v0))
+  (TypeOperator is a String k0))
+'''),
+
+    const TestSpec('''
+main(a) {
+  return a is List<String>;
+}
+''', '''
+(FunctionDefinition main (a return)
+  (LetCont (k0 v0)
+    (InvokeContinuation return v0))
+  (TypeOperator is a List<String> k0))
+'''),
+
+    const TestSpec('''
+main(a) {
+  return a is Comparator<String>;
+}
+''', '''
+(FunctionDefinition main (a return)
+  (LetCont (k0 v0)
+    (InvokeContinuation return v0))
+  (TypeOperator is a Comparator<String> k0))
+'''),
+
+  const TestSpec('''
+main(a) {
+  return a is! String;
+}
+''', '''
+(FunctionDefinition main (a return)
+  (LetCont (k0 v0)
+    (LetCont (k1 v1)
+      (InvokeContinuation return v1))
+    (LetCont (k2)
+      (LetPrim v2 (Constant BoolConstant(false)))
+      (InvokeContinuation k1 v2))
+    (LetCont (k3)
+      (LetPrim v3 (Constant BoolConstant(true)))
+      (InvokeContinuation k1 v3))
+    (Branch (IsTrue v0) k2 k3))
+  (TypeOperator is a String k0))
+'''),
+
+const TestSpec('''
+main(a) {
+  return a as String;
+}
+''', '''
+(FunctionDefinition main (a return)
+  (LetCont (k0 v0)
+    (InvokeContinuation return v0))
+  (TypeOperator as a String k0))
+'''),
+  ]),
+
+  const Group('For in loop', const <TestSpec>[
+// TODO(johnniwinther): Add tests for `i` as top-level, static and instance
+// fields.
+    const TestSpec('''
+main(a) {
+  for (var i in a) {
+    print(i);
+  }
+}
+''', '''
+(FunctionDefinition main (a return)
+  (LetCont (k0 v0)
+    (LetCont* (k1 v1)
+      (LetCont (k2 v2)
+        (LetCont (k3)
+          (LetPrim v3 (Constant NullConstant))
+          (InvokeContinuation return v3))
+        (LetCont (k4)
+          (LetPrim v4 (Constant NullConstant))
+          (LetCont (k5 v5)
+            (LetCont (k6 v6)
+              (InvokeContinuation* k1 v1))
+            (InvokeStatic print v5 k6))
+          (InvokeMethod v0 current  k5))
+        (Branch (IsTrue v2) k4 k3))
+      (InvokeMethod v0 moveNext  k2))
+    (InvokeContinuation k1 a))
+  (InvokeMethod a iterator  k0))
+'''),
+
+    const TestSpec('''
+main(a) {
+  for (var i in a) {
+    print(i);
+    i = 0;
+    print(i);
+  }
+}
+''', '''
+(FunctionDefinition main (a return)
+  (LetCont (k0 v0)
+    (LetCont* (k1 v1)
+      (LetCont (k2 v2)
+        (LetCont (k3)
+          (LetPrim v3 (Constant NullConstant))
+          (InvokeContinuation return v3))
+        (LetCont (k4)
+          (LetPrim v4 (Constant NullConstant))
+          (LetCont (k5 v5)
+            (LetCont (k6 v6)
+              (LetPrim v7 (Constant IntConstant(0)))
+              (LetCont (k7 v8)
+                (InvokeContinuation* k1 v1))
+              (InvokeStatic print v7 k7))
+            (InvokeStatic print v5 k6))
+          (InvokeMethod v0 current  k5))
+        (Branch (IsTrue v2) k4 k3))
+      (InvokeMethod v0 moveNext  k2))
+    (InvokeContinuation k1 a))
+  (InvokeMethod a iterator  k0))
+'''),
+
+    const TestSpec('''
+main(a) {
+  var i;
+  for (i in a) {
+    print(i);
+  }
+}
+''', '''
+(FunctionDefinition main (a return)
+  (LetPrim v0 (Constant NullConstant))
+  (LetCont (k0 v1)
+    (LetCont* (k1 v2 v3)
+      (LetCont (k2 v4)
+        (LetCont (k3)
+          (LetPrim v5 (Constant NullConstant))
+          (InvokeContinuation return v5))
+        (LetCont (k4)
+          (LetCont (k5 v6)
+            (LetCont (k6 v7)
+              (InvokeContinuation* k1 v2 v6))
+            (InvokeStatic print v6 k6))
+          (InvokeMethod v1 current  k5))
+        (Branch (IsTrue v4) k4 k3))
+      (InvokeMethod v1 moveNext  k2))
+    (InvokeContinuation k1 a v0))
+  (InvokeMethod a iterator  k0))
+'''),
+  ]),
 ];
diff --git a/pkg/args/pubspec.yaml b/pkg/args/pubspec.yaml
index a19084c..4dd081d 100644
--- a/pkg/args/pubspec.yaml
+++ b/pkg/args/pubspec.yaml
@@ -1,5 +1,5 @@
 name: args
-version: 0.12.1-dev
+version: 0.12.1
 author: "Dart Team <misc@dartlang.org>"
 homepage: http://www.dartlang.org
 description: >
diff --git a/pkg/collection/CHANGELOG.md b/pkg/collection/CHANGELOG.md
index 1ed9863..6742b4c 100644
--- a/pkg/collection/CHANGELOG.md
+++ b/pkg/collection/CHANGELOG.md
@@ -1,3 +1,7 @@
+## 1.1.0
+
+* Add a `QueueList` class that implements both `Queue` and `List`.
+
 ## 0.9.4
 
 * Add a `CanonicalizedMap` class that canonicalizes its keys to provide a custom
diff --git a/pkg/collection/lib/collection.dart b/pkg/collection/lib/collection.dart
index d24dd39..45d3867 100644
--- a/pkg/collection/lib/collection.dart
+++ b/pkg/collection/lib/collection.dart
@@ -22,4 +22,5 @@
 export "iterable_zip.dart";
 export "priority_queue.dart";
 export "src/canonicalized_map.dart";
+export "src/queue_list.dart";
 export "wrappers.dart";
diff --git a/pkg/collection/lib/src/queue_list.dart b/pkg/collection/lib/src/queue_list.dart
new file mode 100644
index 0000000..0ef888f
--- /dev/null
+++ b/pkg/collection/lib/src/queue_list.dart
@@ -0,0 +1,231 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for 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 'dart:collection';
+
+/**
+ * A class that efficiently implements both [Queue] and [List].
+ */
+// TODO(nweiz): Currently this code is copied almost verbatim from
+// dart:collection. The only changes are to implement List and to remove methods
+// that are redundant with ListMixin. Remove or simplify it when issue 21330 is
+// fixed.
+class QueueList<E> extends Object with ListMixin<E> implements Queue<E> {
+  static const int _INITIAL_CAPACITY = 8;
+  List<E> _table;
+  int _head;
+  int _tail;
+
+  /**
+   * Create an empty queue.
+   *
+   * If [initialCapacity] is given, prepare the queue for at least that many
+   * elements.
+   */
+  QueueList([int initialCapacity]) : _head = 0, _tail = 0 {
+    if (initialCapacity == null || initialCapacity < _INITIAL_CAPACITY) {
+      initialCapacity = _INITIAL_CAPACITY;
+    } else if (!_isPowerOf2(initialCapacity)) {
+      initialCapacity = _nextPowerOf2(initialCapacity);
+    }
+    assert(_isPowerOf2(initialCapacity));
+    _table = new List<E>(initialCapacity);
+  }
+
+  /**
+   * Create a queue initially containing the elements of [source].
+   */
+  factory QueueList.from(Iterable<E> source) {
+    if (source is List) {
+      int length = source.length;
+      QueueList<E> queue = new QueueList(length + 1);
+      assert(queue._table.length > length);
+      List sourceList = source;
+      queue._table.setRange(0, length, sourceList, 0);
+      queue._tail = length;
+      return queue;
+    } else {
+      return new QueueList<E>()..addAll(source);
+    }
+  }
+
+  // Collection interface.
+
+  void add(E element) {
+    _add(element);
+  }
+
+  void addAll(Iterable<E> elements) {
+    if (elements is List) {
+      List list = elements;
+      int addCount = list.length;
+      int length = this.length;
+      if (length + addCount >= _table.length) {
+        _preGrow(length + addCount);
+        // After preGrow, all elements are at the start of the list.
+        _table.setRange(length, length + addCount, list, 0);
+        _tail += addCount;
+      } else {
+        // Adding addCount elements won't reach _head.
+        int endSpace = _table.length - _tail;
+        if (addCount < endSpace) {
+          _table.setRange(_tail, _tail + addCount, list, 0);
+          _tail += addCount;
+        } else {
+          int preSpace = addCount - endSpace;
+          _table.setRange(_tail, _tail + endSpace, list, 0);
+          _table.setRange(0, preSpace, list, endSpace);
+          _tail = preSpace;
+        }
+      }
+    } else {
+      for (E element in elements) _add(element);
+    }
+  }
+
+  String toString() => IterableBase.iterableToFullString(this, "{", "}");
+
+  // Queue interface.
+
+  void addLast(E element) { _add(element); }
+
+  void addFirst(E element) {
+    _head = (_head - 1) & (_table.length - 1);
+    _table[_head] = element;
+    if (_head == _tail) _grow();
+  }
+
+  E removeFirst() {
+    if (_head == _tail) throw new StateError("No element");
+    E result = _table[_head];
+    _table[_head] = null;
+    _head = (_head + 1) & (_table.length - 1);
+    return result;
+  }
+
+  E removeLast() {
+    if (_head == _tail) throw new StateError("No element");
+    _tail = (_tail - 1) & (_table.length - 1);
+    E result = _table[_tail];
+    _table[_tail] = null;
+    return result;
+  }
+
+  // List interface.
+
+  int get length => (_tail - _head) & (_table.length - 1);
+
+  void set length(int value) {
+    if (value < 0) throw new RangeError("Length $value may not be negative.");
+
+    int delta = value - length;
+    if (delta >= 0) {
+      if (_table.length <= value) {
+        _preGrow(value);
+      }
+      _tail = (_tail + delta) & (_table.length - 1);
+      return;
+    }
+
+    int newTail = _tail + delta; // [delta] is negative.
+    if (newTail >= 0) {
+      _table.fillRange(newTail, _tail, null);
+    } else { 
+      newTail += _table.length;
+      _table.fillRange(0, _tail, null);
+      _table.fillRange(newTail, _table.length, null);
+    }
+    _tail = newTail;
+  }
+
+  E operator [](int index) {
+    if (index < 0 || index >= length) {
+      throw new RangeError("Index $index must be in the range [0..$length).");
+    }
+
+    return _table[(_head + index) & (_table.length - 1)];
+  }
+
+  void operator[]=(int index, E value) {
+    if (index < 0 || index >= length) {
+      throw new RangeError("Index $index must be in the range [0..$length).");
+    }
+
+    _table[(_head + index) & (_table.length - 1)] = value;
+  }
+
+  // Internal helper functions.
+
+  /**
+   * Whether [number] is a power of two.
+   *
+   * Only works for positive numbers.
+   */
+  static bool _isPowerOf2(int number) => (number & (number - 1)) == 0;
+
+  /**
+   * Rounds [number] up to the nearest power of 2.
+   *
+   * If [number] is a power of 2 already, it is returned.
+   *
+   * Only works for positive numbers.
+   */
+  static int _nextPowerOf2(int number) {
+    assert(number > 0);
+    number = (number << 1) - 1;
+    for(;;) {
+      int nextNumber = number & (number - 1);
+      if (nextNumber == 0) return number;
+      number = nextNumber;
+    }
+  }
+
+  /** Adds element at end of queue. Used by both [add] and [addAll]. */
+  void _add(E element) {
+    _table[_tail] = element;
+    _tail = (_tail + 1) & (_table.length - 1);
+    if (_head == _tail) _grow();
+  }
+
+  /**
+   * Grow the table when full.
+   */
+  void _grow() {
+    List<E> newTable = new List<E>(_table.length * 2);
+    int split = _table.length - _head;
+    newTable.setRange(0, split, _table, _head);
+    newTable.setRange(split, split + _head, _table, 0);
+    _head = 0;
+    _tail = _table.length;
+    _table = newTable;
+  }
+
+  int _writeToList(List<E> target) {
+    assert(target.length >= length);
+    if (_head <= _tail) {
+      int length = _tail - _head;
+      target.setRange(0, length, _table, _head);
+      return length;
+    } else {
+      int firstPartSize = _table.length - _head;
+      target.setRange(0, firstPartSize, _table, _head);
+      target.setRange(firstPartSize, firstPartSize + _tail, _table, 0);
+      return _tail + firstPartSize;
+    }
+  }
+
+  /** Grows the table even if it is not full. */
+  void _preGrow(int newElementCount) {
+    assert(newElementCount >= length);
+
+    // Add 1.5x extra room to ensure that there's room for more elements after
+    // expansion.
+    newElementCount += newElementCount >> 1;
+    int newCapacity = _nextPowerOf2(newElementCount);
+    List<E> newTable = new List<E>(newCapacity);
+    _tail = _writeToList(newTable);
+    _table = newTable;
+    _head = 0;
+  }
+}
diff --git a/pkg/collection/pubspec.yaml b/pkg/collection/pubspec.yaml
index 9ec80f4..b4396b9 100644
--- a/pkg/collection/pubspec.yaml
+++ b/pkg/collection/pubspec.yaml
@@ -1,5 +1,5 @@
 name: collection
-version: 1.0.0
+version: 1.1.0
 author: Dart Team <misc@dartlang.org>
 description: Collections and utilities functions and classes related to collections.
 homepage: http://www.dartlang.org
diff --git a/pkg/collection/test/queue_list_test.dart b/pkg/collection/test/queue_list_test.dart
new file mode 100644
index 0000000..6b213c8
--- /dev/null
+++ b/pkg/collection/test/queue_list_test.dart
@@ -0,0 +1,276 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for 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 "package:collection/collection.dart";
+import "package:unittest/unittest.dart";
+
+void main() {
+  group("new QueueList()", () {
+    test("creates an empty QueueList", () {
+      expect(new QueueList(), isEmpty);
+    });
+
+    test("takes an initial capacity", () {
+      expect(new QueueList(100), isEmpty);
+    });
+  });
+
+  test("new QueueList.from() copies the contents of an iterable", () {
+    expect(new QueueList.from([1, 2, 3].skip(1)), equals([2, 3]));
+  });
+
+  group("add()", () {
+    test("adds an element to the end of the queue", () {
+      var queue = new QueueList.from([1, 2, 3]);
+      queue.add(4);
+      expect(queue, equals([1, 2, 3, 4]));
+    });
+
+    test("expands a full queue", () {
+      var queue = atCapacity();
+      queue.add(8);
+      expect(queue, equals([1, 2, 3, 4, 5, 6, 7, 8]));
+    });
+  });
+
+  group("addAll()", () {
+    test("adds elements to the end of the queue", () {
+      var queue = new QueueList.from([1, 2, 3]);
+      queue.addAll([4, 5, 6]);
+      expect(queue, equals([1, 2, 3, 4, 5, 6]));
+    });
+
+    test("expands a full queue", () {
+      var queue = atCapacity();
+      queue.addAll([8, 9]);
+      expect(queue, equals([1, 2, 3, 4, 5, 6, 7, 8, 9]));
+    });
+  });
+
+  group("addFirst()", () {
+    test("adds an element to the beginning of the queue", () {
+      var queue = new QueueList.from([1, 2, 3]);
+      queue.addFirst(0);
+      expect(queue, equals([0, 1, 2, 3]));
+    });
+
+    test("expands a full queue", () {
+      var queue = atCapacity();
+      queue.addFirst(0);
+      expect(queue, equals([0, 1, 2, 3, 4, 5, 6, 7]));
+    });
+  });
+
+  group("removeFirst()", () {
+    test("removes an element from the beginning of the queue", () {
+      var queue = new QueueList.from([1, 2, 3]);
+      expect(queue.removeFirst(), equals(1));
+      expect(queue, equals([2, 3]));
+    });
+
+    test("removes an element from the beginning of a queue with an internal "
+        "gap", () {
+      var queue = withInternalGap();
+      expect(queue.removeFirst(), equals(1));
+      expect(queue, equals([2, 3, 4, 5, 6, 7]));
+    });
+
+    test("removes an element from the beginning of a queue at capacity", () {
+      var queue = atCapacity();
+      expect(queue.removeFirst(), equals(1));
+      expect(queue, equals([2, 3, 4, 5, 6, 7]));
+    });
+
+    test("throws a StateError for an empty queue", () {
+      expect(new QueueList().removeFirst, throwsStateError);
+    });
+  });
+
+  group("removeLast()", () {
+    test("removes an element from the end of the queue", () {
+      var queue = new QueueList.from([1, 2, 3]);
+      expect(queue.removeLast(), equals(3));
+      expect(queue, equals([1, 2]));
+    });
+
+    test("removes an element from the end of a queue with an internal gap", () {
+      var queue = withInternalGap();
+      expect(queue.removeLast(), equals(7));
+      expect(queue, equals([1, 2, 3, 4, 5, 6]));
+    });
+
+    test("removes an element from the end of a queue at capacity", () {
+      var queue = atCapacity();
+      expect(queue.removeLast(), equals(7));
+      expect(queue, equals([1, 2, 3, 4, 5, 6]));
+    });
+
+    test("throws a StateError for an empty queue", () {
+      expect(new QueueList().removeLast, throwsStateError);
+    });
+  });
+
+  group("length", () {
+    test("returns the length of a queue", () {
+      expect(new QueueList.from([1, 2, 3]).length, equals(3));
+    });
+
+    test("returns the length of a queue with an internal gap", () {
+      expect(withInternalGap().length, equals(7));
+    });
+
+    test("returns the length of a queue at capacity", () {
+      expect(atCapacity().length, equals(7));
+    });
+  });
+
+  group("length=", () {
+    test("shrinks a larger queue", () {
+      var queue = new QueueList.from([1, 2, 3]);
+      queue.length = 1;
+      expect(queue, equals([1]));
+    });
+
+    test("grows a smaller queue", () {
+      var queue = new QueueList.from([1, 2, 3]);
+      queue.length = 5;
+      expect(queue, equals([1, 2, 3, null, null]));
+    });
+
+    test("throws a RangeError if length is less than 0", () {
+      expect(() => new QueueList().length = -1, throwsRangeError);
+    });
+  });
+
+  group("[]", () {
+    test("returns individual entries in the queue", () {
+      var queue = new QueueList.from([1, 2, 3]);
+      expect(queue[0], equals(1));
+      expect(queue[1], equals(2));
+      expect(queue[2], equals(3));
+    });
+
+    test("returns individual entries in a queue with an internal gap", () {
+      var queue = withInternalGap();
+      expect(queue[0], equals(1));
+      expect(queue[1], equals(2));
+      expect(queue[2], equals(3));
+      expect(queue[3], equals(4));
+      expect(queue[4], equals(5));
+      expect(queue[5], equals(6));
+      expect(queue[6], equals(7));
+    });
+
+    test("throws a RangeError if the index is less than 0", () {
+      var queue = new QueueList.from([1, 2, 3]);
+      expect(() => queue[-1], throwsRangeError);
+    });
+
+    test("throws a RangeError if the index is greater than or equal to the "
+        "length", () {
+      var queue = new QueueList.from([1, 2, 3]);
+      expect(() => queue[3], throwsRangeError);
+    });
+  });
+
+  group("[]=", () {
+    test("sets individual entries in the queue", () {
+      var queue = new QueueList.from([1, 2, 3]);
+      queue[0] = "a";
+      queue[1] = "b";
+      queue[2] = "c";
+      expect(queue, equals(["a", "b", "c"]));
+    });
+
+    test("sets individual entries in a queue with an internal gap", () {
+      var queue = withInternalGap();
+      queue[0] = "a";
+      queue[1] = "b";
+      queue[2] = "c";
+      queue[3] = "d";
+      queue[4] = "e";
+      queue[5] = "f";
+      queue[6] = "g";
+      expect(queue, equals(["a", "b", "c", "d", "e", "f", "g"]));
+    });
+
+    test("throws a RangeError if the index is less than 0", () {
+      var queue = new QueueList.from([1, 2, 3]);
+      expect(() {
+        queue[-1] = 0;
+      }, throwsRangeError);
+    });
+
+    test("throws a RangeError if the index is greater than or equal to the "
+        "length", () {
+      var queue = new QueueList.from([1, 2, 3]);
+      expect(() {
+        queue[3] = 4;
+      }, throwsRangeError);
+    });
+  });
+
+  group("throws a modification error for", () {
+    var queue;
+    setUp(() {
+      queue = new QueueList.from([1, 2, 3]);
+    });
+
+    test("add", () {
+      expect(() => queue.forEach((_) => queue.add(4)),
+          throwsConcurrentModificationError);
+    });
+
+    test("addAll", () {
+      expect(() => queue.forEach((_) => queue.addAll([4, 5, 6])),
+          throwsConcurrentModificationError);
+    });
+
+    test("addFirst", () {
+      expect(() => queue.forEach((_) => queue.addFirst(0)),
+          throwsConcurrentModificationError);
+    });
+
+    test("removeFirst", () {
+      expect(() => queue.forEach((_) => queue.removeFirst()),
+          throwsConcurrentModificationError);
+    });
+
+    test("removeLast", () {
+      expect(() => queue.forEach((_) => queue.removeLast()),
+          throwsConcurrentModificationError);
+    });
+
+    test("length=", () {
+      expect(() => queue.forEach((_) => queue.length = 1),
+          throwsConcurrentModificationError);
+    });
+  });
+}
+
+/// Returns a queue whose internal ring buffer is full enough that adding a new
+/// element will expand it.
+QueueList atCapacity() {
+  // Use addAll because [new QueueList.from(List)] won't use the default initial
+  // capacity of 8.
+  return new QueueList()..addAll([1, 2, 3, 4, 5, 6, 7]);
+}
+
+/// Returns a queue whose internal tail has a lower index than its head.
+QueueList withInternalGap() {
+  var queue = new QueueList.from([null, null, null, null, 1, 2, 3, 4]);
+  for (var i = 0; i < 4; i++) {
+    queue.removeFirst();
+  }
+  for (var i = 5; i < 8; i++) {
+    queue.addLast(i);
+  }
+  return queue;
+}
+
+/// Returns a matcher that expects that a closure throws a
+/// [ConcurrentModificationError].
+final throwsConcurrentModificationError = throwsA(
+    new isInstanceOf<ConcurrentModificationError>(
+        "ConcurrentModificationError"));
diff --git a/pkg/csslib/lib/parser.dart b/pkg/csslib/lib/parser.dart
index 8fbf06e..282fe59 100644
--- a/pkg/csslib/lib/parser.dart
+++ b/pkg/csslib/lib/parser.dart
@@ -2093,7 +2093,7 @@
     return expressions;
   }
 
-  static final int MAX_UNICODE = int.parse('0x10FFFF');
+  static const int MAX_UNICODE = 0x10FFFF;
 
   //  Term grammar:
   //
diff --git a/pkg/custom_element/AUTHORS b/pkg/custom_element/AUTHORS
deleted file mode 100644
index 0617765..0000000
--- a/pkg/custom_element/AUTHORS
+++ /dev/null
@@ -1,9 +0,0 @@
-# Names should be added to this file with this pattern:
-#
-# For individuals:
-#   Name <email address>
-#
-# For organizations:
-#   Organization <fnmatch pattern>
-#
-Google Inc. <*@google.com>
diff --git a/pkg/custom_element/LICENSE b/pkg/custom_element/LICENSE
deleted file mode 100644
index 92d60b0..0000000
--- a/pkg/custom_element/LICENSE
+++ /dev/null
@@ -1,27 +0,0 @@
-// Copyright (c) 2012 The Polymer Authors. All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//    * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//    * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//    * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/pkg/custom_element/PATENTS b/pkg/custom_element/PATENTS
deleted file mode 100644
index e120963..0000000
--- a/pkg/custom_element/PATENTS
+++ /dev/null
@@ -1,23 +0,0 @@
-Additional IP Rights Grant (Patents)
-
-"This implementation" means the copyrightable works distributed by
-Google as part of the Polymer project.
-
-Google 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,
-transfer and otherwise run, modify and propagate the contents of this
-implementation of Polymer, where such license applies only to those
-patent claims, both currently owned or controlled by Google and acquired
-in the future, licensable by Google that are necessarily infringed by
-this implementation of Polymer.  This grant does not include claims
-that would be infringed only as a consequence of further modification of
-this implementation.  If you or your agent or exclusive licensee
-institute or order or agree to the institution of patent litigation
-against any entity (including a cross-claim or counterclaim in a
-lawsuit) alleging that this implementation of Polymer or any code
-incorporated within this implementation of Polymer constitutes
-direct or contributory patent infringement, or inducement of patent
-infringement, then any patent rights granted to you under this License
-for this implementation of Polymer shall terminate as of the date
-such litigation is filed.
diff --git a/pkg/custom_element/lib/custom_element.dart b/pkg/custom_element/lib/custom_element.dart
deleted file mode 100644
index 4fc679f..0000000
--- a/pkg/custom_element/lib/custom_element.dart
+++ /dev/null
@@ -1,500 +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.
-
-/**
- * Custom DOM elements.
- *
- * This library provides access to the Polymer project's
- * [Custom Elements]
- * (http://www.polymer-project.org/platform/custom-elements.html)
- * API, which lets you define your own elements. With custom elements, you
- * associate code with custom tag names, and then use those custom tag names
- * as you would any standard tag. For more information, see the
- * [Polymer.dart homepage](https://www.dartlang.org/polymer-dart/) and its
- * [custom element example]
- * (https://www.dartlang.org/polymer-dart/#custom-elements).
- */
-library custom_element;
-
-import 'dart:html';
-import 'dart:async';
-
-/**
- * *Deprecated* -- do not use. Extend [HtmlElement] and use
- * [document.register] instead. If running on a browser without native
- * document.register, you can add the polyfill script to your page:
- *
- *     <script src="packages/custom_element/custom-elements.debug.js"></script>
- *
- * You can also use "custom-elements.min.js" for the minified version.
- */
-// This is only used by Dart Web UI.
-class CustomElement implements Element {
-  /** The web component element wrapped by this class. */
-  Element _host;
-  List _shadowRoots;
-
-  /**
-   * Shadow roots generated by dwc for each custom element, indexed by the
-   * custom element tag name.
-   */
-  Map<String, dynamic> _generatedRoots = {};
-
-  /**
-   * Temporary property until components extend [Element]. An element can
-   * only be associated with one host, and it is an error to use a web component
-   * without an associated host element.
-   */
-  Element get host {
-    if (_host == null) throw new StateError('host element has not been set.');
-    return _host;
-  }
-
-  set host(Element value) {
-    if (value == null) {
-      throw new ArgumentError('host must not be null.');
-    }
-    // TODO(jmesserly): xtag used to return "null" if unset, now it checks for
-    // "this". Temporarily allow both.
-    var xtag = value.xtag;
-    if (xtag != null && xtag != value) {
-      throw new ArgumentError('host must not have its xtag property set.');
-    }
-    if (_host != null) {
-      throw new StateError('host can only be set once.');
-    }
-
-    value.xtag = this;
-    _host = value;
-  }
-
-  /**
-   * **Note**: This is an implementation helper and should not need to be called
-   * from your code.
-   *
-   * Creates the [ShadowRoot] backing this component.
-   */
-  createShadowRoot([String componentName]) {
-    var root = host.createShadowRoot();
-    if (componentName != null) {
-      _generatedRoots[componentName] = root;
-    }
-    return root;
-  }
-
-  getShadowRoot(String componentName) => _generatedRoots[componentName];
-
-  /**
-   * Invoked when this component gets created.
-   * Note that [root] will be a [ShadowRoot] if the browser supports Shadow DOM.
-   */
-  void created() {}
-  // Added for analyzer warnings
-  @deprecated
-  void createdCallback() {}
-
-  /** Invoked when this component gets inserted in the DOM tree. */
-  void inserted() {}
-  @deprecated
-  void enteredView() {}
-  @deprecated
-  void attached() {}
-
-  /** Invoked when this component is removed from the DOM tree. */
-  void removed() {}
-  @deprecated
-  void leftView() {}
-  @deprecated
-  void detached() {}
-
-  /** Invoked when any attribute of the component is modified. */
-  void attributeChanged(String name, String oldValue, String newValue) =>
-      host.attributeChanged(name, oldValue, newValue);
-
-  // TODO(efortuna): Update these when we decide what to do with these
-  // properties.
-  @deprecated
-  String getAttribute(String name) =>
-      host.getAttribute(name);
-
-  @deprecated
-  String getAttributeNS(String namespaceUri, String localName) =>
-      host.getAttributeNS(namespaceUri, localName);
-
-  @deprecated
-  void setAttributeNS(
-      String namespaceUri, String localName, String value) {
-    host.setAttributeNS(namespaceUri, localName, value);
-  }
-
-  @deprecated
-  void setAttribute(String name, String value) =>
-      host.setAttribute(name, value);
-
-  @deprecated
-  List<Node> get childNodes => host.childNodes;
-
-  // TODO(jmesserly): this forwarding is temporary until Dart supports
-  // subclassing Elements.
-  // TODO(jmesserly): we were missing the setter for title, are other things
-  // missing setters?
-
-  List<Node> get nodes => host.nodes;
-
-  set nodes(Iterable<Node> value) { host.nodes = value; }
-
-  /**
-   * Replaces this node with another node.
-   */
-  Node replaceWith(Node otherNode) => host.replaceWith(otherNode);
-
-  /**
-   * Removes this node from the DOM.
-   */
-  void remove() => host.remove();
-
-  Node get nextNode => host.nextNode;
-
-  String get nodeName => host.nodeName;
-
-  Document get ownerDocument => host.ownerDocument;
-
-  Node get previousNode => host.previousNode;
-
-  String get text => host.text;
-
-  set text(String v) { host.text = v; }
-
-  bool contains(Node other) => host.contains(other);
-
-  bool hasChildNodes() => host.hasChildNodes();
-
-  Node insertBefore(Node newChild, Node refChild) =>
-    host.insertBefore(newChild, refChild);
-
-  Node insertAllBefore(Iterable<Node> newChild, Node refChild) =>
-    host.insertAllBefore(newChild, refChild);
-
-  Map<String, String> get attributes => host.attributes;
-  set attributes(Map<String, String> value) {
-    host.attributes = value;
-  }
-
-  List<Element> get elements => host.children;
-
-  set elements(List<Element> value) {
-    host.children = value;
-  }
-
-  String get baseUri => host.baseUri;
-
-  List<Element> get children => host.children;
-
-  set children(List<Element> value) {
-    host.children = value;
-  }
-
-  Set<String> get classes => host.classes;
-
-  set classes(Iterable<String> value) {
-    host.classes = value;
-  }
-
-  CssRect get contentEdge => host.contentEdge;
-  CssRect get paddingEdge => host.paddingEdge;
-  CssRect get borderEdge => host.borderEdge;
-  CssRect get marginEdge => host.marginEdge;
-  Point get documentOffset => host.documentOffset;
-  Point offsetTo(Element parent) => host.offsetTo(parent);
-
-  Map<String, String> getNamespacedAttributes(String namespace) =>
-      host.getNamespacedAttributes(namespace);
-
-  CssStyleDeclaration getComputedStyle([String pseudoElement])
-    => host.getComputedStyle(pseudoElement);
-
-  Element clone(bool deep) => host.clone(deep);
-
-  Element get parent => host.parent;
-
-  Node get parentNode => host.parentNode;
-
-  String get nodeValue => host.nodeValue;
-
-  Events get on => host.on;
-
-  String get contentEditable => host.contentEditable;
-  set contentEditable(String v) { host.contentEditable = v; }
-
-  String get dir => host.dir;
-  set dir(String v) { host.dir = v; }
-
-  bool get draggable => host.draggable;
-  set draggable(bool v) { host.draggable = v; }
-
-  bool get hidden => host.hidden;
-  set hidden(bool v) { host.hidden = v; }
-
-  String get id => host.id;
-  set id(String v) { host.id = v; }
-
-  String get innerHtml => host.innerHtml;
-  void set innerHtml(String v) {
-    host.innerHtml = v;
-  }
-
-  void setInnerHtml(String html,
-    {NodeValidator validator, NodeTreeSanitizer treeSanitizer}) {
-    host.setInnerHtml(html, validator: validator, treeSanitizer: treeSanitizer);
-  }
-
-  DocumentFragment createFragment(String html,
-      {NodeValidator validator, NodeTreeSanitizer treeSanitizer}) =>
-    host.createFragment(html,
-        validator: validator, treeSanitizer: treeSanitizer);
-
-  bool get isContentEditable => host.isContentEditable;
-
-  String get lang => host.lang;
-  set lang(String v) { host.lang = v; }
-
-  String get outerHtml => host.outerHtml;
-
-  bool get spellcheck => host.spellcheck;
-  set spellcheck(bool v) { host.spellcheck = v; }
-
-  int get tabIndex => host.tabIndex;
-  set tabIndex(int i) { host.tabIndex = i; }
-
-  String get title => host.title;
-
-  set title(String value) { host.title = value; }
-
-  bool get translate => host.translate;
-  set translate(bool v) { host.translate = v; }
-
-  String get dropzone => host.dropzone;
-  set dropzone(String v) { host.dropzone = v; }
-
-  void click() { host.click(); }
-
-  List<Node> getDestinationInsertionPoints() =>
-    host.getDestinationInsertionPoints();
-
-  Element insertAdjacentElement(String where, Element element) =>
-    host.insertAdjacentElement(where, element);
-
-  void insertAdjacentHtml(String where, String html) {
-    host.insertAdjacentHtml(where, html);
-  }
-
-  void insertAdjacentText(String where, String text) {
-    host.insertAdjacentText(where, text);
-  }
-
-  Map<String, String> get dataset => host.dataset;
-
-  set dataset(Map<String, String> value) {
-    host.dataset = value;
-  }
-
-  Element get nextElementSibling => host.nextElementSibling;
-
-  Element get offsetParent => host.offsetParent;
-
-  Element get previousElementSibling => host.previousElementSibling;
-
-  CssStyleDeclaration get style => host.style;
-
-  String get tagName => host.tagName;
-
-  // Note: we are not polyfilling the shadow root here. This will be fixed when
-  // we migrate to the JS Shadow DOM polyfills. You can still use getShadowRoot
-  // to retrieve a node that behaves as the shadow root when Shadow DOM is not
-  // enabled.
-  ShadowRoot get shadowRoot => host.shadowRoot;
-
-  void blur() { host.blur(); }
-
-  void focus() { host.focus(); }
-
-  void scrollByLines(int lines) {
-    host.scrollByLines(lines);
-  }
-
-  void scrollByPages(int pages) {
-    host.scrollByPages(pages);
-  }
-
-  void scrollIntoView([ScrollAlignment alignment]) {
-    host.scrollIntoView(alignment);
-  }
-
-  bool matches(String selectors) => host.matches(selectors);
-
-  bool matchesWithAncestors(String selectors) =>
-      host.matchesWithAncestors(selectors);
-
-  @deprecated
-  void requestFullScreen(int flags) { requestFullscreen(); }
-
-  void requestFullscreen() { host.requestFullscreen(); }
-
-  void requestPointerLock() { host.requestPointerLock(); }
-
-  Element querySelector(String selectors) => host.querySelector(selectors);
-
-  ElementList querySelectorAll(String selectors) =>
-      host.querySelectorAll(selectors);
-
-  @deprecated
-  Element query(String selectors) => host.querySelector(selectors);
-
-  @deprecated
-  ElementList queryAll(String selectors) => host.querySelectorAll(selectors);
-
-  String get className => host.className;
-  set className(String value) { host.className = value; }
-
-  @deprecated
-  int get clientHeight => client.height;
-
-  @deprecated
-  int get clientLeft => client.left;
-
-  @deprecated
-  int get clientTop => client.top;
-
-  @deprecated
-  int get clientWidth => client.width;
-
-  Rectangle get client => host.client;
-
-  @deprecated
-  int get offsetHeight => offset.height;
-
-  @deprecated
-  int get offsetLeft => offset.left;
-
-  @deprecated
-  int get offsetTop => offset.top;
-
-  @deprecated
-  int get offsetWidth => offset.width;
-
-  Rectangle get offset => host.offset;
-
-  int get scrollHeight => host.scrollHeight;
-
-  int get scrollLeft => host.scrollLeft;
-
-  int get scrollTop => host.scrollTop;
-
-  set scrollLeft(int value) { host.scrollLeft = value; }
-
-  set scrollTop(int value) { host.scrollTop = value; }
-
-  int get scrollWidth => host.scrollWidth;
-
-  Rectangle getBoundingClientRect() => host.getBoundingClientRect();
-
-  List<Rectangle> getClientRects() => host.getClientRects();
-
-  List<Node> getElementsByClassName(String name) =>
-      host.getElementsByClassName(name);
-
-  Node get firstChild => host.firstChild;
-
-  Node get lastChild => host.lastChild;
-
-  String get localName => host.localName;
-
-  String get namespaceUri => host.namespaceUri;
-
-  int get nodeType => host.nodeType;
-
-  void addEventListener(String type, EventListener listener,
-      [bool useCapture]) {
-    host.addEventListener(type, listener, useCapture);
-  }
-
-  bool dispatchEvent(Event event) => host.dispatchEvent(event);
-
-  void removeEventListener(String type, EventListener listener,
-      [bool useCapture]) {
-    host.removeEventListener(type, listener, useCapture);
-  }
-
-  get xtag => host.xtag;
-
-  set xtag(value) { host.xtag = value; }
-
-  Node append(Node e) => host.append(e);
-
-  void appendText(String text) => host.appendText(text);
-
-  void appendHtml(String html) => host.appendHtml(html);
-
-  Animation animate(List<Map> keyframes, [num duration]) =>
-      host.animate(keyframes, duration);
-
-  // TODO(jmesserly): rename "created" to "onCreated".
-  void onCreated() => created();
-
-  Stream<Event> get onAbort => host.onAbort;
-  Stream<Event> get onBeforeCopy => host.onBeforeCopy;
-  Stream<Event> get onBeforeCut => host.onBeforeCut;
-  Stream<Event> get onBeforePaste => host.onBeforePaste;
-  Stream<Event> get onBlur => host.onBlur;
-  Stream<Event> get onChange => host.onChange;
-  Stream<MouseEvent> get onClick => host.onClick;
-  Stream<MouseEvent> get onContextMenu => host.onContextMenu;
-  Stream<Event> get onCopy => host.onCopy;
-  Stream<Event> get onCut => host.onCut;
-  Stream<Event> get onDoubleClick => host.onDoubleClick;
-  Stream<MouseEvent> get onDrag => host.onDrag;
-  Stream<MouseEvent> get onDragEnd => host.onDragEnd;
-  Stream<MouseEvent> get onDragEnter => host.onDragEnter;
-  Stream<MouseEvent> get onDragLeave => host.onDragLeave;
-  Stream<MouseEvent> get onDragOver => host.onDragOver;
-  Stream<MouseEvent> get onDragStart => host.onDragStart;
-  Stream<MouseEvent> get onDrop => host.onDrop;
-  Stream<Event> get onError => host.onError;
-  Stream<Event> get onFocus => host.onFocus;
-  Stream<Event> get onInput => host.onInput;
-  Stream<Event> get onInvalid => host.onInvalid;
-  Stream<KeyboardEvent> get onKeyDown => host.onKeyDown;
-  Stream<KeyboardEvent> get onKeyPress => host.onKeyPress;
-  Stream<KeyboardEvent> get onKeyUp => host.onKeyUp;
-  Stream<Event> get onLoad => host.onLoad;
-  Stream<MouseEvent> get onMouseDown => host.onMouseDown;
-  Stream<MouseEvent> get onMouseEnter => host.onMouseEnter;
-  Stream<MouseEvent> get onMouseLeave => host.onMouseLeave;
-  Stream<MouseEvent> get onMouseMove => host.onMouseMove;
-  Stream<Event> get onFullscreenChange => host.onFullscreenChange;
-  Stream<Event> get onFullscreenError => host.onFullscreenError;
-  Stream<Event> get onPaste => host.onPaste;
-  Stream<Event> get onReset => host.onReset;
-  Stream<Event> get onResize => host.onResize;
-  Stream<Event> get onScroll => host.onScroll;
-  Stream<Event> get onSearch => host.onSearch;
-  Stream<Event> get onSelect => host.onSelect;
-  Stream<Event> get onSelectStart => host.onSelectStart;
-  Stream<Event> get onSubmit => host.onSubmit;
-  Stream<MouseEvent> get onMouseOut => host.onMouseOut;
-  Stream<MouseEvent> get onMouseOver => host.onMouseOver;
-  Stream<MouseEvent> get onMouseUp => host.onMouseUp;
-  Stream<TouchEvent> get onTouchCancel => host.onTouchCancel;
-  Stream<TouchEvent> get onTouchEnd => host.onTouchEnd;
-  Stream<TouchEvent> get onTouchEnter => host.onTouchEnter;
-  Stream<TouchEvent> get onTouchLeave => host.onTouchLeave;
-  Stream<TouchEvent> get onTouchMove => host.onTouchMove;
-  Stream<TouchEvent> get onTouchStart => host.onTouchStart;
-  Stream<TransitionEvent> get onTransitionEnd => host.onTransitionEnd;
-
-  // TODO(sigmund): do the normal forwarding when dartbug.com/7919 is fixed.
-  Stream<WheelEvent> get onMouseWheel {
-    throw new UnsupportedError('onMouseWheel is not supported');
-  }
-}
diff --git a/pkg/custom_element/lib/src/custom_tag_name.dart b/pkg/custom_element/lib/src/custom_tag_name.dart
deleted file mode 100644
index 72d9150..0000000
--- a/pkg/custom_element/lib/src/custom_tag_name.dart
+++ /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.
-
-library custom_element.src.custom_tag_name;
-
-/**
- * Returns true if this is a valid custom element name. See:
- * <https://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/custom/index.html#dfn-custom-element-name>
- */
-bool isCustomTag(String name) {
-  if (!name.contains('-')) return false;
-
-  // These names have meaning in SVG or MathML, so they aren't allowed as custom
-  // tags.
-  var invalidNames = const {
-    'annotation-xml': '',
-    'color-profile': '',
-    'font-face': '',
-    'font-face-src': '',
-    'font-face-uri': '',
-    'font-face-format': '',
-    'font-face-name': '',
-    'missing-glyph': '',
-  };
-  return !invalidNames.containsKey(name);
-}
diff --git a/pkg/custom_element/pubspec.yaml b/pkg/custom_element/pubspec.yaml
deleted file mode 100644
index b6baadf..0000000
--- a/pkg/custom_element/pubspec.yaml
+++ /dev/null
@@ -1,11 +0,0 @@
-name: custom_element
-version: 0.10.1
-author: "Polymer.dart Team <web-ui-dev@dartlang.org>"
-homepage: http://www.dartlang.org/
-description: >
-  *Deprecated* newer version is in web_components package. This is for backwards
-  compatibility with polymer.dart 0.4.x (web_ui package).
-dev_dependencies:
-  unittest: ">=0.10.0 <0.11.0"
-environment:
-  sdk: ">=1.3.0-dev.7.5 <2.0.0"
diff --git a/pkg/custom_element/test/analyzer_test.dart b/pkg/custom_element/test/analyzer_test.dart
deleted file mode 100644
index 0cbe620..0000000
--- a/pkg/custom_element/test/analyzer_test.dart
+++ /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.
-
-library custom_element.test.analyzer_test;
-
-import 'package:custom_element/custom_element.dart';
-
-// This test ensures CustomElement compiles without errors.
-void main() {
-}
diff --git a/pkg/dart2js_incremental/lib/library_updater.dart b/pkg/dart2js_incremental/lib/library_updater.dart
index 04d1ba3..b2a8595 100644
--- a/pkg/dart2js_incremental/lib/library_updater.dart
+++ b/pkg/dart2js_incremental/lib/library_updater.dart
@@ -305,20 +305,26 @@
     }
     String name = info.name;
     jsAst.Node function = info.code;
-    jsAst.Node elementAccess = namer.elementAccess(element);
-    jsAst.Expression globalFunctionsAccess =
-        emitter.generateEmbeddedGlobalAccess(embeddedNames.GLOBAL_FUNCTIONS);
     List<jsAst.Statement> statements = <jsAst.Statement>[];
-    statements.add(
-        js.statement(
-            '#.# = # = f',
-            [globalFunctionsAccess, name, elementAccess]));
-    if (info.canTearOff) {
-      String globalName = namer.globalObjectFor(element);
+    if (element.isInstanceMember) {
+      jsAst.Node elementAccess = namer.elementAccess(element.enclosingClass);
+      statements.add(
+          js.statement('#.prototype.# = f', [elementAccess, name]));
+    } else {
+      jsAst.Node elementAccess = namer.elementAccess(element);
+      jsAst.Expression globalFunctionsAccess =
+          emitter.generateEmbeddedGlobalAccess(embeddedNames.GLOBAL_FUNCTIONS);
       statements.add(
           js.statement(
-              '#.#().# = f',
-              [globalName, info.tearOffName, callNameFor(element)]));
+              '#.# = # = f',
+              [globalFunctionsAccess, name, elementAccess]));
+      if (info.canTearOff) {
+        String globalName = namer.globalObjectFor(element);
+        statements.add(
+            js.statement(
+                '#.#().# = f',
+                [globalName, info.tearOffName, callNameFor(element)]));
+      }
     }
     // Create a scope by creating a new function. The updated function literal
     // is passed as an argument to this function which ensures that temporary
diff --git a/pkg/docgen/test/async_await_test.dart b/pkg/docgen/test/async_await_test.dart
new file mode 100644
index 0000000..e129455
--- /dev/null
+++ b/pkg/docgen/test/async_await_test.dart
@@ -0,0 +1,150 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for 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 async_await_test;
+
+import 'dart:io';
+
+import 'package:path/path.dart' as path;
+import 'package:unittest/unittest.dart';
+
+import '../lib/src/exports/mirrors_util.dart' as dart2js_util;
+import '../lib/docgen.dart';
+
+const String DART_LIBRARY = '''
+  library test;
+  /**
+   * Doc comment for class [A].
+   *
+   * Multiline Test
+   */
+  /*
+   * Normal comment for class A.
+   */
+  class A {
+    m1() sync* {
+      yield 0;
+    }
+
+    m2() async {
+      await 0;
+      await for (var e in m1()) {}
+    }
+
+    m3() async* {
+      yield* m1();
+    }
+  }
+
+  m1() sync* {
+    yield 0;
+  }
+
+  m2() async {
+    await 0;
+    await for (var e in m1()) {}
+  }
+
+  m3() async* {
+    yield* m1();
+  }
+
+  main() {
+    m1();
+    m2();
+    m3();
+    A a = new A();
+    a.m1();
+    a.m2();
+    a.m3();
+  }
+''';
+
+main() {
+  group('Generate docs for', () {
+    test('file with async/await.', () {
+      var temporaryDir = Directory.systemTemp.createTempSync('single_library_');
+      var fileName = path.join(temporaryDir.path, 'temp.dart');
+      var file = new File(fileName);
+      file.writeAsStringSync(DART_LIBRARY);
+
+      return getMirrorSystem([new Uri.file(fileName)], false)
+        .then((mirrorSystem) {
+          var testLibraryUri = new Uri.file(path.absolute(fileName),
+                                            windows: Platform.isWindows);
+          var library = new Library(mirrorSystem.libraries[testLibraryUri]);
+          expect(library is Library, isTrue);
+
+          var classTypes = library.classes;
+          var classes = [];
+          classes.addAll(classTypes.values);
+          classes.addAll(library.errors.values);
+          expect(classes.every((e) => e is Class), isTrue);
+
+          expect(library.typedefs.values.every((e) => e is Typedef), isTrue);
+
+          var classMethodTypes = [];
+          classes.forEach((e) {
+            classMethodTypes.add(e.methods);
+            classMethodTypes.add(e.inheritedMethods);
+          });
+          expect(classMethodTypes.every((e) => e is Map<String, Method>),
+                 isTrue);
+
+          var classMethods = [];
+          classMethodTypes.forEach((e) {
+            classMethods.addAll(e.values);
+          });
+          expect(classMethods.every((e) => e is Method), isTrue);
+
+          var methodParameters = [];
+          classMethods.forEach((e) {
+            methodParameters.addAll(e.parameters.values);
+          });
+          expect(methodParameters.every((e) => e is Parameter), isTrue);
+
+          var functionTypes = library.functions;
+          expect(functionTypes is Map<String, Method>, isTrue);
+
+          var functions = [];
+          functions.addAll(functionTypes.values);
+          expect(functions.every((e) => e is Method), isTrue);
+
+          var functionParameters = [];
+          functions.forEach((e) {
+            functionParameters.addAll(e.parameters.values);
+          });
+          expect(functionParameters.every((e) => e is Parameter), isTrue);
+
+          var variables = library.variables.values;
+          expect(variables.every((e) => e is Variable), isTrue);
+
+          /// Testing fixReference
+          // Testing Doc comment for class [A].
+          var libraryMirror = mirrorSystem.libraries[testLibraryUri];
+          var classMirror =
+              dart2js_util.classesOf(libraryMirror.declarations).first;
+          var classDocComment = library.fixReference('A').children.first.text;
+          expect(classDocComment, 'test.A');
+
+          // Test for linking to parameter [A]
+          var method = getDocgenObject(
+              classMirror.declarations[dart2js_util.symbolOf('m1')]);
+
+          // Testing trying to refer to m1 method
+          var methodDocComment = method.fixReference(
+              'm1').children.first.text;
+          expect(methodDocComment, 'test.A.m1');
+
+          // Testing something with no reference
+          var libraryDocComment = method.fixReference('foobar').text;
+          expect(libraryDocComment, 'foobar');
+
+          // Testing trying to refer to m1 function
+          libraryDocComment = library.fixReference('m1').children.first.text;
+          expect(libraryDocComment, 'test.m1');
+        }).whenComplete(() => temporaryDir.deleteSync(recursive: true));
+    });
+  });
+}
diff --git a/pkg/expect/lib/expect.dart b/pkg/expect/lib/expect.dart
index 20d216f..562af8d 100644
--- a/pkg/expect/lib/expect.dart
+++ b/pkg/expect/lib/expect.dart
@@ -346,19 +346,23 @@
   static void throws(void f(),
                      [_CheckExceptionFn check = null,
                       String reason = null]) {
+    String msg = reason == null ? "" : "($reason)";
+    if (f is! _Nullary) {
+      // Only throws from executing the funtion body should count as throwing.
+      // The failure to even call `f` should throw outside the try/catch.
+      _fail("Expect.throws$msg: Funciton f not callable with zero arguments");
+    }
     try {
       f();
     } catch (e, s) {
       if (check != null) {
         if (!check(e)) {
-          String msg = reason == null ? "" : reason;
-          _fail("Expect.throws($msg): Unexpected '$e'\n$s");
+          _fail("Expect.throws$msg: Unexpected '$e'\n$s");
         }
       }
       return;
     }
-    String msg = reason == null ? "" : reason;
-    _fail('Expect.throws($msg) fails');
+    _fail('Expect.throws$msg fails: Did not throw');
   }
 
   static String _getMessage(String reason)
@@ -372,6 +376,7 @@
 bool _identical(a, b) => identical(a, b);
 
 typedef bool _CheckExceptionFn(exception);
+typedef _Nullary();  // Expect.throws argument must be this type.
 
 class ExpectException implements Exception {
   ExpectException(this.message);
diff --git a/pkg/intl/CHANGELOG.md b/pkg/intl/CHANGELOG.md
index c08f649..b1ba358 100644
--- a/pkg/intl/CHANGELOG.md
+++ b/pkg/intl/CHANGELOG.md
@@ -1,3 +1,8 @@
+## 0.11.10
+  * Fix some style glitches with naming. The only publicly visible one
+    is DateFormat.parseUtc, but the parseUTC variant is still retained
+    for backward-compatibility.
+
 ## 0.11.9
   * Fix bug with per-mille parsing (only divided by 100, not 1000)
   
diff --git a/pkg/intl/bin/generate_from_arb.dart b/pkg/intl/bin/generate_from_arb.dart
index 1d576bcf..7156e23 100644
--- a/pkg/intl/bin/generate_from_arb.dart
+++ b/pkg/intl/bin/generate_from_arb.dart
@@ -137,5 +137,5 @@
   List<MainMessage> _findOriginals() => originalMessages = messages[id];
 }
 
-final pluralAndGenderParser = new ICUParser().message;
-final plainParser = new ICUParser().nonIcuMessage;
+final pluralAndGenderParser = new IcuParser().message;
+final plainParser = new IcuParser().nonIcuMessage;
diff --git a/pkg/intl/lib/date_symbol_data_http_request.dart b/pkg/intl/lib/date_symbol_data_http_request.dart
index 4c54147..4f724f8 100644
--- a/pkg/intl/lib/date_symbol_data_http_request.dart
+++ b/pkg/intl/lib/date_symbol_data_http_request.dart
@@ -26,10 +26,10 @@
  *   "http://localhost:8000/dates/"
  */
 Future initializeDateFormatting(String locale, String url) {
-  var reader = new HTTPRequestDataReader('${url}symbols/');
+  var reader = new HttpRequestDataReader('${url}symbols/');
   initializeDateSymbols(() => new LazyLocaleData(
       reader, _createDateSymbol, availableLocalesForDateFormatting));
-  var reader2 = new HTTPRequestDataReader('${url}patterns/');
+  var reader2 = new HttpRequestDataReader('${url}patterns/');
   initializeDatePatterns(() => new LazyLocaleData(
       reader2, (x) => x, availableLocalesForDateFormatting));
   var actualLocale = Intl.verifiedLocale(locale,
diff --git a/pkg/intl/lib/src/http_request_data_reader.dart b/pkg/intl/lib/src/http_request_data_reader.dart
index a79d16f..ce63870 100644
--- a/pkg/intl/lib/src/http_request_data_reader.dart
+++ b/pkg/intl/lib/src/http_request_data_reader.dart
@@ -13,11 +13,11 @@
 import 'dart:html';
 import 'intl_helpers.dart';
 
-class HTTPRequestDataReader implements LocaleDataReader {
+class HttpRequestDataReader implements LocaleDataReader {
 
   /** The base url from which we read the data. */
   String url;
-  HTTPRequestDataReader(this.url);
+  HttpRequestDataReader(this.url);
 
   Future read(String locale) {
     // TODO(alanknight): Remove this once it's not necessary for Chrome.
diff --git a/pkg/intl/lib/src/icu_parser.dart b/pkg/intl/lib/src/icu_parser.dart
index d83c089..0565ce0 100644
--- a/pkg/intl/lib/src/icu_parser.dart
+++ b/pkg/intl/lib/src/icu_parser.dart
@@ -13,11 +13,11 @@
 
 /**
  * This defines a grammar for ICU MessageFormat syntax. Usage is
- *       new ICUParser.message.parse(<string>).value;
+ *       new IcuParser.message.parse(<string>).value;
  * The "parse" method will return a Success or Failure object which responds
  * to "value".
  */
-class ICUParser {
+class IcuParser {
   get openCurly => char("{");
 
   get closeCurly => char("}");
@@ -69,7 +69,7 @@
       gender.map((values) => new Gender.from(values.first, values[3], null));
   get selectClause => (id & openCurly & interiorText & closeCurly).map(
       (x) => [x.first, x[2]]);
-  get generalSelect => preface & selectLiteral & comma & 
+  get generalSelect => preface & selectLiteral & comma &
       selectClause.plus() & closeCurly;
   get intlSelect => generalSelect.map(
       (values) => new Select.from(values.first, values[3], null));
@@ -79,7 +79,7 @@
   get contents => pluralOrGenderOrSelect | parameter | messageText;
   get simpleText => (nonIcuMessageText | parameter | openCurly).plus();
   get empty => epsilon().map((_) => '');
-  
+
   get parameter => (openCurly & id & closeCurly).map(
       (param) => new VariableSubstitution.named(param[1], null));
 
@@ -91,17 +91,16 @@
       Message.from(chunk, null));
 
   /**
-   * Represents an ordinary message, i.e. not a plural/gender/select, although 
+   * Represents an ordinary message, i.e. not a plural/gender/select, although
    * it may have parameters.
    */
   get nonIcuMessage => (simpleText | empty).map((chunk) =>
-      Message.from(chunk, null));  
-  
+      Message.from(chunk, null));
+
   get stuff => (pluralOrGenderOrSelect | empty).map(
       (chunk) => Message.from(chunk, null));
-  
 
-  ICUParser() {
+  IcuParser() {
     // There is a cycle here, so we need the explicit set to avoid
     // infinite recursion.
     interiorText.set(contents.plus() | empty);
diff --git a/pkg/intl/lib/src/intl/date_format.dart b/pkg/intl/lib/src/intl/date_format.dart
index 54fb3f0..3aede36 100644
--- a/pkg/intl/lib/src/intl/date_format.dart
+++ b/pkg/intl/lib/src/intl/date_format.dart
@@ -291,10 +291,24 @@
   /**
    * Given user input, attempt to parse the [inputString] into the anticipated
    * format, treating it as being in UTC.
+   *
+   * The canonical Dart style name
+   * is [parseUtc], but [parseUTC] is retained
+   * for backward-compatibility.
    */
   DateTime parseUTC(String inputString) => parse(inputString, true);
 
   /**
+   * Given user input, attempt to parse the [inputString] into the anticipated
+   * format, treating it as being in UTC.
+   *
+   * The canonical Dart style name
+   * is [parseUtc], but [parseUTC] is retained
+   * for backward-compatibility.
+   */
+  DateTime parseUtc(String inputString) => parse(inputString, true);
+
+  /**
    * Return the locale code in which we operate, e.g. 'en_US' or 'pt'.
    */
   String get locale => _locale;
diff --git a/pkg/mutation_observer/LICENSE b/pkg/mutation_observer/LICENSE
deleted file mode 100644
index 5c60afe..0000000
--- a/pkg/mutation_observer/LICENSE
+++ /dev/null
@@ -1,26 +0,0 @@
-Copyright 2014, the Dart project authors. All rights reserved.
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are
-met:
-
-    * Redistributions of source code must retain the above copyright
-      notice, this list of conditions and the following disclaimer.
-    * Redistributions in binary form must reproduce the above
-      copyright notice, this list of conditions and the following
-      disclaimer in the documentation and/or other materials provided
-      with the distribution.
-    * Neither the name of Google Inc. nor the names of its
-      contributors may be used to endorse or promote products derived
-      from this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/pkg/mutation_observer/README.md b/pkg/mutation_observer/README.md
deleted file mode 100644
index ea4f66a..0000000
--- a/pkg/mutation_observer/README.md
+++ /dev/null
@@ -1,42 +0,0 @@
-# Mutation Observers polyfill
-
-Mutation Observers provide a way to react to changes in the DOM. This is needed
-on IE versions 9 and 10, see <http://caniuse.com/mutationobserver>.
-
-## More information
-
-* [API documentation](http://api.dartlang.org/docs/bleeding_edge/dart_html/MutationObserver.html)
-* [Mozilla Developer Network page](https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver)
-* [Specification](https://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#mutation-observers)
-
-## Getting started
-
-Include the polyfill in your HTML `<head>`:
-
-```html
-    <script src="packages/mutation_observer/mutation_observer.js"></script>
-```
-
-You can also use a minified version for deployment:
-
-```html
-    <script src="packages/mutation_observer/mutation_observer.min.js"></script>
-```
-
-## Getting the source code
-
-The source for this package is at:
-<https://code.google.com/p/dart/source/browse/branches/bleeding_edge/dart/pkg/mutation_observer/>
-
-The original source of the JavaScript code is at:
-<https://github.com/Polymer/MutationObservers/tree/master>
-
-## Building
-
-The minified version is produced with:
-
-```bash
-    uglifyjs mutation_observer.js -o mutation_observer.min.js
-```
-
-See <https://github.com/mishoo/UglifyJS2> for usage of UglifyJS.
diff --git a/pkg/mutation_observer/lib/mutation_observer.js b/pkg/mutation_observer/lib/mutation_observer.js
deleted file mode 100644
index cae8709..0000000
--- a/pkg/mutation_observer/lib/mutation_observer.js
+++ /dev/null
@@ -1,588 +0,0 @@
-/*
- * Copyright 2013 The Polymer Authors. All rights reserved.
- * Use of this source code is goverened by a BSD-style
- * license that can be found in the LICENSE file.
- */
-
-// TODO(jmesserly): polyfill does not have feature testing or the definition of
-// SideTable. The extra code is from:
-// https://github.com/Polymer/CustomElements/blob/master/src/MutationObserver.js
-// https://github.com/Polymer/CustomElements/blob/master/src/sidetable.js
-// I also renamed JsMutationObserver -> MutationObserver to correctly interact
-// with dart2js interceptors.
-
-if (!window.MutationObserver && !window.WebKitMutationObserver) {
-
-(function(global) {
-  // SideTable is a weak map where possible. If WeakMap is not available the
-  // association is stored as an expando property.
-  var SideTable;
-  // TODO(arv): WeakMap does not allow for Node etc to be keys in Firefox
-  if (typeof WeakMap !== 'undefined' && navigator.userAgent.indexOf('Firefox/') < 0) {
-    SideTable = WeakMap;
-  } else {
-    (function() {
-      var defineProperty = Object.defineProperty;
-      var hasOwnProperty = Object.hasOwnProperty;
-      var counter = new Date().getTime() % 1e9;
-
-      SideTable = function() {
-        this.name = '__st' + (Math.random() * 1e9 >>> 0) + (counter++ + '__');
-      };
-
-      SideTable.prototype = {
-        set: function(key, value) {
-          defineProperty(key, this.name, {value: value, writable: true});
-        },
-        get: function(key) {
-          return hasOwnProperty.call(key, this.name) ? key[this.name] : undefined;
-        },
-        delete: function(key) {
-          this.set(key, undefined);
-        }
-      }
-    })();
-  }
-
-  var registrationsTable = new SideTable();
-
-  // We use setImmediate or postMessage for our future callback.
-  var setImmediate = window.msSetImmediate;
-
-  // Use post message to emulate setImmediate.
-  if (!setImmediate) {
-    var setImmediateQueue = [];
-    var sentinel = String(Math.random());
-    window.addEventListener('message', function(e) {
-      if (e.data === sentinel) {
-        var queue = setImmediateQueue;
-        setImmediateQueue = [];
-        queue.forEach(function(func) {
-          func();
-        });
-      }
-    });
-    setImmediate = function(func) {
-      setImmediateQueue.push(func);
-      window.postMessage(sentinel, '*');
-    };
-  }
-
-  // This is used to ensure that we never schedule 2 callas to setImmediate
-  var isScheduled = false;
-
-  // Keep track of observers that needs to be notified next time.
-  var scheduledObservers = [];
-
-  /**
-   * Schedules |dispatchCallback| to be called in the future.
-   * @param {MutationObserver} observer
-   */
-  function scheduleCallback(observer) {
-    scheduledObservers.push(observer);
-    if (!isScheduled) {
-      isScheduled = true;
-      setImmediate(dispatchCallbacks);
-    }
-  }
-
-  function wrapIfNeeded(node) {
-    return window.ShadowDOMPolyfill &&
-        window.ShadowDOMPolyfill.wrapIfNeeded(node) ||
-        node;
-  }
-
-  function dispatchCallbacks() {
-    // http://dom.spec.whatwg.org/#mutation-observers
-
-    isScheduled = false; // Used to allow a new setImmediate call above.
-
-    var observers = scheduledObservers;
-    scheduledObservers = [];
-    // Sort observers based on their creation UID (incremental).
-    observers.sort(function(o1, o2) {
-      return o1.uid_ - o2.uid_;
-    });
-
-    var anyNonEmpty = false;
-    observers.forEach(function(observer) {
-
-      // 2.1, 2.2
-      var queue = observer.takeRecords();
-      // 2.3. Remove all transient registered observers whose observer is mo.
-      removeTransientObserversFor(observer);
-
-      // 2.4
-      if (queue.length) {
-        observer.callback_(queue, observer);
-        anyNonEmpty = true;
-      }
-    });
-
-    // 3.
-    if (anyNonEmpty)
-      dispatchCallbacks();
-  }
-
-  function removeTransientObserversFor(observer) {
-    observer.nodes_.forEach(function(node) {
-      var registrations = registrationsTable.get(node);
-      if (!registrations)
-        return;
-      registrations.forEach(function(registration) {
-        if (registration.observer === observer)
-          registration.removeTransientObservers();
-      });
-    });
-  }
-
-  /**
-   * This function is used for the "For each registered observer observer (with
-   * observer's options as options) in target's list of registered observers,
-   * run these substeps:" and the "For each ancestor ancestor of target, and for
-   * each registered observer observer (with options options) in ancestor's list
-   * of registered observers, run these substeps:" part of the algorithms. The
-   * |options.subtree| is checked to ensure that the callback is called
-   * correctly.
-   *
-   * @param {Node} target
-   * @param {function(MutationObserverInit):MutationRecord} callback
-   */
-  function forEachAncestorAndObserverEnqueueRecord(target, callback) {
-    for (var node = target; node; node = node.parentNode) {
-      var registrations = registrationsTable.get(node);
-
-      if (registrations) {
-        for (var j = 0; j < registrations.length; j++) {
-          var registration = registrations[j];
-          var options = registration.options;
-
-          // Only target ignores subtree.
-          if (node !== target && !options.subtree)
-            continue;
-
-          var record = callback(options);
-          if (record)
-            registration.enqueue(record);
-        }
-      }
-    }
-  }
-
-  var uidCounter = 0;
-
-  /**
-   * The class that maps to the DOM MutationObserver interface.
-   * @param {Function} callback.
-   * @constructor
-   */
-  function MutationObserver(callback) {
-    this.callback_ = callback;
-    this.nodes_ = [];
-    this.records_ = [];
-    this.uid_ = ++uidCounter;
-  }
-
-  MutationObserver.prototype = {
-    observe: function(target, options) {
-      target = wrapIfNeeded(target);
-
-      // 1.1
-      if (!options.childList && !options.attributes && !options.characterData ||
-
-          // 1.2
-          options.attributeOldValue && !options.attributes ||
-
-          // 1.3
-          options.attributeFilter && options.attributeFilter.length &&
-              !options.attributes ||
-
-          // 1.4
-          options.characterDataOldValue && !options.characterData) {
-
-        throw new SyntaxError();
-      }
-
-      var registrations = registrationsTable.get(target);
-      if (!registrations)
-        registrationsTable.set(target, registrations = []);
-
-      // 2
-      // If target's list of registered observers already includes a registered
-      // observer associated with the context object, replace that registered
-      // observer's options with options.
-      var registration;
-      for (var i = 0; i < registrations.length; i++) {
-        if (registrations[i].observer === this) {
-          registration = registrations[i];
-          registration.removeListeners();
-          registration.options = options;
-          break;
-        }
-      }
-
-      // 3.
-      // Otherwise, add a new registered observer to target's list of registered
-      // observers with the context object as the observer and options as the
-      // options, and add target to context object's list of nodes on which it
-      // is registered.
-      if (!registration) {
-        registration = new Registration(this, target, options);
-        registrations.push(registration);
-        this.nodes_.push(target);
-      }
-
-      registration.addListeners();
-    },
-
-    disconnect: function() {
-      this.nodes_.forEach(function(node) {
-        var registrations = registrationsTable.get(node);
-        for (var i = 0; i < registrations.length; i++) {
-          var registration = registrations[i];
-          if (registration.observer === this) {
-            registration.removeListeners();
-            registrations.splice(i, 1);
-            // Each node can only have one registered observer associated with
-            // this observer.
-            break;
-          }
-        }
-      }, this);
-      this.records_ = [];
-    },
-
-    takeRecords: function() {
-      var copyOfRecords = this.records_;
-      this.records_ = [];
-      return copyOfRecords;
-    }
-  };
-
-  /**
-   * @param {string} type
-   * @param {Node} target
-   * @constructor
-   */
-  function MutationRecord(type, target) {
-    this.type = type;
-    this.target = target;
-    this.addedNodes = [];
-    this.removedNodes = [];
-    this.previousSibling = null;
-    this.nextSibling = null;
-    this.attributeName = null;
-    this.attributeNamespace = null;
-    this.oldValue = null;
-  }
-
-  // TODO(jmesserly): this fixes the interceptor dispatch on IE.
-  // Not sure why this is necessary.
-  MutationObserver.prototype.constructor = MutationObserver;
-  MutationObserver.name = 'MutationObserver';
-  MutationRecord.prototype.constructor = MutationRecord;
-  MutationRecord.name = 'MutationRecord';
-
-  function copyMutationRecord(original) {
-    var record = new MutationRecord(original.type, original.target);
-    record.addedNodes = original.addedNodes.slice();
-    record.removedNodes = original.removedNodes.slice();
-    record.previousSibling = original.previousSibling;
-    record.nextSibling = original.nextSibling;
-    record.attributeName = original.attributeName;
-    record.attributeNamespace = original.attributeNamespace;
-    record.oldValue = original.oldValue;
-    return record;
-  };
-
-  // We keep track of the two (possibly one) records used in a single mutation.
-  var currentRecord, recordWithOldValue;
-
-  /**
-   * Creates a record without |oldValue| and caches it as |currentRecord| for
-   * later use.
-   * @param {string} oldValue
-   * @return {MutationRecord}
-   */
-  function getRecord(type, target) {
-    return currentRecord = new MutationRecord(type, target);
-  }
-
-  /**
-   * Gets or creates a record with |oldValue| based in the |currentRecord|
-   * @param {string} oldValue
-   * @return {MutationRecord}
-   */
-  function getRecordWithOldValue(oldValue) {
-    if (recordWithOldValue)
-      return recordWithOldValue;
-    recordWithOldValue = copyMutationRecord(currentRecord);
-    recordWithOldValue.oldValue = oldValue;
-    return recordWithOldValue;
-  }
-
-  function clearRecords() {
-    currentRecord = recordWithOldValue = undefined;
-  }
-
-  /**
-   * @param {MutationRecord} record
-   * @return {boolean} Whether the record represents a record from the current
-   * mutation event.
-   */
-  function recordRepresentsCurrentMutation(record) {
-    return record === recordWithOldValue || record === currentRecord;
-  }
-
-  /**
-   * Selects which record, if any, to replace the last record in the queue.
-   * This returns |null| if no record should be replaced.
-   *
-   * @param {MutationRecord} lastRecord
-   * @param {MutationRecord} newRecord
-   * @param {MutationRecord}
-   */
-  function selectRecord(lastRecord, newRecord) {
-    if (lastRecord === newRecord)
-      return lastRecord;
-
-    // Check if the the record we are adding represents the same record. If
-    // so, we keep the one with the oldValue in it.
-    if (recordWithOldValue && recordRepresentsCurrentMutation(lastRecord))
-      return recordWithOldValue;
-
-    return null;
-  }
-
-  /**
-   * Class used to represent a registered observer.
-   * @param {MutationObserver} observer
-   * @param {Node} target
-   * @param {MutationObserverInit} options
-   * @constructor
-   */
-  function Registration(observer, target, options) {
-    this.observer = observer;
-    this.target = target;
-    this.options = options;
-    this.transientObservedNodes = [];
-  }
-
-  Registration.prototype = {
-    enqueue: function(record) {
-      var records = this.observer.records_;
-      var length = records.length;
-
-      // There are cases where we replace the last record with the new record.
-      // For example if the record represents the same mutation we need to use
-      // the one with the oldValue. If we get same record (this can happen as we
-      // walk up the tree) we ignore the new record.
-      if (records.length > 0) {
-        var lastRecord = records[length - 1];
-        var recordToReplaceLast = selectRecord(lastRecord, record);
-        if (recordToReplaceLast) {
-          records[length - 1] = recordToReplaceLast;
-          return;
-        }
-      } else {
-        scheduleCallback(this.observer);
-      }
-
-      records[length] = record;
-    },
-
-    addListeners: function() {
-      this.addListeners_(this.target);
-    },
-
-    addListeners_: function(node) {
-      var options = this.options;
-      if (options.attributes)
-        node.addEventListener('DOMAttrModified', this, true);
-
-      if (options.characterData)
-        node.addEventListener('DOMCharacterDataModified', this, true);
-
-      if (options.childList)
-        node.addEventListener('DOMNodeInserted', this, true);
-
-      if (options.childList || options.subtree)
-        node.addEventListener('DOMNodeRemoved', this, true);
-    },
-
-    removeListeners: function() {
-      this.removeListeners_(this.target);
-    },
-
-    removeListeners_: function(node) {
-      var options = this.options;
-      if (options.attributes)
-        node.removeEventListener('DOMAttrModified', this, true);
-
-      if (options.characterData)
-        node.removeEventListener('DOMCharacterDataModified', this, true);
-
-      if (options.childList)
-        node.removeEventListener('DOMNodeInserted', this, true);
-
-      if (options.childList || options.subtree)
-        node.removeEventListener('DOMNodeRemoved', this, true);
-    },
-
-    /**
-     * Adds a transient observer on node. The transient observer gets removed
-     * next time we deliver the change records.
-     * @param {Node} node
-     */
-    addTransientObserver: function(node) {
-      // Don't add transient observers on the target itself. We already have all
-      // the required listeners set up on the target.
-      if (node === this.target)
-        return;
-
-      this.addListeners_(node);
-      this.transientObservedNodes.push(node);
-      var registrations = registrationsTable.get(node);
-      if (!registrations)
-        registrationsTable.set(node, registrations = []);
-
-      // We know that registrations does not contain this because we already
-      // checked if node === this.target.
-      registrations.push(this);
-    },
-
-    removeTransientObservers: function() {
-      var transientObservedNodes = this.transientObservedNodes;
-      this.transientObservedNodes = [];
-
-      transientObservedNodes.forEach(function(node) {
-        // Transient observers are never added to the target.
-        this.removeListeners_(node);
-
-        var registrations = registrationsTable.get(node);
-        for (var i = 0; i < registrations.length; i++) {
-          if (registrations[i] === this) {
-            registrations.splice(i, 1);
-            // Each node can only have one registered observer associated with
-            // this observer.
-            break;
-          }
-        }
-      }, this);
-    },
-
-    handleEvent: function(e) {
-      // Stop propagation since we are managing the propagation manually.
-      // This means that other mutation events on the page will not work
-      // correctly but that is by design.
-      e.stopImmediatePropagation();
-
-      switch (e.type) {
-        case 'DOMAttrModified':
-          // http://dom.spec.whatwg.org/#concept-mo-queue-attributes
-
-          var name = e.attrName;
-          var namespace = e.relatedNode.namespaceURI;
-          var target = e.target;
-
-          // 1.
-          var record = new getRecord('attributes', target);
-          record.attributeName = name;
-          record.attributeNamespace = namespace;
-
-          // 2.
-          var oldValue =
-              e.attrChange === MutationEvent.ADDITION ? null : e.prevValue;
-
-          forEachAncestorAndObserverEnqueueRecord(target, function(options) {
-            // 3.1, 4.2
-            if (!options.attributes)
-              return;
-
-            // 3.2, 4.3
-            if (options.attributeFilter && options.attributeFilter.length &&
-                options.attributeFilter.indexOf(name) === -1 &&
-                options.attributeFilter.indexOf(namespace) === -1) {
-              return;
-            }
-            // 3.3, 4.4
-            if (options.attributeOldValue)
-              return getRecordWithOldValue(oldValue);
-
-            // 3.4, 4.5
-            return record;
-          });
-
-          break;
-
-        case 'DOMCharacterDataModified':
-          // http://dom.spec.whatwg.org/#concept-mo-queue-characterdata
-          var target = e.target;
-
-          // 1.
-          var record = getRecord('characterData', target);
-
-          // 2.
-          var oldValue = e.prevValue;
-
-
-          forEachAncestorAndObserverEnqueueRecord(target, function(options) {
-            // 3.1, 4.2
-            if (!options.characterData)
-              return;
-
-            // 3.2, 4.3
-            if (options.characterDataOldValue)
-              return getRecordWithOldValue(oldValue);
-
-            // 3.3, 4.4
-            return record;
-          });
-
-          break;
-
-        case 'DOMNodeRemoved':
-          this.addTransientObserver(e.target);
-          // Fall through.
-        case 'DOMNodeInserted':
-          // http://dom.spec.whatwg.org/#concept-mo-queue-childlist
-          var target = e.relatedNode;
-          var changedNode = e.target;
-          var addedNodes, removedNodes;
-          if (e.type === 'DOMNodeInserted') {
-            addedNodes = [changedNode];
-            removedNodes = [];
-          } else {
-
-            addedNodes = [];
-            removedNodes = [changedNode];
-          }
-          var previousSibling = changedNode.previousSibling;
-          var nextSibling = changedNode.nextSibling;
-
-          // 1.
-          var record = getRecord('childList', target);
-          record.addedNodes = addedNodes;
-          record.removedNodes = removedNodes;
-          record.previousSibling = previousSibling;
-          record.nextSibling = nextSibling;
-
-          forEachAncestorAndObserverEnqueueRecord(target, function(options) {
-            // 2.1, 3.2
-            if (!options.childList)
-              return;
-
-            // 2.2, 3.3
-            return record;
-          });
-
-      }
-
-      clearRecords();
-    }
-  };
-
-  global.MutationObserver = MutationObserver;
-})(window);
-
-}
diff --git a/pkg/mutation_observer/lib/mutation_observer.min.js b/pkg/mutation_observer/lib/mutation_observer.min.js
deleted file mode 100644
index 1c25e0b..0000000
--- a/pkg/mutation_observer/lib/mutation_observer.min.js
+++ /dev/null
@@ -1 +0,0 @@
-if(!window.MutationObserver&&!window.WebKitMutationObserver){!function(global){var SideTable;if(typeof WeakMap!=="undefined"&&navigator.userAgent.indexOf("Firefox/")<0){SideTable=WeakMap}else{!function(){var defineProperty=Object.defineProperty;var hasOwnProperty=Object.hasOwnProperty;var counter=(new Date).getTime()%1e9;SideTable=function(){this.name="__st"+(Math.random()*1e9>>>0)+(counter++ +"__")};SideTable.prototype={set:function(key,value){defineProperty(key,this.name,{value:value,writable:true})},get:function(key){return hasOwnProperty.call(key,this.name)?key[this.name]:undefined},"delete":function(key){this.set(key,undefined)}}}()}var registrationsTable=new SideTable;var setImmediate=window.msSetImmediate;if(!setImmediate){var setImmediateQueue=[];var sentinel=String(Math.random());window.addEventListener("message",function(e){if(e.data===sentinel){var queue=setImmediateQueue;setImmediateQueue=[];queue.forEach(function(func){func()})}});setImmediate=function(func){setImmediateQueue.push(func);window.postMessage(sentinel,"*")}}var isScheduled=false;var scheduledObservers=[];function scheduleCallback(observer){scheduledObservers.push(observer);if(!isScheduled){isScheduled=true;setImmediate(dispatchCallbacks)}}function wrapIfNeeded(node){return window.ShadowDOMPolyfill&&window.ShadowDOMPolyfill.wrapIfNeeded(node)||node}function dispatchCallbacks(){isScheduled=false;var observers=scheduledObservers;scheduledObservers=[];observers.sort(function(o1,o2){return o1.uid_-o2.uid_});var anyNonEmpty=false;observers.forEach(function(observer){var queue=observer.takeRecords();removeTransientObserversFor(observer);if(queue.length){observer.callback_(queue,observer);anyNonEmpty=true}});if(anyNonEmpty)dispatchCallbacks()}function removeTransientObserversFor(observer){observer.nodes_.forEach(function(node){var registrations=registrationsTable.get(node);if(!registrations)return;registrations.forEach(function(registration){if(registration.observer===observer)registration.removeTransientObservers()})})}function forEachAncestorAndObserverEnqueueRecord(target,callback){for(var node=target;node;node=node.parentNode){var registrations=registrationsTable.get(node);if(registrations){for(var j=0;j<registrations.length;j++){var registration=registrations[j];var options=registration.options;if(node!==target&&!options.subtree)continue;var record=callback(options);if(record)registration.enqueue(record)}}}}var uidCounter=0;function MutationObserver(callback){this.callback_=callback;this.nodes_=[];this.records_=[];this.uid_=++uidCounter}MutationObserver.prototype={observe:function(target,options){target=wrapIfNeeded(target);if(!options.childList&&!options.attributes&&!options.characterData||options.attributeOldValue&&!options.attributes||options.attributeFilter&&options.attributeFilter.length&&!options.attributes||options.characterDataOldValue&&!options.characterData){throw new SyntaxError}var registrations=registrationsTable.get(target);if(!registrations)registrationsTable.set(target,registrations=[]);var registration;for(var i=0;i<registrations.length;i++){if(registrations[i].observer===this){registration=registrations[i];registration.removeListeners();registration.options=options;break}}if(!registration){registration=new Registration(this,target,options);registrations.push(registration);this.nodes_.push(target)}registration.addListeners()},disconnect:function(){this.nodes_.forEach(function(node){var registrations=registrationsTable.get(node);for(var i=0;i<registrations.length;i++){var registration=registrations[i];if(registration.observer===this){registration.removeListeners();registrations.splice(i,1);break}}},this);this.records_=[]},takeRecords:function(){var copyOfRecords=this.records_;this.records_=[];return copyOfRecords}};function MutationRecord(type,target){this.type=type;this.target=target;this.addedNodes=[];this.removedNodes=[];this.previousSibling=null;this.nextSibling=null;this.attributeName=null;this.attributeNamespace=null;this.oldValue=null}MutationObserver.prototype.constructor=MutationObserver;MutationObserver.name="MutationObserver";MutationRecord.prototype.constructor=MutationRecord;MutationRecord.name="MutationRecord";function copyMutationRecord(original){var record=new MutationRecord(original.type,original.target);record.addedNodes=original.addedNodes.slice();record.removedNodes=original.removedNodes.slice();record.previousSibling=original.previousSibling;record.nextSibling=original.nextSibling;record.attributeName=original.attributeName;record.attributeNamespace=original.attributeNamespace;record.oldValue=original.oldValue;return record}var currentRecord,recordWithOldValue;function getRecord(type,target){return currentRecord=new MutationRecord(type,target)}function getRecordWithOldValue(oldValue){if(recordWithOldValue)return recordWithOldValue;recordWithOldValue=copyMutationRecord(currentRecord);recordWithOldValue.oldValue=oldValue;return recordWithOldValue}function clearRecords(){currentRecord=recordWithOldValue=undefined}function recordRepresentsCurrentMutation(record){return record===recordWithOldValue||record===currentRecord}function selectRecord(lastRecord,newRecord){if(lastRecord===newRecord)return lastRecord;if(recordWithOldValue&&recordRepresentsCurrentMutation(lastRecord))return recordWithOldValue;return null}function Registration(observer,target,options){this.observer=observer;this.target=target;this.options=options;this.transientObservedNodes=[]}Registration.prototype={enqueue:function(record){var records=this.observer.records_;var length=records.length;if(records.length>0){var lastRecord=records[length-1];var recordToReplaceLast=selectRecord(lastRecord,record);if(recordToReplaceLast){records[length-1]=recordToReplaceLast;return}}else{scheduleCallback(this.observer)}records[length]=record},addListeners:function(){this.addListeners_(this.target)},addListeners_:function(node){var options=this.options;if(options.attributes)node.addEventListener("DOMAttrModified",this,true);if(options.characterData)node.addEventListener("DOMCharacterDataModified",this,true);if(options.childList)node.addEventListener("DOMNodeInserted",this,true);if(options.childList||options.subtree)node.addEventListener("DOMNodeRemoved",this,true)},removeListeners:function(){this.removeListeners_(this.target)},removeListeners_:function(node){var options=this.options;if(options.attributes)node.removeEventListener("DOMAttrModified",this,true);if(options.characterData)node.removeEventListener("DOMCharacterDataModified",this,true);if(options.childList)node.removeEventListener("DOMNodeInserted",this,true);if(options.childList||options.subtree)node.removeEventListener("DOMNodeRemoved",this,true)},addTransientObserver:function(node){if(node===this.target)return;this.addListeners_(node);this.transientObservedNodes.push(node);var registrations=registrationsTable.get(node);if(!registrations)registrationsTable.set(node,registrations=[]);registrations.push(this)},removeTransientObservers:function(){var transientObservedNodes=this.transientObservedNodes;this.transientObservedNodes=[];transientObservedNodes.forEach(function(node){this.removeListeners_(node);var registrations=registrationsTable.get(node);for(var i=0;i<registrations.length;i++){if(registrations[i]===this){registrations.splice(i,1);break}}},this)},handleEvent:function(e){e.stopImmediatePropagation();switch(e.type){case"DOMAttrModified":var name=e.attrName;var namespace=e.relatedNode.namespaceURI;var target=e.target;var record=new getRecord("attributes",target);record.attributeName=name;record.attributeNamespace=namespace;var oldValue=e.attrChange===MutationEvent.ADDITION?null:e.prevValue;forEachAncestorAndObserverEnqueueRecord(target,function(options){if(!options.attributes)return;if(options.attributeFilter&&options.attributeFilter.length&&options.attributeFilter.indexOf(name)===-1&&options.attributeFilter.indexOf(namespace)===-1){return}if(options.attributeOldValue)return getRecordWithOldValue(oldValue);return record});break;case"DOMCharacterDataModified":var target=e.target;var record=getRecord("characterData",target);var oldValue=e.prevValue;forEachAncestorAndObserverEnqueueRecord(target,function(options){if(!options.characterData)return;if(options.characterDataOldValue)return getRecordWithOldValue(oldValue);return record});break;case"DOMNodeRemoved":this.addTransientObserver(e.target);case"DOMNodeInserted":var target=e.relatedNode;var changedNode=e.target;var addedNodes,removedNodes;if(e.type==="DOMNodeInserted"){addedNodes=[changedNode];removedNodes=[]}else{addedNodes=[];removedNodes=[changedNode]}var previousSibling=changedNode.previousSibling;var nextSibling=changedNode.nextSibling;var record=getRecord("childList",target);record.addedNodes=addedNodes;record.removedNodes=removedNodes;record.previousSibling=previousSibling;record.nextSibling=nextSibling;forEachAncestorAndObserverEnqueueRecord(target,function(options){if(!options.childList)return;return record})}clearRecords()}};global.MutationObserver=MutationObserver}(window)}
\ No newline at end of file
diff --git a/pkg/mutation_observer/pubspec.yaml b/pkg/mutation_observer/pubspec.yaml
deleted file mode 100644
index c7b1079..0000000
--- a/pkg/mutation_observer/pubspec.yaml
+++ /dev/null
@@ -1,10 +0,0 @@
-name: mutation_observer
-version: 0.9.0+2
-author: "Polymer.dart Team <web-ui-dev@dartlang.org>"
-homepage: https://code.google.com/p/dart/source/browse/branches/bleeding_edge/dart/pkg/mutation_observer/
-description: >
-  *Deprecated* newer version is in web_components package.
-dev_dependencies:
-  unittest: ">=0.9.0 <0.11.0"
-environment:
-  sdk: ">=1.0.0 <2.0.0"
diff --git a/pkg/mutation_observer/test/mutation_observer_test.dart b/pkg/mutation_observer/test/mutation_observer_test.dart
deleted file mode 100644
index 6f257e4f..0000000
--- a/pkg/mutation_observer/test/mutation_observer_test.dart
+++ /dev/null
@@ -1,105 +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.
-
-library mutation_observer_test;
-
-import 'dart:html';
-import 'package:unittest/unittest.dart';
-import 'package:unittest/html_config.dart';
-
-main() {
-  useHtmlConfiguration();
-
-  // Load the MutationObserver polyfill.
-  HttpRequest.getString('/root_dart/pkg/mutation_observer/lib/'
-      'mutation_observer.min.js').then((code) {
-
-    // Force MutationObserver polyfill to be used so we can test it, even in
-    // browsers with native support.
-    document.head.children.add(new ScriptElement()
-        ..text = 'window.MutationObserver = void 0;'
-                 'window.WebKitMutationObserver = void 0;'
-                 '$code');
-
-    testMutationObserver();
-  });
-}
-
-/**
- * Test suite for Mutation Observers. This is just a small set of sanity
- * checks, not a complete test suite.
- */
-testMutationObserver() {
-  group('supported', () {
-    test('supported', () {
-      expect(MutationObserver.supported, true, reason: 'polyfill loaded.');
-    });
-  });
-
-  group('childList', () {
-    mutationCallback(count, expectation) {
-      var done = false;
-      var nodes = [];
-
-      callback(mutations, observer) {
-        for (MutationRecord mutation in mutations) {
-          for (Node node in mutation.addedNodes) {
-            nodes.add(node);
-          }
-        }
-        if (nodes.length >= count) {
-          done = true;
-          expect(nodes.length, count);
-          expect(nodes, expectation);
-        }
-      }
-
-      return expectAsyncUntil(callback, () => done);
-    }
-
-    test('empty options is syntax error', () {
-      var mutationObserver = new MutationObserver(
-          (mutations, observer) { expect(false, isTrue,
-              reason: 'Should not be reached'); });
-      expect(() { mutationObserver.observe(document); },
-             throws);
-    });
-
-    test('direct-parallel options-named', () {
-      var container = new DivElement();
-      var div1 = new DivElement();
-      var div2 = new DivElement();
-      var mutationObserver = new MutationObserver(
-          mutationCallback(2, orderedEquals([div1, div2])));
-      mutationObserver.observe(container, childList: true);
-
-      container.append(div1);
-      container.append(div2);
-    });
-
-    test('direct-nested options-named', () {
-      var container = new DivElement();
-      var div1 = new DivElement();
-      var div2 = new DivElement();
-      var mutationObserver =
-          new MutationObserver(mutationCallback(1, orderedEquals([div1])));
-      mutationObserver.observe(container, childList: true);
-
-      container.append(div1);
-      div1.append(div2);
-    });
-
-    test('subtree options-named', () {
-      var container = new DivElement();
-      var div1 = new DivElement();
-      var div2 = new DivElement();
-      var mutationObserver = new MutationObserver(
-          mutationCallback(2, orderedEquals([div1, div2])));
-      mutationObserver.observe(container, childList: true, subtree: true);
-
-      container.append(div1);
-      div1.append(div2);
-    });
-  });
-}
diff --git a/pkg/pkg.status b/pkg/pkg.status
index b7f4dbe..7ecf212 100644
--- a/pkg/pkg.status
+++ b/pkg/pkg.status
@@ -73,6 +73,7 @@
 analysis_server/test/analysis_server_test: Skip  # Times out
 analysis_server/test/domain_context_test: Skip  # Times out
 analysis_server/test/domain_server_test: Skip  # Times out
+analysis_server/test/integration/analysis/reanalyze_concurrent_test: Skip # Times out
 analysis_server/test/integration/analysis/update_content_test: Skip # Times out
 analysis_server/tool/spec/check_all_test: Skip # Times out
 analyzer/test/generated/element_test: Skip  # Times out
@@ -252,7 +253,6 @@
 polymer/e2e_test/*: Pass, RuntimeError # Issue 19265
 polymer/test/event_handlers_test: Pass, Timeout # Issue 19327
 polymer_expressions/*: Pass, RuntimeError # Issue 19265
-template_binding/test/custom_element_bindings_test: Pass, RuntimeError # Issue 20714
 template_binding/test/template_binding_test: Pass, RuntimeError # Issue 19265
 typed_data/test/typed_buffers_test/none: Fail # Issue   17607 (I put this here explicitly, since this is not the same as on ie9)
 
@@ -298,7 +298,6 @@
 # This test uses third_party/pkg/perf_api/lib/perf_api.dart, which
 # contains illegal constant constructors.
 third_party/angular_tests/browser_test: CompileTimeError
-custom_element/test/analyzer_test: StaticWarning # Issue 20939
 
 [ $compiler == dart2js && $runtime == none]
 polymer/e2e_test/canonicalization: Skip
@@ -446,7 +445,6 @@
 
 [ $runtime == vm ]
 # Skip tests on the VM if the package depends on dart:html
-custom_element: Skip
 template_binding: Skip
 mutation_observer: Skip
 polymer_expressions/test/syntax_test: Skip
@@ -495,10 +493,3 @@
 
 [ $system == windows ]
 analysis_server/test/integration/search/get_type_hierarchy_test: Pass, Fail # Issue 20436
-
-[ $runtime == safari && $builder_tag == mac10_8 ]
-polymer/e2e_test/good_import/test/import_test: RuntimeError # Issue 21424
-polymer/test/custom_event_test: RuntimeError # Issue 21425
-polymer/test/instance_attrs_test: RuntimeError # Issue 21425
-polymer/test/property_observe_test: RuntimeError # Issue 21425
-intl/test/date_time_format_http_request_test: RuntimeError # Issue 21428
diff --git a/pkg/polymer/lib/src/build/script_compactor.dart b/pkg/polymer/lib/src/build/script_compactor.dart
index 20d8052..16bd7c7 100644
--- a/pkg/polymer/lib/src/build/script_compactor.dart
+++ b/pkg/polymer/lib/src/build/script_compactor.dart
@@ -249,13 +249,19 @@
     // Process all classes and top-level functions to include initializers,
     // register custom elements, and include special fields and methods in
     // custom element classes.
+    var functionsSeen = new Set<FunctionElement>();
+    var classesSeen = new Set<ClassElement>();
     for (var id in entryLibraries) {
       var lib = resolver.getLibrary(id);
       for (var fun in _visibleTopLevelMethodsOf(lib)) {
+        if (functionsSeen.contains(fun)) continue;
+        functionsSeen.add(fun);
         _processFunction(fun, id);
       }
 
       for (var cls in _visibleClassesOf(lib)) {
+        if (classesSeen.contains(cls)) continue;
+        classesSeen.add(cls);
         _processClass(cls, id, recorder);
       }
     }
@@ -824,8 +830,7 @@
   var result = [];
   result.addAll(lib.units.expand((u) => u.functions));
   for (var e in lib.exports) {
-    var exported = e.exportedLibrary.units
-        .expand((u) => u.functions).toList();
+    var exported = e.exportedLibrary.units.expand((u) => u.functions).toList();
     _filter(exported, e.combinators);
     result.addAll(exported);
   }
diff --git a/pkg/polymer/pubspec.yaml b/pkg/polymer/pubspec.yaml
index f94eb8a..ad7a7b7 100644
--- a/pkg/polymer/pubspec.yaml
+++ b/pkg/polymer/pubspec.yaml
@@ -1,5 +1,5 @@
 name: polymer
-version: 0.15.1+3
+version: 0.15.1+4
 author: Polymer.dart Authors <web-ui-dev@dartlang.org>
 description: >
   Polymer.dart is a new type of library for the web, built on top of Web
diff --git a/pkg/polymer/test/build/script_compactor_test.dart b/pkg/polymer/test/build/script_compactor_test.dart
index 3e844d5..2f14cd4 100644
--- a/pkg/polymer/test/build/script_compactor_test.dart
+++ b/pkg/polymer/test/build/script_compactor_test.dart
@@ -245,7 +245,8 @@
           '<!DOCTYPE html><html><head>'
           '</head><body><div></div>',
       'a|web/test.html._data':
-          expectedData(['web/a.dart', 'web/b.dart', 'web/c.dart', 'web/d.dart']),
+          expectedData(['web/a.dart', 'web/b.dart', 'web/c.dart',
+              'web/i.dart', 'web/j.dart', 'web/d.dart']),
       'a|web/d.dart':
           'library d;\n'
           'import "package:polymer/polymer.dart";\n'
@@ -253,6 +254,7 @@
 
       'a|web/a.dart':
           'import "package:polymer/polymer.dart";\n'
+          'export "i.dart" hide mI2;\n'
           '@initMethod mA(){}\n',
 
       'a|web/b.dart':
@@ -296,6 +298,15 @@
           '@initMethod mH1(){}\n'
           '@CustomTag("x-h2") class XH2 extends PolymerElement {}\n'
           '@initMethod mH2(){}\n',
+
+      'a|web/i.dart':
+          'import "package:polymer/polymer.dart";\n'
+          '@CustomTag("x-i") class XI extends PolymerElement {}\n'
+          '@initMethod mI1(){}\n'
+          '@initMethod mI2(){}\n',
+
+      'a|web/j.dart':
+          'export "a.dart";\n',
     }, {
       'a|web/test.html':
           '<!DOCTYPE html><html><head></head><body><div></div>'
@@ -308,36 +319,43 @@
           import 'a.dart' as i0;
           import 'b.dart' as i1;
           import 'c.dart' as i2;
-          import 'd.dart' as i3;
+          import 'i.dart' as i3;
+          import 'j.dart' as i4;
+          import 'd.dart' as i5;
           ${DEFAULT_IMPORTS.join('\n')}
-          import 'e.dart' as smoke_0;
+          import 'i.dart' as smoke_0;
           import 'package:polymer/polymer.dart' as smoke_1;
-          import 'f.dart' as smoke_2;
-          import 'g.dart' as smoke_3;
-          import 'h.dart' as smoke_4;
-          import 'c.dart' as smoke_5;
+          import 'e.dart' as smoke_2;
+          import 'f.dart' as smoke_3;
+          import 'g.dart' as smoke_4;
+          import 'h.dart' as smoke_5;
+          import 'c.dart' as smoke_6;
 
           void main() {
             useGeneratedCode(new StaticConfiguration(
                 checkedMode: false,
                 parents: {
-                  smoke_5.XC1: smoke_1.PolymerElement,
-                  smoke_5.XC2: smoke_1.PolymerElement,
-                  smoke_0.XE: smoke_1.PolymerElement,
-                  smoke_2.XF1: smoke_1.PolymerElement,
-                  smoke_3.XG2: smoke_1.PolymerElement,
-                  smoke_4.XH1: smoke_1.PolymerElement,
+                  smoke_6.XC1: smoke_1.PolymerElement,
+                  smoke_6.XC2: smoke_1.PolymerElement,
+                  smoke_2.XE: smoke_1.PolymerElement,
+                  smoke_3.XF1: smoke_1.PolymerElement,
+                  smoke_4.XG2: smoke_1.PolymerElement,
+                  smoke_5.XH1: smoke_1.PolymerElement,
+                  smoke_0.XI: smoke_1.PolymerElement,
                 },
                 declarations: {
-                  smoke_5.XC1: {},
-                  smoke_5.XC2: {},
-                  smoke_0.XE: {},
-                  smoke_2.XF1: {},
-                  smoke_3.XG2: {},
-                  smoke_4.XH1: {},
+                  smoke_6.XC1: {},
+                  smoke_6.XC2: {},
+                  smoke_2.XE: {},
+                  smoke_3.XF1: {},
+                  smoke_4.XG2: {},
+                  smoke_5.XH1: {},
+                  smoke_0.XI: {},
                 }));
             configureForDeployment([
                 i0.mA,
+                i0.mI1,
+                () => Polymer.register('x-i', i0.XI),
                 i1.mB,
                 i1.mE,
                 i1.mF1,
@@ -348,9 +366,10 @@
                 () => Polymer.register('x-h1', i1.XH1),
                 () => Polymer.register('x-c1', i2.XC1),
                 () => Polymer.register('x-c2', i2.XC2),
-                i3.mD,
+                i3.mI2,
+                i5.mD,
               ]);
-            i3.main();
+            i5.main();
           }
           '''.replaceAll('\n          ', '\n'),
     }, null);
diff --git a/pkg/template_binding/test/template_binding_test.dart b/pkg/template_binding/test/template_binding_test.dart
index fde463b..cc68bf3 100644
--- a/pkg/template_binding/test/template_binding_test.dart
+++ b/pkg/template_binding/test/template_binding_test.dart
@@ -26,15 +26,9 @@
 main() => dirtyCheckZone().run(() {
   useHtmlConfiguration();
 
-  // Load MutationObserver polyfill in case IE needs it.
-  var script = new ScriptElement()
-      ..src = '/root_dart/pkg/mutation_observer/lib/mutation_observer.min.js';
-  var polyfillLoaded = script.onLoad.first;
-  document.head.append(script);
-
-  setUp(() => polyfillLoaded.then((_) {
+  setUp(() {
     document.body.append(testDiv = new DivElement());
-  }));
+  });
 
   tearDown(() {
     testDiv.remove();
diff --git a/runtime/bin/process_patch.dart b/runtime/bin/process_patch.dart
index 9e374ae..22b08aa 100644
--- a/runtime/bin/process_patch.dart
+++ b/runtime/bin/process_patch.dart
@@ -451,6 +451,8 @@
       return encoding.decode(output);
     }
 
+    _processes.remove(_serviceId);
+
     return new _ProcessResult(
         result[0],
         result[1],
diff --git a/runtime/bin/stdio_patch.dart b/runtime/bin/stdio_patch.dart
index 9a0e5af..d400306 100644
--- a/runtime/bin/stdio_patch.dart
+++ b/runtime/bin/stdio_patch.dart
@@ -30,7 +30,7 @@
       case _STDIO_HANDLE_TYPE_PIPE:
       case _STDIO_HANDLE_TYPE_SOCKET:
       case _STDIO_HANDLE_TYPE_FILE:
-        return wrap(new IOSink(new _StdConsumer(fd)));
+        return wrap(new IOSink(new _FileStreamConsumer.fromStdio(fd)));
       default:
         throw new FileSystemException("Unsupported stdin type");
     }
diff --git a/runtime/lib/convert_patch.dart b/runtime/lib/convert_patch.dart
index eea0fa5..d8ca287 100644
--- a/runtime/lib/convert_patch.dart
+++ b/runtime/lib/convert_patch.dart
@@ -21,6 +21,36 @@
   return listener.result;
 }
 
+patch class Utf8Decoder {
+  /* patch */
+  Converter<List<int>, dynamic> fuse(Converter<String, dynamic> next) {
+    if (next is JsonDecoder) {
+      return new _JsonUtf8Decoder(next._reviver, this._allowMalformed);
+    }
+    // TODO(lrn): Recognize a fused decoder where the next step is JsonDecoder.
+    return super.fuse(next);
+  }
+}
+
+class _JsonUtf8Decoder extends Converter<List<int>, Object> {
+  final _Reviver _reviver;
+  final bool _allowMalformed;
+
+  _JsonUtf8Decoder(this._reviver, this._allowMalformed);
+
+  dynamic convert(List<int> input) {
+    var parser = _JsonUtf8DecoderSink._createParser(_reviver, _allowMalformed);
+    parser.chunk = input;
+    parser.chunkEnd = input.length;
+    parser.parse(0);
+    return parser.result;
+  }
+
+  ByteConversionSink startChunkedConversion(Sink<Object> sink) {
+    return new _JsonUtf8DecoderSink(_reviver, sink, _allowMalformed);
+  }
+}
+
 //// Implementation ///////////////////////////////////////////////////////////
 
 // Simple API for JSON parsing.
@@ -760,6 +790,9 @@
     int state = this.state;
     while (position < length) {
       int char = getChar(position);
+      if (char == null) {
+        print("[[[$chunk]]] - $position - ${chunk.runtimeType}");
+      }
       switch (char) {
         case SPACE:
         case CARRIAGE_RETURN:
@@ -847,6 +880,7 @@
         default:
           if ((state & ALLOW_VALUE_MASK) != 0) fail(position);
           state |= VALUE_READ_BITS;
+          if (char == null) print("$chunk - $position");
           position = parseNumber(char, position);
           break;
       }
@@ -1240,7 +1274,7 @@
       listener.handleNumber(sign * intValue);
       return position;
     }
-    // Double values at or above this value (2**53) may have lost precission.
+    // Double values at or above this value (2 ** 53) may have lost precission.
     // Only trust results that are below this value.
     const double maxExactDouble = 9007199254740992.0;
     if (doubleValue < maxExactDouble) {
diff --git a/runtime/lib/mirrors.cc b/runtime/lib/mirrors.cc
index 24c2ef6..ad999b5 100644
--- a/runtime/lib/mirrors.cc
+++ b/runtime/lib/mirrors.cc
@@ -1360,7 +1360,7 @@
   ASSERT(!closure.IsNull());
 
   Function& function = Function::Handle();
-  bool callable = closure.IsCallable(&function, NULL);
+  bool callable = closure.IsCallable(&function);
   if (callable) {
     return CreateMethodMirror(function, Instance::null_instance());
   }
diff --git a/runtime/lib/mirrors_impl.dart b/runtime/lib/mirrors_impl.dart
index f2799ee..acdfaff 100644
--- a/runtime/lib/mirrors_impl.dart
+++ b/runtime/lib/mirrors_impl.dart
@@ -773,7 +773,7 @@
   Map<Symbol, Mirror> get _members {
     if (_cachedMembers == null) {
       var whoseMembers = _isMixinAlias ? _trueSuperclass : this;
-      _cachedMembers = _makeMemberMap(mixin._computeMembers(whoseMembers._reflectee));
+      _cachedMembers = _makeMemberMap(mixin._computeMembers(whoseMembers.mixin._reflectee));
     }
     return _cachedMembers;
   }
diff --git a/runtime/tests/vm/vm.status b/runtime/tests/vm/vm.status
index 03a0715..7e7ab4f 100644
--- a/runtime/tests/vm/vm.status
+++ b/runtime/tests/vm/vm.status
@@ -22,6 +22,14 @@
 [ $mode == debug ]
 # This is a benchmark that is not informative in debug mode.
 cc/CorelibIsolateStartup: Skip
+# Negative tests of VerifiedMemory should crash iff in DEBUG mode.
+# TODO(koda): Improve support for negative tests.
+cc/VerifyImplicit_Crash: Crash
+cc/VerifyExplicit_Crash: Crash
+
+[ $mode == debug && $system == windows ]
+cc/VerifiedMemoryBasic: Crash # Issue 21469
+cc/VerifiedMemoryAccept: Crash # Issue 21469
 
 # The following section refers to the dart vm tests which live under
 # runtime/tests/vm/dart.
diff --git a/runtime/vm/class_finalizer.cc b/runtime/vm/class_finalizer.cc
index 45f44b0..9868440 100644
--- a/runtime/vm/class_finalizer.cc
+++ b/runtime/vm/class_finalizer.cc
@@ -2135,7 +2135,10 @@
       }
       continue;  // Skip the implicit constructor.
     }
-    if (!func.is_static()) {
+    if (!func.is_static() &&
+        !func.IsMethodExtractor() &&
+        !func.IsNoSuchMethodDispatcher() &&
+        !func.IsInvokeFieldDispatcher()) {
       func = func.Clone(cls);
       cloned_funcs.Add(func);
     }
@@ -2153,6 +2156,8 @@
   const intptr_t num_fields = fields.Length();
   for (intptr_t i = 0; i < num_fields; i++) {
     field ^= fields.At(i);
+    // Static fields are shared between the mixin class and the mixin
+    // application class.
     if (!field.is_static()) {
       field = field.Clone(cls);
       cloned_fields.Add(field);
diff --git a/runtime/vm/code_descriptors_test.cc b/runtime/vm/code_descriptors_test.cc
index 7de90df..5e68bea 100644
--- a/runtime/vm/code_descriptors_test.cc
+++ b/runtime/vm/code_descriptors_test.cc
@@ -21,22 +21,8 @@
 
 
 CODEGEN_TEST_GENERATE(StackmapCodegen, test) {
-  Assembler assembler;
-  const String& function_name = String::ZoneHandle(Symbols::New("test"));
-  Class& cls = Class::ZoneHandle();
-  const Script& script = Script::Handle();
-  cls = Class::New(function_name, script, Scanner::kNoSourcePos);
-  const Function& function = Function::ZoneHandle(
-      Function::New(function_name, RawFunction::kRegularFunction,
-                    true, false, false, false, false, cls, 0));
-  function.set_result_type(Type::Handle(Type::DynamicType()));
-  const Array& functions = Array::Handle(Array::New(1));
-  functions.SetAt(0, function);
-  cls.SetFunctions(functions);
-  Library& lib = Library::Handle(Library::CoreLibrary());
-  lib.AddClass(cls);
   ParsedFunction* parsed_function =
-      new ParsedFunction(Isolate::Current(), function);
+      new ParsedFunction(Isolate::Current(), test->function());
   LiteralNode* l = new LiteralNode(kPos, Smi::ZoneHandle(Smi::New(1)));
   test->node_sequence()->Add(new ReturnNode(kPos, l));
   l = new LiteralNode(kPos, Smi::ZoneHandle(Smi::New(2)));
@@ -46,6 +32,11 @@
   parsed_function->SetNodeSequence(test->node_sequence());
   parsed_function->set_instantiator(NULL);
   parsed_function->set_default_parameter_values(Object::null_array());
+  parsed_function->EnsureExpressionTemp();
+  test->node_sequence()->scope()->AddVariable(
+      parsed_function->expression_temp_var());
+  test->node_sequence()->scope()->AddVariable(
+      parsed_function->current_context_var());
   parsed_function->AllocateVariables();
   bool retval;
   Isolate* isolate = Isolate::Current();
@@ -133,7 +124,7 @@
     const Error& error =
         Error::Handle(Compiler::CompileParsedFunction(parsed_function));
     EXPECT(error.IsNull());
-    const Code& code = Code::Handle(function.CurrentCode());
+    const Code& code = Code::Handle(test->function().CurrentCode());
 
     const Array& stack_maps =
         Array::Handle(stackmap_table_builder->FinalizeStackmaps(code));
diff --git a/runtime/vm/compiler.cc b/runtime/vm/compiler.cc
index 22273f1..0c47e54 100644
--- a/runtime/vm/compiler.cc
+++ b/runtime/vm/compiler.cc
@@ -761,9 +761,7 @@
     RawLocalVarDescriptors::VarInfo var_info;
     var_descriptors.GetInfo(i, &var_info);
     const int8_t kind = var_info.kind();
-    if (kind == RawLocalVarDescriptors::kSavedEntryContext) {
-      OS::Print("  saved caller's CTX reg offset %d\n", var_info.index());
-    } else if (kind == RawLocalVarDescriptors::kSavedCurrentContext) {
+    if (kind == RawLocalVarDescriptors::kSavedCurrentContext) {
       OS::Print("  saved current CTX reg offset %d\n", var_info.index());
     } else {
       if (kind == RawLocalVarDescriptors::kContextLevel) {
@@ -1049,8 +1047,9 @@
     ParsedFunction* parsed_function = new ParsedFunction(isolate, func);
     parsed_function->SetNodeSequence(fragment);
     parsed_function->set_default_parameter_values(Object::null_array());
-    parsed_function->EnsureExpressionTemp();
-    fragment->scope()->AddVariable(parsed_function->expression_temp_var());
+    fragment->scope()->AddVariable(parsed_function->EnsureExpressionTemp());
+    fragment->scope()->AddVariable(
+        parsed_function->current_context_var());
     parsed_function->AllocateVariables();
 
     // Non-optimized code generator.
diff --git a/runtime/vm/dart_api_impl.cc b/runtime/vm/dart_api_impl.cc
index b8827c5b..8ab020a 100644
--- a/runtime/vm/dart_api_impl.cc
+++ b/runtime/vm/dart_api_impl.cc
@@ -3987,7 +3987,7 @@
   DARTSCOPE(isolate);
   CHECK_CALLBACK_STATE(isolate);
   const Instance& closure_obj = Api::UnwrapInstanceHandle(isolate, closure);
-  if (closure_obj.IsNull() || !closure_obj.IsCallable(NULL, NULL)) {
+  if (closure_obj.IsNull() || !closure_obj.IsCallable(NULL)) {
     RETURN_TYPE_ERROR(isolate, closure, Instance);
   }
   if (number_of_arguments < 0) {
diff --git a/runtime/vm/dart_entry.cc b/runtime/vm/dart_entry.cc
index 80d54a4..52f0024 100644
--- a/runtime/vm/dart_entry.cc
+++ b/runtime/vm/dart_entry.cc
@@ -28,15 +28,6 @@
 }
 
 
-RawObject* DartEntry::InvokeFunction(const Function& function,
-                                     const Array& arguments,
-                                     const Array& arguments_descriptor) {
-  const Context& context =
-      Context::Handle(Isolate::Current()->object_store()->empty_context());
-  return InvokeFunction(function, arguments, arguments_descriptor, context);
-}
-
-
 class ScopedIsolateStackLimits : public ValueObject {
  public:
   explicit ScopedIsolateStackLimits(Isolate* isolate)
@@ -65,8 +56,7 @@
 
 RawObject* DartEntry::InvokeFunction(const Function& function,
                                      const Array& arguments,
-                                     const Array& arguments_descriptor,
-                                     const Context& context) {
+                                     const Array& arguments_descriptor) {
   // Get the entrypoint corresponding to the function specified, this
   // will result in a compilation of the function if it is not already
   // compiled.
@@ -93,20 +83,19 @@
         static_cast<int64_t>(code.EntryPoint()),
         reinterpret_cast<int64_t>(&arguments_descriptor),
         reinterpret_cast<int64_t>(&arguments),
-        reinterpret_cast<int64_t>(&context)));
+        0));
 #else
     return bit_copy<RawObject*, int64_t>(Simulator::Current()->Call(
         reinterpret_cast<int32_t>(entrypoint),
         static_cast<int32_t>(code.EntryPoint()),
         reinterpret_cast<int32_t>(&arguments_descriptor),
         reinterpret_cast<int32_t>(&arguments),
-        reinterpret_cast<int32_t>(&context)));
+        0));
 #endif
 #else
     return entrypoint(code.EntryPoint(),
                       arguments_descriptor,
-                      arguments,
-                      context);
+                      arguments);
 #endif
 }
 
@@ -126,8 +115,7 @@
   // method of the instance. This will result in a compilation of the function
   // if it is not already compiled.
   Function& function = Function::Handle();
-  Context& context = Context::Handle();
-  if (instance.IsCallable(&function, &context)) {
+  if (instance.IsCallable(&function)) {
     // Only invoke the function if its arguments are compatible.
     const ArgumentsDescriptor args_desc(arguments_descriptor);
     if (function.AreValidArgumentCounts(args_desc.Count(),
@@ -135,7 +123,7 @@
                                         NULL)) {
       // The closure or non-closure object (receiver) is passed as implicit
       // first argument. It is already included in the arguments array.
-      return InvokeFunction(function, arguments, arguments_descriptor, context);
+      return InvokeFunction(function, arguments, arguments_descriptor);
     }
   }
   // There is no compatible 'call' method, so invoke noSuchMethod.
diff --git a/runtime/vm/dart_entry.h b/runtime/vm/dart_entry.h
index 9b9b5c4..d8e86af 100644
--- a/runtime/vm/dart_entry.h
+++ b/runtime/vm/dart_entry.h
@@ -13,7 +13,6 @@
 // Forward declarations.
 class Array;
 class Closure;
-class Context;
 class Function;
 class Instance;
 class Integer;
@@ -103,8 +102,7 @@
   // On success, returns a RawInstance.  On failure, a RawError.
   typedef RawObject* (*invokestub)(uword entry_point,
                                    const Array& arguments_descriptor,
-                                   const Array& arguments,
-                                   const Context& context);
+                                   const Array& arguments);
 
   // Invokes the specified instance function or static function.
   // The first argument of an instance function is the receiver.
@@ -113,18 +111,11 @@
   static RawObject* InvokeFunction(const Function& function,
                                    const Array& arguments);
 
-  // Invokes the specified instance or static function.
-  // On success, returns a RawInstance.  On failure, a RawError.
-  static RawObject* InvokeFunction(const Function& function,
-                                   const Array& arguments,
-                                   const Array& arguments_descriptor);
-
   // Invokes the specified instance, static, or closure function.
   // On success, returns a RawInstance.  On failure, a RawError.
   static RawObject* InvokeFunction(const Function& function,
                                    const Array& arguments,
-                                   const Array& arguments_descriptor,
-                                   const Context& context);
+                                   const Array& arguments_descriptor);
 
   // Invokes the closure object given as the first argument.
   // On success, returns a RawInstance.  On failure, a RawError.
diff --git a/runtime/vm/debugger.cc b/runtime/vm/debugger.cc
index 584cad1..5eface55 100644
--- a/runtime/vm/debugger.cc
+++ b/runtime/vm/debugger.cc
@@ -458,29 +458,7 @@
 }
 
 
-RawContext* ActivationFrame::GetSavedEntryContext() {
-  // Attempt to find a saved context.
-  GetVarDescriptors();
-  intptr_t var_desc_len = var_descriptors_.Length();
-  for (intptr_t i = 0; i < var_desc_len; i++) {
-    RawLocalVarDescriptors::VarInfo var_info;
-    var_descriptors_.GetInfo(i, &var_info);
-    const int8_t kind = var_info.kind();
-    if (kind == RawLocalVarDescriptors::kSavedEntryContext) {
-      if (FLAG_trace_debugger_stacktrace) {
-        OS::PrintErr("\tFound saved entry ctx at index %d\n", var_info.index());
-      }
-      return GetLocalContextVar(var_info.index());
-    }
-  }
-
-  // No saved context.  Return the current context.
-  return ctx_.raw();
-}
-
-
-// Get the saved context if the callee of this activation frame is a
-// closure function.
+// Get the saved current context of this activation.
 RawContext* ActivationFrame::GetSavedCurrentContext() {
   GetVarDescriptors();
   intptr_t var_desc_len = var_descriptors_.Length();
@@ -493,7 +471,8 @@
         OS::PrintErr("\tFound saved current ctx at index %d\n",
             var_info.index());
       }
-      return GetLocalContextVar(var_info.index());
+      ASSERT(Object::Handle(GetLocalVar(var_info.index())).IsContext());
+      return Context::RawCast(GetLocalVar(var_info.index()));
     }
   }
   UNREACHABLE();
@@ -678,21 +657,6 @@
 }
 
 
-RawContext* ActivationFrame::GetLocalContextVar(intptr_t slot_index) {
-  Object& context = Object::Handle(GetLocalVar(slot_index));
-  if (context.IsContext()) {
-    // We found a saved context.
-    return Context::Cast(context).raw();
-  } else if (context.raw() == Symbols::OptimizedOut().raw()) {
-    // The optimizing compiler has eliminated the saved context.
-    return Context::null();
-  } else {
-    UNREACHABLE();
-    return Context::null();
-  }
-}
-
-
 void ActivationFrame::PrintContextMismatchError(
     const String& var_name,
     intptr_t ctx_slot,
@@ -761,13 +725,7 @@
     *value = GetLocalInstanceVar(var_info.index());
   } else {
     ASSERT(kind == RawLocalVarDescriptors::kContextVar);
-    if (ctx_.IsNull()) {
-      // The context has been removed by the optimizing compiler.
-      //
-      // TODO(turnidge): This may be erroneous.  Revisit.
-      *value = Symbols::OptimizedOut().raw();
-      return;
-    }
+    ASSERT(!ctx_.IsNull());
 
     // The context level at the PC/token index of this activation frame.
     intptr_t frame_ctx_level = ContextLevel();
@@ -1234,66 +1192,19 @@
                                             StackFrame* frame,
                                             const Code& code,
                                             const Array& deopt_frame,
-                                            intptr_t deopt_frame_offset,
-                                            ActivationFrame* callee_activation,
-                                            const Context& entry_ctx) {
+                                            intptr_t deopt_frame_offset) {
   ASSERT(code.ContainsInstructionAt(pc));
-  // We provide either a callee activation or an entry context.  Not both.
-  ASSERT(((callee_activation != NULL) && entry_ctx.IsNull()) ||
-         ((callee_activation == NULL) && !entry_ctx.IsNull()));
   ActivationFrame* activation =
       new ActivationFrame(pc, frame->fp(), frame->sp(), code,
                           deopt_frame, deopt_frame_offset);
 
-  // Is there a closure call at the current PC?
-  //
-  // We can't just check the callee_activation to see if it is a
-  // closure function, because it may not be on the stack yet.
-  bool is_closure_call = false;
-  const PcDescriptors& pc_desc =
-      PcDescriptors::Handle(isolate, code.pc_descriptors());
-  PcDescriptors::Iterator iter(pc_desc, RawPcDescriptors::kClosureCall);
-  while (iter.MoveNext()) {
-    if (iter.Pc() == pc) {
-      is_closure_call = true;
-      break;
-    }
-  }
-
   // Recover the context for this frame.
-  if (is_closure_call) {
-    // If the callee is a closure, we should have stored the context
-    // in the current frame before making the call.
-    const Context& closure_call_ctx =
-        Context::Handle(isolate, activation->GetSavedCurrentContext());
-    ASSERT(!closure_call_ctx.IsNull());
-    activation->SetContext(closure_call_ctx);
-    if (FLAG_trace_debugger_stacktrace) {
-      OS::PrintErr("\tUsing closure call ctx: %s\n",
-                   closure_call_ctx.ToCString());
-    }
-  } else if (callee_activation == NULL) {
-    // No callee available.  Use incoming entry context.  Could be from
-    // isolate's top context or from an entry frame.
-    ASSERT(!entry_ctx.IsNull());
-    activation->SetContext(entry_ctx);
-    if (FLAG_trace_debugger_stacktrace) {
-      OS::PrintErr("\tUsing entry ctx: %s\n", entry_ctx.ToCString());
-    }
-  } else {
-    // Use the context provided by our callee.  This is either the
-    // callee's context or a context that was saved in the callee's
-    // frame.
-    //
-    // The callee's saved context may be NULL if it was eliminated by
-    // the optimizing compiler.
-    const Context& callee_ctx =
-        Context::Handle(isolate, callee_activation->GetSavedEntryContext());
-    activation->SetContext(callee_ctx);
-    if (FLAG_trace_debugger_stacktrace) {
-      OS::PrintErr("\tUsing callee call ctx: %s\n",
-                   callee_ctx.ToCString());
-    }
+  const Context& ctx =
+      Context::Handle(isolate, activation->GetSavedCurrentContext());
+  ASSERT(!ctx.IsNull());
+  activation->SetContext(ctx);
+  if (FLAG_trace_debugger_stacktrace) {
+    OS::PrintErr("\tUsing saved context: %s\n", ctx.ToCString());
   }
   if (FLAG_trace_debugger_stacktrace) {
     OS::PrintErr("\tLine number: %" Pd "\n", activation->LineNumber());
@@ -1330,8 +1241,6 @@
   Isolate* isolate = Isolate::Current();
   DebuggerStackTrace* stack_trace = new DebuggerStackTrace(8);
   StackFrameIterator iterator(false);
-  ActivationFrame* current_activation = NULL;
-  Context& entry_ctx = Context::Handle(isolate, isolate->top_context());
   Code& code = Code::Handle(isolate);
   Code& inlined_code = Code::Handle(isolate);
   Array& deopt_frame = Array::Handle(isolate);
@@ -1344,15 +1253,7 @@
       OS::PrintErr("CollectStackTrace: visiting frame:\n\t%s\n",
                    frame->ToCString());
     }
-    if (frame->IsEntryFrame()) {
-      current_activation = NULL;
-      entry_ctx = reinterpret_cast<EntryFrame*>(frame)->SavedContext();
-      if (FLAG_trace_debugger_stacktrace) {
-        OS::PrintErr("\tFound saved ctx in  entry frame:\n\t%s\n",
-                     entry_ctx.ToCString());
-      }
-
-    } else if (frame->IsDartFrame()) {
+    if (frame->IsDartFrame()) {
       code = frame->LookupDartCode();
       if (code.is_optimized()) {
         deopt_frame = DeoptimizeToArray(isolate, frame, code);
@@ -1368,28 +1269,20 @@
                          function.ToFullyQualifiedCString());
           }
           intptr_t deopt_frame_offset = it.GetDeoptFpOffset();
-          current_activation = CollectDartFrame(isolate,
-                                                it.pc(),
-                                                frame,
-                                                inlined_code,
-                                                deopt_frame,
-                                                deopt_frame_offset,
-                                                current_activation,
-                                                entry_ctx);
-          stack_trace->AddActivation(current_activation);
-          entry_ctx = Context::null();  // Only use entry context once.
+          stack_trace->AddActivation(CollectDartFrame(isolate,
+                                                      it.pc(),
+                                                      frame,
+                                                      inlined_code,
+                                                      deopt_frame,
+                                                      deopt_frame_offset));
         }
       } else {
-        current_activation = CollectDartFrame(isolate,
-                                              frame->pc(),
-                                              frame,
-                                              code,
-                                              Object::null_array(),
-                                              0,
-                                              current_activation,
-                                              entry_ctx);
-        stack_trace->AddActivation(current_activation);
-        entry_ctx = Context::null();  // Only use entry context once.
+        stack_trace->AddActivation(CollectDartFrame(isolate,
+                                                    frame->pc(),
+                                                    frame,
+                                                    code,
+                                                    Object::null_array(),
+                                                    0));
       }
     }
   }
diff --git a/runtime/vm/debugger.h b/runtime/vm/debugger.h
index 7cb2f3a..cca84d4 100644
--- a/runtime/vm/debugger.h
+++ b/runtime/vm/debugger.h
@@ -179,7 +179,6 @@
   RawArray* GetLocalVariables();
   RawObject* GetReceiver();
 
-  RawContext* GetSavedEntryContext();
   RawContext* GetSavedCurrentContext();
 
   RawObject* Evaluate(const String& expr);
@@ -199,11 +198,6 @@
 
   RawObject* GetLocalVar(intptr_t slot_index);
   RawInstance* GetLocalInstanceVar(intptr_t slot_index);
-  RawContext* GetLocalContextVar(intptr_t slot_index);
-
-  RawInstance* GetLocalVarValue(intptr_t slot_index);
-  RawInstance* GetInstanceCallReceiver(intptr_t num_actual_args);
-  RawObject* GetClosureObject(intptr_t num_acatual_args);
 
   uword pc_;
   uword fp_;
@@ -481,9 +475,7 @@
                                            StackFrame* frame,
                                            const Code& code,
                                            const Array& deopt_frame,
-                                           intptr_t deopt_frame_offset,
-                                           ActivationFrame* callee_activation,
-                                           const Context& entry_ctx);
+                                           intptr_t deopt_frame_offset);
   static RawArray* DeoptimizeToArray(Isolate* isolate,
                                      StackFrame* frame,
                                      const Code& code);
diff --git a/runtime/vm/debugger_arm.cc b/runtime/vm/debugger_arm.cc
index 43d3031..fc924ca 100644
--- a/runtime/vm/debugger_arm.cc
+++ b/runtime/vm/debugger_arm.cc
@@ -13,26 +13,6 @@
 
 namespace dart {
 
-RawInstance* ActivationFrame::GetInstanceCallReceiver(
-                 intptr_t num_actual_args) {
-  ASSERT(num_actual_args > 0);  // At minimum we have a receiver on the stack.
-  // Stack pointer points to last argument that was pushed on the stack.
-  uword receiver_addr = sp() + ((num_actual_args - 1) * kWordSize);
-  return reinterpret_cast<RawInstance*>(
-             *reinterpret_cast<uword*>(receiver_addr));
-}
-
-
-RawObject* ActivationFrame::GetClosureObject(intptr_t num_actual_args) {
-  // At a minimum we have the closure object on the stack.
-  ASSERT(num_actual_args > 0);
-  // Stack pointer points to last argument that was pushed on the stack.
-  uword closure_addr = sp() + ((num_actual_args - 1) * kWordSize);
-  return reinterpret_cast<RawObject*>(
-             *reinterpret_cast<uword*>(closure_addr));
-}
-
-
 uword CodeBreakpoint::OrigStubAddress() const {
   return saved_value_;
 }
diff --git a/runtime/vm/debugger_arm64.cc b/runtime/vm/debugger_arm64.cc
index 2a74ad6..abef24d 100644
--- a/runtime/vm/debugger_arm64.cc
+++ b/runtime/vm/debugger_arm64.cc
@@ -13,26 +13,6 @@
 
 namespace dart {
 
-RawInstance* ActivationFrame::GetInstanceCallReceiver(
-                 intptr_t num_actual_args) {
-  ASSERT(num_actual_args > 0);  // At minimum we have a receiver on the stack.
-  // Stack pointer points to last argument that was pushed on the stack.
-  const uword receiver_addr = sp() + ((num_actual_args - 1) * kWordSize);
-  const uword receiver = *reinterpret_cast<uword*>(receiver_addr);
-  return reinterpret_cast<RawInstance*>(receiver);
-}
-
-
-RawObject* ActivationFrame::GetClosureObject(intptr_t num_actual_args) {
-  // At a minimum we have the closure object on the stack.
-  ASSERT(num_actual_args > 0);
-  // Stack pointer points to last argument that was pushed on the stack.
-  const uword closure_addr = sp() + ((num_actual_args - 1) * kWordSize);
-  const uword closure = *reinterpret_cast<uword*>(closure_addr);
-  return reinterpret_cast<RawObject*>(closure);
-}
-
-
 uword CodeBreakpoint::OrigStubAddress() const {
   const Code& code = Code::Handle(code_);
   const Array& object_pool = Array::Handle(code.ObjectPool());
diff --git a/runtime/vm/debugger_ia32.cc b/runtime/vm/debugger_ia32.cc
index ed6c944..b05ae16 100644
--- a/runtime/vm/debugger_ia32.cc
+++ b/runtime/vm/debugger_ia32.cc
@@ -17,26 +17,6 @@
 
 namespace dart {
 
-RawInstance* ActivationFrame::GetInstanceCallReceiver(
-                 intptr_t num_actual_args) {
-  ASSERT(num_actual_args > 0);  // At minimum we have a receiver on the stack.
-  // Stack pointer points to last argument that was pushed on the stack.
-  uword receiver_addr = sp() + ((num_actual_args - 1) * kWordSize);
-  return reinterpret_cast<RawInstance*>(
-             *reinterpret_cast<uword*>(receiver_addr));
-}
-
-
-RawObject* ActivationFrame::GetClosureObject(intptr_t num_actual_args) {
-  // At a minimum we have the closure object on the stack.
-  ASSERT(num_actual_args > 0);
-  // Stack pointer points to last argument that was pushed on the stack.
-  uword closure_addr = sp() + ((num_actual_args - 1) * kWordSize);
-  return reinterpret_cast<RawObject*>(
-      *reinterpret_cast<uword*>(closure_addr));
-}
-
-
 uword CodeBreakpoint::OrigStubAddress() const {
   return saved_value_;
 }
diff --git a/runtime/vm/debugger_mips.cc b/runtime/vm/debugger_mips.cc
index eb11fbc..e3918e67 100644
--- a/runtime/vm/debugger_mips.cc
+++ b/runtime/vm/debugger_mips.cc
@@ -13,26 +13,6 @@
 
 namespace dart {
 
-RawInstance* ActivationFrame::GetInstanceCallReceiver(
-                 intptr_t num_actual_args) {
-  ASSERT(num_actual_args > 0);  // At minimum we have a receiver on the stack.
-  // Stack pointer points to last argument that was pushed on the stack.
-  uword receiver_addr = sp() + ((num_actual_args - 1) * kWordSize);
-  return reinterpret_cast<RawInstance*>(
-             *reinterpret_cast<uword*>(receiver_addr));
-}
-
-
-RawObject* ActivationFrame::GetClosureObject(intptr_t num_actual_args) {
-  // At a minimum we have the closure object on the stack.
-  ASSERT(num_actual_args > 0);
-  // Stack pointer points to last argument that was pushed on the stack.
-  uword closure_addr = sp() + ((num_actual_args - 1) * kWordSize);
-  return reinterpret_cast<RawObject*>(
-             *reinterpret_cast<uword*>(closure_addr));
-}
-
-
 uword CodeBreakpoint::OrigStubAddress() const {
   return saved_value_;
 }
diff --git a/runtime/vm/debugger_x64.cc b/runtime/vm/debugger_x64.cc
index b76469e..f32b6a7 100644
--- a/runtime/vm/debugger_x64.cc
+++ b/runtime/vm/debugger_x64.cc
@@ -15,26 +15,6 @@
 
 namespace dart {
 
-RawInstance* ActivationFrame::GetInstanceCallReceiver(
-                 intptr_t num_actual_args) {
-  ASSERT(num_actual_args > 0);  // At minimum we have a receiver on the stack.
-  // Stack pointer points to last argument that was pushed on the stack.
-  uword receiver_addr = sp() + ((num_actual_args - 1) * kWordSize);
-  return reinterpret_cast<RawInstance*>(
-             *reinterpret_cast<uword*>(receiver_addr));
-}
-
-
-RawObject* ActivationFrame::GetClosureObject(intptr_t num_actual_args) {
-  // At a minimum we have the closure object on the stack.
-  ASSERT(num_actual_args > 0);
-  // Stack pointer points to last argument that was pushed on the stack.
-  uword closure_addr = sp() + ((num_actual_args - 1) * kWordSize);
-  return reinterpret_cast<RawObject*>(
-             *reinterpret_cast<uword*>(closure_addr));
-}
-
-
 uword CodeBreakpoint::OrigStubAddress() const {
   const Code& code = Code::Handle(code_);
   const Array& object_pool = Array::Handle(code.ObjectPool());
diff --git a/runtime/vm/exceptions.cc b/runtime/vm/exceptions.cc
index 9f53b58..88b7375 100644
--- a/runtime/vm/exceptions.cc
+++ b/runtime/vm/exceptions.cc
@@ -280,13 +280,6 @@
   RawObject* raw_exception = exception_object.raw();
   RawObject* raw_stacktrace = stacktrace_object.raw();
 
-  // The following operation is part of the 'epilogue' of the CallToRuntime,
-  // CallBootstrapCFunction, and CallNativeCFunction stubs. In the case of an
-  // exception, we skip the epilogues and must set the correct state here.
-  // The other operations performed as part of the 'epilogue' are handled
-  // by the simulator's Longjmp or the JumpToExceptionHandler stub.
-  isolate->set_top_context(Context::null());
-
 #if defined(USING_SIMULATOR)
   // Unwinding of the C++ frames and destroying of their stack resources is done
   // by the simulator, because the target stack_pointer is a simulated stack
diff --git a/runtime/vm/flow_graph.cc b/runtime/vm/flow_graph.cc
index 7caa3f9..78405d3 100644
--- a/runtime/vm/flow_graph.cc
+++ b/runtime/vm/flow_graph.cc
@@ -8,10 +8,12 @@
 #include "vm/flow_graph_builder.h"
 #include "vm/intermediate_language.h"
 #include "vm/growable_array.h"
+#include "vm/object_store.h"
 #include "vm/report.h"
 
 namespace dart {
 
+DEFINE_FLAG(bool, prune_dead_locals, true, "optimize dead locals away");
 DECLARE_FLAG(bool, reorder_basic_blocks);
 DECLARE_FLAG(bool, trace_optimization);
 DECLARE_FLAG(bool, verify_compiler);
@@ -36,6 +38,7 @@
     optimized_block_order_(),
     constant_null_(NULL),
     constant_dead_(NULL),
+    constant_empty_context_(NULL),
     block_effects_(NULL),
     licm_allowed_(true),
     loop_headers_(NULL),
@@ -465,10 +468,13 @@
   // Returns true if the value set by the given store reaches any load from the
   // same local variable.
   bool IsStoreAlive(BlockEntryInstr* block, StoreLocalInstr* store) {
+    if (store->local().Equals(*flow_graph_->CurrentContextVar())) {
+      return true;
+    }
+
     if (store->is_dead()) {
       return false;
     }
-
     if (store->is_last()) {
       const intptr_t index = store->local().BitIndexIn(num_non_copied_params_);
       return GetLiveOutSet(block)->Contains(index);
@@ -480,6 +486,9 @@
   // Returns true if the given load is the last for the local and the value
   // of the local will not flow into another one.
   bool IsLastLoad(BlockEntryInstr* block, LoadLocalInstr* load) {
+    if (load->local().Equals(*flow_graph_->CurrentContextVar())) {
+      return false;
+    }
     const intptr_t index = load->local().BitIndexIn(num_non_copied_params_);
     return load->is_last() && !GetLiveOutSet(block)->Contains(index);
   }
@@ -565,11 +574,13 @@
   VariableLivenessAnalysis variable_liveness(this);
   variable_liveness.Analyze();
 
+  GrowableArray<PhiInstr*> live_phis;
+
   InsertPhis(preorder_,
              variable_liveness.ComputeAssignedVars(),
-             dominance_frontier);
+             dominance_frontier,
+             &live_phis);
 
-  GrowableArray<PhiInstr*> live_phis;
 
   // Rename uses to reference inserted phis where appropriate.
   // Collect phis that reach a non-environment use.
@@ -702,7 +713,8 @@
 void FlowGraph::InsertPhis(
     const GrowableArray<BlockEntryInstr*>& preorder,
     const GrowableArray<BitVector*>& assigned_vars,
-    const GrowableArray<BitVector*>& dom_frontier) {
+    const GrowableArray<BitVector*>& dom_frontier,
+    GrowableArray<PhiInstr*>* live_phis) {
   const intptr_t block_count = preorder.length();
   // Map preorder block number to the highest variable index that has a phi
   // in that block.  Use it to avoid inserting multiple phis for the same
@@ -722,6 +734,8 @@
   // Insert phis for each variable in turn.
   GrowableArray<BlockEntryInstr*> worklist;
   for (intptr_t var_index = 0; var_index < variable_count(); ++var_index) {
+    const bool always_live = !FLAG_prune_dead_locals ||
+        (var_index == CurrentContextEnvIndex());
     // Add to the worklist each block containing an assignment.
     for (intptr_t block_index = 0; block_index < block_count; ++block_index) {
       if (assigned_vars[block_index]->Contains(var_index)) {
@@ -740,7 +754,12 @@
         if (has_already[index] < var_index) {
           BlockEntryInstr* block = preorder[index];
           ASSERT(block->IsJoinEntry());
-          block->AsJoinEntry()->InsertPhi(var_index, variable_count());
+          PhiInstr* phi = block->AsJoinEntry()->InsertPhi(var_index,
+                                                          variable_count());
+          if (always_live) {
+            phi->mark_alive();
+            live_phis->Add(phi);
+          }
           has_already[index] = var_index;
           if (work[index] < var_index) {
             work[index] = var_index;
@@ -764,6 +783,8 @@
   // Add global constants to the initial definitions.
   constant_null_ = GetConstant(Object::ZoneHandle());
   constant_dead_ = GetConstant(Symbols::OptimizedOut());
+  constant_empty_context_ = GetConstant(Context::Handle(
+      isolate()->object_store()->empty_context()));
 
   // Add parameters to the initial definitions and renaming environment.
   if (inlining_parameters != NULL) {
@@ -787,11 +808,22 @@
     }
   }
 
-  // Initialize all locals with #null in the renaming environment.  For OSR,
-  // the locals have already been handled as parameters.
+  // Initialize all locals in the renaming environment  For OSR, the locals have
+  // already been handled as parameters.
   if (!IsCompiledForOsr()) {
     for (intptr_t i = parameter_count(); i < variable_count(); ++i) {
-      env.Add(constant_null());
+      if (i == CurrentContextEnvIndex()) {
+        if (parsed_function().function().IsClosureFunction()) {
+          CurrentContextInstr* context = new CurrentContextInstr();
+          context->set_ssa_temp_index(alloc_ssa_temp_index());  // New SSA temp.
+          AddToInitialDefinitions(context);
+          env.Add(context);
+        } else {
+          env.Add(constant_empty_context());
+        }
+      } else {
+        env.Add(constant_null());
+      }
     }
   }
 
@@ -812,12 +844,6 @@
                         *env,
                         num_non_copied_params_,
                         &parsed_function_);
-  // TODO(fschneider): Add predicates CanEagerlyDeoptimize and
-  // CanLazilyDeoptimize to instructions to generally deal with instructions
-  // that have pushed arguments and input operands.
-  // Right now, closure calls are the only instructions that have both. They
-  // also don't have an eager deoptimziation point, so the environment attached
-  // here is only used for after the call.
   if (instr->IsClosureCall()) {
     deopt_env = deopt_env->DeepCopy(isolate(),
                                     deopt_env->Length() - instr->InputCount());
@@ -846,7 +872,7 @@
         if (phi != NULL) {
           (*env)[i] = phi;
           phi->set_ssa_temp_index(alloc_ssa_temp_index());  // New SSA temp.
-          if (block_entry->InsideTryBlock()) {
+          if (block_entry->InsideTryBlock() && !phi->is_alive()) {
             // This is a safe approximation.  Inside try{} all locals are
             // used at every call implicitly, so we mark all phis as live
             // from the start.
@@ -872,7 +898,11 @@
   // slots with null.
   BitVector* live_in = variable_liveness->GetLiveInSet(block_entry);
   for (intptr_t i = 0; i < variable_count(); i++) {
-    if (!live_in->Contains(i)) {
+    // TODO(fschneider): Make sure that live_in always contains the
+    // CurrentContext variable to avoid the special case here.
+    if (FLAG_prune_dead_locals &&
+        !live_in->Contains(i) &&
+        (i != CurrentContextEnvIndex())) {
       (*env)[i] = constant_dead();
     }
   }
@@ -940,7 +970,8 @@
           intptr_t index = store->local().BitIndexIn(num_non_copied_params_);
           result = store->value()->definition();
 
-          if (variable_liveness->IsStoreAlive(block_entry, store)) {
+          if (!FLAG_prune_dead_locals ||
+              variable_liveness->IsStoreAlive(block_entry, store)) {
             (*env)[index] = result;
           } else {
             (*env)[index] = constant_dead();
@@ -958,7 +989,8 @@
             live_phis->Add(phi);
           }
 
-          if (variable_liveness->IsLastLoad(block_entry, load)) {
+          if (FLAG_prune_dead_locals &&
+              variable_liveness->IsLastLoad(block_entry, load)) {
             (*env)[index] = constant_dead();
           }
 
diff --git a/runtime/vm/flow_graph.h b/runtime/vm/flow_graph.h
index 8d85b4e..c319412 100644
--- a/runtime/vm/flow_graph.h
+++ b/runtime/vm/flow_graph.h
@@ -111,6 +111,15 @@
     return num_non_copied_params_;
   }
 
+  LocalVariable* CurrentContextVar() const {
+    return parsed_function().current_context_var();
+  }
+
+  intptr_t CurrentContextEnvIndex() const {
+    return parsed_function().current_context_var()->BitIndexIn(
+        num_non_copied_params_);
+  }
+
   // Flow graph orders.
   const GrowableArray<BlockEntryInstr*>& preorder() const {
     return preorder_;
@@ -159,6 +168,10 @@
     return constant_dead_;
   }
 
+  ConstantInstr* constant_empty_context() const {
+    return constant_empty_context_;
+  }
+
   intptr_t alloc_ssa_temp_index() { return current_ssa_temp_index_++; }
 
   void AllocateSSAIndexes(Definition* def) {
@@ -296,7 +309,8 @@
   void InsertPhis(
       const GrowableArray<BlockEntryInstr*>& preorder,
       const GrowableArray<BitVector*>& assigned_vars,
-      const GrowableArray<BitVector*>& dom_frontier);
+      const GrowableArray<BitVector*>& dom_frontier,
+      GrowableArray<PhiInstr*>* live_phis);
 
   void RemoveDeadPhis(GrowableArray<PhiInstr*>* live_phis);
 
@@ -333,6 +347,7 @@
   GrowableArray<BlockEntryInstr*> optimized_block_order_;
   ConstantInstr* constant_null_;
   ConstantInstr* constant_dead_;
+  ConstantInstr* constant_empty_context_;
 
   BlockEffects* block_effects_;
   bool licm_allowed_;
diff --git a/runtime/vm/flow_graph_allocator.cc b/runtime/vm/flow_graph_allocator.cc
index 1967960..8a4bc56 100644
--- a/runtime/vm/flow_graph_allocator.cc
+++ b/runtime/vm/flow_graph_allocator.cc
@@ -106,7 +106,6 @@
   for (intptr_t i = kLastFreeCpuRegister + 1; i < kNumberOfCpuRegisters; i++) {
     blocked_cpu_registers_[i] = true;
   }
-  blocked_cpu_registers_[CTX] = true;
   if (TMP != kNoRegister) {
     blocked_cpu_registers_[TMP] = true;
   }
@@ -661,6 +660,16 @@
                                                      param->base_reg()));
     range->set_spill_slot(Location::StackSlot(slot_index,
                                               param->base_reg()));
+  } else if (defn->IsCurrentContext()) {
+    AssignSafepoints(defn, range);
+    range->finger()->Initialize(range);
+    range->set_assigned_location(Location::RegisterLocation(CTX));
+    if (range->End() > kNormalEntryPos) {
+      LiveRange* tail = range->SplitAt(kNormalEntryPos);
+      CompleteRange(tail, Location::kRegister);
+    }
+    ConvertAllUses(range);
+    return;
   } else {
     ConstantInstr* constant = defn->AsConstant();
     ASSERT(constant != NULL);
@@ -2434,6 +2443,14 @@
                                             Location from) {
   ASSERT(!IsBlockEntry(pos));
 
+  if (pos < kNormalEntryPos) {
+    ASSERT(pos > 0);
+    // Parallel moves added to the GraphEntry (B0) will be added at the start
+    // of the normal entry (B1)
+    BlockEntryInstr* entry = InstructionAt(kNormalEntryPos)->AsBlockEntry();
+    return entry->GetParallelMove()->AddMove(to, from);
+  }
+
   Instruction* instr = InstructionAt(pos);
 
   ParallelMoveInstr* parallel_move = NULL;
diff --git a/runtime/vm/flow_graph_allocator.h b/runtime/vm/flow_graph_allocator.h
index 8b106bd..fe2c710 100644
--- a/runtime/vm/flow_graph_allocator.h
+++ b/runtime/vm/flow_graph_allocator.h
@@ -129,6 +129,9 @@
   void ProcessOneInstruction(BlockEntryInstr* block,
                              Instruction* instr,
                              BitVector* interference_set);
+
+  static const intptr_t kNormalEntryPos = 2;
+
   void ProcessInitialDefinition(Definition* defn,
                                 LiveRange* range,
                                 BlockEntryInstr* block);
diff --git a/runtime/vm/flow_graph_builder.cc b/runtime/vm/flow_graph_builder.cc
index 5ae8d6d..3924811 100644
--- a/runtime/vm/flow_graph_builder.cc
+++ b/runtime/vm/flow_graph_builder.cc
@@ -759,7 +759,7 @@
     intptr_t delta =
         owner()->context_level() - local.owner()->context_level();
     ASSERT(delta >= 0);
-    Value* context = Bind(new(I) CurrentContextInstr());
+    Value* context = Bind(BuildCurrentContext());
     while (delta-- > 0) {
       context = Bind(new(I) LoadFieldInstr(
           context, Context::parent_offset(), Type::ZoneHandle(I, Type::null()),
@@ -787,7 +787,7 @@
     intptr_t delta =
         owner()->context_level() - local.owner()->context_level();
     ASSERT(delta >= 0);
-    Value* context = Bind(new(I) CurrentContextInstr());
+    Value* context = Bind(BuildCurrentContext());
     while (delta-- > 0) {
       context = Bind(new(I) LoadFieldInstr(
           context, Context::parent_offset(), Type::ZoneHandle(I, Type::null()),
@@ -805,7 +805,7 @@
 
 // Stores current context into the 'variable'
 void EffectGraphVisitor::BuildSaveContext(const LocalVariable& variable) {
-  Value* context = Bind(new(I) CurrentContextInstr());
+  Value* context = Bind(BuildCurrentContext());
   Do(BuildStoreLocal(variable, context));
 }
 
@@ -813,7 +813,19 @@
 // Loads context saved in 'context_variable' into the current context.
 void EffectGraphVisitor::BuildRestoreContext(const LocalVariable& variable) {
   Value* load_saved_context = Bind(BuildLoadLocal(variable));
-  AddInstruction(new(I) StoreContextInstr(load_saved_context));
+  Do(BuildStoreContext(load_saved_context));
+}
+
+
+Definition* EffectGraphVisitor::BuildStoreContext(Value* value) {
+  return new(I) StoreLocalInstr(
+      *owner()->parsed_function()->current_context_var(), value);
+}
+
+
+Definition* EffectGraphVisitor::BuildCurrentContext() {
+  return new(I) LoadLocalInstr(
+      *owner()->parsed_function()->current_context_var());
 }
 
 
@@ -1086,10 +1098,7 @@
 
   intptr_t current_context_level = owner()->context_level();
   ASSERT(current_context_level >= 0);
-  if (owner()->parsed_function()->saved_entry_context_var() != NULL) {
-    // CTX on entry was saved, but not linked as context parent.
-    BuildRestoreContext(*owner()->parsed_function()->saved_entry_context_var());
-  } else {
+  if (HasContextScope()) {
     UnchainContexts(current_context_level);
   }
 
@@ -1268,12 +1277,12 @@
   const String& name = String::ZoneHandle(I, Symbols::New(node->TokenName()));
   const intptr_t kNumArgsChecked = 2;
   InstanceCallInstr* call = new(I) InstanceCallInstr(node->token_pos(),
-                                                  name,
-                                                  node->kind(),
-                                                  arguments,
-                                                  Object::null_array(),
-                                                  kNumArgsChecked,
-                                                  owner()->ic_data_array());
+                                                     name,
+                                                     node->kind(),
+                                                     arguments,
+                                                     Object::null_array(),
+                                                     kNumArgsChecked,
+                                                     owner()->ic_data_array());
   ReturnDefinition(call);
 }
 
@@ -1366,12 +1375,12 @@
   arguments->Add(push_mask);
   const intptr_t kNumArgsChecked = 2;
   InstanceCallInstr* call = new(I) InstanceCallInstr(node->token_pos(),
-                                                  BinaryOpAndMaskName(node),
-                                                  Token::kILLEGAL,
-                                                  arguments,
-                                                  Object::null_array(),
-                                                  kNumArgsChecked,
-                                                  owner()->ic_data_array());
+                                                     BinaryOpAndMaskName(node),
+                                                     Token::kILLEGAL,
+                                                     arguments,
+                                                     Object::null_array(),
+                                                     kNumArgsChecked,
+                                                     owner()->ic_data_array());
   ReturnDefinition(call);
 }
 
@@ -1496,7 +1505,7 @@
   intptr_t delta = old_ctx_level -
                    continuation_result->owner()->context_level();
   ASSERT(delta >= 0);
-  Value* context = Bind(new(I) CurrentContextInstr());
+  Value* context = Bind(BuildCurrentContext());
   while (delta-- > 0) {
     context = Bind(new(I) LoadFieldInstr(
         context, Context::parent_offset(), Type::ZoneHandle(I, Type::null()),
@@ -1744,14 +1753,14 @@
     PushArgumentInstr* push_right = PushArgument(for_right_value.value());
     arguments->Add(push_right);
 
-    Definition* result =
-        new(I) InstanceCallInstr(node->token_pos(),
-                                 Symbols::EqualOperator(),
-                              Token::kEQ,  // Result is negated later for kNE.
-                              arguments,
-                              Object::null_array(),
-                              2,
-                              owner()->ic_data_array());
+    Definition* result = new(I) InstanceCallInstr(
+        node->token_pos(),
+        Symbols::EqualOperator(),
+        Token::kEQ,  // Result is negated later for kNE.
+        arguments,
+        Object::null_array(),
+        2,
+        owner()->ic_data_array());
     if (node->kind() == Token::kNE) {
       if (FLAG_enable_type_checks) {
         Value* value = Bind(result);
@@ -1780,15 +1789,14 @@
   arguments->Add(push_right);
 
   ASSERT(Token::IsRelationalOperator(node->kind()));
-  InstanceCallInstr* comp =
-      new(I) InstanceCallInstr(node->token_pos(),
-                            String::ZoneHandle(
-                                I, Symbols::New(node->TokenName())),
-                            node->kind(),
-                            arguments,
-                            Object::null_array(),
-                            2,
-                            owner()->ic_data_array());
+  InstanceCallInstr* comp = new(I) InstanceCallInstr(
+      node->token_pos(),
+      String::ZoneHandle(I, Symbols::New(node->TokenName())),
+      node->kind(),
+      arguments,
+      Object::null_array(),
+      2,
+      owner()->ic_data_array());
   ReturnDefinition(comp);
 }
 
@@ -1816,15 +1824,14 @@
   ZoneGrowableArray<PushArgumentInstr*>* arguments =
       new(I) ZoneGrowableArray<PushArgumentInstr*>(1);
   arguments->Add(push_value);
-  InstanceCallInstr* call =
-      new(I) InstanceCallInstr(node->token_pos(),
-                            String::ZoneHandle(
-                                I, Symbols::New(node->TokenName())),
-                            node->kind(),
-                            arguments,
-                            Object::null_array(),
-                            1,
-                            owner()->ic_data_array());
+  InstanceCallInstr* call = new(I) InstanceCallInstr(
+      node->token_pos(),
+      String::ZoneHandle(I, Symbols::New(node->TokenName())),
+      node->kind(),
+      arguments,
+      Object::null_array(),
+      1,
+      owner()->ic_data_array());
   ReturnDefinition(call);
 }
 
@@ -2444,7 +2451,7 @@
     // same closure, do not add a second one. We compare the origin
     // class, token position, and parent function to detect duplicates.
     // Note that we can have two different closure object for the same
-    // source text represntation of the closure: one with a non-closurized
+    // source text representation of the closure: one with a non-closurized
     // parent, and one with a closurized parent function.
 
     const Function& found_func = Function::Handle(
@@ -2525,7 +2532,7 @@
     } else {
       // Store current context in closure.
       closure_tmp_val = Bind(new(I) LoadLocalInstr(*closure_tmp_var));
-      Value* context = Bind(new(I) CurrentContextInstr());
+      Value* context = Bind(BuildCurrentContext());
       Do(new(I) StoreInstanceFieldInstr(Closure::context_offset(),
                                         closure_tmp_val,
                                         context,
@@ -2611,10 +2618,10 @@
   BuildPushArguments(*node->arguments(), arguments);
   StaticCallInstr* call =
       new(I) StaticCallInstr(node->token_pos(),
-                          node->function(),
-                          node->arguments()->names(),
-                          arguments,
-                          owner()->ic_data_array());
+                             node->function(),
+                             node->arguments()->names(),
+                             arguments,
+                             owner()->ic_data_array());
   if (node->function().is_native()) {
     const intptr_t result_cid = GetResultCidOfNativeFactory(node->function());
     if (result_cid != kDynamicCid) {
@@ -2641,18 +2648,6 @@
   arguments->Add(push_closure);
   BuildPushArguments(*node->arguments(), arguments);
 
-  // Save context around the call.
-  ASSERT(owner()->parsed_function()->saved_current_context_var() != NULL);
-  BuildSaveContext(*owner()->parsed_function()->saved_current_context_var());
-  closure_val = Bind(new(I) LoadLocalInstr(*tmp_var));
-  LoadFieldInstr* context_load = new(I) LoadFieldInstr(
-      closure_val,
-      Closure::context_offset(),
-      AbstractType::ZoneHandle(I, AbstractType::null()),
-      node->token_pos());
-  context_load->set_is_immutable(true);
-  Value* context_val = Bind(context_load);
-  AddInstruction(new(I) StoreContextInstr(context_val));
   closure_val = Bind(new(I) LoadLocalInstr(*tmp_var));
   LoadFieldInstr* function_load = new(I) LoadFieldInstr(
       closure_val,
@@ -2661,22 +2656,16 @@
       node->token_pos());
   function_load->set_is_immutable(true);
   Value* function_val = Bind(function_load);
+
   Definition* closure_call =
       new(I) ClosureCallInstr(function_val, node, arguments);
   if (result_needed) {
     Value* result = Bind(closure_call);
     Do(new(I) StoreLocalInstr(*tmp_var, result));
-    // Restore context from temp.
-    BuildRestoreContext(
-        *owner()->parsed_function()->saved_current_context_var());
-    ReturnDefinition(ExitTempLocalScope(tmp_var));
   } else {
     Do(closure_call);
-    // Restore context from saved location.
-    BuildRestoreContext(
-        *owner()->parsed_function()->saved_current_context_var());
-    Do(ExitTempLocalScope(tmp_var));
   }
+  ReturnDefinition(ExitTempLocalScope(tmp_var));
 }
 
 
@@ -2697,9 +2686,9 @@
 
 
 void EffectGraphVisitor::VisitCloneContextNode(CloneContextNode* node) {
-  Value* context = Bind(new(I) CurrentContextInstr());
+  Value* context = Bind(BuildCurrentContext());
   Value* clone = Bind(new(I) CloneContextInstr(node->token_pos(), context));
-  AddInstruction(new(I) StoreContextInstr(clone));
+  Do(BuildStoreContext(clone));
 }
 
 
@@ -2739,10 +2728,10 @@
 
   BuildPushArguments(*node->arguments(), arguments);
   Do(new(I) StaticCallInstr(node->token_pos(),
-                         node->constructor(),
-                         node->arguments()->names(),
-                         arguments,
-                         owner()->ic_data_array()));
+                            node->constructor(),
+                            node->arguments()->names(),
+                            arguments,
+                            owner()->ic_data_array()));
 }
 
 
@@ -2782,10 +2771,10 @@
     BuildPushArguments(*node->arguments(), arguments);
     StaticCallInstr* call =
         new(I) StaticCallInstr(node->token_pos(),
-                            node->constructor(),
-                            node->arguments()->names(),
-                            arguments,
-                            owner()->ic_data_array());
+                               node->constructor(),
+                               node->arguments()->names(),
+                               arguments,
+                               owner()->ic_data_array());
     const intptr_t result_cid = GetResultCidOfListFactory(node);
     if (result_cid != kDynamicCid) {
       call->set_result_cid(result_cid);
@@ -3536,21 +3525,22 @@
   if (super_function != NULL) {
     // Generate static call to super operator.
     StaticCallInstr* load = new(I) StaticCallInstr(node->token_pos(),
-                                                *super_function,
-                                                Object::null_array(),
-                                                arguments,
-                                                owner()->ic_data_array());
+                                                   *super_function,
+                                                   Object::null_array(),
+                                                   arguments,
+                                                   owner()->ic_data_array());
     ReturnDefinition(load);
   } else {
     // Generate dynamic call to index operator.
     const intptr_t checked_argument_count = 1;
-    InstanceCallInstr* load = new(I) InstanceCallInstr(node->token_pos(),
-                                                    Symbols::IndexToken(),
-                                                    Token::kINDEX,
-                                                    arguments,
-                                                    Object::null_array(),
-                                                    checked_argument_count,
-                                                    owner()->ic_data_array());
+    InstanceCallInstr* load = new(I) InstanceCallInstr(
+        node->token_pos(),
+        Symbols::IndexToken(),
+        Token::kINDEX,
+        arguments,
+        Object::null_array(),
+        checked_argument_count,
+        owner()->ic_data_array());
     ReturnDefinition(load);
   }
 }
@@ -3617,10 +3607,10 @@
 
     StaticCallInstr* store =
         new(I) StaticCallInstr(node->token_pos(),
-                            *super_function,
-                            Object::null_array(),
-                            arguments,
-                            owner()->ic_data_array());
+                               *super_function,
+                               Object::null_array(),
+                               arguments,
+                               owner()->ic_data_array());
     if (result_is_needed) {
       Do(store);
       return BuildLoadExprTemp();
@@ -3634,12 +3624,12 @@
         String::ZoneHandle(I, Symbols::New(Token::Str(Token::kASSIGN_INDEX)));
     InstanceCallInstr* store =
         new(I) InstanceCallInstr(node->token_pos(),
-                              name,
-                              Token::kASSIGN_INDEX,
-                              arguments,
-                              Object::null_array(),
-                              checked_argument_count,
-                              owner()->ic_data_array());
+                                 name,
+                                 Token::kASSIGN_INDEX,
+                                 arguments,
+                                 Object::null_array(),
+                                 checked_argument_count,
+                                 owner()->ic_data_array());
     if (result_is_needed) {
       Do(store);
       return BuildLoadExprTemp();
@@ -3660,15 +3650,16 @@
 }
 
 
-bool EffectGraphVisitor::MustSaveRestoreContext(SequenceNode* node) const {
-  return (node == owner()->parsed_function()->node_sequence()) &&
-         (owner()->parsed_function()->saved_entry_context_var() != NULL);
+bool EffectGraphVisitor::HasContextScope() const {
+  const ContextScope& context_scope = ContextScope::Handle(
+      owner()->parsed_function()->function().context_scope());
+  return !context_scope.IsNull() && (context_scope.num_variables() > 0);
 }
 
 
 void EffectGraphVisitor::UnchainContexts(intptr_t n) {
   if (n > 0) {
-    Value* context = Bind(new(I) CurrentContextInstr());
+    Value* context = Bind(BuildCurrentContext());
     while (n-- > 0) {
       context = Bind(
           new(I) LoadFieldInstr(context,
@@ -3677,7 +3668,7 @@
                                 Type::ZoneHandle(I, Type::null()),
                                 Scanner::kNoSourcePos));
     }
-    AddInstruction(new(I) StoreContextInstr(context));
+    Do(BuildStoreContext(context));
   }
 }
 
@@ -3689,47 +3680,35 @@
   LocalScope* scope = node->scope();
   const intptr_t num_context_variables =
       (scope != NULL) ? scope->num_context_variables() : 0;
+  const bool is_top_level_sequence =
+      node == owner()->parsed_function()->node_sequence();
   // The outermost function sequence cannot contain a label.
-  ASSERT((node->label() == NULL) ||
-         (node != owner()->parsed_function()->node_sequence()));
+  ASSERT((node->label() == NULL) || !is_top_level_sequence);
   NestedBlock nested_block(owner(), node);
 
   if (num_context_variables > 0) {
-    // The loop local scope declares variables that are captured.
-    // Allocate and chain a new context.
-    // Allocate context computation (uses current CTX)
+    // The local scope declares variables that are captured.
+    // Allocate and chain a new context (Except don't chain when at the function
+    // entry if the function does not capture any variables from outer scopes).
     Value* allocated_context =
         Bind(new(I) AllocateContextInstr(node->token_pos(),
                                          num_context_variables));
     { LocalVariable* tmp_var = EnterTempLocalScope(allocated_context);
-      // If this node_sequence is the body of the function being compiled, and
-      // if this function allocates context variables, but none of its enclosing
-      // functions do, the context on entry is not linked as parent of the
-      // allocated context but saved on entry and restored on exit as to prevent
-      // memory leaks.
-      // In this case, the parser pre-allocates a variable to save the context.
-      Value* tmp_val = Bind(new(I) LoadLocalInstr(*tmp_var));
-      Value* parent_context = NULL;
-      if (MustSaveRestoreContext(node)) {
-        BuildSaveContext(
-            *owner()->parsed_function()->saved_entry_context_var());
-        parent_context = Bind(
-            new(I) ConstantInstr(Object::ZoneHandle(I, Object::null())));
-      } else {
-        parent_context = Bind(new(I) CurrentContextInstr());
+      if (HasContextScope() || !is_top_level_sequence) {
+        Value* tmp_val = Bind(new(I) LoadLocalInstr(*tmp_var));
+        Value* parent_context = Bind(BuildCurrentContext());
+        Do(new(I) StoreInstanceFieldInstr(Context::parent_offset(),
+                                          tmp_val,
+                                          parent_context,
+                                          kEmitStoreBarrier,
+                                          Scanner::kNoSourcePos));
       }
-      Do(new(I) StoreInstanceFieldInstr(Context::parent_offset(),
-                                        tmp_val,
-                                        parent_context,
-                                        kEmitStoreBarrier,
-                                        Scanner::kNoSourcePos));
-      AddInstruction(
-          new(I) StoreContextInstr(Bind(ExitTempLocalScope(tmp_var))));
+      Do(BuildStoreContext(Bind(ExitTempLocalScope(tmp_var))));
     }
 
     // If this node_sequence is the body of the function being compiled, copy
     // the captured parameters from the frame into the context.
-    if (node == owner()->parsed_function()->node_sequence()) {
+    if (is_top_level_sequence) {
       ASSERT(scope->context_level() == 1);
       const Function& function = owner()->parsed_function()->function();
       const int num_params = function.NumParameters();
@@ -3765,23 +3744,12 @@
         }
       }
     }
-  } else if (MustSaveRestoreContext(node)) {
-    // Even when the current scope has no context variables, we may
-    // still need to save the current context if, for example, there
-    // are loop scopes below this which will allocate a context
-    // object.
-    BuildSaveContext(
-        *owner()->parsed_function()->saved_entry_context_var());
-    AddInstruction(
-        new(I) StoreContextInstr(Bind(new(I) ConstantInstr(Object::ZoneHandle(
-            I, I->object_store()->empty_context())))));
   }
 
   // This check may be deleted if the generated code is leaf.
   // Native functions don't need a stack check at entry.
   const Function& function = owner()->parsed_function()->function();
-  if ((node == owner()->parsed_function()->node_sequence()) &&
-      !function.is_native()) {
+  if (is_top_level_sequence && !function.is_native()) {
     // Always allocate CheckOverflowInstr so that deopt-ids match regardless
     // if we inline or not.
     if (!function.IsImplicitGetterFunction() &&
@@ -3796,8 +3764,7 @@
     }
   }
 
-  if (FLAG_enable_type_checks &&
-      (node == owner()->parsed_function()->node_sequence())) {
+  if (FLAG_enable_type_checks && is_top_level_sequence) {
     const Function& function = owner()->parsed_function()->function();
     const int num_params = function.NumParameters();
     int pos = 0;
@@ -3836,7 +3803,7 @@
   // If this node sequence is the body of an async closure leave room for a
   // preamble. The preamble is generated after visiting the body.
   GotoInstr* preamble_start = NULL;
-  if ((node == owner()->parsed_function()->node_sequence()) &&
+  if (is_top_level_sequence &&
       (owner()->parsed_function()->function().is_async_closure())) {
     JoinEntryInstr* preamble_end = new(I) JoinEntryInstr(
         owner()->AllocateBlockId(), owner()->try_index());
@@ -3862,7 +3829,7 @@
   // Continuation part:
   // After generating the CFG for the body we can create the preamble because we
   // know exactly how many continuation states we need.
-  if ((node == owner()->parsed_function()->node_sequence()) &&
+  if (is_top_level_sequence &&
       (owner()->parsed_function()->function().is_async_closure())) {
     ASSERT(preamble_start != NULL);
     // We are at the top level. Fetch the corresponding scope.
@@ -3923,13 +3890,10 @@
     exit_ = saved_exit;
   }
 
-  if (is_open()) {
-    if (MustSaveRestoreContext(node)) {
-      BuildRestoreContext(
-          *owner()->parsed_function()->saved_entry_context_var());
-    } else if (num_context_variables > 0) {
-      UnchainContexts(1);
-    }
+  if (is_open() &&
+      (num_context_variables > 0) &&
+      (HasContextScope() || !is_top_level_sequence)) {
+    UnchainContexts(1);
   }
 
   // If this node sequence is labeled, a break out of the sequence will have
@@ -3943,7 +3907,7 @@
 
 void EffectGraphVisitor::VisitCatchClauseNode(CatchClauseNode* node) {
   InlineBailout("EffectGraphVisitor::VisitCatchClauseNode (exception)");
-  // Restores CTX from local variable ':saved_context'.
+  // Restores current context from local variable ':saved_context'.
   BuildRestoreContext(node->context_var());
 
   EffectGraphVisitor for_catch(owner());
@@ -3959,7 +3923,7 @@
   ASSERT(try_handler_index != original_handler_index);
   owner()->set_try_index(try_handler_index);
 
-  // Preserve CTX into local variable '%saved_context'.
+  // Preserve current context into local variable '%saved_context'.
   BuildSaveContext(node->context_var());
 
   EffectGraphVisitor for_try(owner());
diff --git a/runtime/vm/flow_graph_builder.h b/runtime/vm/flow_graph_builder.h
index 66b4697..a86a2cc 100644
--- a/runtime/vm/flow_graph_builder.h
+++ b/runtime/vm/flow_graph_builder.h
@@ -407,7 +407,7 @@
   virtual void BuildTypeTest(ComparisonNode* node);
   virtual void BuildTypeCast(ComparisonNode* node);
 
-  bool MustSaveRestoreContext(SequenceNode* node) const;
+  bool HasContextScope() const;
 
   // Moves the nth parent context into the context register.
   void UnchainContexts(intptr_t n);
@@ -425,6 +425,9 @@
   void BuildSaveContext(const LocalVariable& variable);
   void BuildRestoreContext(const LocalVariable& variable);
 
+  Definition* BuildStoreContext(Value* value);
+  Definition* BuildCurrentContext();
+
   void BuildThrowNode(ThrowNode* node);
 
   StaticCallInstr* BuildStaticNoSuchMethodCall(
diff --git a/runtime/vm/flow_graph_compiler.cc b/runtime/vm/flow_graph_compiler.cc
index d3258f9..5bb8e09 100644
--- a/runtime/vm/flow_graph_compiler.cc
+++ b/runtime/vm/flow_graph_compiler.cc
@@ -225,7 +225,8 @@
 
 
 static bool IsEmptyBlock(BlockEntryInstr* block) {
-  return !block->HasNonRedundantParallelMove() &&
+  return !block->IsCatchBlockEntry() &&
+         !block->HasNonRedundantParallelMove() &&
          block->next()->IsGoto() &&
          !block->next()->AsGoto()->HasNonRedundantParallelMove();
 }
@@ -287,7 +288,7 @@
       // own so that it can control the placement.
       AddCurrentDescriptor(RawPcDescriptors::kDeopt,
                            instr->deopt_id(),
-                           Scanner::kNoSourcePos);
+                           instr->token_pos());
     }
     AllocateRegistersLocally(instr);
   } else if (instr->MayThrow()  &&
@@ -1108,7 +1109,6 @@
   }
 
   // Do not allocate known registers.
-  blocked_registers[CTX] = true;
   blocked_registers[SPREG] = true;
   blocked_registers[FPREG] = true;
   if (TMP != kNoRegister) {
@@ -1385,7 +1385,6 @@
       reg_(kNoRegister),
       spilled_(false) {
   uword blocked_mask = MaskBit(blocked)
-                     | MaskBit(CTX)
                      | MaskBit(SPREG)
                      | MaskBit(FPREG)
                      | MaskBit(TMP)
@@ -1497,4 +1496,24 @@
   return threshold;
 }
 
+
+const Class& FlowGraphCompiler::BoxClassFor(Representation rep) {
+  switch (rep) {
+    case kUnboxedDouble:
+      return double_class();
+    case kUnboxedFloat32x4:
+      return float32x4_class();
+    case kUnboxedFloat64x2:
+      return float64x2_class();
+    case kUnboxedInt32x4:
+      return int32x4_class();
+    case kUnboxedMint:
+      return mint_class();
+    default:
+      UNREACHABLE();
+      return Class::ZoneHandle();
+  }
+}
+
+
 }  // namespace dart
diff --git a/runtime/vm/flow_graph_compiler.h b/runtime/vm/flow_graph_compiler.h
index 79cb82c..0cb7dc4 100644
--- a/runtime/vm/flow_graph_compiler.h
+++ b/runtime/vm/flow_graph_compiler.h
@@ -473,6 +473,8 @@
   const Class& float64x2_class() const { return float64x2_class_; }
   const Class& int32x4_class() const { return int32x4_class_; }
 
+  const Class& BoxClassFor(Representation rep);
+
   void SaveLiveRegisters(LocationSummary* locs);
   void RestoreLiveRegisters(LocationSummary* locs);
 
diff --git a/runtime/vm/flow_graph_compiler_arm.cc b/runtime/vm/flow_graph_compiler_arm.cc
index 9b9030c..c6993f1 100644
--- a/runtime/vm/flow_graph_compiler_arm.cc
+++ b/runtime/vm/flow_graph_compiler_arm.cc
@@ -1074,15 +1074,40 @@
     CopyParameters();
   }
 
+  if (function.IsClosureFunction() && !flow_graph().IsCompiledForOsr()) {
+    // Load context from the closure object (first argument).
+    LocalScope* scope = parsed_function().node_sequence()->scope();
+    LocalVariable* closure_parameter = scope->VariableAt(0);
+    __ ldr(CTX, Address(FP, closure_parameter->index() * kWordSize));
+    __ ldr(CTX, FieldAddress(CTX, Closure::context_offset()));
+  }
+
   // In unoptimized code, initialize (non-argument) stack allocated slots to
   // null.
-  if (!is_optimizing() && (num_locals > 0)) {
+  if (!is_optimizing()) {
+    ASSERT(num_locals > 0);  // There is always at least context_var.
     __ Comment("Initialize spill slots");
     const intptr_t slot_base = parsed_function().first_stack_local_index();
-    __ LoadImmediate(R0, reinterpret_cast<intptr_t>(Object::null()));
+    const intptr_t context_index =
+        parsed_function().current_context_var()->index();
+    if (num_locals > 1) {
+      __ LoadImmediate(R0, reinterpret_cast<intptr_t>(Object::null()));
+    }
     for (intptr_t i = 0; i < num_locals; ++i) {
       // Subtract index i (locals lie at lower addresses than FP).
-      __ StoreToOffset(kWord, R0, FP, (slot_base - i) * kWordSize);
+      if (((slot_base - i) == context_index)) {
+        if (function.IsClosureFunction()) {
+          __ StoreToOffset(kWord, CTX, FP, (slot_base - i) * kWordSize);
+        } else {
+          const Context& empty_context = Context::ZoneHandle(
+              isolate(), isolate()->object_store()->empty_context());
+          __ LoadObject(R1, empty_context);
+          __ StoreToOffset(kWord, R1, FP, (slot_base - i) * kWordSize);
+        }
+      } else {
+        ASSERT(num_locals > 1);
+        __ StoreToOffset(kWord, R0, FP, (slot_base - i) * kWordSize);
+      }
     }
   }
 
diff --git a/runtime/vm/flow_graph_compiler_arm64.cc b/runtime/vm/flow_graph_compiler_arm64.cc
index 1b1195f..8513588 100644
--- a/runtime/vm/flow_graph_compiler_arm64.cc
+++ b/runtime/vm/flow_graph_compiler_arm64.cc
@@ -1079,15 +1079,40 @@
     CopyParameters();
   }
 
+  if (function.IsClosureFunction() && !flow_graph().IsCompiledForOsr()) {
+    // Load context from the closure object (first argument).
+    LocalScope* scope = parsed_function().node_sequence()->scope();
+    LocalVariable* closure_parameter = scope->VariableAt(0);
+    __ ldr(CTX, Address(FP, closure_parameter->index() * kWordSize));
+    __ ldr(CTX, FieldAddress(CTX, Closure::context_offset()));
+  }
+
   // In unoptimized code, initialize (non-argument) stack allocated slots to
   // null.
-  if (!is_optimizing() && (num_locals > 0)) {
+  if (!is_optimizing()) {
+    ASSERT(num_locals > 0);  // There is always at least context_var.
     __ Comment("Initialize spill slots");
     const intptr_t slot_base = parsed_function().first_stack_local_index();
-    __ LoadObject(R0, Object::null_object(), PP);
+    const intptr_t context_index =
+        parsed_function().current_context_var()->index();
+    if (num_locals > 1) {
+      __ LoadObject(R0, Object::null_object(), PP);
+    }
     for (intptr_t i = 0; i < num_locals; ++i) {
       // Subtract index i (locals lie at lower addresses than FP).
-      __ StoreToOffset(R0, FP, (slot_base - i) * kWordSize, PP);
+      if (((slot_base - i) == context_index)) {
+        if (function.IsClosureFunction()) {
+          __ StoreToOffset(CTX, FP, (slot_base - i) * kWordSize, PP);
+        } else {
+          const Context& empty_context = Context::ZoneHandle(
+              isolate(), isolate()->object_store()->empty_context());
+          __ LoadObject(R1, empty_context, PP);
+          __ StoreToOffset(R1, FP, (slot_base - i) * kWordSize, PP);
+        }
+      } else {
+        ASSERT(num_locals > 1);
+        __ StoreToOffset(R0, FP, (slot_base - i) * kWordSize, PP);
+      }
     }
   }
 
diff --git a/runtime/vm/flow_graph_compiler_ia32.cc b/runtime/vm/flow_graph_compiler_ia32.cc
index 6236d5c8..5879192 100644
--- a/runtime/vm/flow_graph_compiler_ia32.cc
+++ b/runtime/vm/flow_graph_compiler_ia32.cc
@@ -1074,17 +1074,52 @@
     CopyParameters();
   }
 
+  if (function.IsClosureFunction() && !flow_graph().IsCompiledForOsr()) {
+    // Load context from the closure object (first argument).
+    LocalScope* scope = parsed_function().node_sequence()->scope();
+    LocalVariable* closure_parameter = scope->VariableAt(0);
+    // TODO(fschneider): Don't load context for optimized functions that
+    // don't use it.
+    __ movl(CTX, Address(EBP, closure_parameter->index() * kWordSize));
+    __ movl(CTX, FieldAddress(CTX, Closure::context_offset()));
+#ifdef dEBUG
+    Label ok;
+    __ LoadClassId(EBX, CTX);
+    __ cmpl(EBX, Immediate(kContextCid));
+    __ j(EQUAL, &ok, Assembler::kNearJump);
+    __ Stop("Incorrect context at entry");
+    __ Bind(&ok);
+#endif
+  }
+
   // In unoptimized code, initialize (non-argument) stack allocated slots to
   // null.
-  if (!is_optimizing() && (num_locals > 0)) {
+  if (!is_optimizing()) {
+    ASSERT(num_locals > 0);  // There is always at least context_var.
     __ Comment("Initialize spill slots");
     const intptr_t slot_base = parsed_function().first_stack_local_index();
-    const Immediate& raw_null =
-        Immediate(reinterpret_cast<intptr_t>(Object::null()));
-    __ movl(EAX, raw_null);
+    const intptr_t context_index =
+        parsed_function().current_context_var()->index();
+    if (num_locals > 1) {
+      const Immediate& raw_null =
+          Immediate(reinterpret_cast<intptr_t>(Object::null()));
+      __ movl(EAX, raw_null);
+    }
     for (intptr_t i = 0; i < num_locals; ++i) {
       // Subtract index i (locals lie at lower addresses than EBP).
-      __ movl(Address(EBP, (slot_base - i) * kWordSize), EAX);
+      if (((slot_base - i) == context_index)) {
+        if (function.IsClosureFunction()) {
+          __ movl(Address(EBP, (slot_base - i) * kWordSize), CTX);
+        } else {
+          const Immediate& raw_empty_context =
+              Immediate(reinterpret_cast<intptr_t>(
+                  isolate()->object_store()->empty_context()));
+          __ movl(Address(EBP, (slot_base - i) * kWordSize), raw_empty_context);
+        }
+      } else {
+        ASSERT(num_locals > 1);
+        __ movl(Address(EBP, (slot_base - i) * kWordSize), EAX);
+      }
     }
   }
 
diff --git a/runtime/vm/flow_graph_compiler_mips.cc b/runtime/vm/flow_graph_compiler_mips.cc
index 583de9b..c0ac35d 100644
--- a/runtime/vm/flow_graph_compiler_mips.cc
+++ b/runtime/vm/flow_graph_compiler_mips.cc
@@ -1102,16 +1102,41 @@
     CopyParameters();
   }
 
+  if (function.IsClosureFunction() && !flow_graph().IsCompiledForOsr()) {
+    // Load context from the closure object (first argument).
+    LocalScope* scope = parsed_function().node_sequence()->scope();
+    LocalVariable* closure_parameter = scope->VariableAt(0);
+    __ lw(CTX, Address(FP, closure_parameter->index() * kWordSize));
+    __ lw(CTX, FieldAddress(CTX, Closure::context_offset()));
+  }
+
   // In unoptimized code, initialize (non-argument) stack allocated slots to
   // null.
-  if (!is_optimizing() && (num_locals > 0)) {
+  if (!is_optimizing()) {
+    ASSERT(num_locals > 0);  // There is always at least context_var.
     __ TraceSimMsg("Initialize spill slots");
     __ Comment("Initialize spill slots");
     const intptr_t slot_base = parsed_function().first_stack_local_index();
+    const intptr_t context_index =
+        parsed_function().current_context_var()->index();
+    if (num_locals > 1) {
+      __ LoadImmediate(V0, reinterpret_cast<int32_t>(Object::null()));
+    }
     for (intptr_t i = 0; i < num_locals; ++i) {
       // Subtract index i (locals lie at lower addresses than FP).
-      __ LoadImmediate(TMP, reinterpret_cast<int32_t>(Object::null()));
-      __ sw(TMP, Address(FP, (slot_base - i) * kWordSize));
+      if (((slot_base - i) == context_index)) {
+        if (function.IsClosureFunction()) {
+          __ sw(CTX, Address(FP, (slot_base - i) * kWordSize));
+        } else {
+          const Context& empty_context = Context::ZoneHandle(
+              isolate(), isolate()->object_store()->empty_context());
+          __ LoadObject(V1, empty_context);
+          __ sw(V1, Address(FP, (slot_base - i) * kWordSize));
+        }
+      } else {
+        ASSERT(num_locals > 1);
+        __ sw(V0, Address(FP, (slot_base - i) * kWordSize));
+      }
     }
   }
 
diff --git a/runtime/vm/flow_graph_compiler_x64.cc b/runtime/vm/flow_graph_compiler_x64.cc
index 790fea4..1c4b7d7 100644
--- a/runtime/vm/flow_graph_compiler_x64.cc
+++ b/runtime/vm/flow_graph_compiler_x64.cc
@@ -1113,15 +1113,48 @@
     CopyParameters();
   }
 
+  if (function.IsClosureFunction() && !flow_graph().IsCompiledForOsr()) {
+    // Load context from the closure object (first argument).
+    LocalScope* scope = parsed_function().node_sequence()->scope();
+    LocalVariable* closure_parameter = scope->VariableAt(0);
+    __ movq(CTX, Address(RBP, closure_parameter->index() * kWordSize));
+    __ movq(CTX, FieldAddress(CTX, Closure::context_offset()));
+#ifdef dEBUG
+    Label ok;
+    __ LoadClassId(RAX, CTX);
+    __ cmpq(RAX, Immediate(kContextCid));
+    __ j(EQUAL, &ok, Assembler::kNearJump);
+    __ Stop("Incorrect context at entry");
+    __ Bind(&ok);
+#endif
+  }
+
   // In unoptimized code, initialize (non-argument) stack allocated slots to
   // null.
-  if (!is_optimizing() && (num_locals > 0)) {
+  if (!is_optimizing()) {
+    ASSERT(num_locals > 0);  // There is always at least context_var.
     __ Comment("Initialize spill slots");
     const intptr_t slot_base = parsed_function().first_stack_local_index();
-    __ LoadObject(RAX, Object::null_object(), PP);
+    const intptr_t context_index =
+        parsed_function().current_context_var()->index();
+    if (num_locals > 1) {
+      __ LoadObject(RAX, Object::null_object(), PP);
+    }
     for (intptr_t i = 0; i < num_locals; ++i) {
       // Subtract index i (locals lie at lower addresses than RBP).
-      __ movq(Address(RBP, (slot_base - i) * kWordSize), RAX);
+      if (((slot_base - i) == context_index)) {
+        if (function.IsClosureFunction()) {
+          __ movq(Address(RBP, (slot_base - i) * kWordSize), CTX);
+        } else {
+          const Context& empty_context = Context::ZoneHandle(
+              isolate(), isolate()->object_store()->empty_context());
+          __ StoreObject(
+              Address(RBP, (slot_base - i) * kWordSize), empty_context, PP);
+        }
+      } else {
+        ASSERT(num_locals > 1);
+        __ movq(Address(RBP, (slot_base - i) * kWordSize), RAX);
+      }
     }
   }
 
diff --git a/runtime/vm/flow_graph_inliner.cc b/runtime/vm/flow_graph_inliner.cc
index 848cbfd..1a2cea8 100644
--- a/runtime/vm/flow_graph_inliner.cc
+++ b/runtime/vm/flow_graph_inliner.cc
@@ -926,6 +926,20 @@
         constant->ReplaceUsesWith(
             caller_graph_->GetConstant(constant->value()));
       }
+      CurrentContextInstr* context = (*defns)[i]->AsCurrentContext();
+      if ((context != NULL) && context->HasUses()) {
+        ASSERT(call->IsClosureCall());
+        LoadFieldInstr* context_load = new(isolate()) LoadFieldInstr(
+            new Value((*arguments)[0]->definition()),
+            Closure::context_offset(),
+            AbstractType::ZoneHandle(isolate(), AbstractType::null()),
+            call_data->call->token_pos());
+        context_load->set_is_immutable(true);
+        context_load->set_ssa_temp_index(
+            caller_graph_->alloc_ssa_temp_index());
+        context_load->InsertBefore(callee_entry->next());
+        context->ReplaceUsesWith(context_load);
+      }
     }
 
     // Check that inlining maintains use lists.
@@ -1335,6 +1349,20 @@
       constant->ReplaceUsesWith(
           owner_->caller_graph()->GetConstant(constant->value()));
     }
+    CurrentContextInstr* context = (*defns)[i]->AsCurrentContext();
+    if ((context != NULL) && context->HasUses()) {
+      ASSERT(call_data.call->IsClosureCall());
+      LoadFieldInstr* context_load = new(isolate()) LoadFieldInstr(
+          new Value(redefinition),
+          Closure::context_offset(),
+          AbstractType::ZoneHandle(isolate(), AbstractType::null()),
+          call_data.call->token_pos());
+      context_load->set_is_immutable(true);
+      context_load->set_ssa_temp_index(
+          owner_->caller_graph()->alloc_ssa_temp_index());
+      context_load->InsertAfter(redefinition);
+      context->ReplaceUsesWith(context_load);
+    }
   }
   return true;
 }
diff --git a/runtime/vm/flow_graph_optimizer.cc b/runtime/vm/flow_graph_optimizer.cc
index 7a70da4..709d42b 100644
--- a/runtime/vm/flow_graph_optimizer.cc
+++ b/runtime/vm/flow_graph_optimizer.cc
@@ -628,138 +628,41 @@
   }
 
   Definition* converted = NULL;
-  if ((from == kTagged) && (to == kUnboxedMint)) {
-    ASSERT((deopt_target != NULL) ||
-           (use->Type()->ToCid() == kUnboxedMint));
-    const intptr_t deopt_id = (deopt_target != NULL) ?
-        deopt_target->DeoptimizationTarget() : Isolate::kNoDeoptId;
-    converted = new(I) UnboxIntegerInstr(use->CopyWithType(), deopt_id);
-  } else if ((from == kUnboxedMint) && (to == kTagged)) {
-    converted = new(I) BoxIntegerInstr(use->CopyWithType());
-  } else if ((from == kUnboxedUint32) && (to == kTagged)) {
-    converted = new(I) BoxUint32Instr(use->CopyWithType());
-  } else if (IsUnboxedInteger(from) && IsUnboxedInteger(to)) {
+  if (IsUnboxedInteger(from) && IsUnboxedInteger(to)) {
     const intptr_t deopt_id = (to == kUnboxedInt32) && (deopt_target != NULL) ?
-        deopt_target->DeoptimizationTarget() : Isolate::kNoDeoptId;
+      deopt_target->DeoptimizationTarget() : Isolate::kNoDeoptId;
     converted = new(I) UnboxedIntConverterInstr(from,
                                                 to,
                                                 use->CopyWithType(),
                                                 deopt_id);
   } else if ((from == kUnboxedInt32) && (to == kUnboxedDouble)) {
     converted = new Int32ToDoubleInstr(use->CopyWithType());
-  } else if ((from == kTagged) && (to == kUnboxedInt32)) {
+  } else if ((from == kUnboxedMint) &&
+             (to == kUnboxedDouble) &&
+             CanConvertUnboxedMintToDouble()) {
     const intptr_t deopt_id = (deopt_target != NULL) ?
-        deopt_target->DeoptimizationTarget() : Isolate::kNoDeoptId;
-    converted = new UnboxInt32Instr(use->CopyWithType(), deopt_id);
-  } else if ((from == kUnboxedInt32) && (to == kTagged)) {
-    converted = new BoxInt32Instr(use->CopyWithType());
-  } else if ((from == kTagged) && (to == kUnboxedUint32)) {
-    const intptr_t deopt_id = (deopt_target != NULL) ?
-        deopt_target->DeoptimizationTarget() : Isolate::kNoDeoptId;
-    converted = new UnboxUint32Instr(use->CopyWithType(), deopt_id);
-  } else if (from == kUnboxedMint && to == kUnboxedDouble) {
+      deopt_target->DeoptimizationTarget() : Isolate::kNoDeoptId;
     ASSERT(CanUnboxDouble());
+    converted = new MintToDoubleInstr(use->CopyWithType(), deopt_id);
+  } else if ((from == kTagged) && Boxing::Supports(to)) {
     const intptr_t deopt_id = (deopt_target != NULL) ?
-        deopt_target->DeoptimizationTarget() : Isolate::kNoDeoptId;
-    if (CanConvertUnboxedMintToDouble()) {
-      // Fast path.
-      converted = new MintToDoubleInstr(use->CopyWithType(), deopt_id);
-    } else {
-      // Slow path.
-      BoxIntegerInstr* boxed = new(I) BoxIntegerInstr(use->CopyWithType());
-      use->BindTo(boxed);
-      InsertBefore(insert_before, boxed, NULL, FlowGraph::kValue);
-      converted = new(I) UnboxDoubleInstr(new(I) Value(boxed), deopt_id);
-    }
-  } else if ((from == kUnboxedDouble) && (to == kTagged)) {
-    ASSERT(CanUnboxDouble());
-    converted = new(I) BoxDoubleInstr(use->CopyWithType());
-  } else if ((from == kTagged) && (to == kUnboxedDouble)) {
-    ASSERT(CanUnboxDouble());
-    ASSERT((deopt_target != NULL) ||
-           (use->Type()->ToCid() == kDoubleCid));
-    const intptr_t deopt_id = (deopt_target != NULL) ?
-        deopt_target->DeoptimizationTarget() : Isolate::kNoDeoptId;
-    ConstantInstr* constant = use->definition()->AsConstant();
-    if ((constant != NULL) && constant->value().IsSmi()) {
-      const double dbl_val = Smi::Cast(constant->value()).AsDoubleValue();
-      const Double& dbl_obj =
-          Double::ZoneHandle(I, Double::NewCanonical(dbl_val));
-      ConstantInstr* double_const = flow_graph()->GetConstant(dbl_obj);
-      converted = new(I) UnboxDoubleInstr(new(I) Value(double_const), deopt_id);
-    } else {
-      converted = new(I) UnboxDoubleInstr(use->CopyWithType(), deopt_id);
-    }
-  } else if ((from == kTagged) && (to == kUnboxedFloat32x4)) {
-    ASSERT((deopt_target != NULL) ||
-           (use->Type()->ToCid() == kFloat32x4Cid));
-    const intptr_t deopt_id = (deopt_target != NULL) ?
-        deopt_target->DeoptimizationTarget() : Isolate::kNoDeoptId;
-    converted = new(I) UnboxFloat32x4Instr(
-        use->CopyWithType(), deopt_id);
-  } else if ((from == kUnboxedFloat32x4) && (to == kTagged)) {
-    converted = new(I) BoxFloat32x4Instr(use->CopyWithType());
-  } else if ((from == kTagged) && (to == kUnboxedInt32x4)) {
-    ASSERT((deopt_target != NULL) || (use->Type()->ToCid() == kInt32x4Cid));
-    const intptr_t deopt_id = (deopt_target != NULL) ?
-        deopt_target->DeoptimizationTarget() : Isolate::kNoDeoptId;
-    converted = new(I) UnboxInt32x4Instr(use->CopyWithType(), deopt_id);
-  } else if ((from == kUnboxedInt32x4) && (to == kTagged)) {
-    converted = new(I) BoxInt32x4Instr(use->CopyWithType());
-  } else if ((from == kTagged) && (to == kUnboxedFloat64x2)) {
-    ASSERT((deopt_target != NULL) || (use->Type()->ToCid() == kFloat64x2Cid));
-    const intptr_t deopt_id = (deopt_target != NULL) ?
-        deopt_target->DeoptimizationTarget() : Isolate::kNoDeoptId;
-    converted = new(I) UnboxFloat64x2Instr(use->CopyWithType(), deopt_id);
-  } else if ((from == kUnboxedFloat64x2) && (to == kTagged)) {
-    converted = new(I) BoxFloat64x2Instr(use->CopyWithType());
+      deopt_target->DeoptimizationTarget() : Isolate::kNoDeoptId;
+    converted = UnboxInstr::Create(to, use->CopyWithType(), deopt_id);
+  } else if ((to == kTagged) && Boxing::Supports(from)) {
+    converted = BoxInstr::Create(from, use->CopyWithType());
   } else {
     // We have failed to find a suitable conversion instruction.
     // Insert two "dummy" conversion instructions with the correct
     // "from" and "to" representation. The inserted instructions will
     // trigger a deoptimization if executed. See #12417 for a discussion.
     const intptr_t deopt_id = (deopt_target != NULL) ?
-        deopt_target->DeoptimizationTarget() : Isolate::kNoDeoptId;
-    ASSERT(from != kTagged);
-    ASSERT(to != kTagged);
-    Definition* boxed = NULL;
-    if (from == kUnboxedDouble) {
-      boxed = new(I) BoxDoubleInstr(use->CopyWithType());
-    } else if (from == kUnboxedInt32x4) {
-      boxed = new(I) BoxInt32x4Instr(use->CopyWithType());
-    } else if (from == kUnboxedFloat32x4) {
-      boxed = new(I) BoxFloat32x4Instr(use->CopyWithType());
-    } else if (from == kUnboxedMint) {
-      boxed = new(I) BoxIntegerInstr(use->CopyWithType());
-    } else if (from == kUnboxedFloat64x2) {
-      boxed = new(I) BoxFloat64x2Instr(use->CopyWithType());
-    } else if (from == kUnboxedInt32) {
-      boxed = new(I) BoxInt32Instr(use->CopyWithType());
-    } else if (from == kUnboxedUint32) {
-      boxed = new(I) BoxUint32Instr(use->CopyWithType());
-    } else {
-      UNIMPLEMENTED();
-    }
+      deopt_target->DeoptimizationTarget() : Isolate::kNoDeoptId;
+    ASSERT(Boxing::Supports(from));
+    ASSERT(Boxing::Supports(to));
+    Definition* boxed = BoxInstr::Create(from, use->CopyWithType());
     use->BindTo(boxed);
     InsertBefore(insert_before, boxed, NULL, FlowGraph::kValue);
-    Value* to_value = new(I) Value(boxed);
-    if (to == kUnboxedDouble) {
-      converted = new(I) UnboxDoubleInstr(to_value, deopt_id);
-    } else if (to == kUnboxedInt32x4) {
-      converted = new(I) UnboxInt32x4Instr(to_value, deopt_id);
-    } else if (to == kUnboxedFloat32x4) {
-      converted = new(I) UnboxFloat32x4Instr(to_value, deopt_id);
-    } else if (to == kUnboxedMint) {
-      converted = new(I) UnboxIntegerInstr(to_value, deopt_id);
-    } else if (to == kUnboxedFloat64x2) {
-      converted = new(I) UnboxFloat64x2Instr(to_value, deopt_id);
-    } else if (to == kUnboxedInt32) {
-      boxed = new(I) UnboxInt32Instr(use->CopyWithType(), deopt_id);
-    } else if (to == kUnboxedUint32) {
-      boxed = new(I) UnboxUint32Instr(use->CopyWithType(), deopt_id);
-    } else {
-      UNIMPLEMENTED();
-    }
+    converted = UnboxInstr::Create(to, new(I) Value(boxed), deopt_id);
   }
   ASSERT(converted != NULL);
   InsertBefore(insert_before, converted, use->instruction()->env(),
@@ -1394,9 +1297,9 @@
                                     FlowGraph::kValue);
   } else if (array_cid == kTypedDataInt32ArrayCid) {
     stored_value = new(I) UnboxInt32Instr(
+        UnboxInt32Instr::kTruncate,
         new(I) Value(stored_value),
         call->deopt_id());
-    stored_value->AsUnboxIntN()->mark_truncating();
     cursor = flow_graph()->AppendTo(cursor,
                                     stored_value,
                                     call->env(),
@@ -1405,7 +1308,7 @@
     stored_value = new(I) UnboxUint32Instr(
         new(I) Value(stored_value),
         call->deopt_id());
-    ASSERT(stored_value->AsUnboxIntN()->is_truncating());
+    ASSERT(stored_value->AsUnboxInteger()->is_truncating());
     cursor = flow_graph()->AppendTo(cursor,
                                     stored_value,
                                     call->env(),
@@ -3882,9 +3785,9 @@
                                     FlowGraph::kValue);
   } else if (view_cid == kTypedDataInt32ArrayCid) {
     stored_value = new(I) UnboxInt32Instr(
+        UnboxInt32Instr::kTruncate,
         new(I) Value(stored_value),
         call->deopt_id());
-    stored_value->AsUnboxIntN()->mark_truncating();
     cursor = flow_graph()->AppendTo(cursor,
                                     stored_value,
                                     call->env(),
@@ -3893,7 +3796,7 @@
     stored_value = new(I) UnboxUint32Instr(
         new(I) Value(stored_value),
         call->deopt_id());
-    ASSERT(stored_value->AsUnboxIntN()->is_truncating());
+    ASSERT(stored_value->AsUnboxInteger()->is_truncating());
     cursor = flow_graph()->AppendTo(cursor,
                                     stored_value,
                                     call->env(),
@@ -5140,8 +5043,7 @@
 static bool IsLoadEliminationCandidate(Instruction* instr) {
   return instr->IsLoadField()
       || instr->IsLoadIndexed()
-      || instr->IsLoadStaticField()
-      || instr->IsCurrentContext();
+      || instr->IsLoadStaticField();
 }
 
 
@@ -5284,9 +5186,6 @@
 
     // Indexed location with a constant index.
     kConstantIndexed,
-
-    // Current context.
-    kContext
   };
 
   Place(const Place& other)
@@ -5373,21 +5272,6 @@
         break;
       }
 
-      case Instruction::kCurrentContext:
-        kind_ = kContext;
-        ASSERT(instr->AsCurrentContext()->representation() == kTagged);
-        representation_ = kTagged;
-        *is_load = true;
-        break;
-
-      case Instruction::kStoreContext:
-        kind_ = kContext;
-        ASSERT(instr->AsStoreContext()->RequiredInputRepresentation(
-            StoreContextInstr::kValuePos) == kTagged);
-        representation_ = kTagged;
-        *is_store = true;
-        break;
-
       default:
         break;
     }
@@ -5427,7 +5311,6 @@
       case kConstantIndexed:
         return true;
 
-      case kContext:
       case kNone:
         return false;
     }
@@ -5527,9 +5410,6 @@
             "<%s[%" Pd "]>",
             DefinitionName(instance()),
             index_constant());
-
-      case kContext:
-        return "<context>";
     }
     UNREACHABLE();
     return "<?>";
@@ -5956,9 +5836,7 @@
           // X.f or X.@offs alias with *.f and *.@offs respectively.
           CrossAlias(alias, alias->CopyWithoutInstance());
         }
-
-      case Place::kContext:
-        return;
+        break;
 
       case Place::kNone:
         UNREACHABLE();
@@ -6158,10 +6036,6 @@
     return store_static_field->value()->definition();
   }
 
-  if (instr->IsStoreContext()) {
-    return instr->InputAt(0)->definition();
-  }
-
   UNREACHABLE();  // Should only be called for supported store instructions.
   return NULL;
 }
@@ -7225,7 +7099,6 @@
           // Can't eliminate stores that initialized unboxed fields.
           return false;
         }
-      case Instruction::kStoreContext:
       case Instruction::kStoreIndexed:
       case Instruction::kStoreStaticField:
         return true;
@@ -7765,9 +7638,6 @@
 // --------------------------------------------------------------------------
 // Analysis of non-definition instructions.  They do not have values so they
 // cannot have constant values.
-void ConstantPropagator::VisitStoreContext(StoreContextInstr* instr) { }
-
-
 void ConstantPropagator::VisitCheckStackOverflow(
     CheckStackOverflowInstr* instr) { }
 
@@ -8400,13 +8270,13 @@
 }
 
 
-void ConstantPropagator::VisitBoxInteger(BoxIntegerInstr* instr) {
+void ConstantPropagator::VisitBoxInt64(BoxInt64Instr* instr) {
   // TODO(kmillikin): Handle box operation.
   SetValue(instr, non_constant_);
 }
 
 
-void ConstantPropagator::VisitUnboxInteger(UnboxIntegerInstr* instr) {
+void ConstantPropagator::VisitUnboxInt64(UnboxInt64Instr* instr) {
   // TODO(kmillikin): Handle unbox operation.
   SetValue(instr, non_constant_);
 }
@@ -8789,7 +8659,7 @@
 }
 
 
-void ConstantPropagator::VisitUnboxDouble(UnboxDoubleInstr* instr) {
+void ConstantPropagator::VisitUnbox(UnboxInstr* instr) {
   const Object& value = instr->value()->definition()->constant_value();
   if (IsNonConstant(value)) {
     SetValue(instr, non_constant_);
@@ -8800,73 +8670,7 @@
 }
 
 
-void ConstantPropagator::VisitBoxDouble(BoxDoubleInstr* instr) {
-  const Object& value = instr->value()->definition()->constant_value();
-  if (IsNonConstant(value)) {
-    SetValue(instr, non_constant_);
-  } else if (IsConstant(value)) {
-    // TODO(kmillikin): Handle conversion.
-    SetValue(instr, non_constant_);
-  }
-}
-
-
-void ConstantPropagator::VisitUnboxFloat32x4(UnboxFloat32x4Instr* instr) {
-  const Object& value = instr->value()->definition()->constant_value();
-  if (IsNonConstant(value)) {
-    SetValue(instr, non_constant_);
-  } else if (IsConstant(value)) {
-    // TODO(kmillikin): Handle conversion.
-    SetValue(instr, non_constant_);
-  }
-}
-
-
-void ConstantPropagator::VisitBoxFloat32x4(BoxFloat32x4Instr* instr) {
-  const Object& value = instr->value()->definition()->constant_value();
-  if (IsNonConstant(value)) {
-    SetValue(instr, non_constant_);
-  } else if (IsConstant(value)) {
-    // TODO(kmillikin): Handle conversion.
-    SetValue(instr, non_constant_);
-  }
-}
-
-
-void ConstantPropagator::VisitUnboxFloat64x2(UnboxFloat64x2Instr* instr) {
-  const Object& value = instr->value()->definition()->constant_value();
-  if (IsNonConstant(value)) {
-    SetValue(instr, non_constant_);
-  } else if (IsConstant(value)) {
-    // TODO(kmillikin): Handle conversion.
-    SetValue(instr, non_constant_);
-  }
-}
-
-
-void ConstantPropagator::VisitBoxFloat64x2(BoxFloat64x2Instr* instr) {
-  const Object& value = instr->value()->definition()->constant_value();
-  if (IsNonConstant(value)) {
-    SetValue(instr, non_constant_);
-  } else if (IsConstant(value)) {
-    // TODO(kmillikin): Handle conversion.
-    SetValue(instr, non_constant_);
-  }
-}
-
-
-void ConstantPropagator::VisitUnboxInt32x4(UnboxInt32x4Instr* instr) {
-  const Object& value = instr->value()->definition()->constant_value();
-  if (IsNonConstant(value)) {
-    SetValue(instr, non_constant_);
-  } else if (IsConstant(value)) {
-    // TODO(kmillikin): Handle conversion.
-    SetValue(instr, non_constant_);
-  }
-}
-
-
-void ConstantPropagator::VisitBoxInt32x4(BoxInt32x4Instr* instr) {
+void ConstantPropagator::VisitBox(BoxInstr* instr) {
   const Object& value = instr->value()->definition()->constant_value();
   if (IsNonConstant(value)) {
     SetValue(instr, non_constant_);
@@ -9893,9 +9697,7 @@
     MaterializeObjectInstr* mat = materializations_[i];
     for (intptr_t j = 0; j < mat->InputCount(); j++) {
       Definition* defn = mat->InputAt(j)->definition();
-      if (defn->IsBoxDouble() ||
-          defn->IsBoxFloat32x4() ||
-          defn->IsBoxInt32x4()) {
+      if (defn->IsBox()) {
         mat->InputAt(j)->BindTo(defn->InputAt(0)->definition());
       }
     }
diff --git a/runtime/vm/flow_graph_range_analysis.cc b/runtime/vm/flow_graph_range_analysis.cc
index 8b597d7..18487cc 100644
--- a/runtime/vm/flow_graph_range_analysis.cc
+++ b/runtime/vm/flow_graph_range_analysis.cc
@@ -506,7 +506,7 @@
     // range possible for this value.
     // We don't need to handle kMintCid here because all external mints
     // (e.g. results of loads or function call) can be used only after they
-    // pass through UnboxIntegerInstr which is considered as mint-definition
+    // pass through UnboxInt64Instr which is considered as mint-definition
     // and will have a range assigned to it.
     // Note: that we can't return NULL here because it is used as lattice's
     // bottom element to indicate that the range was not computed *yet*.
@@ -1647,8 +1647,8 @@
   // TODO(johnmccutchan): Consider Smi operations, to avoid unnecessary tagging
   // & untagged of intermediate results.
   // TODO(johnmccutchan): Consider phis.
-  return def->IsBoxInteger()   ||   // BoxMint.
-         def->IsUnboxInteger() ||   // UnboxMint.
+  return def->IsBoxInt64() ||
+         def->IsUnboxInt64() ||
          def->IsBinaryMintOp() ||
          def->IsShiftMintOp()  ||
          def->IsUnaryMintOp();
@@ -1740,10 +1740,9 @@
 
 bool IntegerInstructionSelector::CanBecomeUint32(Definition* def) {
   ASSERT(IsPotentialUint32Definition(def));
-  if (def->IsBoxInteger()) {
-    // If a BoxInteger's input is a candidate, the box is a candidate.
-    BoxIntegerInstr* box = def->AsBoxInteger();
-    Definition* box_input = box->value()->definition();
+  if (def->IsBoxInt64()) {
+    // If a BoxInt64's input is a candidate, the box is a candidate.
+    Definition* box_input = def->AsBoxInt64()->value()->definition();
     return selected_uint32_defs_->Contains(box_input->ssa_temp_index());
   }
   // A right shift with an input outside of Uint32 range cannot be converted
@@ -1818,14 +1817,13 @@
     Value* right = op->right()->CopyWithType();
     intptr_t deopt_id = op->DeoptimizationTarget();
     return new(I) BinaryUint32OpInstr(op_kind, left, right, deopt_id);
-  } else if (def->IsBoxInteger()) {
-    BoxIntegerInstr* box = def->AsBoxInteger();
-    Value* value = box->value()->CopyWithType();
+  } else if (def->IsBoxInt64()) {
+    Value* value = def->AsBoxInt64()->value()->CopyWithType();
     return new(I) BoxUint32Instr(value);
-  } else if (def->IsUnboxInteger()) {
-    UnboxIntegerInstr* unbox = def->AsUnboxInteger();
+  } else if (def->IsUnboxInt64()) {
+    UnboxInstr* unbox = def->AsUnboxInt64();
     Value* value = unbox->value()->CopyWithType();
-    intptr_t deopt_id = unbox->deopt_id();
+    intptr_t deopt_id = unbox->DeoptimizationTarget();
     return new(I) UnboxUint32Instr(value, deopt_id);
   } else if (def->IsUnaryMintOp()) {
     UnaryMintOpInstr* op = def->AsUnaryMintOp();
@@ -2908,7 +2906,7 @@
 }
 
 
-void BoxInt32Instr::InferRange(RangeAnalysis* analysis, Range* range) {
+void BoxIntegerInstr::InferRange(RangeAnalysis* analysis, Range* range) {
   const Range* value_range = value()->definition()->range();
   if (!Range::IsUnknown(value_range)) {
     *range = *value_range;
@@ -2936,6 +2934,17 @@
 }
 
 
+void UnboxInt64Instr::InferRange(RangeAnalysis* analysis, Range* range) {
+  const Range* value_range = value()->definition()->range();
+  if (value_range != NULL) {
+    *range = *value_range;
+  } else if (!value()->definition()->IsMintDefinition() &&
+             (value()->definition()->Type()->ToCid() != kSmiCid)) {
+    *range = Range::Full(RangeBoundary::kRangeBoundaryInt64);
+  }
+}
+
+
 void UnboxedIntConverterInstr::InferRange(RangeAnalysis* analysis,
                                           Range* range) {
   ASSERT((from() == kUnboxedInt32) ||
@@ -2963,28 +2972,6 @@
 }
 
 
-void BoxIntegerInstr::InferRange(RangeAnalysis* analysis, Range* range) {
-  const Range* input_range = value()->definition()->range();
-  if (input_range != NULL) {
-    bool is_smi = input_range->Fits(RangeBoundary::kRangeBoundarySmi);
-    set_is_smi(is_smi);
-    // The output range is the same as the input range.
-    *range = *input_range;
-  }
-}
-
-
-void UnboxIntegerInstr::InferRange(RangeAnalysis* analysis, Range* range) {
-  const Range* value_range = value()->definition()->range();
-  if (value_range != NULL) {
-    *range = *value_range;
-  } else if (!value()->definition()->IsMintDefinition() &&
-             (value()->definition()->Type()->ToCid() != kSmiCid)) {
-    *range = Range::Full(RangeBoundary::kRangeBoundaryInt64);
-  }
-}
-
-
 bool CheckArrayBoundInstr::IsRedundant(const RangeBoundary& length) {
   Range* index_range = index()->definition()->range();
 
diff --git a/runtime/vm/flow_graph_type_propagator.cc b/runtime/vm/flow_graph_type_propagator.cc
index 0501f6a..fc33aaf 100644
--- a/runtime/vm/flow_graph_type_propagator.cc
+++ b/runtime/vm/flow_graph_type_propagator.cc
@@ -548,12 +548,14 @@
   if (type_ == NULL) {
     ASSERT(cid_ != kIllegalCid);
 
-    // VM internal Function objects don't have a compile-type. Return
-    // dynamic-type in this case.
-    if (cid_ == kFunctionCid) {
+    // VM internal Function and Context objects don't have a compile-type.
+    // Return dynamic-type in this case.
+    if (cid_ == kFunctionCid || cid_ == kContextCid) {
       type_ = &Type::ZoneHandle(Type::DynamicType());
       return type_;
     }
+    // Except the special cases above, only instances are expected.
+    ASSERT(cid_ >= kInstanceCid);
 
     const Class& type_class =
         Class::Handle(Isolate::Current()->class_table()->At(cid_));
@@ -1042,7 +1044,7 @@
 }
 
 // Note that MintOp may produce Smi-s as result of an
-// appended BoxIntegerInstr node.
+// appended BoxInt64Instr node.
 CompileType BinaryMintOpInstr::ComputeType() const {
   return CompileType::Int();
 }
@@ -1059,29 +1061,11 @@
 
 
 CompileType BoxIntegerInstr::ComputeType() const {
-  if (is_smi()) {
-    return CompileType::FromCid(kSmiCid);
-  }
-  return CompileType::Int();
-}
-
-
-bool BoxIntegerInstr::RecomputeType() {
-  return UpdateType(ComputeType());
-}
-
-
-CompileType BoxIntNInstr::ComputeType() const {
   return ValueFitsSmi() ? CompileType::FromCid(kSmiCid) : CompileType::Int();
 }
 
 
-CompileType UnboxIntNInstr::ComputeType() const {
-  return CompileType::Int();
-}
-
-
-bool BoxIntNInstr::RecomputeType() {
+bool BoxIntegerInstr::RecomputeType() {
   return UpdateType(ComputeType());
 }
 
@@ -1288,43 +1272,48 @@
 }
 
 
-CompileType UnboxDoubleInstr::ComputeType() const {
-  return CompileType::FromCid(kDoubleCid);
+CompileType UnboxInstr::ComputeType() const {
+  switch (representation()) {
+    case kUnboxedDouble:
+      return CompileType::FromCid(kDoubleCid);
+
+    case kUnboxedFloat32x4:
+      return CompileType::FromCid(kFloat32x4Cid);
+
+    case kUnboxedFloat64x2:
+      return CompileType::FromCid(kFloat64x2Cid);
+
+    case kUnboxedInt32x4:
+      return CompileType::FromCid(kInt32x4Cid);
+
+    case kUnboxedMint:
+      return CompileType::Int();
+
+    default:
+      UNREACHABLE();
+      return CompileType::Dynamic();
+  }
 }
 
 
-CompileType BoxDoubleInstr::ComputeType() const {
-  return CompileType::FromCid(kDoubleCid);
-}
+CompileType BoxInstr::ComputeType() const {
+  switch (from_representation()) {
+    case kUnboxedDouble:
+      return CompileType::FromCid(kDoubleCid);
 
+    case kUnboxedFloat32x4:
+      return CompileType::FromCid(kFloat32x4Cid);
 
-CompileType UnboxFloat32x4Instr::ComputeType() const {
-  return CompileType::FromCid(kFloat32x4Cid);
-}
+    case kUnboxedFloat64x2:
+      return CompileType::FromCid(kFloat64x2Cid);
 
+    case kUnboxedInt32x4:
+      return CompileType::FromCid(kInt32x4Cid);
 
-CompileType BoxFloat32x4Instr::ComputeType() const {
-  return CompileType::FromCid(kFloat32x4Cid);
-}
-
-
-CompileType UnboxFloat64x2Instr::ComputeType() const {
-  return CompileType::FromCid(kFloat64x2Cid);
-}
-
-
-CompileType BoxFloat64x2Instr::ComputeType() const {
-  return CompileType::FromCid(kFloat64x2Cid);
-}
-
-
-CompileType UnboxInt32x4Instr::ComputeType() const {
-  return CompileType::FromCid(kInt32x4Cid);
-}
-
-
-CompileType BoxInt32x4Instr::ComputeType() const {
-  return CompileType::FromCid(kInt32x4Cid);
+    default:
+      UNREACHABLE();
+      return CompileType::Dynamic();
+  }
 }
 
 
diff --git a/runtime/vm/il_printer.cc b/runtime/vm/il_printer.cc
index 5a34fcc..df8c95c 100644
--- a/runtime/vm/il_printer.cc
+++ b/runtime/vm/il_printer.cc
@@ -356,7 +356,7 @@
 
 
 void ClosureCallInstr::PrintOperandsTo(BufferFormatter* f) const {
-  f->Print("function=");
+  f->Print(" function=");
   InputAt(0)->PrintTo(f);
   for (intptr_t i = 0; i < ArgumentCount(); ++i) {
     f->Print(", ");
@@ -366,7 +366,7 @@
 
 
 void InstanceCallInstr::PrintOperandsTo(BufferFormatter* f) const {
-  f->Print("%s", function_name().ToCString());
+  f->Print(" %s", function_name().ToCString());
   for (intptr_t i = 0; i < ArgumentCount(); ++i) {
     f->Print(", ");
     PushArgumentAt(i)->value()->PrintTo(f);
@@ -378,7 +378,7 @@
 
 
 void PolymorphicInstanceCallInstr::PrintOperandsTo(BufferFormatter* f) const {
-  f->Print("%s", instance_call()->function_name().ToCString());
+  f->Print(" %s", instance_call()->function_name().ToCString());
   for (intptr_t i = 0; i < ArgumentCount(); ++i) {
     f->Print(", ");
     PushArgumentAt(i)->value()->PrintTo(f);
@@ -417,7 +417,7 @@
 
 
 void StaticCallInstr::PrintOperandsTo(BufferFormatter* f) const {
-  f->Print("%s ", String::Handle(function().name()).ToCString());
+  f->Print(" %s ", String::Handle(function().name()).ToCString());
   for (intptr_t i = 0; i < ArgumentCount(); ++i) {
     if (i > 0) f->Print(", ");
     PushArgumentAt(i)->value()->PrintTo(f);
@@ -986,7 +986,7 @@
 }
 
 
-void UnboxIntNInstr::PrintOperandsTo(BufferFormatter* f) const {
+void UnboxIntegerInstr::PrintOperandsTo(BufferFormatter* f) const {
   if (is_truncating()) {
     f->Print("[tr], ");
   }
diff --git a/runtime/vm/intermediate_language.cc b/runtime/vm/intermediate_language.cc
index 7a80023..c0a4f03 100644
--- a/runtime/vm/intermediate_language.cc
+++ b/runtime/vm/intermediate_language.cc
@@ -390,12 +390,12 @@
 
 
 bool Value::BindsTo32BitMaskConstant() const {
-  if (!definition()->IsUnboxInteger() || !definition()->IsUnboxUint32()) {
+  if (!definition()->IsUnboxInt64() || !definition()->IsUnboxUint32()) {
     return false;
   }
-  // Two cases to consider: UnboxInteger and UnboxUint32.
-  if (definition()->IsUnboxInteger()) {
-    UnboxIntegerInstr* instr = definition()->AsUnboxInteger();
+  // Two cases to consider: UnboxInt64 and UnboxUint32.
+  if (definition()->IsUnboxInt64()) {
+    UnboxInt64Instr* instr = definition()->AsUnboxInt64();
     if (!instr->value()->BindsToConstant()) {
       return false;
     }
@@ -1055,7 +1055,7 @@
 }
 
 
-void JoinEntryInstr::InsertPhi(intptr_t var_index, intptr_t var_count) {
+PhiInstr* JoinEntryInstr::InsertPhi(intptr_t var_index, intptr_t var_count) {
   // Lazily initialize the array of phis.
   // Currently, phis are stored in a sparse array that holds the phi
   // for variable with index i at position i.
@@ -1067,7 +1067,7 @@
     }
   }
   ASSERT((*phis_)[var_index] == NULL);
-  (*phis_)[var_index] = new PhiInstr(this, PredecessorCount());
+  return (*phis_)[var_index] = new PhiInstr(this, PredecessorCount());
 }
 
 
@@ -1262,9 +1262,9 @@
 
 static bool ToIntegerConstant(Value* value, int64_t* result) {
   if (!value->BindsToConstant()) {
-    if (value->definition()->IsUnboxDouble()) {
-      return ToIntegerConstant(value->definition()->AsUnboxDouble()->value(),
-                               result);
+    UnboxInstr* unbox = value->definition()->AsUnbox();
+    if ((unbox != NULL) && (unbox->representation() == kUnboxedDouble)) {
+      return ToIntegerConstant(unbox->value(), result);
     }
     return false;
   }
@@ -1904,164 +1904,47 @@
 }
 
 
-Definition* BoxDoubleInstr::Canonicalize(FlowGraph* flow_graph) {
+Definition* BoxInstr::Canonicalize(FlowGraph* flow_graph) {
   if ((input_use_list() == NULL) && !HasTryBlockUse(env_use_list())) {
     // Environments can accomodate any representation. No need to box.
     return value()->definition();
   }
 
-  // Fold away BoxDouble(UnboxDouble(v)) if value is known to be double.
-  UnboxDoubleInstr* defn = value()->definition()->AsUnboxDouble();
-  if ((defn != NULL) && (defn->value()->Type()->ToCid() == kDoubleCid)) {
-    return defn->value()->definition();
+  // Fold away Box<rep>(Unbox<rep>(v)) if value is known to be of the
+  // right class.
+  UnboxInstr* unbox_defn = value()->definition()->AsUnbox();
+  if ((unbox_defn != NULL) &&
+      (unbox_defn->representation() == from_representation()) &&
+      (unbox_defn->value()->Type()->ToCid() == Type()->ToCid())) {
+    return unbox_defn->value()->definition();
   }
 
   return this;
 }
 
 
-bool BoxIntNInstr::ValueFitsSmi() const {
+bool BoxIntegerInstr::ValueFitsSmi() const {
   Range* range = value()->definition()->range();
   return RangeUtils::Fits(range, RangeBoundary::kRangeBoundarySmi);
 }
 
 
-Definition* BoxIntNInstr::Canonicalize(FlowGraph* flow_graph) {
-  if ((input_use_list() == NULL) && !HasTryBlockUse(env_use_list())) {
-    // Environments can accomodate any representation. No need to box.
-    return value()->definition();
-  }
-
-  return this;
-}
-
-
-Definition* UnboxIntNInstr::Canonicalize(FlowGraph* flow_graph) {
-  if (!HasUses()) return NULL;
-
-  // Fold away UnboxInt<N>Instr(BoxInt<N>Instr(v)).
-  BoxIntNInstr* box_defn = value()->definition()->AsBoxIntN();
-  if (box_defn != NULL) {
-    if (box_defn->value()->definition()->representation() == representation()) {
-      return box_defn->value()->definition();
-    } else {
-      UnboxedIntConverterInstr* converter = new UnboxedIntConverterInstr(
-          box_defn->value()->definition()->representation(),
-          representation(),
-          box_defn->value()->CopyWithType(),
-          (representation() == kUnboxedInt32) ?
-              GetDeoptId() : Isolate::kNoDeoptId);
-      if ((representation() == kUnboxedInt32) && is_truncating()) {
-        converter->mark_truncating();
-      }
-      flow_graph->InsertBefore(this, converter, env(), FlowGraph::kValue);
-      return converter;
-    }
-  }
-
-  return this;
-}
-
-
-Definition* UnboxedIntConverterInstr::Canonicalize(FlowGraph* flow_graph) {
-  if (!HasUses()) return NULL;
-
-  UnboxedIntConverterInstr* box_defn =
-      value()->definition()->AsUnboxedIntConverter();
-  if ((box_defn != NULL) && (box_defn->representation() == from())) {
-    if (box_defn->from() == to()) {
-      return box_defn->value()->definition();
-    }
-
-    UnboxedIntConverterInstr* converter = new UnboxedIntConverterInstr(
-        box_defn->from(),
-        representation(),
-        box_defn->value()->CopyWithType(),
-        (to() == kUnboxedInt32) ? GetDeoptId() : Isolate::kNoDeoptId);
-    if ((representation() == kUnboxedInt32) && is_truncating()) {
-      converter->mark_truncating();
-    }
-    flow_graph->InsertBefore(this, converter, env(), FlowGraph::kValue);
-    return converter;
-  }
-
-  UnboxIntegerInstr* unbox_defn = value()->definition()->AsUnboxInteger();
-  if (unbox_defn != NULL &&
-      (from() == kUnboxedMint) &&
-      (to() == kUnboxedInt32) &&
-      unbox_defn->HasOnlyInputUse(value())) {
-    // TODO(vegorov): there is a duplication of code between UnboxedIntCoverter
-    // and code path that unboxes Mint into Int32. We should just schedule
-    // these instructions close to each other instead of fusing them.
-    Definition* replacement =
-        new UnboxInt32Instr(unbox_defn->value()->CopyWithType(), GetDeoptId());
-    if (is_truncating()) {
-      replacement->AsUnboxInt32()->mark_truncating();
-    }
-    flow_graph->InsertBefore(this,
-                             replacement,
-                             env(),
-                             FlowGraph::kValue);
-    return replacement;
-  }
-
-  return this;
-}
-
-
-Definition* UnboxInt32Instr::Canonicalize(FlowGraph* flow_graph) {
-  Definition* replacement = UnboxIntNInstr::Canonicalize(flow_graph);
-  if (replacement != this) {
-    return replacement;
-  }
-
-  ConstantInstr* c = value()->definition()->AsConstant();
-  if ((c != NULL) && c->value().IsSmi()) {
-    if (!is_truncating() && (kSmiBits > 32)) {
-      // Check that constant fits into 32-bit integer.
-      const int64_t value =
-          static_cast<int64_t>(Smi::Cast(c->value()).Value());
-      if (!Utils::IsInt(32, value)) {
-        return this;
-      }
-    }
-
-    UnboxedConstantInstr* uc =
-        new UnboxedConstantInstr(c->value(), kUnboxedInt32);
-    flow_graph->InsertBefore(this, uc, NULL, FlowGraph::kValue);
-    return uc;
-  }
-
-  return this;
-}
-
-
-Definition* UnboxDoubleInstr::Canonicalize(FlowGraph* flow_graph) {
-  if (!HasUses()) return NULL;
-  // Fold away UnboxDouble(BoxDouble(v)).
-  BoxDoubleInstr* box_defn = value()->definition()->AsBoxDouble();
-  if (box_defn != NULL) {
-    return box_defn->value()->definition();
-  }
-
-  ConstantInstr* c = value()->definition()->AsConstant();
-  if ((c != NULL) && c->value().IsDouble()) {
-    UnboxedConstantInstr* uc =
-        new UnboxedConstantInstr(c->value(), kUnboxedDouble);
-    flow_graph->InsertBefore(this, uc, NULL, FlowGraph::kValue);
-    return uc;
-  }
-
-  return this;
-}
-
-
 Definition* BoxIntegerInstr::Canonicalize(FlowGraph* flow_graph) {
   if ((input_use_list() == NULL) && !HasTryBlockUse(env_use_list())) {
     // Environments can accomodate any representation. No need to box.
     return value()->definition();
   }
 
+  return this;
+}
+
+
+Definition* BoxInt64Instr::Canonicalize(FlowGraph* flow_graph) {
+  Definition* replacement = BoxIntegerInstr::Canonicalize(flow_graph);
+  if (replacement != this) {
+    return replacement;
+  }
+
   UnboxedIntConverterInstr* conv =
       value()->definition()->AsUnboxedIntConverter();
   if (conv != NULL) {
@@ -2093,82 +1976,138 @@
 }
 
 
+Definition* UnboxInstr::Canonicalize(FlowGraph* flow_graph) {
+  if (!HasUses()) return NULL;
+
+  // Fold away Unbox<rep>(Box<rep>(v)).
+  BoxInstr* box_defn = value()->definition()->AsBox();
+  if ((box_defn != NULL) &&
+      (box_defn->from_representation() == representation())) {
+    return box_defn->value()->definition();
+  }
+
+  if ((representation() == kUnboxedDouble) && value()->BindsToConstant()) {
+    UnboxedConstantInstr* uc = NULL;
+
+    const Object& val = value()->BoundConstant();
+    if (val.IsSmi()) {
+      const Double& double_val = Double::ZoneHandle(flow_graph->isolate(),
+          Double::NewCanonical(Smi::Cast(val).AsDoubleValue()));
+      uc = new UnboxedConstantInstr(double_val, kUnboxedDouble);
+    } else if (val.IsDouble()) {
+      uc = new UnboxedConstantInstr(val, kUnboxedDouble);
+    }
+
+    if (uc != NULL) {
+      flow_graph->InsertBefore(this, uc, NULL, FlowGraph::kValue);
+      return uc;
+    }
+  }
+
+  return this;
+}
+
+
 Definition* UnboxIntegerInstr::Canonicalize(FlowGraph* flow_graph) {
   if (!HasUses()) return NULL;
-  return this;
-}
 
-
-Definition* BoxFloat32x4Instr::Canonicalize(FlowGraph* flow_graph) {
-  if ((input_use_list() == NULL) && !HasTryBlockUse(env_use_list())) {
-    // Environments can accomodate any representation. No need to box.
-    return value()->definition();
-  }
-
-  // Fold away BoxFloat32x4(UnboxFloat32x4(v)).
-  UnboxFloat32x4Instr* defn = value()->definition()->AsUnboxFloat32x4();
-  if ((defn != NULL) && (defn->value()->Type()->ToCid() == kFloat32x4Cid)) {
-    return defn->value()->definition();
+  // Fold away UnboxInteger<rep_to>(BoxInteger<rep_from>(v)).
+  BoxIntegerInstr* box_defn = value()->definition()->AsBoxInteger();
+  if (box_defn != NULL) {
+    if (box_defn->value()->definition()->representation() == representation()) {
+      return box_defn->value()->definition();
+    } else {
+      UnboxedIntConverterInstr* converter = new UnboxedIntConverterInstr(
+          box_defn->value()->definition()->representation(),
+          representation(),
+          box_defn->value()->CopyWithType(),
+          (representation() == kUnboxedInt32) ?
+              GetDeoptId() : Isolate::kNoDeoptId);
+      if ((representation() == kUnboxedInt32) && is_truncating()) {
+        converter->mark_truncating();
+      }
+      flow_graph->InsertBefore(this, converter, env(), FlowGraph::kValue);
+      return converter;
+    }
   }
 
   return this;
 }
 
 
-Definition* UnboxFloat32x4Instr::Canonicalize(FlowGraph* flow_graph) {
-  // Fold away UnboxFloat32x4(BoxFloat32x4(v)).
-  BoxFloat32x4Instr* defn = value()->definition()->AsBoxFloat32x4();
-  return (defn != NULL) ? defn->value()->definition() : this;
-}
-
-
-Definition* BoxFloat64x2Instr::Canonicalize(FlowGraph* flow_graph) {
-  if ((input_use_list() == NULL) && !HasTryBlockUse(env_use_list())) {
-    // Environments can accomodate any representation. No need to box.
-    return value()->definition();
+Definition* UnboxInt32Instr::Canonicalize(FlowGraph* flow_graph) {
+  Definition* replacement = UnboxIntegerInstr::Canonicalize(flow_graph);
+  if (replacement != this) {
+    return replacement;
   }
 
-  // Fold away BoxFloat64x2(UnboxFloat64x2(v)).
-  UnboxFloat64x2Instr* defn = value()->definition()->AsUnboxFloat64x2();
-  if ((defn != NULL) && (defn->value()->Type()->ToCid() == kFloat64x2Cid)) {
-    return defn->value()->definition();
+  ConstantInstr* c = value()->definition()->AsConstant();
+  if ((c != NULL) && c->value().IsSmi()) {
+    if (!is_truncating() && (kSmiBits > 32)) {
+      // Check that constant fits into 32-bit integer.
+      const int64_t value =
+          static_cast<int64_t>(Smi::Cast(c->value()).Value());
+      if (!Utils::IsInt(32, value)) {
+        return this;
+      }
+    }
+
+    UnboxedConstantInstr* uc =
+        new UnboxedConstantInstr(c->value(), kUnboxedInt32);
+    flow_graph->InsertBefore(this, uc, NULL, FlowGraph::kValue);
+    return uc;
   }
 
   return this;
 }
 
 
-Definition* UnboxFloat64x2Instr::Canonicalize(FlowGraph* flow_graph) {
-  // Fold away UnboxFloat64x2(BoxFloat64x2(v)).
-  BoxFloat64x2Instr* defn = value()->definition()->AsBoxFloat64x2();
-  return (defn != NULL) ? defn->value()->definition() : this;
-}
+Definition* UnboxedIntConverterInstr::Canonicalize(FlowGraph* flow_graph) {
+  if (!HasUses()) return NULL;
 
+  UnboxedIntConverterInstr* box_defn =
+      value()->definition()->AsUnboxedIntConverter();
+  if ((box_defn != NULL) && (box_defn->representation() == from())) {
+    if (box_defn->from() == to()) {
+      return box_defn->value()->definition();
+    }
 
-
-Definition* BoxInt32x4Instr::Canonicalize(FlowGraph* flow_graph) {
-  if ((input_use_list() == NULL) && !HasTryBlockUse(env_use_list())) {
-    // Environments can accomodate any representation. No need to box.
-    return value()->definition();
+    UnboxedIntConverterInstr* converter = new UnboxedIntConverterInstr(
+        box_defn->from(),
+        representation(),
+        box_defn->value()->CopyWithType(),
+        (to() == kUnboxedInt32) ? GetDeoptId() : Isolate::kNoDeoptId);
+    if ((representation() == kUnboxedInt32) && is_truncating()) {
+      converter->mark_truncating();
+    }
+    flow_graph->InsertBefore(this, converter, env(), FlowGraph::kValue);
+    return converter;
   }
 
-  // Fold away BoxInt32x4(UnboxInt32x4(v)).
-  UnboxInt32x4Instr* defn = value()->definition()->AsUnboxInt32x4();
-  if ((defn != NULL) && (defn->value()->Type()->ToCid() == kInt32x4Cid)) {
-    return defn->value()->definition();
+  UnboxInt64Instr* unbox_defn = value()->definition()->AsUnboxInt64();
+  if (unbox_defn != NULL &&
+      (from() == kUnboxedMint) &&
+      (to() == kUnboxedInt32) &&
+      unbox_defn->HasOnlyInputUse(value())) {
+    // TODO(vegorov): there is a duplication of code between UnboxedIntCoverter
+    // and code path that unboxes Mint into Int32. We should just schedule
+    // these instructions close to each other instead of fusing them.
+    Definition* replacement =
+        new UnboxInt32Instr(is_truncating() ? UnboxInt32Instr::kTruncate
+                                            : UnboxInt32Instr::kNoTruncation,
+                            unbox_defn->value()->CopyWithType(),
+                            GetDeoptId());
+    flow_graph->InsertBefore(this,
+                             replacement,
+                             env(),
+                             FlowGraph::kValue);
+    return replacement;
   }
 
   return this;
 }
 
 
-Definition* UnboxInt32x4Instr::Canonicalize(FlowGraph* flow_graph) {
-  // Fold away UnboxInt32x4(BoxInt32x4(v)).
-  BoxInt32x4Instr* defn = value()->definition()->AsBoxInt32x4();
-  return (defn != NULL) ? defn->value()->definition() : this;
-}
-
-
 Definition* BooleanNegateInstr::Canonicalize(FlowGraph* flow_graph) {
   Definition* defn = value()->definition();
   if (defn->IsComparison() && defn->HasOnlyUse(value())) {
@@ -2460,6 +2399,75 @@
 }
 
 
+BoxInstr* BoxInstr::Create(Representation from, Value* value) {
+  switch (from) {
+    case kUnboxedInt32:
+      return new BoxInt32Instr(value);
+
+    case kUnboxedUint32:
+      return new BoxUint32Instr(value);
+
+    case kUnboxedMint:
+      return new BoxInt64Instr(value);
+
+    case kUnboxedDouble:
+    case kUnboxedFloat32x4:
+    case kUnboxedFloat64x2:
+    case kUnboxedInt32x4:
+      return new BoxInstr(from, value);
+
+    default:
+      UNREACHABLE();
+      return NULL;
+  }
+}
+
+
+UnboxInstr* UnboxInstr::Create(Representation to,
+                               Value* value,
+                               intptr_t deopt_id) {
+  switch (to) {
+    case kUnboxedInt32:
+      return new UnboxInt32Instr(
+          UnboxInt32Instr::kNoTruncation, value, deopt_id);
+
+    case kUnboxedUint32:
+      return new UnboxUint32Instr(value, deopt_id);
+
+    case kUnboxedMint:
+      return new UnboxInt64Instr(value, deopt_id);
+
+    case kUnboxedDouble:
+    case kUnboxedFloat32x4:
+    case kUnboxedFloat64x2:
+    case kUnboxedInt32x4:
+      return new UnboxInstr(to, value, deopt_id);
+
+    default:
+      UNREACHABLE();
+      return NULL;
+  }
+}
+
+
+bool UnboxInstr::CanConvertSmi() const {
+  switch (representation()) {
+    case kUnboxedDouble:
+    case kUnboxedMint:
+      return true;
+
+    case kUnboxedFloat32x4:
+    case kUnboxedFloat64x2:
+    case kUnboxedInt32x4:
+      return false;
+
+    default:
+      UNREACHABLE();
+      return false;
+  }
+}
+
+
 // Shared code generation methods (EmitNativeCode and
 // MakeLocationSummary). Only assembly code that can be shared across all
 // architectures can be used. Machine specific register allocation and code
@@ -2645,33 +2653,15 @@
 
 LocationSummary* CurrentContextInstr::MakeLocationSummary(Isolate* isolate,
                                                           bool opt) const {
-  return LocationSummary::Make(isolate,
-                               0,
-                               Location::RegisterLocation(CTX),
-                               LocationSummary::kNoCall);
+  // Only appears in initial definitions, never in normal code.
+  UNREACHABLE();
+  return NULL;
 }
 
 
 void CurrentContextInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
-  // No code to emit. Just assert the correct result register.
-  ASSERT(locs()->out(0).reg() == CTX);
-}
-
-
-LocationSummary* StoreContextInstr::MakeLocationSummary(Isolate* isolate,
-                                                        bool optimizing) const {
-  const intptr_t kNumInputs = 1;
-  const intptr_t kNumTemps = 0;
-  LocationSummary* summary = new(isolate) LocationSummary(
-      isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall);
-  summary->set_in(0, Location::RegisterLocation(CTX));
-  return summary;
-}
-
-
-void StoreContextInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
-  // Nothing to do.  Context register was loaded by the register allocator.
-  ASSERT(locs()->in(0).reg() == CTX);
+  // Only appears in initial definitions, never in normal code.
+  UNREACHABLE();
 }
 
 
@@ -2729,7 +2719,7 @@
 
 LocationSummary* InstanceCallInstr::MakeLocationSummary(Isolate* isolate,
                                                         bool optimizing) const {
-  return MakeCallSummary();
+  return MakeCallSummary(isolate);
 }
 
 
@@ -2847,7 +2837,7 @@
 
 LocationSummary* StaticCallInstr::MakeLocationSummary(Isolate* isolate,
                                                       bool optimizing) const {
-  return MakeCallSummary();
+  return MakeCallSummary(isolate);
 }
 
 
diff --git a/runtime/vm/intermediate_language.h b/runtime/vm/intermediate_language.h
index 26733a5..83106c7 100644
--- a/runtime/vm/intermediate_language.h
+++ b/runtime/vm/intermediate_language.h
@@ -20,7 +20,7 @@
 
 class BitVector;
 class BlockEntryInstr;
-class BoxIntNInstr;
+class BoxIntegerInstr;
 class BufferFormatter;
 class CatchBlockEntryInstr;
 class ComparisonInstr;
@@ -36,7 +36,7 @@
 class Range;
 class RangeAnalysis;
 class RangeBoundary;
-class UnboxIntNInstr;
+class UnboxIntegerInstr;
 
 // CompileType describes type of the value produced by the definition.
 //
@@ -437,7 +437,6 @@
   M(AssertAssignable)                                                          \
   M(AssertBoolean)                                                             \
   M(CurrentContext)                                                            \
-  M(StoreContext)                                                              \
   M(ClosureCall)                                                               \
   M(InstanceCall)                                                              \
   M(PolymorphicInstanceCall)                                                   \
@@ -491,14 +490,10 @@
   M(BinaryDoubleOp)                                                            \
   M(MathUnary)                                                                 \
   M(MathMinMax)                                                                \
-  M(UnboxDouble)                                                               \
-  M(BoxDouble)                                                                 \
-  M(BoxFloat32x4)                                                              \
-  M(UnboxFloat32x4)                                                            \
-  M(BoxInt32x4)                                                                \
-  M(UnboxInt32x4)                                                              \
-  M(UnboxInteger)                                                              \
-  M(BoxInteger)                                                                \
+  M(Box)                                                                       \
+  M(Unbox)                                                                     \
+  M(BoxInt64)                                                                  \
+  M(UnboxInt64)                                                                \
   M(BinaryMintOp)                                                              \
   M(ShiftMintOp)                                                               \
   M(UnaryMintOp)                                                               \
@@ -537,8 +532,6 @@
   M(BinaryInt32x4Op)                                                           \
   M(TestSmi)                                                                   \
   M(TestCids)                                                                  \
-  M(BoxFloat64x2)                                                              \
-  M(UnboxFloat64x2)                                                            \
   M(BinaryFloat64x2Op)                                                         \
   M(Float64x2Zero)                                                             \
   M(Float64x2Constructor)                                                      \
@@ -561,8 +554,8 @@
 
 #define FOR_EACH_ABSTRACT_INSTRUCTION(M)                                       \
   M(BlockEntry)                                                                \
-  M(BoxIntN)                                                                   \
-  M(UnboxIntN)                                                                 \
+  M(BoxInteger)                                                                \
+  M(UnboxInteger)                                                              \
   M(Comparison)                                                                \
   M(UnaryIntegerOp)                                                            \
   M(BinaryIntegerOp)                                                           \
@@ -726,7 +719,7 @@
     locs_ = MakeLocationSummary(isolate, optimizing);
   }
 
-  static LocationSummary* MakeCallSummary();
+  static LocationSummary* MakeCallSummary(Isolate* isolate);
 
   virtual void EmitNativeCode(FlowGraphCompiler* compiler) {
     UNIMPLEMENTED();
@@ -1358,7 +1351,7 @@
 
   ZoneGrowableArray<PhiInstr*>* phis() const { return phis_; }
 
-  void InsertPhi(intptr_t var_index, intptr_t var_count);
+  PhiInstr* InsertPhi(intptr_t var_index, intptr_t var_count);
   void RemoveDeadPhis(Definition* replacement);
 
   void InsertPhi(PhiInstr* phi);
@@ -1621,14 +1614,7 @@
   }
 
   // Does this define a mint?
-  bool IsMintDefinition() {
-    return (Type()->ToCid() == kMintCid) ||
-            IsBinaryMintOp() ||
-            IsUnaryMintOp() ||
-            IsShiftMintOp() ||
-            IsBoxInteger() ||
-            IsUnboxInteger();
-  }
+  inline bool IsMintDefinition();
 
   bool IsInt32Definition() {
     return IsBinaryInt32Op() ||
@@ -2330,31 +2316,6 @@
 };
 
 
-class StoreContextInstr : public TemplateInstruction<1, NoThrow> {
- public:
-  explicit StoreContextInstr(Value* value) {
-    SetInputAt(kValuePos, value);
-  }
-
-  enum {
-    kValuePos = 0
-  };
-
-  DECLARE_INSTRUCTION(StoreContext)
-
-  virtual intptr_t ArgumentCount() const { return 0; }
-
-  Value* value() const { return inputs_[kValuePos]; }
-
-  virtual bool CanDeoptimize() const { return false; }
-
-  virtual EffectSet Effects() const { return EffectSet::None(); }
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(StoreContextInstr);
-};
-
-
 class DeoptimizeInstr : public TemplateInstruction<0, NoThrow, Pure> {
  public:
   DeoptimizeInstr(ICData::DeoptReasonId deopt_reason, intptr_t deopt_id)
@@ -4419,321 +4380,358 @@
 };
 
 
-class BoxDoubleInstr : public TemplateDefinition<1, NoThrow, Pure> {
+class Boxing : public AllStatic {
  public:
-  explicit BoxDoubleInstr(Value* value) {
-    SetInputAt(0, value);
+  static bool Supports(Representation rep) {
+    switch (rep) {
+      case kUnboxedDouble:
+      case kUnboxedFloat32x4:
+      case kUnboxedFloat64x2:
+      case kUnboxedInt32x4:
+      case kUnboxedMint:
+      case kUnboxedInt32:
+      case kUnboxedUint32:
+        return true;
+      default:
+        return false;
+    }
   }
 
-  Value* value() const { return inputs_[0]; }
+  static intptr_t ValueOffset(Representation rep) {
+    switch (rep) {
+      case kUnboxedDouble:
+        return Double::value_offset();
 
-  DECLARE_INSTRUCTION(BoxDouble)
-  virtual CompileType ComputeType() const;
+      case kUnboxedFloat32x4:
+        return Float32x4::value_offset();
 
-  virtual bool CanDeoptimize() const { return false; }
+      case kUnboxedFloat64x2:
+        return Float64x2::value_offset();
 
-  virtual intptr_t DeoptimizationTarget() const {
-    return Isolate::kNoDeoptId;
+      case kUnboxedInt32x4:
+        return Int32x4::value_offset();
+
+      case kUnboxedMint:
+        return Mint::value_offset();
+
+      default:
+        UNREACHABLE();
+        return 0;
+    }
   }
 
-  virtual Representation RequiredInputRepresentation(intptr_t idx) const {
-    ASSERT(idx == 0);
-    return kUnboxedDouble;
+  static intptr_t BoxCid(Representation rep) {
+    switch (rep) {
+      case kUnboxedMint:
+        return kMintCid;
+      case kUnboxedDouble:
+        return kDoubleCid;
+      case kUnboxedFloat32x4:
+        return kFloat32x4Cid;
+      case kUnboxedFloat64x2:
+        return kFloat64x2Cid;
+      case kUnboxedInt32x4:
+        return kInt32x4Cid;
+      default:
+        UNREACHABLE();
+        return kIllegalCid;
+    }
   }
-
-  virtual bool AttributesEqual(Instruction* other) const { return true; }
-
-  Definition* Canonicalize(FlowGraph* flow_graph);
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(BoxDoubleInstr);
 };
 
 
-class BoxFloat32x4Instr : public TemplateDefinition<1, NoThrow, Pure> {
+class BoxInstr : public TemplateDefinition<1, NoThrow, Pure> {
  public:
-  explicit BoxFloat32x4Instr(Value* value) {
-    SetInputAt(0, value);
-  }
+  static BoxInstr* Create(Representation from, Value* value);
 
   Value* value() const { return inputs_[0]; }
+  Representation from_representation() const { return from_representation_; }
+
+  DECLARE_INSTRUCTION(Box)
+  virtual CompileType ComputeType() const;
 
   virtual bool CanDeoptimize() const { return false; }
-
   virtual intptr_t DeoptimizationTarget() const {
     return Isolate::kNoDeoptId;
   }
 
   virtual Representation RequiredInputRepresentation(intptr_t idx) const {
     ASSERT(idx == 0);
-    return kUnboxedFloat32x4;
+    return from_representation();
   }
 
-  DECLARE_INSTRUCTION(BoxFloat32x4)
-  virtual CompileType ComputeType() const;
-
-  virtual bool AttributesEqual(Instruction* other) const { return true; }
+  virtual bool AttributesEqual(Instruction* other) const {
+    return other->AsBox()->from_representation() == from_representation();
+  }
 
   Definition* Canonicalize(FlowGraph* flow_graph);
 
- private:
-  DISALLOW_COPY_AND_ASSIGN(BoxFloat32x4Instr);
-};
-
-
-class BoxFloat64x2Instr : public TemplateDefinition<1, NoThrow, Pure> {
- public:
-  explicit BoxFloat64x2Instr(Value* value) {
+ protected:
+  BoxInstr(Representation from_representation, Value* value)
+      : from_representation_(from_representation) {
     SetInputAt(0, value);
   }
 
-  Value* value() const { return inputs_[0]; }
-
-  virtual bool CanDeoptimize() const { return false; }
-
-  virtual intptr_t DeoptimizationTarget() const {
-    return Isolate::kNoDeoptId;
-  }
-
-  virtual Representation RequiredInputRepresentation(intptr_t idx) const {
-    ASSERT(idx == 0);
-    return kUnboxedFloat64x2;
-  }
-
-  DECLARE_INSTRUCTION(BoxFloat64x2)
-  virtual CompileType ComputeType() const;
-
-  virtual bool AttributesEqual(Instruction* other) const { return true; }
-
-  Definition* Canonicalize(FlowGraph* flow_graph);
-
  private:
-  DISALLOW_COPY_AND_ASSIGN(BoxFloat64x2Instr);
+  intptr_t ValueOffset() const {
+    return Boxing::ValueOffset(from_representation());
+  }
+
+  const Representation from_representation_;
+
+  DISALLOW_COPY_AND_ASSIGN(BoxInstr);
 };
 
 
-
-class BoxInt32x4Instr : public TemplateDefinition<1, NoThrow, Pure> {
+class BoxIntegerInstr : public BoxInstr {
  public:
-  explicit BoxInt32x4Instr(Value* value) {
-    SetInputAt(0, value);
-  }
+  BoxIntegerInstr(Representation representation, Value* value)
+      : BoxInstr(representation, value) { }
 
-  Value* value() const { return inputs_[0]; }
-
-  virtual bool CanDeoptimize() const { return false; }
-
-  virtual intptr_t DeoptimizationTarget() const {
-    return Isolate::kNoDeoptId;
-  }
-
-  virtual Representation RequiredInputRepresentation(intptr_t idx) const {
-    ASSERT(idx == 0);
-    return kUnboxedInt32x4;
-  }
-
-  DECLARE_INSTRUCTION(BoxInt32x4)
-  virtual CompileType ComputeType() const;
-
-  virtual bool AttributesEqual(Instruction* other) const { return true; }
-
-  Definition* Canonicalize(FlowGraph* flow_graph);
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(BoxInt32x4Instr);
-};
-
-
-class BoxIntegerInstr : public TemplateDefinition<1, NoThrow, Pure> {
- public:
-  explicit BoxIntegerInstr(Value* value) : is_smi_(false) {
-    SetInputAt(0, value);
-  }
-
-  Value* value() const { return inputs_[0]; }
-
-  bool is_smi() const { return is_smi_; }
-  void set_is_smi(bool is_smi) { is_smi_ = is_smi; }
-
-  virtual bool CanDeoptimize() const { return false; }
-
-  virtual intptr_t DeoptimizationTarget() const {
-    return Isolate::kNoDeoptId;
-  }
-
-  virtual Representation RequiredInputRepresentation(intptr_t idx) const {
-    ASSERT(idx == 0);
-    return kUnboxedMint;
-  }
-
-  DECLARE_INSTRUCTION(BoxInteger)
-  virtual CompileType ComputeType() const;
-  virtual bool RecomputeType();
+  virtual bool ValueFitsSmi() const;
 
   virtual void InferRange(RangeAnalysis* analysis, Range* range);
 
-  virtual bool AttributesEqual(Instruction* other) const { return true; }
+  virtual CompileType ComputeType() const;
+  virtual bool RecomputeType();
 
   virtual Definition* Canonicalize(FlowGraph* flow_graph);
 
- private:
-  bool is_smi_;
+  DEFINE_INSTRUCTION_TYPE_CHECK(BoxInteger)
 
+ private:
   DISALLOW_COPY_AND_ASSIGN(BoxIntegerInstr);
 };
 
 
-class UnboxDoubleInstr : public TemplateDefinition<1, NoThrow, Pure> {
+class BoxInteger32Instr : public BoxIntegerInstr {
  public:
-  UnboxDoubleInstr(Value* value, intptr_t deopt_id)
-      : TemplateDefinition(deopt_id) {
-    SetInputAt(0, value);
-  }
+  BoxInteger32Instr(Representation representation, Value* value)
+      : BoxIntegerInstr(representation, value) { }
 
-  Value* value() const { return inputs_[0]; }
-
-  virtual bool CanDeoptimize() const {
-    return (value()->Type()->ToCid() != kDoubleCid)
-        && (value()->Type()->ToCid() != kSmiCid);
-  }
-
-  virtual Representation representation() const {
-    return kUnboxedDouble;
-  }
-
-  DECLARE_INSTRUCTION(UnboxDouble)
-  virtual CompileType ComputeType() const;
-
-  virtual bool AttributesEqual(Instruction* other) const { return true; }
-
-  Definition* Canonicalize(FlowGraph* flow_graph);
+  DECLARE_INSTRUCTION_BACKEND()
 
  private:
-  DISALLOW_COPY_AND_ASSIGN(UnboxDoubleInstr);
+  DISALLOW_COPY_AND_ASSIGN(BoxInteger32Instr);
 };
 
 
-class UnboxFloat32x4Instr : public TemplateDefinition<1, NoThrow, Pure> {
+class BoxInt32Instr : public BoxInteger32Instr {
  public:
-  UnboxFloat32x4Instr(Value* value, intptr_t deopt_id)
-      : TemplateDefinition(deopt_id) {
-    SetInputAt(0, value);
-  }
+  explicit BoxInt32Instr(Value* value)
+      : BoxInteger32Instr(kUnboxedInt32, value) { }
 
-  Value* value() const { return inputs_[0]; }
-
-  virtual bool CanDeoptimize() const {
-    return (value()->Type()->ToCid() != kFloat32x4Cid);
-  }
-
-  virtual Representation representation() const {
-    return kUnboxedFloat32x4;
-  }
-
-  DECLARE_INSTRUCTION(UnboxFloat32x4)
-  virtual CompileType ComputeType() const;
-
-  virtual bool AttributesEqual(Instruction* other) const { return true; }
-
-  Definition* Canonicalize(FlowGraph* flow_graph);
+  DECLARE_INSTRUCTION_NO_BACKEND(BoxInt32)
 
  private:
-  DISALLOW_COPY_AND_ASSIGN(UnboxFloat32x4Instr);
+  DISALLOW_COPY_AND_ASSIGN(BoxInt32Instr);
 };
 
 
-class UnboxFloat64x2Instr : public TemplateDefinition<1, NoThrow, Pure> {
+class BoxUint32Instr : public BoxInteger32Instr {
  public:
-  UnboxFloat64x2Instr(Value* value, intptr_t deopt_id)
-      : TemplateDefinition(deopt_id) {
-    SetInputAt(0, value);
-  }
+  explicit BoxUint32Instr(Value* value)
+      : BoxInteger32Instr(kUnboxedUint32, value) { }
 
-  Value* value() const { return inputs_[0]; }
-
-  virtual bool CanDeoptimize() const {
-    return (value()->Type()->ToCid() != kFloat64x2Cid);
-  }
-
-  virtual Representation representation() const {
-    return kUnboxedFloat64x2;
-  }
-
-  DECLARE_INSTRUCTION(UnboxFloat64x2)
-  virtual CompileType ComputeType() const;
-
-  virtual bool AttributesEqual(Instruction* other) const { return true; }
-
-  Definition* Canonicalize(FlowGraph* flow_graph);
+  DECLARE_INSTRUCTION_NO_BACKEND(BoxUint32)
 
  private:
-  DISALLOW_COPY_AND_ASSIGN(UnboxFloat64x2Instr);
+  DISALLOW_COPY_AND_ASSIGN(BoxUint32Instr);
 };
 
 
-class UnboxInt32x4Instr : public TemplateDefinition<1, NoThrow, Pure> {
+class BoxInt64Instr : public BoxIntegerInstr {
  public:
-  UnboxInt32x4Instr(Value* value, intptr_t deopt_id)
-      : TemplateDefinition(deopt_id) {
-    SetInputAt(0, value);
-  }
+  explicit BoxInt64Instr(Value* value)
+      : BoxIntegerInstr(kUnboxedMint, value) { }
 
-  Value* value() const { return inputs_[0]; }
+  virtual Definition* Canonicalize(FlowGraph* flow_graph);
 
-  virtual bool CanDeoptimize() const {
-    return (value()->Type()->ToCid() != kInt32x4Cid);
-  }
-
-  virtual Representation representation() const {
-    return kUnboxedInt32x4;
-  }
-
-  virtual bool AttributesEqual(Instruction* other) const { return true; }
-
-  DECLARE_INSTRUCTION(UnboxInt32x4)
-  virtual CompileType ComputeType() const;
-
-  Definition* Canonicalize(FlowGraph* flow_graph);
+  DECLARE_INSTRUCTION(BoxInt64)
 
  private:
-  DISALLOW_COPY_AND_ASSIGN(UnboxInt32x4Instr);
+  DISALLOW_COPY_AND_ASSIGN(BoxInt64Instr);
 };
 
 
-class UnboxIntegerInstr : public TemplateDefinition<1, NoThrow, Pure> {
+class UnboxInstr : public TemplateDefinition<1, NoThrow, Pure> {
  public:
-  UnboxIntegerInstr(Value* value, intptr_t deopt_id)
-      : TemplateDefinition(deopt_id) {
-    SetInputAt(0, value);
-  }
+  static UnboxInstr* Create(Representation to, Value* value, intptr_t deopt_id);
 
   Value* value() const { return inputs_[0]; }
 
   virtual bool CanDeoptimize() const {
+    const intptr_t value_cid = value()->Type()->ToCid();
+
+    if (CanConvertSmi() &&
+        (value()->Type()->ToCid() == kSmiCid)) {
+      return false;
+    }
+
+    return (value_cid != BoxCid());
+  }
+
+  virtual Representation representation() const {
+    return representation_;
+  }
+
+  DECLARE_INSTRUCTION(Unbox)
+  virtual CompileType ComputeType() const;
+
+  virtual bool AttributesEqual(Instruction* other) const {
+    return representation() == other->AsUnbox()->representation();
+  }
+
+  Definition* Canonicalize(FlowGraph* flow_graph);
+
+  virtual intptr_t DeoptimizationTarget() const {
+    return GetDeoptId();
+  }
+
+ protected:
+  UnboxInstr(Representation representation,
+             Value* value,
+             intptr_t deopt_id)
+      : TemplateDefinition(deopt_id),
+        representation_(representation) {
+    SetInputAt(0, value);
+  }
+
+ private:
+  bool CanConvertSmi() const;
+  void EmitLoadFromBox(FlowGraphCompiler* compiler);
+  void EmitSmiConversion(FlowGraphCompiler* compiler);
+
+  intptr_t BoxCid() const {
+    return Boxing::BoxCid(representation_);
+  }
+
+  intptr_t ValueOffset() const {
+    return Boxing::ValueOffset(representation_);
+  }
+
+  const Representation representation_;
+
+  DISALLOW_COPY_AND_ASSIGN(UnboxInstr);
+};
+
+
+class UnboxIntegerInstr : public UnboxInstr {
+ public:
+  enum TruncationMode { kTruncate, kNoTruncation };
+
+  UnboxIntegerInstr(Representation representation,
+                    TruncationMode truncation_mode,
+                    Value* value,
+                    intptr_t deopt_id)
+      : UnboxInstr(representation, value, deopt_id),
+        is_truncating_(truncation_mode == kTruncate) {
+  }
+
+  bool is_truncating() const { return is_truncating_; }
+
+  virtual CompileType ComputeType() const;
+
+  virtual bool AttributesEqual(Instruction* other) const {
+    UnboxIntegerInstr* other_unbox = other->AsUnboxInteger();
+    return UnboxInstr::AttributesEqual(other) &&
+        (other_unbox->is_truncating_ == is_truncating_);
+  }
+
+  virtual Definition* Canonicalize(FlowGraph* flow_graph);
+
+  virtual void PrintOperandsTo(BufferFormatter* f) const;
+
+  DEFINE_INSTRUCTION_TYPE_CHECK(UnboxInteger)
+
+ private:
+  bool is_truncating_;
+
+  DISALLOW_COPY_AND_ASSIGN(UnboxIntegerInstr);
+};
+
+
+class UnboxInteger32Instr : public UnboxIntegerInstr {
+ public:
+  UnboxInteger32Instr(Representation representation,
+                      TruncationMode truncation_mode,
+                      Value* value,
+                      intptr_t deopt_id)
+      : UnboxIntegerInstr(representation, truncation_mode, value, deopt_id) { }
+
+  DECLARE_INSTRUCTION_BACKEND()
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(UnboxInteger32Instr);
+};
+
+
+class UnboxUint32Instr : public UnboxInteger32Instr {
+ public:
+  UnboxUint32Instr(Value* value, intptr_t deopt_id)
+      : UnboxInteger32Instr(kUnboxedUint32, kTruncate, value, deopt_id) {
+    ASSERT(is_truncating());
+  }
+
+  virtual bool CanDeoptimize() const {
+    ASSERT(is_truncating());
     return (value()->Type()->ToCid() != kSmiCid)
         && (value()->Type()->ToCid() != kMintCid);
   }
 
-  virtual Representation representation() const {
-    return kUnboxedMint;
+  DECLARE_INSTRUCTION_NO_BACKEND(UnboxUint32)
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(UnboxUint32Instr);
+};
+
+
+class UnboxInt32Instr : public UnboxInteger32Instr {
+ public:
+  UnboxInt32Instr(TruncationMode truncation_mode,
+                  Value* value,
+                  intptr_t deopt_id)
+      : UnboxInteger32Instr(kUnboxedInt32, truncation_mode, value, deopt_id) {
   }
 
-  intptr_t deopt_id() const { return GetDeoptId(); }
+  virtual bool CanDeoptimize() const;
 
   virtual void InferRange(RangeAnalysis* analysis, Range* range);
 
-  DECLARE_INSTRUCTION(UnboxInteger)
-  virtual CompileType ComputeType() const;
-
-  virtual bool AttributesEqual(Instruction* other) const { return true; }
-
   virtual Definition* Canonicalize(FlowGraph* flow_graph);
 
+  DECLARE_INSTRUCTION_NO_BACKEND(UnboxInt32)
+
  private:
-  DISALLOW_COPY_AND_ASSIGN(UnboxIntegerInstr);
+  DISALLOW_COPY_AND_ASSIGN(UnboxInt32Instr);
 };
 
 
+class UnboxInt64Instr : public UnboxIntegerInstr {
+ public:
+  UnboxInt64Instr(Value* value, intptr_t deopt_id)
+      : UnboxIntegerInstr(kUnboxedMint, kNoTruncation, value, deopt_id) {
+  }
+
+  virtual void InferRange(RangeAnalysis* analysis, Range* range);
+
+  DECLARE_INSTRUCTION_NO_BACKEND(UnboxInt64)
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(UnboxInt64Instr);
+};
+
+
+bool Definition::IsMintDefinition() {
+  return (Type()->ToCid() == kMintCid) ||
+          IsBinaryMintOp() ||
+          IsUnaryMintOp() ||
+          IsShiftMintOp() ||
+          IsBoxInt64() ||
+          IsUnboxInt64();
+}
+
+
 class MathUnaryInstr : public TemplateDefinition<1, NoThrow, Pure> {
  public:
   enum MathUnaryKind {
@@ -7470,155 +7468,6 @@
 };
 
 
-class BoxIntNInstr : public TemplateDefinition<1, NoThrow, Pure> {
- public:
-  BoxIntNInstr(Representation representation, Value* value)
-      : from_representation_(representation) {
-    SetInputAt(0, value);
-  }
-
-  Representation from_representation() const { return from_representation_; }
-
-  Value* value() const { return inputs_[0]; }
-  virtual bool ValueFitsSmi() const;
-
-  virtual CompileType ComputeType() const;
-  virtual bool RecomputeType();
-
-  virtual bool CanDeoptimize() const { return false; }
-
-  virtual intptr_t DeoptimizationTarget() const {
-    return Isolate::kNoDeoptId;
-  }
-
-  virtual Representation RequiredInputRepresentation(intptr_t idx) const {
-    ASSERT(idx == 0);
-    return from_representation_;
-  }
-
-  virtual bool AttributesEqual(Instruction* other) const {
-    return other->AsBoxIntN()->from_representation_ == from_representation_;
-  }
-
-  virtual Definition* Canonicalize(FlowGraph* flow_graph);
-
-  DEFINE_INSTRUCTION_TYPE_CHECK(BoxIntN)
-  DECLARE_INSTRUCTION_BACKEND()
-
- private:
-  const Representation from_representation_;
-
-  DISALLOW_COPY_AND_ASSIGN(BoxIntNInstr);
-};
-
-
-class BoxUint32Instr : public BoxIntNInstr {
- public:
-  explicit BoxUint32Instr(Value* value)
-      : BoxIntNInstr(kUnboxedUint32, value) { }
-
-  DECLARE_INSTRUCTION_NO_BACKEND(BoxUint32)
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(BoxUint32Instr);
-};
-
-
-class BoxInt32Instr : public BoxIntNInstr {
- public:
-  explicit BoxInt32Instr(Value* value)
-      : BoxIntNInstr(kUnboxedInt32, value) { }
-
-  virtual void InferRange(RangeAnalysis* analysis, Range* range);
-
-  DECLARE_INSTRUCTION_NO_BACKEND(BoxInt32)
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(BoxInt32Instr);
-};
-
-
-class UnboxIntNInstr : public TemplateDefinition<1, NoThrow, Pure> {
- public:
-  UnboxIntNInstr(Representation representation,
-                 Value* value,
-                 intptr_t deopt_id)
-      : TemplateDefinition(deopt_id),
-        representation_(representation),
-        is_truncating_(representation == kUnboxedUint32) {
-    SetInputAt(0, value);
-  }
-
-  Value* value() const { return inputs_[0]; }
-
-  bool is_truncating() const { return is_truncating_; }
-  void mark_truncating() { is_truncating_ = true; }
-
-  virtual Representation representation() const {
-    return representation_;
-  }
-
-  virtual CompileType ComputeType() const;
-
-  virtual bool AttributesEqual(Instruction* other) const {
-    UnboxIntNInstr* other_unbox = other->AsUnboxIntN();
-    return (other_unbox->representation_ == representation_) &&
-        (other_unbox->is_truncating_ == is_truncating_);
-  }
-
-  virtual Definition* Canonicalize(FlowGraph* flow_graph);
-
-  virtual void PrintOperandsTo(BufferFormatter* f) const;
-
-  DEFINE_INSTRUCTION_TYPE_CHECK(UnboxIntN)
-  DECLARE_INSTRUCTION_BACKEND()
-
- private:
-  const Representation representation_;
-  bool is_truncating_;
-
-  DISALLOW_COPY_AND_ASSIGN(UnboxIntNInstr);
-};
-
-
-class UnboxUint32Instr : public UnboxIntNInstr {
- public:
-  UnboxUint32Instr(Value* value, intptr_t deopt_id)
-      : UnboxIntNInstr(kUnboxedUint32, value, deopt_id) {
-    ASSERT(is_truncating());
-  }
-
-  virtual bool CanDeoptimize() const {
-    return (value()->Type()->ToCid() != kSmiCid)
-        && (value()->Type()->ToCid() != kMintCid);
-  }
-
-  DECLARE_INSTRUCTION_NO_BACKEND(UnboxUint32)
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(UnboxUint32Instr);
-};
-
-
-class UnboxInt32Instr : public UnboxIntNInstr {
- public:
-  UnboxInt32Instr(Value* value, intptr_t deopt_id)
-      : UnboxIntNInstr(kUnboxedInt32, value, deopt_id) {
-  }
-
-  virtual bool CanDeoptimize() const;
-
-  virtual void InferRange(RangeAnalysis* analysis, Range* range);
-
-  virtual Definition* Canonicalize(FlowGraph* flow_graph);
-
-  DECLARE_INSTRUCTION_NO_BACKEND(UnboxInt32)
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(UnboxInt32Instr);
-};
-
-
 class UnboxedIntConverterInstr : public TemplateDefinition<1, NoThrow> {
  public:
   UnboxedIntConverterInstr(Representation from,
diff --git a/runtime/vm/intermediate_language_arm.cc b/runtime/vm/intermediate_language_arm.cc
index 5de809b..05ebe6c 100644
--- a/runtime/vm/intermediate_language_arm.cc
+++ b/runtime/vm/intermediate_language_arm.cc
@@ -31,8 +31,7 @@
 
 // Generic summary for call instructions that have all arguments pushed
 // on the stack and return the result in a fixed register R0.
-LocationSummary* Instruction::MakeCallSummary() {
-  Isolate* isolate = Isolate::Current();
+LocationSummary* Instruction::MakeCallSummary(Isolate* isolate) {
   LocationSummary* result = new(isolate) LocationSummary(
       isolate, 0, 0, LocationSummary::kCall);
   result->set_out(0, Location::RegisterLocation(R0));
@@ -919,22 +918,11 @@
 
 LocationSummary* NativeCallInstr::MakeLocationSummary(Isolate* isolate,
                                                       bool opt) const {
-  const intptr_t kNumInputs = 0;
-  const intptr_t kNumTemps = 3;
-  LocationSummary* locs = new(isolate) LocationSummary(
-      isolate, kNumInputs, kNumTemps, LocationSummary::kCall);
-  locs->set_temp(0, Location::RegisterLocation(R1));
-  locs->set_temp(1, Location::RegisterLocation(R2));
-  locs->set_temp(2, Location::RegisterLocation(R5));
-  locs->set_out(0, Location::RegisterLocation(R0));
-  return locs;
+  return MakeCallSummary(isolate);
 }
 
 
 void NativeCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
-  ASSERT(locs()->temp(0).reg() == R1);
-  ASSERT(locs()->temp(1).reg() == R2);
-  ASSERT(locs()->temp(2).reg() == R5);
   const Register result = locs()->out(0).reg();
 
   // Push the result place holder initialized to NULL.
@@ -3563,7 +3551,7 @@
 }
 
 
-LocationSummary* BoxDoubleInstr::MakeLocationSummary(Isolate* isolate,
+LocationSummary* BoxInstr::MakeLocationSummary(Isolate* isolate,
                                                      bool opt) const {
   const intptr_t kNumInputs = 1;
   const intptr_t kNumTemps = 1;
@@ -3578,280 +3566,344 @@
 }
 
 
-void BoxDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+void BoxInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
   const Register out_reg = locs()->out(0).reg();
   const DRegister value = EvenDRegisterOf(locs()->in(0).fpu_reg());
 
   BoxAllocationSlowPath::Allocate(
       compiler,
       this,
-      compiler->double_class(),
+      compiler->BoxClassFor(from_representation()),
       out_reg,
       locs()->temp(0).reg());
-  __ StoreDToOffset(value, out_reg, Double::value_offset() - kHeapObjectTag);
+
+  switch (from_representation()) {
+    case kUnboxedDouble:
+      __ StoreDToOffset(
+          value, out_reg, ValueOffset() - kHeapObjectTag);
+      break;
+    case kUnboxedFloat32x4:
+    case kUnboxedFloat64x2:
+    case kUnboxedInt32x4:
+      __ StoreMultipleDToOffset(
+          value, 2, out_reg, ValueOffset() - kHeapObjectTag);
+      break;
+    default:
+      UNREACHABLE();
+      break;
+  }
 }
 
 
-LocationSummary* UnboxDoubleInstr::MakeLocationSummary(Isolate* isolate,
+LocationSummary* UnboxInstr::MakeLocationSummary(Isolate* isolate,
                                                        bool opt) const {
+  const bool needs_temp = CanDeoptimize();
   const intptr_t kNumInputs = 1;
-  const intptr_t value_cid = value()->Type()->ToCid();
-  const bool needs_temp = ((value_cid != kSmiCid) && (value_cid != kDoubleCid));
   const intptr_t kNumTemps = needs_temp ? 1 : 0;
   LocationSummary* summary = new(isolate) LocationSummary(
       isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall);
   summary->set_in(0, Location::RequiresRegister());
-  if (needs_temp) summary->set_temp(0, Location::RequiresRegister());
-  summary->set_out(0, Location::RequiresFpuRegister());
+  if (needs_temp) {
+    summary->set_temp(0, Location::RequiresRegister());
+  }
+  if (representation() == kUnboxedMint) {
+    summary->set_out(0, Location::Pair(Location::RequiresRegister(),
+                                       Location::RequiresRegister()));
+  } else {
+    summary->set_out(0, Location::RequiresFpuRegister());
+  }
   return summary;
 }
 
 
-void UnboxDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
-  CompileType* value_type = value()->Type();
-  const intptr_t value_cid = value_type->ToCid();
-  const Register value = locs()->in(0).reg();
-  const DRegister result = EvenDRegisterOf(locs()->out(0).fpu_reg());
+void UnboxInstr::EmitLoadFromBox(FlowGraphCompiler* compiler) {
+  const Register box = locs()->in(0).reg();
 
-  if (value_cid == kDoubleCid) {
-    __ LoadDFromOffset(result, value, Double::value_offset() - kHeapObjectTag);
-  } else if (value_cid == kSmiCid) {
-    __ SmiUntag(IP, value);
-    __ vmovdr(DTMP, 0, IP);
-    __ vcvtdi(result, STMP);
-  } else {
-    Label* deopt = compiler->AddDeoptStub(deopt_id(),
-                                          ICData::kDeoptBinaryDoubleOp);
-    const Register temp = locs()->temp(0).reg();
-    if (value_type->is_nullable() &&
-        (value_type->ToNullableCid() == kDoubleCid)) {
-      __ CompareImmediate(value, reinterpret_cast<intptr_t>(Object::null()));
-      __ b(deopt, EQ);
-      // It must be double now.
-      __ LoadDFromOffset(result, value,
-          Double::value_offset() - kHeapObjectTag);
-    } else {
-      Label is_smi, done;
-      __ tst(value, Operand(kSmiTagMask));
-      __ b(&is_smi, EQ);
-      __ CompareClassId(value, kDoubleCid, temp);
-      __ b(deopt, NE);
-      __ LoadDFromOffset(result, value,
-          Double::value_offset() - kHeapObjectTag);
-      __ b(&done);
-      __ Bind(&is_smi);
-      __ SmiUntag(IP, value);
+  switch (representation()) {
+    case kUnboxedMint: {
+      PairLocation* result = locs()->out(0).AsPairLocation();
+      __ LoadFromOffset(kWord,
+                        result->At(0).reg(),
+                        box,
+                        ValueOffset() - kHeapObjectTag);
+      __ LoadFromOffset(kWord,
+                        result->At(1).reg(),
+                        box,
+                        ValueOffset() - kHeapObjectTag + kWordSize);
+      break;
+    }
+
+    case kUnboxedDouble: {
+      const DRegister result = EvenDRegisterOf(locs()->out(0).fpu_reg());
+      __ LoadDFromOffset(
+          result, box, ValueOffset() - kHeapObjectTag);
+      break;
+    }
+
+    case kUnboxedFloat32x4:
+    case kUnboxedFloat64x2:
+    case kUnboxedInt32x4: {
+      const DRegister result = EvenDRegisterOf(locs()->out(0).fpu_reg());
+      __ LoadMultipleDFromOffset(
+          result, 2, box, ValueOffset() - kHeapObjectTag);
+      break;
+    }
+
+    default:
+      UNREACHABLE();
+      break;
+  }
+}
+
+
+void UnboxInstr::EmitSmiConversion(FlowGraphCompiler* compiler) {
+  const Register box = locs()->in(0).reg();
+
+  switch (representation()) {
+    case kUnboxedMint: {
+      PairLocation* result = locs()->out(0).AsPairLocation();
+      __ SmiUntag(result->At(0).reg(), box);
+      __ SignFill(result->At(1).reg(), result->At(0).reg());
+      break;
+    }
+
+    case kUnboxedDouble: {
+      const DRegister result = EvenDRegisterOf(locs()->out(0).fpu_reg());
+      __ SmiUntag(IP, box);
       __ vmovdr(DTMP, 0, IP);
       __ vcvtdi(result, STMP);
+      break;
+    }
+
+    default:
+      UNREACHABLE();
+      break;
+  }
+}
+
+
+void UnboxInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+  const intptr_t value_cid = value()->Type()->ToCid();
+  const intptr_t box_cid = BoxCid();
+
+  if (value_cid == box_cid) {
+    EmitLoadFromBox(compiler);
+  } else if (CanConvertSmi() && (value_cid == kSmiCid)) {
+    EmitSmiConversion(compiler);
+  } else {
+    const Register box = locs()->in(0).reg();
+    const Register temp = locs()->temp(0).reg();
+    Label* deopt = compiler->AddDeoptStub(GetDeoptId(),
+                                          ICData::kDeoptCheckClass);
+    Label is_smi;
+
+    if ((value()->Type()->ToNullableCid() == box_cid) &&
+        value()->Type()->is_nullable()) {
+      __ CompareImmediate(box, reinterpret_cast<intptr_t>(Object::null()));
+      __ b(deopt, EQ);
+    } else {
+      __ tst(box, Operand(kSmiTagMask));
+      __ b(CanConvertSmi() ? &is_smi : deopt, EQ);
+      __ CompareClassId(box, box_cid, temp);
+      __ b(deopt, NE);
+    }
+
+    EmitLoadFromBox(compiler);
+
+    if (is_smi.IsLinked()) {
+      Label done;
+      __ b(&done);
+      __ Bind(&is_smi);
+      EmitSmiConversion(compiler);
       __ Bind(&done);
     }
   }
 }
 
 
-LocationSummary* BoxFloat32x4Instr::MakeLocationSummary(Isolate* isolate,
-                                                        bool opt) const {
+LocationSummary* BoxInteger32Instr::MakeLocationSummary(Isolate* isolate,
+                                                   bool opt) const {
+  ASSERT((from_representation() == kUnboxedInt32) ||
+         (from_representation() == kUnboxedUint32));
   const intptr_t kNumInputs = 1;
-  const intptr_t kNumTemps = 1;
+  const intptr_t kNumTemps = ValueFitsSmi() ? 0 : 1;
   LocationSummary* summary = new(isolate) LocationSummary(
-      isolate, kNumInputs,
-                          kNumTemps,
-                          LocationSummary::kCallOnSlowPath);
-  summary->set_in(0, Location::RequiresFpuRegister());
-  summary->set_temp(0, Location::RequiresRegister());
+      isolate,
+      kNumInputs,
+      kNumTemps,
+      ValueFitsSmi() ? LocationSummary::kNoCall
+                     : LocationSummary::kCallOnSlowPath);
+  summary->set_in(0, Location::RequiresRegister());
+  if (!ValueFitsSmi()) {
+    summary->set_temp(0, Location::RequiresRegister());
+  }
   summary->set_out(0, Location::RequiresRegister());
   return summary;
 }
 
 
-void BoxFloat32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) {
-  const Register out_reg = locs()->out(0).reg();
-  const QRegister value = locs()->in(0).fpu_reg();
-  const DRegister dvalue0 = EvenDRegisterOf(value);
+void BoxInteger32Instr::EmitNativeCode(FlowGraphCompiler* compiler) {
+  Register value = locs()->in(0).reg();
+  Register out = locs()->out(0).reg();
+  ASSERT(value != out);
 
-  BoxAllocationSlowPath::Allocate(
-      compiler,
-      this,
-      compiler->float32x4_class(),
-      out_reg,
-      locs()->temp(0).reg());
-  __ StoreMultipleDToOffset(dvalue0, 2, out_reg,
-      Float32x4::value_offset() - kHeapObjectTag);
-}
-
-
-LocationSummary* UnboxFloat32x4Instr::MakeLocationSummary(Isolate* isolate,
-                                                          bool opt) const {
-  const intptr_t value_cid = value()->Type()->ToCid();
-  const intptr_t kNumInputs = 1;
-  const intptr_t kNumTemps = value_cid == kFloat32x4Cid ? 0 : 1;
-  LocationSummary* summary = new(isolate) LocationSummary(
-      isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall);
-  summary->set_in(0, Location::RequiresRegister());
-  if (kNumTemps > 0) {
-    ASSERT(kNumTemps == 1);
-    summary->set_temp(0, Location::RequiresRegister());
+  __ SmiTag(out, value);
+  if (!ValueFitsSmi()) {
+    Register temp = locs()->temp(0).reg();
+    Label done;
+    if (from_representation() == kUnboxedInt32) {
+      __ cmp(value, Operand(out, ASR, 1));
+    } else {
+      ASSERT(from_representation() == kUnboxedUint32);
+      // Note: better to test upper bits instead of comparing with
+      // kSmiMax as kSmiMax does not fit into immediate operand.
+      __ TestImmediate(value, 0xC0000000);
+    }
+    __ b(&done, EQ);
+    BoxAllocationSlowPath::Allocate(
+        compiler,
+        this,
+        compiler->mint_class(),
+        out,
+        temp);
+    if (from_representation() == kUnboxedInt32) {
+      __ Asr(temp, value, Operand(kBitsPerWord - 1));
+    } else {
+      ASSERT(from_representation() == kUnboxedUint32);
+      __ eor(temp, temp, Operand(temp));
+    }
+    __ StoreToOffset(kWord,
+                     value,
+                     out,
+                     Mint::value_offset() - kHeapObjectTag);
+    __ StoreToOffset(kWord,
+                     temp,
+                     out,
+                     Mint::value_offset() - kHeapObjectTag + kWordSize);
+    __ Bind(&done);
   }
-  summary->set_out(0, Location::RequiresFpuRegister());
-  return summary;
 }
 
 
-void UnboxFloat32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) {
-  const intptr_t value_cid = value()->Type()->ToCid();
-  const Register value = locs()->in(0).reg();
-  const QRegister result = locs()->out(0).fpu_reg();
-
-  if (value_cid != kFloat32x4Cid) {
-    const Register temp = locs()->temp(0).reg();
-    Label* deopt = compiler->AddDeoptStub(deopt_id(), ICData::kDeoptCheckClass);
-    __ tst(value, Operand(kSmiTagMask));
-    __ b(deopt, EQ);
-    __ CompareClassId(value, kFloat32x4Cid, temp);
-    __ b(deopt, NE);
-  }
-
-  const DRegister dresult0 = EvenDRegisterOf(result);
-  __ LoadMultipleDFromOffset(dresult0, 2, value,
-      Float32x4::value_offset() - kHeapObjectTag);
-}
-
-
-LocationSummary* BoxFloat64x2Instr::MakeLocationSummary(Isolate* isolate,
-                                                        bool opt) const {
-  const intptr_t kNumInputs = 1;
-  const intptr_t kNumTemps = 1;
-  LocationSummary* summary = new(isolate) LocationSummary(
-      isolate, kNumInputs,
-                          kNumTemps,
-                          LocationSummary::kCallOnSlowPath);
-  summary->set_in(0, Location::RequiresFpuRegister());
-  summary->set_temp(0, Location::RequiresRegister());
-  summary->set_out(0, Location::RequiresRegister());
-  return summary;
-}
-
-
-void BoxFloat64x2Instr::EmitNativeCode(FlowGraphCompiler* compiler) {
-  const Register out_reg = locs()->out(0).reg();
-  const QRegister value = locs()->in(0).fpu_reg();
-  const DRegister dvalue0 = EvenDRegisterOf(value);
-
-  BoxAllocationSlowPath::Allocate(
-      compiler,
-      this,
-      compiler->float64x2_class(),
-      out_reg,
-      locs()->temp(0).reg());
-  __ StoreMultipleDToOffset(dvalue0, 2, out_reg,
-      Float64x2::value_offset() - kHeapObjectTag);
-}
-
-
-LocationSummary* UnboxFloat64x2Instr::MakeLocationSummary(Isolate* isolate,
-                                                          bool opt) const {
-  const intptr_t value_cid = value()->Type()->ToCid();
-  const intptr_t kNumInputs = 1;
-  const intptr_t kNumTemps = value_cid == kFloat64x2Cid ? 0 : 1;
-  LocationSummary* summary = new(isolate) LocationSummary(
-      isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall);
-  summary->set_in(0, Location::RequiresRegister());
-  if (kNumTemps > 0) {
-    ASSERT(kNumTemps == 1);
-    summary->set_temp(0, Location::RequiresRegister());
-  }
-  summary->set_out(0, Location::RequiresFpuRegister());
-  return summary;
-}
-
-
-void UnboxFloat64x2Instr::EmitNativeCode(FlowGraphCompiler* compiler) {
-  const intptr_t value_cid = value()->Type()->ToCid();
-  const Register value = locs()->in(0).reg();
-  const QRegister result = locs()->out(0).fpu_reg();
-
-  if (value_cid != kFloat64x2Cid) {
-    const Register temp = locs()->temp(0).reg();
-    Label* deopt = compiler->AddDeoptStub(GetDeoptId(),
-                                          ICData::kDeoptCheckClass);
-    __ tst(value, Operand(kSmiTagMask));
-    __ b(deopt, EQ);
-    __ CompareClassId(value, kFloat64x2Cid, temp);
-    __ b(deopt, NE);
-  }
-
-  const DRegister dresult0 = EvenDRegisterOf(result);
-  __ LoadMultipleDFromOffset(dresult0, 2, value,
-      Float64x2::value_offset() - kHeapObjectTag);
-}
-
-
-LocationSummary* BoxInt32x4Instr::MakeLocationSummary(Isolate* isolate,
+LocationSummary* BoxInt64Instr::MakeLocationSummary(Isolate* isolate,
                                                       bool opt) const {
   const intptr_t kNumInputs = 1;
-  const intptr_t kNumTemps = 1;
+  const intptr_t kNumTemps = ValueFitsSmi() ? 0 : 1;
   LocationSummary* summary = new(isolate) LocationSummary(
-      isolate, kNumInputs,
-                          kNumTemps,
-                          LocationSummary::kCallOnSlowPath);
-  summary->set_in(0, Location::RequiresFpuRegister());
-  summary->set_temp(0, Location::RequiresRegister());
+      isolate,
+      kNumInputs,
+      kNumTemps,
+      ValueFitsSmi() ? LocationSummary::kNoCall
+                     : LocationSummary::kCallOnSlowPath);
+  summary->set_in(0, Location::Pair(Location::RequiresRegister(),
+                                    Location::RequiresRegister()));
+  if (!ValueFitsSmi()) {
+    summary->set_temp(0, Location::RequiresRegister());
+  }
   summary->set_out(0, Location::RequiresRegister());
   return summary;
 }
 
 
-void BoxInt32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) {
-  const Register out_reg = locs()->out(0).reg();
-  const QRegister value = locs()->in(0).fpu_reg();
-  const DRegister dvalue0 = EvenDRegisterOf(value);
+void BoxInt64Instr::EmitNativeCode(FlowGraphCompiler* compiler) {
+  if (ValueFitsSmi()) {
+    PairLocation* value_pair = locs()->in(0).AsPairLocation();
+    Register value_lo = value_pair->At(0).reg();
+    Register out_reg = locs()->out(0).reg();
+    __ SmiTag(out_reg, value_lo);
+    return;
+  }
+
+  PairLocation* value_pair = locs()->in(0).AsPairLocation();
+  Register value_lo = value_pair->At(0).reg();
+  Register value_hi = value_pair->At(1).reg();
+  Register tmp = locs()->temp(0).reg();
+  Register out_reg = locs()->out(0).reg();
+
+  Label done;
+  __ SmiTag(out_reg, value_lo);
+  __ cmp(value_lo, Operand(out_reg, ASR, kSmiTagSize));
+  __ cmp(value_hi, Operand(out_reg, ASR, 31), EQ);
+  __ b(&done, EQ);
 
   BoxAllocationSlowPath::Allocate(
       compiler,
       this,
-      compiler->int32x4_class(),
+      compiler->mint_class(),
       out_reg,
-      locs()->temp(0).reg());
-  __ StoreMultipleDToOffset(dvalue0, 2, out_reg,
-      Int32x4::value_offset() - kHeapObjectTag);
+      tmp);
+  __ StoreToOffset(kWord,
+                   value_lo,
+                   out_reg,
+                   Mint::value_offset() - kHeapObjectTag);
+  __ StoreToOffset(kWord,
+                   value_hi,
+                   out_reg,
+                   Mint::value_offset() - kHeapObjectTag + kWordSize);
+  __ Bind(&done);
 }
 
 
-LocationSummary* UnboxInt32x4Instr::MakeLocationSummary(Isolate* isolate,
-                                                        bool opt) const {
-  const intptr_t value_cid = value()->Type()->ToCid();
+static void LoadInt32FromMint(FlowGraphCompiler* compiler,
+                              Register mint,
+                              Register result,
+                              Register temp,
+                              Label* deopt) {
+  __ LoadFromOffset(kWord,
+                    result,
+                    mint,
+                    Mint::value_offset() - kHeapObjectTag);
+  if (deopt != NULL) {
+    __ LoadFromOffset(kWord,
+                      temp,
+                      mint,
+                      Mint::value_offset() - kHeapObjectTag + kWordSize);
+    __ cmp(temp, Operand(result, ASR, kBitsPerWord - 1));
+    __ b(deopt, NE);
+  }
+}
+
+
+LocationSummary* UnboxInteger32Instr::MakeLocationSummary(Isolate* isolate,
+                                                          bool opt) const {
+  ASSERT((representation() == kUnboxedInt32) ||
+         (representation() == kUnboxedUint32));
+  ASSERT((representation() != kUnboxedUint32) || is_truncating());
   const intptr_t kNumInputs = 1;
-  const intptr_t kNumTemps = value_cid == kInt32x4Cid ? 0 : 1;
+  const intptr_t kNumTemps = CanDeoptimize() ? 1 : 0;
   LocationSummary* summary = new(isolate) LocationSummary(
       isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall);
   summary->set_in(0, Location::RequiresRegister());
   if (kNumTemps > 0) {
-    ASSERT(kNumTemps == 1);
     summary->set_temp(0, Location::RequiresRegister());
   }
-  summary->set_out(0, Location::RequiresFpuRegister());
+  summary->set_out(0, Location::RequiresRegister());
   return summary;
 }
 
 
-void UnboxInt32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) {
+void UnboxInteger32Instr::EmitNativeCode(FlowGraphCompiler* compiler) {
   const intptr_t value_cid = value()->Type()->ToCid();
   const Register value = locs()->in(0).reg();
-  const QRegister result = locs()->out(0).fpu_reg();
+  const Register out = locs()->out(0).reg();
+  const Register temp = CanDeoptimize() ? locs()->temp(0).reg() : kNoRegister;
+  Label* deopt = CanDeoptimize() ?
+        compiler->AddDeoptStub(GetDeoptId(), ICData::kDeoptUnboxInteger) : NULL;
+  Label* out_of_range = !is_truncating() ? deopt : NULL;
+  ASSERT(value != out);
 
-  if (value_cid != kInt32x4Cid) {
-    const Register temp = locs()->temp(0).reg();
-    Label* deopt = compiler->AddDeoptStub(GetDeoptId(),
-                                          ICData::kDeoptCheckClass);
-    __ tst(value, Operand(kSmiTagMask));
-    __ b(deopt, EQ);
-    __ CompareClassId(value, kInt32x4Cid, temp);
+  if (value_cid == kSmiCid) {
+    __ SmiUntag(out, value);
+  } else if (value_cid == kMintCid) {
+    LoadInt32FromMint(compiler, value, out, temp, out_of_range);
+  } else {
+    Label done;
+    __ SmiUntag(out, value, &done);
+    __ CompareClassId(value, kMintCid, temp);
     __ b(deopt, NE);
+    LoadInt32FromMint(compiler, value, out, temp, out_of_range);
+    __ Bind(&done);
   }
-
-  const DRegister dresult0 = EvenDRegisterOf(result);
-  __ LoadMultipleDFromOffset(dresult0, 2, value,
-      Int32x4::value_offset() - kHeapObjectTag);
 }
 
 
@@ -5746,7 +5798,7 @@
 
 LocationSummary* PolymorphicInstanceCallInstr::MakeLocationSummary(
     Isolate* isolate, bool opt) const {
-  return MakeCallSummary();
+  return MakeCallSummary(isolate);
 }
 
 
@@ -5994,168 +6046,6 @@
 }
 
 
-LocationSummary* UnboxIntegerInstr::MakeLocationSummary(Isolate* isolate,
-                                                        bool opt) const {
-  const intptr_t kNumInputs = 1;
-  const intptr_t kNumTemps = 1;
-  LocationSummary* summary = new(isolate) LocationSummary(
-      isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall);
-  summary->set_in(0, Location::RequiresRegister());
-  summary->set_temp(0, Location::RequiresRegister());
-  summary->set_out(0,  Location::Pair(Location::RequiresRegister(),
-                                      Location::RequiresRegister()));
-  return summary;
-}
-
-
-void UnboxIntegerInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
-  const intptr_t value_cid = value()->Type()->ToCid();
-  const Register value = locs()->in(0).reg();
-  PairLocation* result_pair = locs()->out(0).AsPairLocation();
-  Register result_lo = result_pair->At(0).reg();
-  Register result_hi = result_pair->At(1).reg();
-  ASSERT(value != result_lo);
-  ASSERT(value != result_hi);
-
-  __ Comment("UnboxIntegerInstr");
-  if (value_cid == kMintCid) {
-    // Load low word.
-    __ LoadFromOffset(kWord,
-                      result_lo,
-                      value,
-                      Mint::value_offset() - kHeapObjectTag);
-    // Load high word.
-    __ LoadFromOffset(kWord,
-                      result_hi,
-                      value,
-                      Mint::value_offset() - kHeapObjectTag + kWordSize);
-  } else if (value_cid == kSmiCid) {
-    // Load Smi into result_lo.
-    __ mov(result_lo, Operand(value));
-    // Untag.
-    __ SmiUntag(result_lo);
-    __ SignFill(result_hi, result_lo);
-  } else {
-    const Register temp = locs()->temp(0).reg();
-    Label* deopt = compiler->AddDeoptStub(GetDeoptId(),
-                                          ICData::kDeoptUnboxInteger);
-    Label is_smi, done;
-    __ tst(value, Operand(kSmiTagMask));
-    __ b(&is_smi, EQ);
-    __ CompareClassId(value, kMintCid, temp);
-    __ b(deopt, NE);
-
-    // It's a Mint.
-    // Load low word.
-    __ LoadFromOffset(kWord,
-                      result_lo,
-                      value,
-                      Mint::value_offset() - kHeapObjectTag);
-    // Load high word.
-    __ LoadFromOffset(kWord,
-                      result_hi,
-                      value,
-                      Mint::value_offset() - kHeapObjectTag + kWordSize);
-    __ b(&done);
-
-    // It's a Smi.
-    __ Bind(&is_smi);
-    // Load Smi into result_lo.
-    __ mov(result_lo, Operand(value));
-    // Untag.
-    __ SmiUntag(result_lo);
-    // Sign extend result_lo into result_hi.
-    __ SignFill(result_hi, result_lo);
-    __ Bind(&done);
-  }
-}
-
-
-LocationSummary* BoxIntegerInstr::MakeLocationSummary(Isolate* isolate,
-                                                      bool opt) const {
-  const intptr_t kNumInputs = 1;
-  const intptr_t kNumTemps = is_smi() ? 0 : 1;
-  LocationSummary* summary = new(isolate) LocationSummary(
-      isolate, kNumInputs,
-                          kNumTemps,
-                          is_smi()
-                              ? LocationSummary::kNoCall
-                              : LocationSummary::kCallOnSlowPath);
-  summary->set_in(0, Location::Pair(Location::RequiresRegister(),
-                                    Location::RequiresRegister()));
-  if (!is_smi()) {
-    summary->set_temp(0, Location::RequiresRegister());
-  }
-  summary->set_out(0, Location::RequiresRegister());
-  return summary;
-}
-
-
-void BoxIntegerInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
-  if (is_smi()) {
-    PairLocation* value_pair = locs()->in(0).AsPairLocation();
-    Register value_lo = value_pair->At(0).reg();
-    Register out_reg = locs()->out(0).reg();
-    __ mov(out_reg, Operand(value_lo));
-    __ SmiTag(out_reg);
-    return;
-  }
-
-  PairLocation* value_pair = locs()->in(0).AsPairLocation();
-  Register value_lo = value_pair->At(0).reg();
-  Register value_hi = value_pair->At(1).reg();
-  Register tmp = locs()->temp(0).reg();
-  Register out_reg = locs()->out(0).reg();
-
-  // Unboxed operations produce smis or mint-sized values.
-  // Check if value fits into a smi.
-  __ Comment("BoxIntegerInstr");
-  Label not_smi, done, maybe_pos_smi, maybe_neg_smi, is_smi;
-  // Check high word.
-  __ CompareImmediate(value_hi, 0);
-  __ b(&maybe_pos_smi, EQ);
-
-  __ CompareImmediate(value_hi, -1);
-  __ b(&maybe_neg_smi, EQ);
-  __ b(&not_smi);
-
-  __ Bind(&maybe_pos_smi);
-  __ CompareImmediate(value_lo, kSmiMax);
-  __ b(&is_smi, LS);  // unsigned lower or same.
-  __ b(&not_smi);
-
-  __ Bind(&maybe_neg_smi);
-  __ CompareImmediate(value_lo, 0);
-  __ b(&not_smi, GE);
-  __ CompareImmediate(value_lo, kSmiMin);
-  __ b(&not_smi, LT);
-
-  // lo is a Smi. Tag it and return.
-  __ Bind(&is_smi);
-  __ mov(out_reg, Operand(value_lo));
-  __ SmiTag(out_reg);
-  __ b(&done);
-
-  // Not a smi. Box it.
-  __ Bind(&not_smi);
-  BoxAllocationSlowPath::Allocate(
-      compiler,
-      this,
-      compiler->mint_class(),
-      out_reg,
-      tmp);
-  __ StoreToOffset(kWord,
-                   value_lo,
-                   out_reg,
-                   Mint::value_offset() - kHeapObjectTag);
-  __ StoreToOffset(kWord,
-                   value_hi,
-                   out_reg,
-                   Mint::value_offset() - kHeapObjectTag + kWordSize);
-  __ Bind(&done);
-}
-
-
 LocationSummary* BinaryMintOpInstr::MakeLocationSummary(Isolate* isolate,
                                                         bool opt) const {
   const intptr_t kNumInputs = 2;
@@ -6577,133 +6467,6 @@
 }
 
 
-LocationSummary* BoxIntNInstr::MakeLocationSummary(Isolate* isolate,
-                                                   bool opt) const {
-  ASSERT((from_representation() == kUnboxedInt32) ||
-         (from_representation() == kUnboxedUint32));
-  const intptr_t kNumInputs = 1;
-  const intptr_t kNumTemps = ValueFitsSmi() ? 0 : 1;
-  LocationSummary* summary = new(isolate) LocationSummary(
-      isolate,
-      kNumInputs,
-      kNumTemps,
-      ValueFitsSmi() ? LocationSummary::kNoCall
-                     : LocationSummary::kCallOnSlowPath);
-  summary->set_in(0, Location::RequiresRegister());
-  if (!ValueFitsSmi()) {
-    summary->set_temp(0, Location::RequiresRegister());
-  }
-  summary->set_out(0, Location::RequiresRegister());
-  return summary;
-}
-
-
-void BoxIntNInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
-  Register value = locs()->in(0).reg();
-  Register out = locs()->out(0).reg();
-  ASSERT(value != out);
-
-  __ SmiTag(out, value);
-  if (!ValueFitsSmi()) {
-    Register temp = locs()->temp(0).reg();
-    Label done;
-    if (from_representation() == kUnboxedInt32) {
-      __ cmp(value, Operand(out, ASR, 1));
-    } else {
-      ASSERT(from_representation() == kUnboxedUint32);
-      // Note: better to test upper bits instead of comparing with
-      // kSmiMax as kSmiMax does not fit into immediate operand.
-      __ TestImmediate(value, 0xC0000000);
-    }
-    __ b(&done, EQ);
-    BoxAllocationSlowPath::Allocate(
-        compiler,
-        this,
-        compiler->mint_class(),
-        out,
-        temp);
-    if (from_representation() == kUnboxedInt32) {
-      __ Asr(temp, value, Operand(kBitsPerWord - 1));
-    } else {
-      ASSERT(from_representation() == kUnboxedUint32);
-      __ eor(temp, temp, Operand(temp));
-    }
-    __ StoreToOffset(kWord,
-                     value,
-                     out,
-                     Mint::value_offset() - kHeapObjectTag);
-    __ StoreToOffset(kWord,
-                     temp,
-                     out,
-                     Mint::value_offset() - kHeapObjectTag + kWordSize);
-    __ Bind(&done);
-  }
-}
-
-
-static void LoadInt32FromMint(FlowGraphCompiler* compiler,
-                              Register mint,
-                              Register result,
-                              Register temp,
-                              Label* deopt) {
-  __ LoadFromOffset(kWord,
-                    result,
-                    mint,
-                    Mint::value_offset() - kHeapObjectTag);
-  if (deopt != NULL) {
-    __ LoadFromOffset(kWord,
-                      temp,
-                      mint,
-                      Mint::value_offset() - kHeapObjectTag + kWordSize);
-    __ cmp(temp, Operand(result, ASR, kBitsPerWord - 1));
-    __ b(deopt, NE);
-  }
-}
-
-
-LocationSummary* UnboxIntNInstr::MakeLocationSummary(Isolate* isolate,
-                                                     bool opt) const {
-  ASSERT((representation() == kUnboxedInt32) ||
-         (representation() == kUnboxedUint32));
-  ASSERT((representation() != kUnboxedUint32) || is_truncating());
-  const intptr_t kNumInputs = 1;
-  const intptr_t kNumTemps = CanDeoptimize() ? 1 : 0;
-  LocationSummary* summary = new(isolate) LocationSummary(
-      isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall);
-  summary->set_in(0, Location::RequiresRegister());
-  if (kNumTemps > 0) {
-    summary->set_temp(0, Location::RequiresRegister());
-  }
-  summary->set_out(0, Location::RequiresRegister());
-  return summary;
-}
-
-
-void UnboxIntNInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
-  const intptr_t value_cid = value()->Type()->ToCid();
-  const Register value = locs()->in(0).reg();
-  const Register out = locs()->out(0).reg();
-  const Register temp = CanDeoptimize() ? locs()->temp(0).reg() : kNoRegister;
-  Label* deopt = CanDeoptimize() ?
-        compiler->AddDeoptStub(GetDeoptId(), ICData::kDeoptUnboxInteger) : NULL;
-  Label* out_of_range = !is_truncating() ? deopt : NULL;
-  ASSERT(value != out);
-
-  if (value_cid == kSmiCid) {
-    __ SmiUntag(out, value);
-  } else if (value_cid == kMintCid) {
-    LoadInt32FromMint(compiler, value, out, temp, out_of_range);
-  } else {
-    Label done;
-    __ SmiUntag(out, value, &done);
-    __ CompareClassId(value, kMintCid, temp);
-    __ b(deopt, NE);
-    LoadInt32FromMint(compiler, value, out, temp, out_of_range);
-    __ Bind(&done);
-  }
-}
-
-
 LocationSummary* UnboxedIntConverterInstr::MakeLocationSummary(Isolate* isolate,
                                                                bool opt) const {
   const intptr_t kNumInputs = 1;
@@ -6961,7 +6724,7 @@
 
 LocationSummary* AllocateObjectInstr::MakeLocationSummary(Isolate* isolate,
                                                           bool opt) const {
-  return MakeCallSummary();
+  return MakeCallSummary(isolate);
 }
 
 
diff --git a/runtime/vm/intermediate_language_arm64.cc b/runtime/vm/intermediate_language_arm64.cc
index d550611..ecea14d 100644
--- a/runtime/vm/intermediate_language_arm64.cc
+++ b/runtime/vm/intermediate_language_arm64.cc
@@ -29,8 +29,7 @@
 
 // Generic summary for call instructions that have all arguments pushed
 // on the stack and return the result in a fixed register R0.
-LocationSummary* Instruction::MakeCallSummary() {
-  Isolate* isolate = Isolate::Current();
+LocationSummary* Instruction::MakeCallSummary(Isolate* isolate) {
   LocationSummary* result = new(isolate) LocationSummary(
       isolate, 0, 0, LocationSummary::kCall);
   result->set_out(0, Location::RegisterLocation(R0));
@@ -766,22 +765,11 @@
 
 LocationSummary* NativeCallInstr::MakeLocationSummary(Isolate* isolate,
                                                       bool opt) const {
-  const intptr_t kNumInputs = 0;
-  const intptr_t kNumTemps = 3;
-  LocationSummary* locs = new(isolate) LocationSummary(
-      isolate, kNumInputs, kNumTemps, LocationSummary::kCall);
-  locs->set_temp(0, Location::RegisterLocation(R1));
-  locs->set_temp(1, Location::RegisterLocation(R2));
-  locs->set_temp(2, Location::RegisterLocation(R5));
-  locs->set_out(0, Location::RegisterLocation(R0));
-  return locs;
+  return MakeCallSummary(isolate);
 }
 
 
 void NativeCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
-  ASSERT(locs()->temp(0).reg() == R1);
-  ASSERT(locs()->temp(1).reg() == R2);
-  ASSERT(locs()->temp(2).reg() == R5);
   const Register result = locs()->out(0).reg();
 
   // Push the result place holder initialized to NULL.
@@ -3054,8 +3042,8 @@
 }
 
 
-LocationSummary* BoxDoubleInstr::MakeLocationSummary(Isolate* isolate,
-                                                     bool opt) const {
+LocationSummary* BoxInstr::MakeLocationSummary(Isolate* isolate,
+                                               bool opt) const {
   const intptr_t kNumInputs = 1;
   const intptr_t kNumTemps = 1;
   LocationSummary* summary = new(isolate) LocationSummary(
@@ -3067,19 +3055,36 @@
 }
 
 
-void BoxDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+void BoxInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
   const Register out_reg = locs()->out(0).reg();
   const Register temp_reg = locs()->temp(0).reg();
   const VRegister value = locs()->in(0).fpu_reg();
 
   BoxAllocationSlowPath::Allocate(
-      compiler, this, compiler->double_class(), out_reg, temp_reg);
-  __ StoreDFieldToOffset(value, out_reg, Double::value_offset(), PP);
+      compiler,
+      this,
+      compiler->BoxClassFor(from_representation()),
+      out_reg,
+      temp_reg);
+
+  switch (from_representation()) {
+    case kUnboxedDouble:
+      __ StoreDFieldToOffset(value, out_reg, ValueOffset(), PP);
+      break;
+    case kUnboxedFloat32x4:
+    case kUnboxedFloat64x2:
+    case kUnboxedInt32x4:
+      __ StoreQFieldToOffset(value, out_reg, ValueOffset(), PP);
+      break;
+    default:
+      UNREACHABLE();
+      break;
+  }
 }
 
 
-LocationSummary* UnboxDoubleInstr::MakeLocationSummary(Isolate* isolate,
-                                                       bool opt) const {
+LocationSummary* UnboxInstr::MakeLocationSummary(Isolate* isolate,
+                                                 bool opt) const {
   const intptr_t kNumInputs = 1;
   const intptr_t kNumTemps = 0;
   LocationSummary* summary = new(isolate) LocationSummary(
@@ -3090,201 +3095,175 @@
 }
 
 
-void UnboxDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
-  CompileType* value_type = value()->Type();
-  const intptr_t value_cid = value_type->ToCid();
-  const Register value = locs()->in(0).reg();
-  const VRegister result = locs()->out(0).fpu_reg();
+void UnboxInstr::EmitLoadFromBox(FlowGraphCompiler* compiler) {
+  const Register box = locs()->in(0).reg();
 
-  if (value_cid == kDoubleCid) {
-    __ LoadDFieldFromOffset(result, value, Double::value_offset(), PP);
-  } else if (value_cid == kSmiCid) {
-    __ SmiUntag(TMP, value);  // Untag input before conversion.
-    __ scvtfdx(result, TMP);
+  switch (representation()) {
+    case kUnboxedMint: {
+      UNIMPLEMENTED();
+      break;
+    }
+
+    case kUnboxedDouble: {
+      const VRegister result = locs()->out(0).fpu_reg();
+      __ LoadDFieldFromOffset(result, box, ValueOffset(), PP);
+      break;
+    }
+
+    case kUnboxedFloat32x4:
+    case kUnboxedFloat64x2:
+    case kUnboxedInt32x4: {
+      const VRegister result = locs()->out(0).fpu_reg();
+      __ LoadQFieldFromOffset(result, box, ValueOffset(), PP);
+      break;
+    }
+
+    default:
+      UNREACHABLE();
+      break;
+  }
+}
+
+
+void UnboxInstr::EmitSmiConversion(FlowGraphCompiler* compiler) {
+  const Register box = locs()->in(0).reg();
+
+  switch (representation()) {
+    case kUnboxedMint: {
+      UNIMPLEMENTED();
+      break;
+    }
+
+    case kUnboxedDouble: {
+      const VRegister result = locs()->out(0).fpu_reg();
+      __ SmiUntag(TMP, box);
+      __ scvtfdx(result, TMP);
+      break;
+    }
+
+    default:
+      UNREACHABLE();
+      break;
+  }
+}
+
+
+void UnboxInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+  const intptr_t value_cid = value()->Type()->ToCid();
+  const intptr_t box_cid = BoxCid();
+
+  if (value_cid == box_cid) {
+    EmitLoadFromBox(compiler);
+  } else if (CanConvertSmi() && (value_cid == kSmiCid)) {
+    EmitSmiConversion(compiler);
   } else {
+    const Register box = locs()->in(0).reg();
     Label* deopt = compiler->AddDeoptStub(GetDeoptId(),
-                                          ICData::kDeoptBinaryDoubleOp);
-    if (value_type->is_nullable() &&
-        (value_type->ToNullableCid() == kDoubleCid)) {
-      __ CompareObject(value, Object::null_object(), PP);
+                                          ICData::kDeoptCheckClass);
+    Label is_smi;
+
+    if ((value()->Type()->ToNullableCid() == box_cid) &&
+        value()->Type()->is_nullable()) {
+      __ CompareObject(box, Object::null_object(), PP);
       __ b(deopt, EQ);
-      // It must be double now.
-      __ LoadDFieldFromOffset(result, value, Double::value_offset(), PP);
     } else {
-      Label is_smi, done;
-      __ tsti(value, Immediate(kSmiTagMask));
-      __ b(&is_smi, EQ);
-      __ CompareClassId(value, kDoubleCid, PP);
+      __ tsti(box, Immediate(kSmiTagMask));
+      __ b(CanConvertSmi() ? &is_smi : deopt, EQ);
+      __ CompareClassId(box, box_cid, PP);
       __ b(deopt, NE);
-      __ LoadDFieldFromOffset(result, value, Double::value_offset(), PP);
+    }
+
+    EmitLoadFromBox(compiler);
+
+    if (is_smi.IsLinked()) {
+      Label done;
       __ b(&done);
       __ Bind(&is_smi);
-      __ SmiUntag(TMP, value);  // Copy and untag.
-      __ scvtfdx(result, TMP);
+      EmitSmiConversion(compiler);
       __ Bind(&done);
     }
   }
 }
 
 
-LocationSummary* BoxFloat32x4Instr::MakeLocationSummary(Isolate* isolate,
+LocationSummary* BoxInteger32Instr::MakeLocationSummary(Isolate* isolate,
                                                         bool opt) const {
+  ASSERT((from_representation() == kUnboxedInt32) ||
+         (from_representation() == kUnboxedUint32));
   const intptr_t kNumInputs = 1;
-  const intptr_t kNumTemps = 1;
+  const intptr_t kNumTemps = 0;
   LocationSummary* summary = new(isolate) LocationSummary(
-      isolate, kNumInputs, kNumTemps, LocationSummary::kCallOnSlowPath);
-  summary->set_in(0, Location::RequiresFpuRegister());
-  summary->set_temp(0, Location::RequiresRegister());
+      isolate,
+      kNumInputs,
+      kNumTemps,
+      LocationSummary::kNoCall);
+  summary->set_in(0, Location::RequiresRegister());
   summary->set_out(0, Location::RequiresRegister());
   return summary;
 }
 
 
-void BoxFloat32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) {
-  const Register out_reg = locs()->out(0).reg();
-  const Register temp_reg = locs()->temp(0).reg();
-  const VRegister value = locs()->in(0).fpu_reg();
+void BoxInteger32Instr::EmitNativeCode(FlowGraphCompiler* compiler) {
+  Register value = locs()->in(0).reg();
+  Register out = locs()->out(0).reg();
+  ASSERT(value != out);
 
-  BoxAllocationSlowPath::Allocate(
-      compiler, this, compiler->float32x4_class(), out_reg, temp_reg);
-  __ StoreQFieldToOffset(value, out_reg, Float32x4::value_offset(), PP);
+  ASSERT(kSmiTagSize == 1);
+  // TODO(vegorov) implement and use UBFM/SBFM for this.
+  __ LslImmediate(out, value, 32);
+  if (from_representation() == kUnboxedInt32) {
+    __ AsrImmediate(out, out, 32 - kSmiTagSize);
+  } else {
+    ASSERT(from_representation() == kUnboxedUint32);
+    __ LsrImmediate(out, out, 32 - kSmiTagSize);
+  }
 }
 
 
-LocationSummary* UnboxFloat32x4Instr::MakeLocationSummary(Isolate* isolate,
+DEFINE_UNIMPLEMENTED_INSTRUCTION(BoxInt64Instr)
+
+
+LocationSummary* UnboxInteger32Instr::MakeLocationSummary(Isolate* isolate,
                                                           bool opt) const {
   const intptr_t kNumInputs = 1;
   const intptr_t kNumTemps = 0;
   LocationSummary* summary = new(isolate) LocationSummary(
       isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall);
   summary->set_in(0, Location::RequiresRegister());
-  summary->set_out(0, Location::RequiresFpuRegister());
-  return summary;
-}
-
-
-void UnboxFloat32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) {
-  const intptr_t value_cid = value()->Type()->ToCid();
-  const Register value = locs()->in(0).reg();
-  const VRegister result = locs()->out(0).fpu_reg();
-
-  if (value_cid != kFloat32x4Cid) {
-    Label* deopt =
-        compiler->AddDeoptStub(GetDeoptId(), ICData::kDeoptCheckClass);
-    __ tsti(value, Immediate(kSmiTagMask));
-    __ b(deopt, EQ);
-    __ CompareClassId(value, kFloat32x4Cid, PP);
-    __ b(deopt, NE);
-  }
-
-  __ LoadQFieldFromOffset(result, value, Float32x4::value_offset(), PP);
-}
-
-
-LocationSummary* BoxFloat64x2Instr::MakeLocationSummary(Isolate* isolate,
-                                                        bool opt) const {
-  const intptr_t kNumInputs = 1;
-  const intptr_t kNumTemps = 1;
-  LocationSummary* summary = new(isolate) LocationSummary(
-      isolate, kNumInputs, kNumTemps, LocationSummary::kCallOnSlowPath);
-  summary->set_in(0, Location::RequiresFpuRegister());
-  summary->set_temp(0, Location::RequiresRegister());
   summary->set_out(0, Location::RequiresRegister());
   return summary;
 }
 
 
-void BoxFloat64x2Instr::EmitNativeCode(FlowGraphCompiler* compiler) {
-  const Register out_reg = locs()->out(0).reg();
-  const Register temp_reg = locs()->temp(0).reg();
-  const VRegister value = locs()->in(0).fpu_reg();
-
-  BoxAllocationSlowPath::Allocate(
-      compiler, this, compiler->float64x2_class(), out_reg, temp_reg);
-  __ StoreQFieldToOffset(value, out_reg, Float64x2::value_offset(), PP);
-}
-
-
-LocationSummary* UnboxFloat64x2Instr::MakeLocationSummary(Isolate* isolate,
-                                                          bool opt) const {
-  const intptr_t kNumInputs = 1;
-  const intptr_t kNumTemps = 0;
-  LocationSummary* summary = new(isolate) LocationSummary(
-      isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall);
-  summary->set_in(0, Location::RequiresRegister());
-  summary->set_out(0, Location::RequiresFpuRegister());
-  return summary;
-}
-
-
-void UnboxFloat64x2Instr::EmitNativeCode(FlowGraphCompiler* compiler) {
+void UnboxInteger32Instr::EmitNativeCode(FlowGraphCompiler* compiler) {
   const intptr_t value_cid = value()->Type()->ToCid();
+  const Register out = locs()->out(0).reg();
   const Register value = locs()->in(0).reg();
-  const VRegister result = locs()->out(0).fpu_reg();
+  Label* deopt = CanDeoptimize() ?
+      compiler->AddDeoptStub(GetDeoptId(), ICData::kDeoptUnboxInteger) : NULL;
 
-  if (value_cid != kFloat64x2Cid) {
-    Label* deopt =
-        compiler->AddDeoptStub(GetDeoptId(), ICData::kDeoptCheckClass);
-    __ tsti(value, Immediate(kSmiTagMask));
-    __ b(deopt, EQ);
-    __ CompareClassId(value, kFloat64x2Cid, PP);
+  if (value_cid == kSmiCid) {
+    __ SmiUntag(out, value);
+  } else if (value_cid == kMintCid) {
+    __ LoadFieldFromOffset(out, value, Mint::value_offset(), PP);
+  } else {
+    Label done;
+    __ SmiUntag(out, value);
+    __ TestImmediate(value, kSmiTagMask, PP);
+    __ b(&done, EQ);
+    __ CompareClassId(value, kMintCid, PP);
     __ b(deopt, NE);
+    __ LoadFieldFromOffset(out, value, Mint::value_offset(), PP);
+    __ Bind(&done);
   }
 
-  __ LoadQFieldFromOffset(result, value, Float64x2::value_offset(), PP);
-}
-
-
-LocationSummary* BoxInt32x4Instr::MakeLocationSummary(Isolate* isolate,
-                                                      bool opt) const {
-  const intptr_t kNumInputs = 1;
-  const intptr_t kNumTemps = 1;
-  LocationSummary* summary = new(isolate) LocationSummary(
-      isolate, kNumInputs, kNumTemps, LocationSummary::kCallOnSlowPath);
-  summary->set_in(0, Location::RequiresFpuRegister());
-  summary->set_temp(0, Location::RequiresRegister());
-  summary->set_out(0, Location::RequiresRegister());
-  return summary;
-}
-
-
-void BoxInt32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) {
-  const Register out_reg = locs()->out(0).reg();
-  const Register temp_reg = locs()->temp(0).reg();
-  const VRegister value = locs()->in(0).fpu_reg();
-  BoxAllocationSlowPath::Allocate(
-      compiler, this, compiler->int32x4_class(), out_reg, temp_reg);
-  __ StoreQFieldToOffset(value, out_reg, Int32x4::value_offset(), PP);
-}
-
-
-LocationSummary* UnboxInt32x4Instr::MakeLocationSummary(Isolate* isolate,
-                                                        bool opt) const {
-  const intptr_t kNumInputs = 1;
-  const intptr_t kNumTemps = 0;
-  LocationSummary* summary = new(isolate) LocationSummary(
-      isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall);
-  summary->set_in(0, Location::RequiresRegister());
-  summary->set_out(0, Location::RequiresFpuRegister());
-  return summary;
-}
-
-
-void UnboxInt32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) {
-  const intptr_t value_cid = value()->Type()->ToCid();
-  const Register value = locs()->in(0).reg();
-  const VRegister result = locs()->out(0).fpu_reg();
-
-  if (value_cid != kInt32x4Cid) {
-    Label* deopt =
-        compiler->AddDeoptStub(GetDeoptId(), ICData::kDeoptCheckClass);
-    __ tsti(value, Immediate(kSmiTagMask));
-    __ b(deopt, EQ);
-    __ CompareClassId(value, kInt32x4Cid, PP);
+  // TODO(vegorov): as it is implemented right now truncating unboxing would
+  // leave "garbage" in the higher word.
+  if (!is_truncating() && (deopt != NULL)) {
+    ASSERT(representation() == kUnboxedInt32);
+    __ cmp(out, Operand(out, SXTW, 0));
     __ b(deopt, NE);
   }
-
-  __ LoadQFieldFromOffset(result, value, Int32x4::value_offset(), PP);
 }
 
 
@@ -4948,7 +4927,7 @@
 
 LocationSummary* PolymorphicInstanceCallInstr::MakeLocationSummary(
     Isolate* isolate, bool opt) const {
-  return MakeCallSummary();
+  return MakeCallSummary(isolate);
 }
 
 
@@ -5182,30 +5161,6 @@
 }
 
 
-LocationSummary* UnboxIntegerInstr::MakeLocationSummary(Isolate* isolate,
-                                                        bool opt) const {
-  UNIMPLEMENTED();
-  return NULL;
-}
-
-
-void UnboxIntegerInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
-  UNIMPLEMENTED();
-}
-
-
-LocationSummary* BoxIntegerInstr::MakeLocationSummary(Isolate* isolate,
-                                                      bool opt) const {
-  UNIMPLEMENTED();
-  return NULL;
-}
-
-
-void BoxIntegerInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
-  UNIMPLEMENTED();
-}
-
-
 LocationSummary* BinaryMintOpInstr::MakeLocationSummary(Isolate* isolate,
                                                         bool opt) const {
   UNIMPLEMENTED();
@@ -5269,84 +5224,6 @@
 DEFINE_UNIMPLEMENTED_INSTRUCTION(BinaryInt32OpInstr)
 
 
-LocationSummary* UnboxIntNInstr::MakeLocationSummary(Isolate* isolate,
-                                                       bool opt) const {
-  const intptr_t kNumInputs = 1;
-  const intptr_t kNumTemps = 0;
-  LocationSummary* summary = new(isolate) LocationSummary(
-      isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall);
-  summary->set_in(0, Location::RequiresRegister());
-  summary->set_out(0, Location::RequiresRegister());
-  return summary;
-}
-
-
-void UnboxIntNInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
-  const intptr_t value_cid = value()->Type()->ToCid();
-  const Register out = locs()->out(0).reg();
-  const Register value = locs()->in(0).reg();
-  Label* deopt = CanDeoptimize() ?
-      compiler->AddDeoptStub(GetDeoptId(), ICData::kDeoptUnboxInteger) : NULL;
-
-  if (value_cid == kSmiCid) {
-    __ SmiUntag(out, value);
-  } else if (value_cid == kMintCid) {
-    __ LoadFieldFromOffset(out, value, Mint::value_offset(), PP);
-  } else {
-    Label done;
-    __ SmiUntag(out, value);
-    __ TestImmediate(value, kSmiTagMask, PP);
-    __ b(&done, EQ);
-    __ CompareClassId(value, kMintCid, PP);
-    __ b(deopt, NE);
-    __ LoadFieldFromOffset(out, value, Mint::value_offset(), PP);
-    __ Bind(&done);
-  }
-
-  // TODO(vegorov): as it is implemented right now truncating unboxing would
-  // leave "garbage" in the higher word.
-  if (!is_truncating() && (deopt != NULL)) {
-    ASSERT(representation() == kUnboxedInt32);
-    __ cmp(out, Operand(out, SXTW, 0));
-    __ b(deopt, NE);
-  }
-}
-
-
-LocationSummary* BoxIntNInstr::MakeLocationSummary(Isolate* isolate,
-                                                   bool opt) const {
-  ASSERT((from_representation() == kUnboxedInt32) ||
-         (from_representation() == kUnboxedUint32));
-  const intptr_t kNumInputs = 1;
-  const intptr_t kNumTemps = 0;
-  LocationSummary* summary = new(isolate) LocationSummary(
-      isolate,
-      kNumInputs,
-      kNumTemps,
-      LocationSummary::kNoCall);
-  summary->set_in(0, Location::RequiresRegister());
-  summary->set_out(0, Location::RequiresRegister());
-  return summary;
-}
-
-
-void BoxIntNInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
-  Register value = locs()->in(0).reg();
-  Register out = locs()->out(0).reg();
-  ASSERT(value != out);
-
-  ASSERT(kSmiTagSize == 1);
-  // TODO(vegorov) implement and use UBFM/SBFM for this.
-  __ LslImmediate(out, value, 32);
-  if (from_representation() == kUnboxedInt32) {
-    __ AsrImmediate(out, out, 32 - kSmiTagSize);
-  } else {
-    ASSERT(from_representation() == kUnboxedUint32);
-    __ LsrImmediate(out, out, 32 - kSmiTagSize);
-  }
-}
-
-
 LocationSummary* UnboxedIntConverterInstr::MakeLocationSummary(Isolate* isolate,
                                                                bool opt) const {
   const intptr_t kNumInputs = 1;
@@ -5579,7 +5456,7 @@
 
 LocationSummary* AllocateObjectInstr::MakeLocationSummary(Isolate* isolate,
                                                           bool opt) const {
-  return MakeCallSummary();
+  return MakeCallSummary(isolate);
 }
 
 
diff --git a/runtime/vm/intermediate_language_ia32.cc b/runtime/vm/intermediate_language_ia32.cc
index 2c16100..7eb2995 100644
--- a/runtime/vm/intermediate_language_ia32.cc
+++ b/runtime/vm/intermediate_language_ia32.cc
@@ -30,10 +30,11 @@
 
 // Generic summary for call instructions that have all arguments pushed
 // on the stack and return the result in a fixed register EAX.
-LocationSummary* Instruction::MakeCallSummary() {
-  Isolate* isolate = Isolate::Current();
+LocationSummary* Instruction::MakeCallSummary(Isolate* isolate) {
+  const intptr_t kNumInputs = 0;
+  const intptr_t kNumTemps= 0;
   LocationSummary* result = new(isolate) LocationSummary(
-      isolate, 0, 0, LocationSummary::kCall);
+      isolate, kNumInputs, kNumTemps, LocationSummary::kCall);
   result->set_out(0, Location::RegisterLocation(EAX));
   return result;
 }
@@ -803,22 +804,11 @@
 
 LocationSummary* NativeCallInstr::MakeLocationSummary(Isolate* isolate,
                                                       bool opt) const {
-  const intptr_t kNumInputs = 0;
-  const intptr_t kNumTemps = 3;
-  LocationSummary* locs = new(isolate) LocationSummary(
-      isolate, kNumInputs, kNumTemps, LocationSummary::kCall);
-  locs->set_temp(0, Location::RegisterLocation(EAX));
-  locs->set_temp(1, Location::RegisterLocation(ECX));
-  locs->set_temp(2, Location::RegisterLocation(EDX));
-  locs->set_out(0, Location::RegisterLocation(EAX));
-  return locs;
+  return MakeCallSummary(isolate);
 }
 
 
 void NativeCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
-  ASSERT(locs()->temp(0).reg() == EAX);
-  ASSERT(locs()->temp(1).reg() == ECX);
-  ASSERT(locs()->temp(2).reg() == EDX);
   Register result = locs()->out(0).reg();
   const intptr_t argc_tag = NativeArguments::ComputeArgcTag(function());
   const bool is_leaf_call =
@@ -3329,10 +3319,7 @@
 }
 
 
-
-
-
-LocationSummary* BoxDoubleInstr::MakeLocationSummary(Isolate* isolate,
+LocationSummary* BoxInstr::MakeLocationSummary(Isolate* isolate,
                                                      bool opt) const {
   const intptr_t kNumInputs = 1;
   const intptr_t kNumTemps = 0;
@@ -3344,252 +3331,370 @@
 }
 
 
-void BoxDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+void BoxInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
   Register out_reg = locs()->out(0).reg();
   XmmRegister value = locs()->in(0).fpu_reg();
+
   BoxAllocationSlowPath::Allocate(
-      compiler, this, compiler->double_class(), out_reg, kNoRegister);
-  __ movsd(FieldAddress(out_reg, Double::value_offset()), value);
+      compiler,
+      this,
+      compiler->BoxClassFor(from_representation()),
+      out_reg,
+      kNoRegister);
+
+  switch (from_representation()) {
+    case kUnboxedDouble:
+      __ movsd(FieldAddress(out_reg, ValueOffset()), value);
+      break;
+    case kUnboxedFloat32x4:
+    case kUnboxedFloat64x2:
+    case kUnboxedInt32x4:
+      __ movups(FieldAddress(out_reg, ValueOffset()), value);
+      break;
+    default:
+      UNREACHABLE();
+      break;
+  }
 }
 
 
-LocationSummary* UnboxDoubleInstr::MakeLocationSummary(Isolate* isolate,
+LocationSummary* UnboxInstr::MakeLocationSummary(Isolate* isolate,
                                                        bool opt) const {
+  const bool needs_temp = CanDeoptimize() ||
+      (CanConvertSmi() && (value()->Type()->ToCid() == kSmiCid));
+
   const intptr_t kNumInputs = 1;
-  const intptr_t value_cid = value()->Type()->ToCid();
-  const bool needs_temp = ((value_cid != kSmiCid) && (value_cid != kDoubleCid));
-  const bool needs_writable_input = (value_cid == kSmiCid);
   const intptr_t kNumTemps = needs_temp ? 1 : 0;
   LocationSummary* summary = new(isolate) LocationSummary(
       isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall);
-  summary->set_in(0, needs_writable_input
-                     ? Location::WritableRegister()
-                     : Location::RequiresRegister());
-  if (needs_temp) summary->set_temp(0, Location::RequiresRegister());
-  summary->set_out(0, Location::RequiresFpuRegister());
+  summary->set_in(0, Location::RequiresRegister());
+  if (needs_temp) {
+    summary->set_temp(0, Location::RequiresRegister());
+  }
+  if (representation() == kUnboxedMint) {
+    summary->set_out(0, Location::Pair(Location::RegisterLocation(EAX),
+                                       Location::RegisterLocation(EDX)));
+  } else {
+    summary->set_out(0, Location::RequiresFpuRegister());
+  }
   return summary;
 }
 
 
-void UnboxDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
-  CompileType* value_type = value()->Type();
-  const intptr_t value_cid = value_type->ToCid();
-  const Register value = locs()->in(0).reg();
-  const XmmRegister result = locs()->out(0).fpu_reg();
+void UnboxInstr::EmitLoadFromBox(FlowGraphCompiler* compiler) {
+  const Register box = locs()->in(0).reg();
 
-  if (value_cid == kDoubleCid) {
-    __ movsd(result, FieldAddress(value, Double::value_offset()));
-  } else if (value_cid == kSmiCid) {
-    __ SmiUntag(value);  // Untag input before conversion.
-    __ cvtsi2sd(result, value);
-  } else {
-    Label* deopt = compiler->AddDeoptStub(GetDeoptId(),
-                                          ICData::kDeoptBinaryDoubleOp);
-    Register temp = locs()->temp(0).reg();
-    if (value_type->is_nullable() &&
-        (value_type->ToNullableCid() == kDoubleCid)) {
-      const Immediate& raw_null =
-          Immediate(reinterpret_cast<intptr_t>(Object::null()));
-      __ cmpl(value, raw_null);
-      __ j(EQUAL, deopt);
-      // It must be double now.
-      __ movsd(result, FieldAddress(value, Double::value_offset()));
-    } else {
-      Label is_smi, done;
-      __ testl(value, Immediate(kSmiTagMask));
-      __ j(ZERO, &is_smi);
-      __ CompareClassId(value, kDoubleCid, temp);
-      __ j(NOT_EQUAL, deopt);
-      __ movsd(result, FieldAddress(value, Double::value_offset()));
-      __ jmp(&done);
-      __ Bind(&is_smi);
-      __ movl(temp, value);
+  switch (representation()) {
+    case kUnboxedMint: {
+      PairLocation* result = locs()->out(0).AsPairLocation();
+      __ movl(result->At(0).reg(), FieldAddress(box, ValueOffset()));
+      __ movl(result->At(1).reg(),
+              FieldAddress(box, ValueOffset() + kWordSize));
+      break;
+    }
+
+    case kUnboxedDouble: {
+      const FpuRegister result = locs()->out(0).fpu_reg();
+      __ movsd(result, FieldAddress(box, ValueOffset()));
+      break;
+    }
+
+    case kUnboxedFloat32x4:
+    case kUnboxedFloat64x2:
+    case kUnboxedInt32x4: {
+      const FpuRegister result = locs()->out(0).fpu_reg();
+      __ movups(result, FieldAddress(box, ValueOffset()));
+      break;
+    }
+
+    default:
+      UNREACHABLE();
+      break;
+  }
+}
+
+
+void UnboxInstr::EmitSmiConversion(FlowGraphCompiler* compiler) {
+  const Register box = locs()->in(0).reg();
+
+  switch (representation()) {
+    case kUnboxedMint: {
+      PairLocation* result = locs()->out(0).AsPairLocation();
+      ASSERT(result->At(0).reg() == EAX);
+      ASSERT(result->At(1).reg() == EDX);
+      __ movl(EAX, box);
+      __ SmiUntag(EAX);
+      __ cdq();
+      break;
+    }
+
+    case kUnboxedDouble: {
+      const Register temp = locs()->temp(0).reg();
+      const FpuRegister result = locs()->out(0).fpu_reg();
+      __ movl(temp, box);
       __ SmiUntag(temp);
       __ cvtsi2sd(result, temp);
+      break;
+    }
+
+    default:
+      UNREACHABLE();
+      break;
+  }
+}
+
+
+void UnboxInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+  const intptr_t value_cid = value()->Type()->ToCid();
+  const intptr_t box_cid = BoxCid();
+
+  if (value_cid == box_cid) {
+    EmitLoadFromBox(compiler);
+  } else if (CanConvertSmi() && (value_cid == kSmiCid)) {
+    EmitSmiConversion(compiler);
+  } else {
+    const Register box = locs()->in(0).reg();
+    const Register temp = locs()->temp(0).reg();
+    Label* deopt = compiler->AddDeoptStub(GetDeoptId(),
+                                          ICData::kDeoptCheckClass);
+    Label is_smi;
+
+    if ((value()->Type()->ToNullableCid() == box_cid) &&
+        value()->Type()->is_nullable()) {
+      const Immediate& raw_null =
+          Immediate(reinterpret_cast<intptr_t>(Object::null()));
+      __ cmpl(box, raw_null);
+      __ j(EQUAL, deopt);
+    } else {
+      __ testl(box, Immediate(kSmiTagMask));
+      __ j(ZERO, CanConvertSmi() ? &is_smi : deopt);
+      __ CompareClassId(box, box_cid, temp);
+      __ j(NOT_EQUAL, deopt);
+    }
+
+    EmitLoadFromBox(compiler);
+
+    if (is_smi.IsLinked()) {
+      Label done;
+      __ jmp(&done);
+      __ Bind(&is_smi);
+      EmitSmiConversion(compiler);
       __ Bind(&done);
     }
   }
 }
 
 
-LocationSummary* BoxFloat32x4Instr::MakeLocationSummary(Isolate* isolate,
+LocationSummary* BoxInteger32Instr::MakeLocationSummary(Isolate* isolate,
                                                         bool opt) const {
   const intptr_t kNumInputs = 1;
   const intptr_t kNumTemps = 0;
   LocationSummary* summary = new(isolate) LocationSummary(
+      isolate, kNumInputs, kNumTemps,
+      ValueFitsSmi() ? LocationSummary::kNoCall
+                     : LocationSummary::kCallOnSlowPath);
+  const bool needs_writable_input = ValueFitsSmi() ||
+      (from_representation() == kUnboxedUint32);
+  summary->set_in(0, needs_writable_input ? Location::RequiresRegister()
+                                          : Location::WritableRegister());
+  summary->set_out(0, ValueFitsSmi() ? Location::SameAsFirstInput()
+                                     : Location::RequiresRegister());
+  return summary;
+}
+
+
+void BoxInteger32Instr::EmitNativeCode(FlowGraphCompiler* compiler) {
+  const Register value = locs()->in(0).reg();
+  const Register out = locs()->out(0).reg();
+
+  __ MoveRegister(out, value);
+  __ shll(out, Immediate(kSmiTagSize));
+  if (!ValueFitsSmi()) {
+    Label done;
+    ASSERT(value != out);
+    if (from_representation() == kUnboxedInt32) {
+      __ j(NO_OVERFLOW, &done);
+    } else {
+      __ testl(value, Immediate(0xC0000000));
+      __ j(ZERO, &done);
+    }
+
+    // Allocate a mint.
+    // Value input is writable register and has to be manually preserved
+    // on the slow path.
+    locs()->live_registers()->Add(locs()->in(0), kUnboxedInt32);
+    BoxAllocationSlowPath::Allocate(
+        compiler, this, compiler->mint_class(), out, kNoRegister);
+    __ movl(FieldAddress(out, Mint::value_offset()), value);
+    if (from_representation() == kUnboxedInt32) {
+      __ sarl(value, Immediate(31));  // Sign extend.
+      __ movl(FieldAddress(out, Mint::value_offset() + kWordSize), value);
+    } else {
+      __ movl(FieldAddress(out, Mint::value_offset() + kWordSize),
+              Immediate(0));
+    }
+    __ Bind(&done);
+  }
+}
+
+
+LocationSummary* BoxInt64Instr::MakeLocationSummary(Isolate* isolate,
+                                                    bool opt) const {
+  const intptr_t kNumInputs = 1;
+  const intptr_t kNumTemps = ValueFitsSmi() ? 0 : 1;
+  LocationSummary* summary = new(isolate) LocationSummary(
       isolate, kNumInputs,
                           kNumTemps,
-                          LocationSummary::kCallOnSlowPath);
-  summary->set_in(0, Location::RequiresFpuRegister());
+                          ValueFitsSmi()
+                              ? LocationSummary::kNoCall
+                              : LocationSummary::kCallOnSlowPath);
+  summary->set_in(0, Location::Pair(Location::RequiresRegister(),
+                                    Location::RequiresRegister()));
+  if (!ValueFitsSmi()) {
+    summary->set_temp(0, Location::RequiresRegister());
+  }
   summary->set_out(0, Location::RequiresRegister());
   return summary;
 }
 
 
-void BoxFloat32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) {
+void BoxInt64Instr::EmitNativeCode(FlowGraphCompiler* compiler) {
+  if (ValueFitsSmi()) {
+    PairLocation* value_pair = locs()->in(0).AsPairLocation();
+    Register value_lo = value_pair->At(0).reg();
+    Register out_reg = locs()->out(0).reg();
+    __ movl(out_reg, value_lo);
+    __ SmiTag(out_reg);
+    return;
+  }
+
+  PairLocation* value_pair = locs()->in(0).AsPairLocation();
+  Register value_lo = value_pair->At(0).reg();
+  Register value_hi = value_pair->At(1).reg();
   Register out_reg = locs()->out(0).reg();
-  XmmRegister value = locs()->in(0).fpu_reg();
+
+  // Copy value_hi into out_reg as a temporary.
+  // We modify value_lo but restore it before using it.
+  __ movl(out_reg, value_hi);
+
+  // Unboxed operations produce smis or mint-sized values.
+  // Check if value fits into a smi.
+  Label not_smi, done;
+
+  // 1. Compute (x + -kMinSmi) which has to be in the range
+  //    0 .. -kMinSmi+kMaxSmi for x to fit into a smi.
+  __ addl(value_lo, Immediate(0x40000000));
+  __ adcl(out_reg, Immediate(0));
+  // 2. Unsigned compare to -kMinSmi+kMaxSmi.
+  __ cmpl(value_lo, Immediate(0x80000000));
+  __ sbbl(out_reg, Immediate(0));
+  __ j(ABOVE_EQUAL, &not_smi);
+  // 3. Restore lower half if result is a smi.
+  __ subl(value_lo, Immediate(0x40000000));
+  __ movl(out_reg, value_lo);
+  __ SmiTag(out_reg);
+  __ jmp(&done);
+  __ Bind(&not_smi);
+  // 3. Restore lower half of input before using it.
+  __ subl(value_lo, Immediate(0x40000000));
 
   BoxAllocationSlowPath::Allocate(
-      compiler, this, compiler->float32x4_class(), out_reg, kNoRegister);
-  __ movups(FieldAddress(out_reg, Float32x4::value_offset()), value);
+      compiler, this, compiler->mint_class(), out_reg, kNoRegister);
+  __ movl(FieldAddress(out_reg, Mint::value_offset()), value_lo);
+  __ movl(FieldAddress(out_reg, Mint::value_offset() + kWordSize), value_hi);
+  __ Bind(&done);
 }
 
 
-LocationSummary* UnboxFloat32x4Instr::MakeLocationSummary(Isolate* isolate,
+LocationSummary* UnboxInteger32Instr::MakeLocationSummary(Isolate* isolate,
                                                           bool opt) const {
   const intptr_t value_cid = value()->Type()->ToCid();
   const intptr_t kNumInputs = 1;
-  const intptr_t kNumTemps = value_cid == kFloat32x4Cid ? 0 : 1;
+  intptr_t kNumTemps = 0;
+
+  if (CanDeoptimize()) {
+    if ((value_cid != kSmiCid) &&
+        (value_cid != kMintCid) &&
+        !is_truncating()) {
+      kNumTemps = 2;
+    } else {
+      kNumTemps = 1;
+    }
+  }
+
   LocationSummary* summary = new(isolate) LocationSummary(
       isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall);
   summary->set_in(0, Location::RequiresRegister());
-  if (kNumTemps > 0) {
-    ASSERT(kNumTemps == 1);
-    summary->set_temp(0, Location::RequiresRegister());
+  for (int i = 0; i < kNumTemps; i++) {
+    summary->set_temp(i, Location::RequiresRegister());
   }
-  summary->set_out(0, Location::RequiresFpuRegister());
+  summary->set_out(0, ((value_cid == kSmiCid) || (value_cid != kMintCid)) ?
+      Location::SameAsFirstInput() : Location::RequiresRegister());
   return summary;
 }
 
 
-void UnboxFloat32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) {
-  const intptr_t value_cid = value()->Type()->ToCid();
-  const Register value = locs()->in(0).reg();
-  const XmmRegister result = locs()->out(0).fpu_reg();
-
-  if (value_cid != kFloat32x4Cid) {
-    const Register temp = locs()->temp(0).reg();
-    Label* deopt =
-        compiler->AddDeoptStub(GetDeoptId(), ICData::kDeoptCheckClass);
-    __ testl(value, Immediate(kSmiTagMask));
-    __ j(ZERO, deopt);
-    __ CompareClassId(value, kFloat32x4Cid, temp);
+static void LoadInt32FromMint(FlowGraphCompiler* compiler,
+                              Register result,
+                              const Address& lo,
+                              const Address& hi,
+                              Register temp,
+                              Label* deopt) {
+  __ movl(result, lo);
+  if (deopt != NULL) {
+    ASSERT(temp != result);
+    __ movl(temp, result);
+    __ sarl(temp, Immediate(31));
+    __ cmpl(temp, hi);
     __ j(NOT_EQUAL, deopt);
   }
-  __ movups(result, FieldAddress(value, Float32x4::value_offset()));
 }
 
 
-LocationSummary* BoxFloat64x2Instr::MakeLocationSummary(Isolate* isolate,
-                                                        bool opt) const {
-  const intptr_t kNumInputs = 1;
-  const intptr_t kNumTemps = 0;
-  LocationSummary* summary = new(isolate) LocationSummary(
-      isolate, kNumInputs,
-                          kNumTemps,
-                          LocationSummary::kCallOnSlowPath);
-  summary->set_in(0, Location::RequiresFpuRegister());
-  summary->set_out(0, Location::RequiresRegister());
-  return summary;
-}
-
-
-void BoxFloat64x2Instr::EmitNativeCode(FlowGraphCompiler* compiler) {
-  Register out_reg = locs()->out(0).reg();
-  XmmRegister value = locs()->in(0).fpu_reg();
-
-  BoxAllocationSlowPath::Allocate(
-      compiler, this, compiler->float64x2_class(), out_reg, kNoRegister);
-  __ movups(FieldAddress(out_reg, Float64x2::value_offset()), value);
-}
-
-
-LocationSummary* UnboxFloat64x2Instr::MakeLocationSummary(Isolate* isolate,
-                                                          bool opt) const {
+void UnboxInteger32Instr::EmitNativeCode(FlowGraphCompiler* compiler) {
   const intptr_t value_cid = value()->Type()->ToCid();
-  const intptr_t kNumInputs = 1;
-  const intptr_t kNumTemps = value_cid == kFloat64x2Cid ? 0 : 1;
-  LocationSummary* summary = new(isolate) LocationSummary(
-      isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall);
-  summary->set_in(0, Location::RequiresRegister());
-  if (kNumTemps > 0) {
-    ASSERT(kNumTemps == 1);
-    summary->set_temp(0, Location::RequiresRegister());
-  }
-  summary->set_out(0, Location::RequiresFpuRegister());
-  return summary;
-}
+  Register value = locs()->in(0).reg();
+  const Register result = locs()->out(0).reg();
+  const Register temp = CanDeoptimize() ? locs()->temp(0).reg() : kNoRegister;
+  Label* deopt = CanDeoptimize() ?
+      compiler->AddDeoptStub(GetDeoptId(), ICData::kDeoptUnboxInteger) : NULL;
+  Label* out_of_range = !is_truncating() ? deopt : NULL;
 
+  const intptr_t lo_offset = Mint::value_offset();
+  const intptr_t hi_offset = Mint::value_offset() + kWordSize;
 
-void UnboxFloat64x2Instr::EmitNativeCode(FlowGraphCompiler* compiler) {
-  const intptr_t value_cid = value()->Type()->ToCid();
-  const Register value = locs()->in(0).reg();
-  const XmmRegister result = locs()->out(0).fpu_reg();
-
-  if (value_cid != kFloat64x2Cid) {
-    const Register temp = locs()->temp(0).reg();
-    Label* deopt =
-        compiler->AddDeoptStub(GetDeoptId(), ICData::kDeoptCheckClass);
-    __ testl(value, Immediate(kSmiTagMask));
-    __ j(ZERO, deopt);
-    __ CompareClassId(value, kFloat64x2Cid, temp);
+  if (value_cid == kSmiCid) {
+    ASSERT(value == result);
+    __ SmiUntag(value);
+  } else if (value_cid == kMintCid) {
+    ASSERT((value != result) || (out_of_range == NULL));
+    LoadInt32FromMint(compiler,
+                      result,
+                      FieldAddress(value, lo_offset),
+                      FieldAddress(value, hi_offset),
+                      temp,
+                      out_of_range);
+  } else {
+    ASSERT(value == result);
+    Label done;
+    __ SmiUntagOrCheckClass(value, kMintCid, temp, &done);
     __ j(NOT_EQUAL, deopt);
+    if (out_of_range != NULL) {
+      Register value_temp = locs()->temp(1).reg();
+      __ movl(value_temp, value);
+      value = value_temp;
+    }
+    LoadInt32FromMint(compiler,
+                      result,
+                      Address(value, TIMES_2, lo_offset),
+                      Address(value, TIMES_2, hi_offset),
+                      temp,
+                      out_of_range);
+    __ Bind(&done);
   }
-  __ movups(result, FieldAddress(value, Float64x2::value_offset()));
 }
 
 
-LocationSummary* BoxInt32x4Instr::MakeLocationSummary(Isolate* isolate,
-                                                      bool opt) const {
-  const intptr_t kNumInputs = 1;
-  const intptr_t kNumTemps = 0;
-  LocationSummary* summary = new(isolate) LocationSummary(
-      isolate, kNumInputs,
-                          kNumTemps,
-                          LocationSummary::kCallOnSlowPath);
-  summary->set_in(0, Location::RequiresFpuRegister());
-  summary->set_out(0, Location::RequiresRegister());
-  return summary;
-}
-
-
-void BoxInt32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) {
-  Register out_reg = locs()->out(0).reg();
-  XmmRegister value = locs()->in(0).fpu_reg();
-
-  BoxAllocationSlowPath::Allocate(
-      compiler, this, compiler->int32x4_class(), out_reg, kNoRegister);
-  __ movups(FieldAddress(out_reg, Int32x4::value_offset()), value);
-}
-
-
-LocationSummary* UnboxInt32x4Instr::MakeLocationSummary(Isolate* isolate,
-                                                        bool opt) const {
-  const intptr_t value_cid = value()->Type()->ToCid();
-  const intptr_t kNumInputs = 1;
-  const intptr_t kNumTemps = value_cid == kInt32x4Cid ? 0 : 1;
-  LocationSummary* summary = new(isolate) LocationSummary(
-      isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall);
-  summary->set_in(0, Location::RequiresRegister());
-  if (kNumTemps > 0) {
-    ASSERT(kNumTemps == 1);
-    summary->set_temp(0, Location::RequiresRegister());
-  }
-  summary->set_out(0, Location::RequiresFpuRegister());
-  return summary;
-}
-
-
-void UnboxInt32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) {
-  const intptr_t value_cid = value()->Type()->ToCid();
-  const Register value = locs()->in(0).reg();
-  const XmmRegister result = locs()->out(0).fpu_reg();
-
-  if (value_cid != kInt32x4Cid) {
-    const Register temp = locs()->temp(0).reg();
-    Label* deopt =
-        compiler->AddDeoptStub(GetDeoptId(), ICData::kDeoptCheckClass);
-    __ testl(value, Immediate(kSmiTagMask));
-    __ j(ZERO, deopt);
-    __ CompareClassId(value, kInt32x4Cid, temp);
-    __ j(NOT_EQUAL, deopt);
-  }
-  __ movups(result, FieldAddress(value, Int32x4::value_offset()));
-}
-
-
-
 LocationSummary* BinaryDoubleOpInstr::MakeLocationSummary(Isolate* isolate,
                                                           bool opt) const {
   const intptr_t kNumInputs = 2;
@@ -5395,7 +5500,7 @@
 
 LocationSummary* PolymorphicInstanceCallInstr::MakeLocationSummary(
     Isolate* isolate, bool opt) const {
-  return MakeCallSummary();
+  return MakeCallSummary(isolate);
 }
 
 
@@ -5643,128 +5748,6 @@
 }
 
 
-LocationSummary* UnboxIntegerInstr::MakeLocationSummary(Isolate* isolate,
-                                                        bool opt) const {
-  const intptr_t kNumInputs = 1;
-  const intptr_t kNumTemps = 0;
-  LocationSummary* summary = new(isolate) LocationSummary(
-      isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall);
-  summary->set_in(0, Location::RequiresRegister());
-  summary->set_out(0, Location::Pair(Location::RegisterLocation(EAX),
-                                     Location::RegisterLocation(EDX)));
-  return summary;
-}
-
-
-void UnboxIntegerInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
-  const intptr_t value_cid = value()->Type()->ToCid();
-  const Register value = locs()->in(0).reg();
-  PairLocation* result_pair = locs()->out(0).AsPairLocation();
-  Register result_lo = result_pair->At(0).reg();
-  Register result_hi = result_pair->At(1).reg();
-
-  ASSERT(value != result_lo);
-  ASSERT(value != result_hi);
-  ASSERT(result_lo == EAX);
-  ASSERT(result_hi == EDX);
-
-  if (value_cid == kMintCid) {
-    __ movl(result_lo, FieldAddress(value, Mint::value_offset()));
-    __ movl(result_hi, FieldAddress(value, Mint::value_offset() + kWordSize));
-  } else if (value_cid == kSmiCid) {
-    __ movl(result_lo, value);
-    __ SmiUntag(result_lo);
-    // Sign extend into result_hi.
-    __ cdq();
-  } else {
-    Label* deopt = compiler->AddDeoptStub(GetDeoptId(),
-                                          ICData::kDeoptUnboxInteger);
-    Label is_smi, done;
-    __ testl(value, Immediate(kSmiTagMask));
-    __ j(ZERO, &is_smi);
-    __ CompareClassId(value, kMintCid, result_lo);
-    __ j(NOT_EQUAL, deopt);
-    __ movl(result_lo, FieldAddress(value, Mint::value_offset()));
-    __ movl(result_hi, FieldAddress(value, Mint::value_offset() + kWordSize));
-    __ jmp(&done);
-    __ Bind(&is_smi);
-    __ movl(result_lo, value);
-    __ SmiUntag(result_lo);
-    // Sign extend into result_hi.
-    __ cdq();
-    __ Bind(&done);
-  }
-}
-
-
-LocationSummary* BoxIntegerInstr::MakeLocationSummary(Isolate* isolate,
-                                                      bool opt) const {
-  const intptr_t kNumInputs = 1;
-  const intptr_t kNumTemps = is_smi() ? 0 : 1;
-  LocationSummary* summary = new(isolate) LocationSummary(
-      isolate, kNumInputs,
-                          kNumTemps,
-                          is_smi()
-                              ? LocationSummary::kNoCall
-                              : LocationSummary::kCallOnSlowPath);
-  summary->set_in(0, Location::Pair(Location::RequiresRegister(),
-                                    Location::RequiresRegister()));
-  if (!is_smi()) {
-    summary->set_temp(0, Location::RequiresRegister());
-  }
-  summary->set_out(0, Location::RequiresRegister());
-  return summary;
-}
-
-
-void BoxIntegerInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
-  if (is_smi()) {
-    PairLocation* value_pair = locs()->in(0).AsPairLocation();
-    Register value_lo = value_pair->At(0).reg();
-    Register out_reg = locs()->out(0).reg();
-    __ movl(out_reg, value_lo);
-    __ SmiTag(out_reg);
-    return;
-  }
-
-  PairLocation* value_pair = locs()->in(0).AsPairLocation();
-  Register value_lo = value_pair->At(0).reg();
-  Register value_hi = value_pair->At(1).reg();
-  Register out_reg = locs()->out(0).reg();
-
-  // Copy value_hi into out_reg as a temporary.
-  // We modify value_lo but restore it before using it.
-  __ movl(out_reg, value_hi);
-
-  // Unboxed operations produce smis or mint-sized values.
-  // Check if value fits into a smi.
-  Label not_smi, done;
-
-  // 1. Compute (x + -kMinSmi) which has to be in the range
-  //    0 .. -kMinSmi+kMaxSmi for x to fit into a smi.
-  __ addl(value_lo, Immediate(0x40000000));
-  __ adcl(out_reg, Immediate(0));
-  // 2. Unsigned compare to -kMinSmi+kMaxSmi.
-  __ cmpl(value_lo, Immediate(0x80000000));
-  __ sbbl(out_reg, Immediate(0));
-  __ j(ABOVE_EQUAL, &not_smi);
-  // 3. Restore lower half if result is a smi.
-  __ subl(value_lo, Immediate(0x40000000));
-  __ movl(out_reg, value_lo);
-  __ SmiTag(out_reg);
-  __ jmp(&done);
-  __ Bind(&not_smi);
-  // 3. Restore lower half of input before using it.
-  __ subl(value_lo, Immediate(0x40000000));
-
-  BoxAllocationSlowPath::Allocate(
-      compiler, this, compiler->mint_class(), out_reg, kNoRegister);
-  __ movl(FieldAddress(out_reg, Mint::value_offset()), value_lo);
-  __ movl(FieldAddress(out_reg, Mint::value_offset() + kWordSize), value_hi);
-  __ Bind(&done);
-}
-
-
 LocationSummary* BinaryMintOpInstr::MakeLocationSummary(Isolate* isolate,
                                                         bool opt) const {
   const intptr_t kNumInputs = 2;
@@ -6221,148 +6204,6 @@
 }
 
 
-LocationSummary* BoxIntNInstr::MakeLocationSummary(Isolate* isolate,
-                                                    bool opt) const {
-  const intptr_t kNumInputs = 1;
-  const intptr_t kNumTemps = 0;
-  LocationSummary* summary = new(isolate) LocationSummary(
-      isolate, kNumInputs, kNumTemps,
-      ValueFitsSmi() ? LocationSummary::kNoCall
-                     : LocationSummary::kCallOnSlowPath);
-  const bool needs_writable_input = ValueFitsSmi() ||
-      (from_representation() == kUnboxedUint32);
-  summary->set_in(0, needs_writable_input ? Location::RequiresRegister()
-                                          : Location::WritableRegister());
-  summary->set_out(0, ValueFitsSmi() ? Location::SameAsFirstInput()
-                                     : Location::RequiresRegister());
-  return summary;
-}
-
-
-void BoxIntNInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
-  const Register value = locs()->in(0).reg();
-  const Register out = locs()->out(0).reg();
-
-  __ MoveRegister(out, value);
-  __ shll(out, Immediate(kSmiTagSize));
-  if (!ValueFitsSmi()) {
-    Label done;
-    ASSERT(value != out);
-    if (from_representation() == kUnboxedInt32) {
-      __ j(NO_OVERFLOW, &done);
-    } else {
-      __ testl(value, Immediate(0xC0000000));
-      __ j(ZERO, &done);
-    }
-
-    // Allocate a mint.
-    // Value input is writable register and has to be manually preserved
-    // on the slow path.
-    locs()->live_registers()->Add(locs()->in(0), kUnboxedInt32);
-    BoxAllocationSlowPath::Allocate(
-        compiler, this, compiler->mint_class(), out, kNoRegister);
-    __ movl(FieldAddress(out, Mint::value_offset()), value);
-    if (from_representation() == kUnboxedInt32) {
-      __ sarl(value, Immediate(31));  // Sign extend.
-      __ movl(FieldAddress(out, Mint::value_offset() + kWordSize), value);
-    } else {
-      __ movl(FieldAddress(out, Mint::value_offset() + kWordSize),
-              Immediate(0));
-    }
-    __ Bind(&done);
-  }
-}
-
-
-LocationSummary* UnboxIntNInstr::MakeLocationSummary(Isolate* isolate,
-                                                       bool opt) const {
-  const intptr_t value_cid = value()->Type()->ToCid();
-  const intptr_t kNumInputs = 1;
-  intptr_t kNumTemps = 0;
-
-  if (CanDeoptimize()) {
-    if ((value_cid != kSmiCid) &&
-        (value_cid != kMintCid) &&
-        !is_truncating()) {
-      kNumTemps = 2;
-    } else {
-      kNumTemps = 1;
-    }
-  }
-
-  LocationSummary* summary = new(isolate) LocationSummary(
-      isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall);
-  summary->set_in(0, Location::RequiresRegister());
-  for (int i = 0; i < kNumTemps; i++) {
-    summary->set_temp(i, Location::RequiresRegister());
-  }
-  summary->set_out(0, ((value_cid == kSmiCid) || (value_cid != kMintCid)) ?
-      Location::SameAsFirstInput() : Location::RequiresRegister());
-  return summary;
-}
-
-
-static void LoadInt32FromMint(FlowGraphCompiler* compiler,
-                              Register result,
-                              const Address& lo,
-                              const Address& hi,
-                              Register temp,
-                              Label* deopt) {
-  __ movl(result, lo);
-  if (deopt != NULL) {
-    ASSERT(temp != result);
-    __ movl(temp, result);
-    __ sarl(temp, Immediate(31));
-    __ cmpl(temp, hi);
-    __ j(NOT_EQUAL, deopt);
-  }
-}
-
-
-void UnboxIntNInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
-  const intptr_t value_cid = value()->Type()->ToCid();
-  Register value = locs()->in(0).reg();
-  const Register result = locs()->out(0).reg();
-  const Register temp = CanDeoptimize() ? locs()->temp(0).reg() : kNoRegister;
-  Label* deopt = CanDeoptimize() ?
-      compiler->AddDeoptStub(GetDeoptId(), ICData::kDeoptUnboxInteger) : NULL;
-  Label* out_of_range = !is_truncating() ? deopt : NULL;
-
-  const intptr_t lo_offset = Mint::value_offset();
-  const intptr_t hi_offset = Mint::value_offset() + kWordSize;
-
-  if (value_cid == kSmiCid) {
-    ASSERT(value == result);
-    __ SmiUntag(value);
-  } else if (value_cid == kMintCid) {
-    ASSERT((value != result) || (out_of_range == NULL));
-    LoadInt32FromMint(compiler,
-                      result,
-                      FieldAddress(value, lo_offset),
-                      FieldAddress(value, hi_offset),
-                      temp,
-                      out_of_range);
-  } else {
-    ASSERT(value == result);
-    Label done;
-    __ SmiUntagOrCheckClass(value, kMintCid, temp, &done);
-    __ j(NOT_EQUAL, deopt);
-    if (out_of_range != NULL) {
-      Register value_temp = locs()->temp(1).reg();
-      __ movl(value_temp, value);
-      value = value_temp;
-    }
-    LoadInt32FromMint(compiler,
-                      result,
-                      Address(value, TIMES_2, lo_offset),
-                      Address(value, TIMES_2, hi_offset),
-                      temp,
-                      out_of_range);
-    __ Bind(&done);
-  }
-}
-
-
 LocationSummary* UnboxedIntConverterInstr::MakeLocationSummary(Isolate* isolate,
                                                                bool opt) const {
   const intptr_t kNumInputs = 1;
@@ -6407,7 +6248,7 @@
     }
   } else if (from() == kUnboxedMint) {
     // TODO(vegorov) kUnboxedMint -> kInt32 conversion is currently usually
-    // dominated by a CheckSmi(BoxInteger(val)) which is an artifact of ordering
+    // dominated by a CheckSmi(BoxInt64(val)) which is an artifact of ordering
     // of optimization passes and the way we check smi-ness of values.
     // Optimize it away.
     ASSERT(to() == kUnboxedInt32 || to() == kUnboxedUint32);
@@ -6740,7 +6581,7 @@
 
 LocationSummary* AllocateObjectInstr::MakeLocationSummary(Isolate* isolate,
                                                           bool opt) const {
-  return MakeCallSummary();
+  return MakeCallSummary(isolate);
 }
 
 
@@ -6766,7 +6607,6 @@
   compiler->GenerateCall(token_pos(), &label, stub_kind_, locs());
 #if defined(DEBUG)
   __ movl(EDX, Immediate(kInvalidObjectPointer));
-  __ movl(EDX, Immediate(kInvalidObjectPointer));
 #endif
 }
 
diff --git a/runtime/vm/intermediate_language_mips.cc b/runtime/vm/intermediate_language_mips.cc
index f23a56e..46b2555 100644
--- a/runtime/vm/intermediate_language_mips.cc
+++ b/runtime/vm/intermediate_language_mips.cc
@@ -30,8 +30,7 @@
 
 // Generic summary for call instructions that have all arguments pushed
 // on the stack and return the result in a fixed register V0.
-LocationSummary* Instruction::MakeCallSummary() {
-  Isolate* isolate = Isolate::Current();
+LocationSummary* Instruction::MakeCallSummary(Isolate* isolate) {
   LocationSummary* result = new(isolate) LocationSummary(
       isolate, 0, 0, LocationSummary::kCall);
   result->set_out(0, Location::RegisterLocation(V0));
@@ -876,23 +875,12 @@
 
 LocationSummary* NativeCallInstr::MakeLocationSummary(Isolate* isolate,
                                                       bool opt) const {
-  const intptr_t kNumInputs = 0;
-  const intptr_t kNumTemps = 3;
-  LocationSummary* locs = new(isolate) LocationSummary(
-      isolate, kNumInputs, kNumTemps, LocationSummary::kCall);
-  locs->set_temp(0, Location::RegisterLocation(A1));
-  locs->set_temp(1, Location::RegisterLocation(A2));
-  locs->set_temp(2, Location::RegisterLocation(T5));
-  locs->set_out(0, Location::RegisterLocation(V0));
-  return locs;
+  return MakeCallSummary(isolate);
 }
 
 
 void NativeCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
   __ TraceSimMsg("NativeCallInstr");
-  ASSERT(locs()->temp(0).reg() == A1);
-  ASSERT(locs()->temp(1).reg() == A2);
-  ASSERT(locs()->temp(2).reg() == T5);
   Register result = locs()->out(0).reg();
 
   // Push the result place holder initialized to NULL.
@@ -3077,14 +3065,12 @@
 }
 
 
-LocationSummary* BoxDoubleInstr::MakeLocationSummary(Isolate* isolate,
+LocationSummary* BoxInstr::MakeLocationSummary(Isolate* isolate,
                                                      bool opt) const {
   const intptr_t kNumInputs = 1;
   const intptr_t kNumTemps = 1;
   LocationSummary* summary = new(isolate) LocationSummary(
-      isolate, kNumInputs,
-                          kNumTemps,
-                          LocationSummary::kCallOnSlowPath);
+      isolate, kNumInputs, kNumTemps, LocationSummary::kCallOnSlowPath);
   summary->set_in(0, Location::RequiresFpuRegister());
   summary->set_temp(0, Location::RequiresRegister());
   summary->set_out(0, Location::RequiresRegister());
@@ -3092,7 +3078,9 @@
 }
 
 
-void BoxDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+void BoxInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+  ASSERT(from_representation() == kUnboxedDouble);
+
   Register out_reg = locs()->out(0).reg();
   DRegister value = locs()->in(0).fpu_reg();
 
@@ -3102,7 +3090,7 @@
 }
 
 
-LocationSummary* UnboxDoubleInstr::MakeLocationSummary(Isolate* isolate,
+LocationSummary* UnboxInstr::MakeLocationSummary(Isolate* isolate,
                                                        bool opt) const {
   const intptr_t kNumInputs = 1;
   const intptr_t kNumTemps = 0;
@@ -3114,116 +3102,209 @@
 }
 
 
-void UnboxDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
-  CompileType* value_type = value()->Type();
-  const intptr_t value_cid = value_type->ToCid();
-  const Register value = locs()->in(0).reg();
-  const DRegister result = locs()->out(0).fpu_reg();
+void UnboxInstr::EmitLoadFromBox(FlowGraphCompiler* compiler) {
+  const Register box = locs()->in(0).reg();
 
-  if (value_cid == kDoubleCid) {
-    __ LoadDFromOffset(result, value, Double::value_offset() - kHeapObjectTag);
-  } else if (value_cid == kSmiCid) {
-    __ SmiUntag(TMP, value);
-    __ mtc1(TMP, STMP1);
-    __ cvtdw(result, STMP1);
-  } else {
-    Label* deopt = compiler->AddDeoptStub(GetDeoptId(),
-                                          ICData::kDeoptBinaryDoubleOp);
-    if (value_type->is_nullable() &&
-        (value_type->ToNullableCid() == kDoubleCid)) {
-      __ BranchEqual(value, Object::null_object(), deopt);
-      // It must be double now.
-      __ LoadDFromOffset(result, value,
-          Double::value_offset() - kHeapObjectTag);
-    } else {
-      Label is_smi, done;
+  switch (representation()) {
+    case kUnboxedMint: {
+      UNIMPLEMENTED();
+      break;
+    }
 
-      __ andi(CMPRES1, value, Immediate(kSmiTagMask));
-      __ beq(CMPRES1, ZR, &is_smi);
-      __ LoadClassId(CMPRES1, value);
-      __ BranchNotEqual(CMPRES1, Immediate(kDoubleCid), deopt);
-      __ LoadDFromOffset(result, value,
-          Double::value_offset() - kHeapObjectTag);
-      __ b(&done);
-      __ Bind(&is_smi);
-      __ SmiUntag(TMP, value);
+    case kUnboxedDouble: {
+      const DRegister result = locs()->out(0).fpu_reg();
+      __ LoadDFromOffset(result, box, Double::value_offset() - kHeapObjectTag);
+      break;
+    }
+
+    case kUnboxedFloat32x4:
+    case kUnboxedFloat64x2:
+    case kUnboxedInt32x4: {
+      UNIMPLEMENTED();
+      break;
+    }
+
+    default:
+      UNREACHABLE();
+      break;
+  }
+}
+
+
+void UnboxInstr::EmitSmiConversion(FlowGraphCompiler* compiler) {
+  const Register box = locs()->in(0).reg();
+
+  switch (representation()) {
+    case kUnboxedMint: {
+      UNIMPLEMENTED();
+      break;
+    }
+
+    case kUnboxedDouble: {
+      const DRegister result = locs()->out(0).fpu_reg();
+      __ SmiUntag(TMP, box);
       __ mtc1(TMP, STMP1);
       __ cvtdw(result, STMP1);
+      break;
+    }
+
+    default:
+      UNREACHABLE();
+      break;
+  }
+}
+
+
+void UnboxInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+  const intptr_t value_cid = value()->Type()->ToCid();
+  const intptr_t box_cid = BoxCid();
+
+  if (value_cid == box_cid) {
+    EmitLoadFromBox(compiler);
+  } else if (CanConvertSmi() && (value_cid == kSmiCid)) {
+    EmitSmiConversion(compiler);
+  } else {
+    const Register box = locs()->in(0).reg();
+    Label* deopt = compiler->AddDeoptStub(GetDeoptId(),
+                                          ICData::kDeoptCheckClass);
+    Label is_smi;
+
+    if ((value()->Type()->ToNullableCid() == box_cid) &&
+        value()->Type()->is_nullable()) {
+      __ BranchEqual(box, Object::null_object(), deopt);
+    } else {
+      __ andi(CMPRES1, box, Immediate(kSmiTagMask));
+      __ beq(CMPRES1, ZR, CanConvertSmi() ? &is_smi : deopt);
+      __ LoadClassId(CMPRES1, box);
+      __ BranchNotEqual(CMPRES1, Immediate(box_cid), deopt);
+    }
+
+    EmitLoadFromBox(compiler);
+
+    if (is_smi.IsLinked()) {
+      Label done;
+      __ b(&done);
+      __ Bind(&is_smi);
+      EmitSmiConversion(compiler);
       __ Bind(&done);
     }
   }
 }
 
 
-LocationSummary* BoxFloat32x4Instr::MakeLocationSummary(Isolate* isolate,
+LocationSummary* BoxInteger32Instr::MakeLocationSummary(Isolate* isolate,
                                                         bool opt) const {
-  UNIMPLEMENTED();
-  return NULL;
+  ASSERT((from_representation() == kUnboxedInt32) ||
+         (from_representation() == kUnboxedUint32));
+  const intptr_t kNumInputs = 1;
+  const intptr_t kNumTemps = 1;
+  LocationSummary* summary = new(isolate) LocationSummary(
+      isolate, kNumInputs, kNumTemps, LocationSummary::kCallOnSlowPath);
+  summary->set_in(0, Location::RequiresRegister());
+  summary->set_temp(0, Location::RequiresRegister());
+  summary->set_out(0, Location::RequiresRegister());
+  return summary;
 }
 
 
-void BoxFloat32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) {
-  UNIMPLEMENTED();
+void BoxInteger32Instr::EmitNativeCode(FlowGraphCompiler* compiler) {
+  Register value = locs()->in(0).reg();
+  Register out = locs()->out(0).reg();
+  ASSERT(value != out);
+
+  Label done;
+  __ SmiTag(out, value);
+  if (!ValueFitsSmi()) {
+    Register temp = locs()->temp(0).reg();
+    if (from_representation() == kUnboxedInt32) {
+      __ SmiUntag(CMPRES1, out);
+      __ BranchEqual(CMPRES1, value, &done);
+    } else {
+      ASSERT(from_representation() == kUnboxedUint32);
+      __ AndImmediate(CMPRES1, value, 0xC0000000);
+      __ BranchEqual(CMPRES1, ZR, &done);
+    }
+    BoxAllocationSlowPath::Allocate(
+        compiler,
+        this,
+        compiler->mint_class(),
+        out,
+        temp);
+    Register hi;
+    if (from_representation() == kUnboxedInt32) {
+      hi = temp;
+      __ sra(hi, value, kBitsPerWord - 1);
+    } else {
+      ASSERT(from_representation() == kUnboxedUint32);
+      hi = ZR;
+    }
+    __ StoreToOffset(value,
+                     out,
+                     Mint::value_offset() - kHeapObjectTag);
+    __ StoreToOffset(hi,
+                     out,
+                     Mint::value_offset() - kHeapObjectTag + kWordSize);
+    __ Bind(&done);
+  }
 }
 
 
-LocationSummary* UnboxFloat32x4Instr::MakeLocationSummary(Isolate* isolate,
+DEFINE_UNIMPLEMENTED_INSTRUCTION(BoxInt64Instr);
+
+LocationSummary* UnboxInteger32Instr::MakeLocationSummary(Isolate* isolate,
                                                           bool opt) const {
-  UNIMPLEMENTED();
-  return NULL;
+  ASSERT((representation() == kUnboxedInt32) ||
+         (representation() == kUnboxedUint32));
+  const intptr_t kNumInputs = 1;
+  const intptr_t kNumTemps = 0;
+  LocationSummary* summary = new(isolate) LocationSummary(
+      isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall);
+  summary->set_in(0, Location::RequiresRegister());
+  summary->set_out(0, Location::RequiresRegister());
+  return summary;
 }
 
 
-void UnboxFloat32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) {
-  UNIMPLEMENTED();
+static void LoadInt32FromMint(FlowGraphCompiler* compiler,
+                              Register mint,
+                              Register result,
+                              Label* deopt) {
+  __ LoadFromOffset(result,
+                    mint,
+                    Mint::value_offset() - kHeapObjectTag);
+  if (deopt != NULL) {
+    __ LoadFromOffset(CMPRES1,
+                      mint,
+                      Mint::value_offset() - kHeapObjectTag + kWordSize);
+    __ sra(CMPRES2, result, kBitsPerWord - 1);
+    __ BranchNotEqual(CMPRES1, CMPRES2, deopt);
+  }
 }
 
 
-LocationSummary* BoxFloat64x2Instr::MakeLocationSummary(Isolate* isolate,
-                                                        bool opt) const {
-  UNIMPLEMENTED();
-  return NULL;
-}
+void UnboxInteger32Instr::EmitNativeCode(FlowGraphCompiler* compiler) {
+  const intptr_t value_cid = value()->Type()->ToCid();
+  const Register value = locs()->in(0).reg();
+  const Register out = locs()->out(0).reg();
+  Label* deopt = CanDeoptimize() ?
+        compiler->AddDeoptStub(GetDeoptId(), ICData::kDeoptUnboxInteger) : NULL;
+  Label* out_of_range = !is_truncating() ? deopt : NULL;
+  ASSERT(value != out);
 
-
-void BoxFloat64x2Instr::EmitNativeCode(FlowGraphCompiler* compiler) {
-  UNIMPLEMENTED();
-}
-
-
-LocationSummary* UnboxFloat64x2Instr::MakeLocationSummary(Isolate* isolate,
-                                                          bool opt) const {
-  UNIMPLEMENTED();
-  return NULL;
-}
-
-
-void UnboxFloat64x2Instr::EmitNativeCode(FlowGraphCompiler* compiler) {
-  UNIMPLEMENTED();
-}
-
-
-LocationSummary* BoxInt32x4Instr::MakeLocationSummary(Isolate* isolate,
-                                                      bool opt) const {
-  UNIMPLEMENTED();
-  return NULL;
-}
-
-
-void BoxInt32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) {
-  UNIMPLEMENTED();
-}
-
-
-LocationSummary* UnboxInt32x4Instr::MakeLocationSummary(Isolate* isolate,
-                                                        bool opt) const {
-  UNIMPLEMENTED();
-  return NULL;
-}
-
-
-void UnboxInt32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) {
-  UNIMPLEMENTED();
+  if (value_cid == kSmiCid) {
+    __ SmiUntag(out, value);
+  } else if (value_cid == kMintCid) {
+    LoadInt32FromMint(compiler, value, out, out_of_range);
+  } else {
+    Label done;
+    __ SmiUntag(out, value);
+    __ andi(CMPRES1, value, Immediate(kSmiTagMask));
+    __ beq(CMPRES1, ZR, &done);
+    __ LoadClassId(CMPRES1, value);
+    __ BranchNotEqual(CMPRES1, Immediate(kMintCid), deopt);
+    LoadInt32FromMint(compiler, value, out, out_of_range);
+    __ Bind(&done);
+  }
 }
 
 
@@ -4265,7 +4346,7 @@
 
 LocationSummary* PolymorphicInstanceCallInstr::MakeLocationSummary(
     Isolate* isolate, bool opt) const {
-  return MakeCallSummary();
+  return MakeCallSummary(isolate);
 }
 
 
@@ -4490,72 +4571,15 @@
   }
 }
 
-
-LocationSummary* UnboxIntegerInstr::MakeLocationSummary(Isolate* isolate,
-                                                        bool opt) const {
-  UNIMPLEMENTED();
-  return NULL;
-}
-
-
-void UnboxIntegerInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
-  UNIMPLEMENTED();
-}
-
-
-LocationSummary* BoxIntegerInstr::MakeLocationSummary(Isolate* isolate,
-                                                      bool opt) const {
-  UNIMPLEMENTED();
-  return NULL;
-}
-
-
-void BoxIntegerInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
-  UNIMPLEMENTED();
-}
-
-
-LocationSummary* BinaryMintOpInstr::MakeLocationSummary(Isolate* isolate,
-                                                        bool opt) const {
-  UNIMPLEMENTED();
-  return NULL;
-}
-
-
-void BinaryMintOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
-  UNIMPLEMENTED();
-}
-
+DEFINE_UNIMPLEMENTED_INSTRUCTION(BinaryMintOpInstr);
 
 bool ShiftMintOpInstr::has_shift_count_check() const {
   UNREACHABLE();
   return false;
 }
 
-
-LocationSummary* ShiftMintOpInstr::MakeLocationSummary(Isolate* isolate,
-                                                       bool opt) const {
-  UNIMPLEMENTED();
-  return NULL;
-}
-
-
-void ShiftMintOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
-  UNIMPLEMENTED();
-}
-
-
-LocationSummary* UnaryMintOpInstr::MakeLocationSummary(Isolate* isolate,
-                                                       bool opt) const {
-  UNIMPLEMENTED();
-  return NULL;
-}
-
-
-void UnaryMintOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
-  UNIMPLEMENTED();
-}
-
+DEFINE_UNIMPLEMENTED_INSTRUCTION(ShiftMintOpInstr);
+DEFINE_UNIMPLEMENTED_INSTRUCTION(UnaryMintOpInstr);
 
 CompileType BinaryUint32OpInstr::ComputeType() const {
   return CompileType::Int();
@@ -4578,120 +4602,6 @@
 DEFINE_UNIMPLEMENTED_INSTRUCTION(BinaryInt32OpInstr)
 
 
-LocationSummary* BoxIntNInstr::MakeLocationSummary(Isolate* isolate,
-                                                   bool opt) const {
-  ASSERT((from_representation() == kUnboxedInt32) ||
-         (from_representation() == kUnboxedUint32));
-  const intptr_t kNumInputs = 1;
-  const intptr_t kNumTemps = 1;
-  LocationSummary* summary = new(isolate) LocationSummary(
-      isolate, kNumInputs, kNumTemps, LocationSummary::kCallOnSlowPath);
-  summary->set_in(0, Location::RequiresRegister());
-  summary->set_temp(0, Location::RequiresRegister());
-  summary->set_out(0, Location::RequiresRegister());
-  return summary;
-}
-
-
-void BoxIntNInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
-  Register value = locs()->in(0).reg();
-  Register out = locs()->out(0).reg();
-  ASSERT(value != out);
-
-  Label done;
-  __ SmiTag(out, value);
-  if (!ValueFitsSmi()) {
-    Register temp = locs()->temp(0).reg();
-    if (from_representation() == kUnboxedInt32) {
-      __ SmiUntag(CMPRES1, out);
-      __ BranchEqual(CMPRES1, value, &done);
-    } else {
-      ASSERT(from_representation() == kUnboxedUint32);
-      __ AndImmediate(CMPRES1, value, 0xC0000000);
-      __ BranchEqual(CMPRES1, ZR, &done);
-    }
-    BoxAllocationSlowPath::Allocate(
-        compiler,
-        this,
-        compiler->mint_class(),
-        out,
-        temp);
-    Register hi;
-    if (from_representation() == kUnboxedInt32) {
-      hi = temp;
-      __ sra(hi, value, kBitsPerWord - 1);
-    } else {
-      ASSERT(from_representation() == kUnboxedUint32);
-      hi = ZR;
-    }
-    __ StoreToOffset(value,
-                     out,
-                     Mint::value_offset() - kHeapObjectTag);
-    __ StoreToOffset(hi,
-                     out,
-                     Mint::value_offset() - kHeapObjectTag + kWordSize);
-    __ Bind(&done);
-  }
-}
-
-
-LocationSummary* UnboxIntNInstr::MakeLocationSummary(Isolate* isolate,
-                                                      bool opt) const {
-  ASSERT((representation() == kUnboxedInt32) ||
-         (representation() == kUnboxedUint32));
-  const intptr_t kNumInputs = 1;
-  const intptr_t kNumTemps = 0;
-  LocationSummary* summary = new(isolate) LocationSummary(
-      isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall);
-  summary->set_in(0, Location::RequiresRegister());
-  summary->set_out(0, Location::RequiresRegister());
-  return summary;
-}
-
-
-static void LoadInt32FromMint(FlowGraphCompiler* compiler,
-                              Register mint,
-                              Register result,
-                              Label* deopt) {
-  __ LoadFromOffset(result,
-                    mint,
-                    Mint::value_offset() - kHeapObjectTag);
-  if (deopt != NULL) {
-    __ LoadFromOffset(CMPRES1,
-                      mint,
-                      Mint::value_offset() - kHeapObjectTag + kWordSize);
-    __ sra(CMPRES2, result, kBitsPerWord - 1);
-    __ BranchNotEqual(CMPRES1, CMPRES2, deopt);
-  }
-}
-
-
-void UnboxIntNInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
-  const intptr_t value_cid = value()->Type()->ToCid();
-  const Register value = locs()->in(0).reg();
-  const Register out = locs()->out(0).reg();
-  Label* deopt = CanDeoptimize() ?
-        compiler->AddDeoptStub(GetDeoptId(), ICData::kDeoptUnboxInteger) : NULL;
-  Label* out_of_range = !is_truncating() ? deopt : NULL;
-  ASSERT(value != out);
-
-  if (value_cid == kSmiCid) {
-    __ SmiUntag(out, value);
-  } else if (value_cid == kMintCid) {
-    LoadInt32FromMint(compiler, value, out, out_of_range);
-  } else {
-    Label done;
-    __ SmiUntag(out, value);
-    __ andi(CMPRES1, value, Immediate(kSmiTagMask));
-    __ beq(CMPRES1, ZR, &done);
-    __ LoadClassId(CMPRES1, value);
-    __ BranchNotEqual(CMPRES1, Immediate(kMintCid), deopt);
-    LoadInt32FromMint(compiler, value, out, out_of_range);
-    __ Bind(&done);
-  }
-}
-
-
 LocationSummary* UnboxedIntConverterInstr::MakeLocationSummary(Isolate* isolate,
                                                                bool opt) const {
   const intptr_t kNumInputs = 1;
@@ -4916,7 +4826,7 @@
 
 LocationSummary* AllocateObjectInstr::MakeLocationSummary(Isolate* isolate,
                                                           bool opt) const {
-  return MakeCallSummary();
+  return MakeCallSummary(isolate);
 }
 
 
diff --git a/runtime/vm/intermediate_language_x64.cc b/runtime/vm/intermediate_language_x64.cc
index 1167b3a..0616adb 100644
--- a/runtime/vm/intermediate_language_x64.cc
+++ b/runtime/vm/intermediate_language_x64.cc
@@ -30,8 +30,8 @@
 
 // Generic summary for call instructions that have all arguments pushed
 // on the stack and return the result in a fixed register RAX.
-LocationSummary* Instruction::MakeCallSummary() {
-  LocationSummary* result = new LocationSummary(
+LocationSummary* Instruction::MakeCallSummary(Isolate* isolate) {
+  LocationSummary* result = new(isolate) LocationSummary(
       Isolate::Current(), 0, 0, LocationSummary::kCall);
   result->set_out(0, Location::RegisterLocation(RAX));
   return result;
@@ -752,22 +752,11 @@
 
 LocationSummary* NativeCallInstr::MakeLocationSummary(Isolate* isolate,
                                                       bool opt) const {
-  const intptr_t kNumInputs = 0;
-  const intptr_t kNumTemps = 3;
-  LocationSummary* locs = new(isolate) LocationSummary(
-      isolate, kNumInputs, kNumTemps, LocationSummary::kCall);
-  locs->set_temp(0, Location::RegisterLocation(RAX));
-  locs->set_temp(1, Location::RegisterLocation(RBX));
-  locs->set_temp(2, Location::RegisterLocation(R10));
-  locs->set_out(0, Location::RegisterLocation(RAX));
-  return locs;
+  return MakeCallSummary(isolate);
 }
 
 
 void NativeCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
-  ASSERT(locs()->temp(0).reg() == RAX);
-  ASSERT(locs()->temp(1).reg() == RBX);
-  ASSERT(locs()->temp(2).reg() == R10);
   Register result = locs()->out(0).reg();
   const intptr_t argc_tag = NativeArguments::ComputeArgcTag(function());
   const bool is_leaf_call =
@@ -3194,239 +3183,267 @@
 }
 
 
-LocationSummary* BoxDoubleInstr::MakeLocationSummary(Isolate* isolate,
+LocationSummary* BoxInstr::MakeLocationSummary(Isolate* isolate,
                                                      bool opt) const {
   const intptr_t kNumInputs = 1;
   const intptr_t kNumTemps = 0;
   LocationSummary* summary = new(isolate) LocationSummary(
-      isolate, kNumInputs,
-                          kNumTemps,
-                          LocationSummary::kCallOnSlowPath);
+      isolate, kNumInputs, kNumTemps, LocationSummary::kCallOnSlowPath);
   summary->set_in(0, Location::RequiresFpuRegister());
   summary->set_out(0, Location::RequiresRegister());
   return summary;
 }
 
 
-void BoxDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+void BoxInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
   Register out_reg = locs()->out(0).reg();
   XmmRegister value = locs()->in(0).fpu_reg();
 
   BoxAllocationSlowPath::Allocate(
-      compiler, this, compiler->double_class(), out_reg);
+      compiler, this, compiler->BoxClassFor(from_representation()), out_reg);
   __ movsd(FieldAddress(out_reg, Double::value_offset()), value);
+  switch (from_representation()) {
+    case kUnboxedDouble:
+      __ movsd(FieldAddress(out_reg, ValueOffset()), value);
+      break;
+    case kUnboxedFloat32x4:
+    case kUnboxedFloat64x2:
+    case kUnboxedInt32x4:
+      __ movups(FieldAddress(out_reg, ValueOffset()), value);
+      break;
+    default:
+      UNREACHABLE();
+      break;
+  }
 }
 
 
-LocationSummary* UnboxDoubleInstr::MakeLocationSummary(Isolate* isolate,
-                                                       bool opt) const {
+LocationSummary* UnboxInstr::MakeLocationSummary(Isolate* isolate,
+                                                 bool opt) const {
   const intptr_t kNumInputs = 1;
   const intptr_t kNumTemps = 0;
+  const bool needs_writable_input =
+      (representation() != kUnboxedMint) &&
+      (value()->Type()->ToNullableCid() != BoxCid());
   LocationSummary* summary = new(isolate) LocationSummary(
       isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall);
-  const bool needs_writable_input = (value()->Type()->ToCid() != kDoubleCid);
-  summary->set_in(0, needs_writable_input
-                     ? Location::WritableRegister()
-                     : Location::RequiresRegister());
-  summary->set_out(0, Location::RequiresFpuRegister());
+  summary->set_in(0, needs_writable_input ? Location::WritableRegister()
+                                          : Location::RequiresRegister());
+  if (representation() == kUnboxedMint) {
+    summary->set_out(0, Location::SameAsFirstInput());
+  } else {
+    summary->set_out(0, Location::RequiresFpuRegister());
+  }
   return summary;
 }
 
 
-void UnboxDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
-  CompileType* value_type = value()->Type();
-  const intptr_t value_cid = value_type->ToCid();
-  const Register value = locs()->in(0).reg();
-  const XmmRegister result = locs()->out(0).fpu_reg();
+void UnboxInstr::EmitLoadFromBox(FlowGraphCompiler* compiler) {
+  const Register box = locs()->in(0).reg();
 
-  if (value_cid == kDoubleCid) {
-    __ movsd(result, FieldAddress(value, Double::value_offset()));
-  } else if (value_cid == kSmiCid) {
-    __ SmiUntag(value);  // Untag input before conversion.
-    __ cvtsi2sdq(result, value);
+  switch (representation()) {
+    case kUnboxedMint: {
+      const Register result = locs()->out(0).reg();
+      __ movq(result, FieldAddress(box, ValueOffset()));
+      break;
+    }
+
+    case kUnboxedDouble: {
+      const FpuRegister result = locs()->out(0).fpu_reg();
+      __ movsd(result, FieldAddress(box, ValueOffset()));
+      break;
+    }
+
+    case kUnboxedFloat32x4:
+    case kUnboxedFloat64x2:
+    case kUnboxedInt32x4: {
+      const FpuRegister result = locs()->out(0).fpu_reg();
+      __ movups(result, FieldAddress(box, ValueOffset()));
+      break;
+    }
+
+    default:
+      UNREACHABLE();
+      break;
+  }
+}
+
+
+void UnboxInstr::EmitSmiConversion(FlowGraphCompiler* compiler) {
+  const Register box = locs()->in(0).reg();
+
+  switch (representation()) {
+    case kUnboxedMint: {
+      const Register result = locs()->out(0).reg();
+      ASSERT(result == box);
+      __ SmiUntag(box);
+      break;
+    }
+
+    case kUnboxedDouble: {
+      const FpuRegister result = locs()->out(0).fpu_reg();
+      __ SmiUntag(box);
+      __ cvtsi2sdq(result, box);
+      break;
+    }
+
+    default:
+      UNREACHABLE();
+      break;
+  }
+}
+
+
+void UnboxInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+  const intptr_t value_cid = value()->Type()->ToCid();
+  const intptr_t box_cid = BoxCid();
+
+  if (value_cid == box_cid) {
+    EmitLoadFromBox(compiler);
+  } else if (CanConvertSmi() && (value_cid == kSmiCid)) {
+    EmitSmiConversion(compiler);
   } else {
+    const Register box = locs()->in(0).reg();
     Label* deopt = compiler->AddDeoptStub(GetDeoptId(),
-                                          ICData::kDeoptBinaryDoubleOp);
-    if (value_type->is_nullable() &&
-        (value_type->ToNullableCid() == kDoubleCid)) {
+                                          ICData::kDeoptCheckClass);
+    Label is_smi;
+
+    if ((value()->Type()->ToNullableCid() == box_cid) &&
+        value()->Type()->is_nullable()) {
       const Immediate& raw_null =
           Immediate(reinterpret_cast<intptr_t>(Object::null()));
-      __ cmpq(value, raw_null);
+      __ cmpq(box, raw_null);
       __ j(EQUAL, deopt);
-      // It must be double now.
-      __ movsd(result, FieldAddress(value, Double::value_offset()));
     } else {
-      Label is_smi, done;
-      __ testq(value, Immediate(kSmiTagMask));
-      __ j(ZERO, &is_smi);
-      __ CompareClassId(value, kDoubleCid);
+      __ testq(box, Immediate(kSmiTagMask));
+      __ j(ZERO, CanConvertSmi() ? &is_smi : deopt);
+      __ CompareClassId(box, box_cid);
       __ j(NOT_EQUAL, deopt);
-      __ movsd(result, FieldAddress(value, Double::value_offset()));
+    }
+
+    EmitLoadFromBox(compiler);
+
+    if (is_smi.IsLinked()) {
+      Label done;
       __ jmp(&done);
       __ Bind(&is_smi);
-      __ SmiUntag(value);
-      __ cvtsi2sdq(result, value);
+      EmitSmiConversion(compiler);
       __ Bind(&done);
     }
   }
 }
 
 
-LocationSummary* BoxFloat32x4Instr::MakeLocationSummary(Isolate* isolate,
-                                                        bool opt) const {
-  const intptr_t kNumInputs = 1;
-  const intptr_t kNumTemps = 0;
-  LocationSummary* summary = new(isolate) LocationSummary(
-      isolate, kNumInputs,
-                          kNumTemps,
-                          LocationSummary::kCallOnSlowPath);
-  summary->set_in(0, Location::RequiresFpuRegister());
-  summary->set_out(0, Location::RequiresRegister());
-  return summary;
-}
-
-
-void BoxFloat32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) {
-  Register out_reg = locs()->out(0).reg();
-  XmmRegister value = locs()->in(0).fpu_reg();
-
-  BoxAllocationSlowPath::Allocate(
-      compiler, this, compiler->float32x4_class(), out_reg);
-  __ movups(FieldAddress(out_reg, Float32x4::value_offset()), value);
-}
-
-
-LocationSummary* UnboxFloat32x4Instr::MakeLocationSummary(Isolate* isolate,
+LocationSummary* UnboxInteger32Instr::MakeLocationSummary(Isolate* isolate,
                                                           bool opt) const {
   const intptr_t kNumInputs = 1;
-  return LocationSummary::Make(isolate,
-                               kNumInputs,
-                               Location::RequiresFpuRegister(),
-                               LocationSummary::kNoCall);
-}
-
-
-void UnboxFloat32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) {
-  const intptr_t value_cid = value()->Type()->ToCid();
-  const Register value = locs()->in(0).reg();
-  const XmmRegister result = locs()->out(0).fpu_reg();
-
-  if (value_cid != kFloat32x4Cid) {
-    Label* deopt =
-        compiler->AddDeoptStub(GetDeoptId(), ICData::kDeoptCheckClass);
-    __ testq(value, Immediate(kSmiTagMask));
-    __ j(ZERO, deopt);
-    __ CompareClassId(value, kFloat32x4Cid);
-    __ j(NOT_EQUAL, deopt);
-  }
-  __ movups(result, FieldAddress(value, Float32x4::value_offset()));
-}
-
-
-LocationSummary* BoxFloat64x2Instr::MakeLocationSummary(Isolate* isolate,
-                                                        bool opt) const {
-  const intptr_t kNumInputs = 1;
-  const intptr_t kNumTemps = 0;
-  LocationSummary* summary = new(isolate) LocationSummary(
-      isolate, kNumInputs,
-                          kNumTemps,
-                          LocationSummary::kCallOnSlowPath);
-  summary->set_in(0, Location::RequiresFpuRegister());
-  summary->set_out(0, Location::RequiresRegister());
-  return summary;
-}
-
-
-void BoxFloat64x2Instr::EmitNativeCode(FlowGraphCompiler* compiler) {
-  Register out_reg = locs()->out(0).reg();
-  XmmRegister value = locs()->in(0).fpu_reg();
-
-  BoxAllocationSlowPath::Allocate(
-      compiler, this, compiler->float64x2_class(), out_reg);
-  __ movups(FieldAddress(out_reg, Float64x2::value_offset()), value);
-}
-
-
-LocationSummary* UnboxFloat64x2Instr::MakeLocationSummary(Isolate* isolate,
-                                                          bool opt) const {
-  const intptr_t value_cid = value()->Type()->ToCid();
-  const intptr_t kNumInputs = 1;
-  const intptr_t kNumTemps = value_cid == kFloat64x2Cid ? 0 : 1;
+  const intptr_t kNumTemps = (!is_truncating() && CanDeoptimize()) ? 1 : 0;
   LocationSummary* summary = new(isolate) LocationSummary(
       isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall);
   summary->set_in(0, Location::RequiresRegister());
-  summary->set_out(0, Location::RequiresFpuRegister());
+  summary->set_out(0, Location::SameAsFirstInput());
+  if (kNumTemps > 0) {
+    summary->set_temp(0, Location::RequiresRegister());
+  }
   return summary;
 }
 
 
-void UnboxFloat64x2Instr::EmitNativeCode(FlowGraphCompiler* compiler) {
+void UnboxInteger32Instr::EmitNativeCode(FlowGraphCompiler* compiler) {
   const intptr_t value_cid = value()->Type()->ToCid();
   const Register value = locs()->in(0).reg();
-  const XmmRegister result = locs()->out(0).fpu_reg();
+  Label* deopt = CanDeoptimize() ?
+      compiler->AddDeoptStub(GetDeoptId(), ICData::kDeoptUnboxInteger) : NULL;
+  ASSERT(value == locs()->out(0).reg());
 
-  if (value_cid != kFloat64x2Cid) {
-    Label* deopt =
-        compiler->AddDeoptStub(GetDeoptId(), ICData::kDeoptCheckClass);
-    __ testq(value, Immediate(kSmiTagMask));
-    __ j(ZERO, deopt);
-    __ CompareClassId(value, kFloat64x2Cid);
+  if (value_cid == kSmiCid) {
+    __ SmiUntag(value);
+  } else if (value_cid == kMintCid) {
+    __ movq(value, FieldAddress(value, Mint::value_offset()));
+  } else {
+    Label done;
+    // Optimistically untag value.
+    __ SmiUntagOrCheckClass(value, kMintCid, &done);
+    __ j(NOT_EQUAL, deopt);
+    // Undo untagging by multiplying value with 2.
+    __ movq(value, Address(value, TIMES_2, Mint::value_offset()));
+    __ Bind(&done);
+  }
+
+  // TODO(vegorov): as it is implemented right now truncating unboxing would
+  // leave "garbage" in the higher word.
+  if (!is_truncating() && (deopt != NULL)) {
+    ASSERT(representation() == kUnboxedInt32);
+    Register temp = locs()->temp(0).reg();
+    __ movsxd(temp, value);
+    __ cmpq(temp, value);
     __ j(NOT_EQUAL, deopt);
   }
-  __ movups(result, FieldAddress(value, Float64x2::value_offset()));
 }
 
 
-LocationSummary* BoxInt32x4Instr::MakeLocationSummary(Isolate* isolate,
+LocationSummary* BoxInteger32Instr::MakeLocationSummary(Isolate* isolate,
+                                                   bool opt) const {
+  ASSERT((from_representation() == kUnboxedInt32) ||
+         (from_representation() == kUnboxedUint32));
+  const intptr_t kNumInputs = 1;
+  const intptr_t kNumTemps = 0;
+  LocationSummary* summary = new(isolate) LocationSummary(
+      isolate,
+      kNumInputs,
+      kNumTemps,
+      LocationSummary::kNoCall);
+  summary->set_in(0, Location::RequiresRegister());
+  summary->set_out(0, Location::RequiresRegister());
+  return summary;
+}
+
+
+void BoxInteger32Instr::EmitNativeCode(FlowGraphCompiler* compiler) {
+  const Register value = locs()->in(0).reg();
+  const Register out = locs()->out(0).reg();
+  ASSERT(value != out);
+
+  ASSERT(kSmiTagSize == 1);
+  if (from_representation() == kUnboxedInt32) {
+    __ movsxd(out, value);
+  } else {
+    ASSERT(from_representation() == kUnboxedUint32);
+    __ movl(out, value);
+  }
+  __ SmiTag(out);
+}
+
+
+LocationSummary* BoxInt64Instr::MakeLocationSummary(Isolate* isolate,
                                                       bool opt) const {
   const intptr_t kNumInputs = 1;
   const intptr_t kNumTemps = 0;
   LocationSummary* summary = new(isolate) LocationSummary(
-      isolate, kNumInputs,
-                          kNumTemps,
-                          LocationSummary::kCallOnSlowPath);
-  summary->set_in(0, Location::RequiresFpuRegister());
+      isolate,
+      kNumInputs,
+      kNumTemps,
+      ValueFitsSmi() ? LocationSummary::kNoCall
+                     : LocationSummary::kCallOnSlowPath);
+  summary->set_in(0, Location::RequiresRegister());
   summary->set_out(0, Location::RequiresRegister());
   return summary;
 }
 
 
-void BoxInt32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) {
-  Register out_reg = locs()->out(0).reg();
-  XmmRegister value = locs()->in(0).fpu_reg();
-
-  BoxAllocationSlowPath::Allocate(
-      compiler, this, compiler->int32x4_class(), out_reg);
-  __ movups(FieldAddress(out_reg, Int32x4::value_offset()), value);
-}
-
-
-LocationSummary* UnboxInt32x4Instr::MakeLocationSummary(Isolate* isolate,
-                                                        bool opt) const {
-  const intptr_t kNumInputs = 1;
-  const intptr_t kNumTemps = 0;
-  LocationSummary* summary = new(isolate) LocationSummary(
-      isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall);
-  summary->set_in(0, Location::RequiresRegister());
-  summary->set_out(0, Location::RequiresFpuRegister());
-  return summary;
-}
-
-
-void UnboxInt32x4Instr::EmitNativeCode(FlowGraphCompiler* compiler) {
-  const intptr_t value_cid = value()->Type()->ToCid();
+void BoxInt64Instr::EmitNativeCode(FlowGraphCompiler* compiler) {
+  const Register out = locs()->out(0).reg();
   const Register value = locs()->in(0).reg();
-  const XmmRegister result = locs()->out(0).fpu_reg();
-
-  if (value_cid != kInt32x4Cid) {
-    Label* deopt =
-        compiler->AddDeoptStub(GetDeoptId(), ICData::kDeoptCheckClass);
-    __ testq(value, Immediate(kSmiTagMask));
-    __ j(ZERO, deopt);
-    __ CompareClassId(value, kInt32x4Cid);
-    __ j(NOT_EQUAL, deopt);
+  __ MoveRegister(out, value);
+  __ SmiTag(out);
+  if (!ValueFitsSmi()) {
+    Label done;
+    __ j(NO_OVERFLOW, &done);
+    BoxAllocationSlowPath::Allocate(
+        compiler, this, compiler->mint_class(), out);
+    __ movq(FieldAddress(out, Mint::value_offset()), value);
+    __ Bind(&done);
   }
-  __ movups(result, FieldAddress(value, Int32x4::value_offset()));
 }
 
 
@@ -5299,7 +5316,7 @@
 
 LocationSummary* PolymorphicInstanceCallInstr::MakeLocationSummary(
     Isolate* isolate, bool opt) const {
-  return MakeCallSummary();
+  return MakeCallSummary(isolate);
 }
 
 
@@ -5532,77 +5549,6 @@
 }
 
 
-LocationSummary* UnboxIntegerInstr::MakeLocationSummary(Isolate* isolate,
-                                                        bool opt) const {
-  const intptr_t kNumInputs = 1;
-  const intptr_t kNumTemps = 0;
-  LocationSummary* locs = new(isolate) LocationSummary(
-      isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall);
-  locs->set_in(0, Location::RequiresRegister());
-  locs->set_out(0, Location::SameAsFirstInput());
-  return locs;
-}
-
-
-void UnboxIntegerInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
-  const intptr_t value_cid = value()->Type()->ToCid();
-  const Register value = locs()->in(0).reg();
-  const Register result = locs()->out(0).reg();
-  ASSERT(value == result);
-
-  if (value_cid == kMintCid) {
-    __ movq(result, FieldAddress(value, Mint::value_offset()));
-  } else if (value_cid == kSmiCid) {
-    __ SmiUntag(result);
-  } else {
-    Label* deopt = compiler->AddDeoptStub(GetDeoptId(),
-                                          ICData::kDeoptUnboxInteger);
-    Label done;
-    __ SmiUntagOrCheckClass(value, kMintCid, &done);
-    __ j(NOT_EQUAL, deopt);
-    // Undo untagging by multiplying value with 2.
-    __ movq(result, Address(value, TIMES_2, Mint::value_offset()));
-    __ Bind(&done);
-  }
-}
-
-
-LocationSummary* BoxIntegerInstr::MakeLocationSummary(Isolate* isolate,
-                                                      bool opt) const {
-  const intptr_t kNumInputs = 1;
-  const intptr_t kNumTemps = 0;
-  LocationSummary* summary = new(isolate) LocationSummary(
-      isolate, kNumInputs, kNumTemps, is_smi()
-                                          ? LocationSummary::kNoCall
-                                          : LocationSummary::kCallOnSlowPath);
-  summary->set_in(0, Location::RequiresRegister());
-  summary->set_out(0, Location::RequiresRegister());
-  return summary;
-}
-
-
-void BoxIntegerInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
-  const Register out = locs()->out(0).reg();
-  const Register value = locs()->in(0).reg();
-
-  if (is_smi()) {
-    __ movq(out, value);
-    __ SmiTag(out);
-    return;
-  }
-
-  Label is_smi;
-  Label done;
-  __ movq(out, value);
-  __ SmiTag(out);   // shlq sets OF := SF ^ CF on 1 bit shifts
-  __ j(NO_OVERFLOW, &done);
-  BoxAllocationSlowPath::Allocate(
-      compiler, this, compiler->mint_class(), out);
-  __ movq(FieldAddress(out, Mint::value_offset()), value);
-  __ Bind(&done);
-}
-
-
 template<typename OperandType>
 static void EmitInt64Arithmetic(FlowGraphCompiler* compiler,
                                 Token::Kind op_kind,
@@ -5987,87 +5933,6 @@
 DEFINE_UNIMPLEMENTED_INSTRUCTION(BinaryInt32OpInstr)
 
 
-LocationSummary* UnboxIntNInstr::MakeLocationSummary(Isolate* isolate,
-                                                     bool opt) const {
-  const intptr_t kNumInputs = 1;
-  const intptr_t kNumTemps = (!is_truncating() && CanDeoptimize()) ? 1 : 0;
-  LocationSummary* summary = new(isolate) LocationSummary(
-      isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall);
-  summary->set_in(0, Location::RequiresRegister());
-  summary->set_out(0, Location::SameAsFirstInput());
-  if (kNumTemps > 0) {
-    summary->set_temp(0, Location::RequiresRegister());
-  }
-  return summary;
-}
-
-
-void UnboxIntNInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
-  const intptr_t value_cid = value()->Type()->ToCid();
-  const Register value = locs()->in(0).reg();
-  Label* deopt = CanDeoptimize() ?
-      compiler->AddDeoptStub(GetDeoptId(), ICData::kDeoptUnboxInteger) : NULL;
-  ASSERT(value == locs()->out(0).reg());
-
-  if (value_cid == kSmiCid) {
-    __ SmiUntag(value);
-  } else if (value_cid == kMintCid) {
-    __ movq(value, FieldAddress(value, Mint::value_offset()));
-  } else {
-    Label done;
-    // Optimistically untag value.
-    __ SmiUntagOrCheckClass(value, kMintCid, &done);
-    __ j(NOT_EQUAL, deopt);
-    // Undo untagging by multiplying value with 2.
-    __ movq(value, Address(value, TIMES_2, Mint::value_offset()));
-    __ Bind(&done);
-  }
-
-  // TODO(vegorov): as it is implemented right now truncating unboxing would
-  // leave "garbage" in the higher word.
-  if (!is_truncating() && (deopt != NULL)) {
-    ASSERT(representation() == kUnboxedInt32);
-    Register temp = locs()->temp(0).reg();
-    __ movsxd(temp, value);
-    __ cmpq(temp, value);
-    __ j(NOT_EQUAL, deopt);
-  }
-}
-
-
-LocationSummary* BoxIntNInstr::MakeLocationSummary(Isolate* isolate,
-                                                   bool opt) const {
-  ASSERT((from_representation() == kUnboxedInt32) ||
-         (from_representation() == kUnboxedUint32));
-  const intptr_t kNumInputs = 1;
-  const intptr_t kNumTemps = 0;
-  LocationSummary* summary = new(isolate) LocationSummary(
-      isolate,
-      kNumInputs,
-      kNumTemps,
-      LocationSummary::kNoCall);
-  summary->set_in(0, Location::RequiresRegister());
-  summary->set_out(0, Location::RequiresRegister());
-  return summary;
-}
-
-
-void BoxIntNInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
-  const Register value = locs()->in(0).reg();
-  const Register out = locs()->out(0).reg();
-  ASSERT(value != out);
-
-  ASSERT(kSmiTagSize == 1);
-  if (from_representation() == kUnboxedInt32) {
-    __ movsxd(out, value);
-  } else {
-    ASSERT(from_representation() == kUnboxedUint32);
-    __ movl(out, value);
-  }
-  __ SmiTag(out);
-}
-
-
 LocationSummary* UnboxedIntConverterInstr::MakeLocationSummary(Isolate* isolate,
                                                                bool opt) const {
   const intptr_t kNumInputs = 1;
@@ -6375,7 +6240,7 @@
 
 LocationSummary* AllocateObjectInstr::MakeLocationSummary(Isolate* isolate,
                                                           bool opt) const {
-  return MakeCallSummary();
+  return MakeCallSummary(isolate);
 }
 
 
diff --git a/runtime/vm/intrinsifier.cc b/runtime/vm/intrinsifier.cc
index 0ba74eb..c195e30 100644
--- a/runtime/vm/intrinsifier.cc
+++ b/runtime/vm/intrinsifier.cc
@@ -451,10 +451,12 @@
                           value_check,
                           builder.TokenPos()));
   Definition* double_value = builder.AddDefinition(
-      new UnboxDoubleInstr(new Value(value), Isolate::kNoDeoptId));
+      UnboxInstr::Create(kUnboxedDouble,
+                         new Value(value),
+                         Isolate::kNoDeoptId));
   // Manually adjust reaching type because there is no type propagation
   // when building intrinsics.
-  double_value->AsUnboxDouble()->value()->SetReachingType(
+  double_value->AsUnbox()->value()->SetReachingType(
       ZoneCompileType::Wrap(CompileType::FromCid(kDoubleCid)));
 
   builder.AddInstruction(
@@ -494,7 +496,7 @@
                            Isolate::kNoDeoptId,
                            builder.TokenPos()));
   Definition* result = builder.AddDefinition(
-      new BoxDoubleInstr(new Value(unboxed_value)));
+      BoxInstr::Create(kUnboxedDouble, new Value(unboxed_value)));
   builder.AddIntrinsicReturn(new Value(result));
   return true;
 }
diff --git a/runtime/vm/isolate.cc b/runtime/vm/isolate.cc
index a87a87a..3c5e938 100644
--- a/runtime/vm/isolate.cc
+++ b/runtime/vm/isolate.cc
@@ -401,7 +401,6 @@
       terminate_capability_(0),
       heap_(NULL),
       object_store_(NULL),
-      top_context_(Context::null()),
       top_exit_frame_info_(0),
       init_callback_data_(NULL),
       environment_callback_(NULL),
@@ -461,7 +460,6 @@
       terminate_capability_(0),
       heap_(NULL),
       object_store_(NULL),
-      top_context_(Context::null()),
       top_exit_frame_info_(0),
       init_callback_data_(NULL),
       environment_callback_(NULL),
@@ -1130,9 +1128,6 @@
     api_state()->VisitObjectPointers(visitor, visit_prologue_weak_handles);
   }
 
-  // Visit the top context which is stored in the isolate.
-  visitor->VisitPointer(reinterpret_cast<RawObject**>(&top_context_));
-
   // Visit the current tag which is stored in the isolate.
   visitor->VisitPointer(reinterpret_cast<RawObject**>(&current_tag_));
 
diff --git a/runtime/vm/isolate.h b/runtime/vm/isolate.h
index befb386..e0bbf42 100644
--- a/runtime/vm/isolate.h
+++ b/runtime/vm/isolate.h
@@ -187,12 +187,6 @@
     return OFFSET_OF(Isolate, object_store_);
   }
 
-  RawContext* top_context() const { return top_context_; }
-  void set_top_context(RawContext* value) { top_context_ = value; }
-  static intptr_t top_context_offset() {
-    return OFFSET_OF(Isolate, top_context_);
-  }
-
   uword top_exit_frame_info() const { return top_exit_frame_info_; }
   void set_top_exit_frame_info(uword value) { top_exit_frame_info_ = value; }
   static intptr_t top_exit_frame_info_offset() {
@@ -640,7 +634,6 @@
   uint64_t terminate_capability_;
   Heap* heap_;
   ObjectStore* object_store_;
-  RawContext* top_context_;
   uword top_exit_frame_info_;
   void* init_callback_data_;
   Dart_EnvironmentCallback environment_callback_;
diff --git a/runtime/vm/native_arguments.h b/runtime/vm/native_arguments.h
index 1451856..197f9ab 100644
--- a/runtime/vm/native_arguments.h
+++ b/runtime/vm/native_arguments.h
@@ -101,7 +101,9 @@
     int function_bits = FunctionBits::decode(argc_tag_);
     if (function_bits == (kClosureFunctionBit | kInstanceFunctionBit)) {
       // Retrieve the receiver from the context.
-      const Context& context = Context::Handle(isolate_->top_context());
+      const Object& closure = Object::Handle(ArgAt(0));
+      const Context& context =
+          Context::Handle(Closure::context(Instance::Cast(closure)));
       return context.At(0);
     }
     return ArgAt(NumHiddenArgs(function_bits));
diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc
index 197ef30..47ce72f 100644
--- a/runtime/vm/object.cc
+++ b/runtime/vm/object.cc
@@ -4955,6 +4955,27 @@
 }
 
 
+RawTypeArguments* TypeArguments::CloneUninstantiated(
+    const Class& new_owner) const {
+  ASSERT(!IsNull());
+  ASSERT(IsFinalized());
+  ASSERT(!IsInstantiated());
+  AbstractType& type = AbstractType::Handle();
+  const intptr_t num_types = Length();
+  const TypeArguments& clone = TypeArguments::Handle(
+      TypeArguments::New(num_types));
+  for (intptr_t i = 0; i < num_types; i++) {
+    type = TypeAt(i);
+    if (!type.IsInstantiated()) {
+      type = type.CloneUninstantiated(new_owner);
+    }
+    clone.SetTypeAt(i, type);
+  }
+  ASSERT(clone.IsFinalized());
+  return clone.raw();
+}
+
+
 RawTypeArguments* TypeArguments::Canonicalize(
     GrowableObjectArray* trail) const {
   if (IsNull() || IsCanonical()) {
@@ -5459,7 +5480,7 @@
 void Function::SetParameterTypeAt(
     intptr_t index, const AbstractType& value) const {
   ASSERT(!value.IsNull());
-  // Method extractor parameters are in the VM heap.
+  // Method extractor parameters are shared and are in the VM heap.
   ASSERT(kind() != RawFunction::kMethodExtractor);
   const Array& parameter_types = Array::Handle(raw_ptr()->parameter_types_);
   parameter_types.SetAt(index, value);
@@ -6155,6 +6176,21 @@
   clone.set_optimized_instruction_count(0);
   clone.set_optimized_call_site_count(0);
   clone.set_ic_data_array(Array::Handle());
+  if (new_owner.NumTypeParameters() > 0) {
+    // Adjust uninstantiated types to refer to type parameters of the new owner.
+    AbstractType& type = AbstractType::Handle(clone.result_type());
+    type ^= type.CloneUninstantiated(new_owner);
+    clone.set_result_type(type);
+    const intptr_t num_params = clone.NumParameters();
+    Array& array = Array::Handle(clone.parameter_types());
+    array ^= Object::Clone(array, Heap::kOld);
+    clone.set_parameter_types(array);
+    for (intptr_t i = 0; i < num_params; i++) {
+      type = clone.ParameterTypeAt(i);
+      type ^= type.CloneUninstantiated(new_owner);
+      clone.SetParameterTypeAt(i, type);
+    }
+  }
   return clone.raw();
 }
 
@@ -7027,6 +7063,12 @@
   if (!clone.is_static()) {
     clone.SetOffset(0);
   }
+  if (new_owner.NumTypeParameters() > 0) {
+    // Adjust the field type to refer to type parameters of the new owner.
+    AbstractType& type = AbstractType::Handle(clone.type());
+    type ^= type.CloneUninstantiated(new_owner);
+    clone.set_type(type);
+  }
   return clone.raw();
 }
 
@@ -10785,11 +10827,8 @@
     case RawLocalVarDescriptors::kContextLevel:
       return "ContextLevel";
       break;
-    case RawLocalVarDescriptors::kSavedEntryContext:
-      return "SavedEntryCtx";
-      break;
     case RawLocalVarDescriptors::kSavedCurrentContext:
-      return "SavedCurrentCtx";
+      return "CurrentCtx";
       break;
     default:
       UNREACHABLE();
@@ -10907,8 +10946,6 @@
       return "ContextVar";
     case RawLocalVarDescriptors::kContextLevel:
       return "ContextLevel";
-    case RawLocalVarDescriptors::kSavedEntryContext:
-      return "SavedEntryContext";
     case RawLocalVarDescriptors::kSavedCurrentContext:
       return "SavedCurrentContext";
     default:
@@ -13493,15 +13530,12 @@
 }
 
 
-bool Instance::IsCallable(Function* function, Context* context) const {
+bool Instance::IsCallable(Function* function) const {
   Class& cls = Class::Handle(clazz());
   if (cls.IsSignatureClass()) {
     if (function != NULL) {
       *function = Closure::function(*this);
     }
-    if (context != NULL) {
-      *context = Closure::context(*this);
-    }
     return true;
   }
   // Try to resolve a "call" method.
@@ -13512,9 +13546,6 @@
       if (function != NULL) {
         *function = call_function.raw();
       }
-      if (context != NULL) {
-        *context = Isolate::Current()->object_store()->empty_context();
-      }
       return true;
     }
     cls = cls.SuperClass();
@@ -13834,6 +13865,14 @@
 }
 
 
+RawAbstractType* AbstractType::CloneUninstantiated(
+    const Class& new_owner) const {
+  // AbstractType is an abstract class.
+  UNREACHABLE();
+  return NULL;
+}
+
+
 RawAbstractType* AbstractType::Canonicalize(GrowableObjectArray* trail) const {
   // AbstractType is an abstract class.
   UNREACHABLE();
@@ -14533,9 +14572,24 @@
   TypeArguments& type_args = TypeArguments::Handle(arguments());
   type_args = type_args.CloneUnfinalized();
   const Class& type_cls = Class::Handle(type_class());
-  const Type& type = Type::Handle(Type::New(type_cls, type_args, token_pos()));
-  type.set_is_resolved();
-  return type.raw();
+  const Type& clone = Type::Handle(Type::New(type_cls, type_args, token_pos()));
+  clone.set_is_resolved();
+  return clone.raw();
+}
+
+
+RawAbstractType* Type::CloneUninstantiated(const Class& new_owner) const {
+  ASSERT(IsFinalized());
+  ASSERT(!IsMalformed());
+  if (IsInstantiated()) {
+    return raw();
+  }
+  TypeArguments& type_args = TypeArguments::Handle(arguments());
+  type_args = type_args.CloneUninstantiated(new_owner);
+  const Class& type_cls = Class::Handle(type_class());
+  const Type& clone = Type::Handle(Type::New(type_cls, type_args, token_pos()));
+  clone.SetIsFinalized();
+  return clone.raw();
 }
 
 
@@ -15075,6 +15129,25 @@
 }
 
 
+RawAbstractType* TypeParameter::CloneUninstantiated(
+    const Class& new_owner) const {
+  ASSERT(IsFinalized());
+  AbstractType& upper_bound = AbstractType::Handle(bound());
+  upper_bound = upper_bound.CloneUninstantiated(new_owner);
+  const Class& old_owner = Class::Handle(parameterized_class());
+  const intptr_t new_index = index() +
+      new_owner.NumTypeArguments() - old_owner.NumTypeArguments();
+  const TypeParameter& clone = TypeParameter::Handle(
+      TypeParameter::New(new_owner,
+                         new_index,
+                         String::Handle(name()),
+                         upper_bound,
+                         token_pos()));
+  clone.set_is_finalized();
+  return clone.raw();
+}
+
+
 intptr_t TypeParameter::Hash() const {
   ASSERT(IsFinalized());
   uint32_t result = Class::Handle(parameterized_class()).id();
@@ -15295,6 +15368,21 @@
 }
 
 
+RawAbstractType* BoundedType::CloneUninstantiated(
+    const Class& new_owner) const {
+  if (IsInstantiated()) {
+    return raw();
+  }
+  AbstractType& bounded_type = AbstractType::Handle(type());
+  bounded_type = bounded_type.CloneUninstantiated(new_owner);
+  AbstractType& upper_bound = AbstractType::Handle(bound());
+  upper_bound = upper_bound.CloneUninstantiated(new_owner);
+  TypeParameter& type_param =  TypeParameter::Handle(type_parameter());
+  type_param ^= type_param.CloneUninstantiated(new_owner);
+  return BoundedType::New(bounded_type, upper_bound, type_param);
+}
+
+
 intptr_t BoundedType::Hash() const {
   uint32_t result = AbstractType::Handle(type()).Hash();
   // No need to include the hash of the bound, since the bound is defined by the
diff --git a/runtime/vm/object.h b/runtime/vm/object.h
index d5e012a..dacb7ff 100644
--- a/runtime/vm/object.h
+++ b/runtime/vm/object.h
@@ -1563,6 +1563,11 @@
   // Finalized type arguments are shared.
   RawTypeArguments* CloneUnfinalized() const;
 
+  // Clone this type argument vector and clone all uninstantiated type
+  // arguments, changing the class owner of type parameters.
+  // Instantiated type arguments are shared.
+  RawTypeArguments* CloneUninstantiated(const Class& new_owner) const;
+
   // Canonicalize only if instantiated, otherwise returns 'this'.
   RawTypeArguments* Canonicalize(GrowableObjectArray* trail = NULL) const;
 
@@ -4505,9 +4510,8 @@
 
   // If the instance is a callable object, i.e. a closure or the instance of a
   // class implementing a 'call' method, return true and set the function
-  // (if not NULL) to call and the context (if not NULL) to pass to the
-  // function.
-  bool IsCallable(Function* function, Context* context) const;
+  // (if not NULL) to call.
+  bool IsCallable(Function* function) const;
 
   // Evaluate the given expression as if it appeared in an instance
   // method of this instance and return the resulting value, or an
@@ -4665,6 +4669,13 @@
   // type arguments of an unfinalized type are not cloned, but shared.
   virtual RawAbstractType* CloneUnfinalized() const;
 
+  // Return a clone of this uninstantiated type where all references to type
+  // parameters are replaced with references to type parameters of the same name
+  // but belonging to the new owner class.
+  // Apply recursively to type arguments, i.e. instantiated type arguments of
+  // an uninstantiated type are not cloned, but shared.
+  virtual RawAbstractType* CloneUninstantiated(const Class& new_owner) const;
+
   virtual RawInstance* CheckAndCanonicalize(const char** error_str) const {
     return Canonicalize();
   }
@@ -4825,6 +4836,7 @@
       Error* malformed_error,
       GrowableObjectArray* trail = NULL) const;
   virtual RawAbstractType* CloneUnfinalized() const;
+  virtual RawAbstractType* CloneUninstantiated(const Class& new_owner) const;
   virtual RawAbstractType* Canonicalize(
       GrowableObjectArray* trail = NULL) const;
 
@@ -5024,6 +5036,7 @@
       Error* bound_error,
       GrowableObjectArray* trail = NULL) const;
   virtual RawAbstractType* CloneUnfinalized() const;
+  virtual RawAbstractType* CloneUninstantiated(const Class& new_owner) const;
   virtual RawAbstractType* Canonicalize(
       GrowableObjectArray* trail = NULL) const {
     return raw();
@@ -5108,6 +5121,7 @@
       Error* bound_error,
       GrowableObjectArray* trail = NULL) const;
   virtual RawAbstractType* CloneUnfinalized() const;
+  virtual RawAbstractType* CloneUninstantiated(const Class& new_owner) const;
   virtual RawAbstractType* Canonicalize(
       GrowableObjectArray* trail = NULL) const {
     return raw();
diff --git a/runtime/vm/parser.cc b/runtime/vm/parser.cc
index 775ed5f..26bca7f 100644
--- a/runtime/vm/parser.cc
+++ b/runtime/vm/parser.cc
@@ -193,30 +193,6 @@
                                &context_owner,
                                &found_captured_variables);
 
-  // We save the entry context for a function when...
-  //
-  //   - some variable in the function is captured by nested functions, and
-  //   - the function does not capture any variables from parent functions.
-  //
-  // We used to link to the parent context in these cases, but this
-  // had the effect of unintentionally retaining parent contexts which
-  // would never be accessed.  By breaking the context chain at this
-  // point, we allow these outer contexts to be collected.
-  if (found_captured_variables) {
-    const ContextScope& context_scope =
-        ContextScope::Handle(function().context_scope());
-    if (context_scope.IsNull() || (context_scope.num_variables() == 0)) {
-      // Allocate a local variable for saving the entry context.
-      LocalVariable* context_var =
-          new LocalVariable(function().token_pos(),
-                            Symbols::SavedEntryContextVar(),
-                            Type::ZoneHandle(Type::DynamicType()));
-      context_var->set_index(next_free_frame_index--);
-      scope->AddVariable(context_var);
-      set_saved_entry_context_var(context_var);
-    }
-  }
-
   // Frame indices are relative to the frame pointer and are decreasing.
   ASSERT(next_free_frame_index <= first_stack_local_index_);
   num_stack_locals_ = first_stack_local_index_ - next_free_frame_index;
@@ -864,10 +840,8 @@
   if (parsed_function->has_expression_temp_var()) {
     node_sequence->scope()->AddVariable(parsed_function->expression_temp_var());
   }
-  if (parsed_function->has_saved_current_context_var()) {
-    node_sequence->scope()->AddVariable(
-        parsed_function->saved_current_context_var());
-  }
+  node_sequence->scope()->AddVariable(
+      parsed_function->current_context_var());
   if (parsed_function->has_finally_return_temp_var()) {
     node_sequence->scope()->AddVariable(
         parsed_function->finally_return_temp_var());
@@ -1068,9 +1042,7 @@
   if (parsed_function->has_expression_temp_var()) {
     body->scope()->AddVariable(parsed_function->expression_temp_var());
   }
-  if (parsed_function->has_saved_current_context_var()) {
-    body->scope()->AddVariable(parsed_function->saved_current_context_var());
-  }
+  body->scope()->AddVariable(parsed_function->current_context_var());
   if (parsed_function->has_finally_return_temp_var()) {
     body->scope()->AddVariable(parsed_function->finally_return_temp_var());
   }
@@ -1387,7 +1359,6 @@
   ASSERT(!owner.IsNull());
   AstNode* result = NULL;
   if (owner.IsSignatureClass() && name.Equals(Symbols::Call())) {
-    EnsureSavedCurrentContext();
     result = new ClosureCallNode(token_pos, getter_call, args);
   } else {
     result = BuildClosureCall(token_pos, getter_call, args);
@@ -8695,19 +8666,6 @@
 }
 
 
-void Parser::EnsureSavedCurrentContext() {
-  // Used later by the flow_graph_builder to save current context.
-  if (!parsed_function()->has_saved_current_context_var()) {
-    LocalVariable* temp = new(I) LocalVariable(
-        current_function().token_pos(),
-        Symbols::SavedCurrentContextVar(),
-        Type::ZoneHandle(I, Type::DynamicType()));
-    ASSERT(temp != NULL);
-    parsed_function()->set_saved_current_context_var(temp);
-  }
-}
-
-
 LocalVariable* Parser::CreateTempConstVariable(intptr_t token_pos,
                                                const char* s) {
   char name[64];
diff --git a/runtime/vm/parser.h b/runtime/vm/parser.h
index 207b03d..ca54975 100644
--- a/runtime/vm/parser.h
+++ b/runtime/vm/parser.h
@@ -44,8 +44,7 @@
         node_sequence_(NULL),
         instantiator_(NULL),
         default_parameter_values_(Array::ZoneHandle(isolate, Array::null())),
-        saved_current_context_var_(NULL),
-        saved_entry_context_var_(NULL),
+        current_context_var_(NULL),
         expression_temp_var_(NULL),
         finally_return_temp_var_(NULL),
         deferred_prefixes_(new ZoneGrowableArray<const LibraryPrefix*>()),
@@ -58,6 +57,13 @@
         async_saved_try_ctx_name_(String::ZoneHandle(isolate, String::null())),
         isolate_(isolate) {
     ASSERT(function.IsZoneHandle());
+    // Every function has a local variable for the current context.
+    LocalVariable* temp = new(isolate) LocalVariable(
+        function.token_pos(),
+        Symbols::CurrentContextVar(),
+        Type::ZoneHandle(isolate, Type::DynamicType()));
+    ASSERT(temp != NULL);
+    current_context_var_ = temp;
   }
 
   const Function& function() const { return function_; }
@@ -81,23 +87,8 @@
     default_parameter_values_ = default_parameter_values.raw();
   }
 
-  LocalVariable* saved_current_context_var() const {
-    return saved_current_context_var_;
-  }
-  void set_saved_current_context_var(LocalVariable* saved_current_context_var) {
-    ASSERT(saved_current_context_var != NULL);
-    saved_current_context_var_ = saved_current_context_var;
-  }
-  bool has_saved_current_context_var() const {
-    return saved_current_context_var_ != NULL;
-  }
-
-  LocalVariable* saved_entry_context_var() const {
-    return saved_entry_context_var_;
-  }
-  void set_saved_entry_context_var(LocalVariable* saved_entry_context_var) {
-    ASSERT(saved_entry_context_var != NULL);
-    saved_entry_context_var_ = saved_entry_context_var;
+  LocalVariable* current_context_var() const {
+    return current_context_var_;
   }
 
   LocalVariable* expression_temp_var() const {
@@ -125,7 +116,6 @@
   }
   void EnsureFinallyReturnTemp();
 
-  static LocalVariable* CreateExpressionTempVar(intptr_t token_pos);
   LocalVariable* EnsureExpressionTemp();
 
   bool HasDeferredPrefixes() const { return deferred_prefixes_->length() != 0; }
@@ -173,8 +163,7 @@
   SequenceNode* node_sequence_;
   LocalVariable* instantiator_;
   Array& default_parameter_values_;
-  LocalVariable* saved_current_context_var_;
-  LocalVariable* saved_entry_context_var_;
+  LocalVariable* current_context_var_;
   LocalVariable* expression_temp_var_;
   LocalVariable* finally_return_temp_var_;
   ZoneGrowableArray<const LibraryPrefix*>* deferred_prefixes_;
@@ -734,7 +723,6 @@
   void CheckOperatorArity(const MemberDesc& member);
 
   void EnsureExpressionTemp();
-  void EnsureSavedCurrentContext();
   bool IsLegalAssignableSyntax(AstNode* expr, intptr_t end_pos);
   AstNode* CreateAssignmentNode(AstNode* original,
                                 AstNode* rhs,
diff --git a/runtime/vm/parser_test.cc b/runtime/vm/parser_test.cc
index 3595c16..1fb592f 100644
--- a/runtime/vm/parser_test.cc
+++ b/runtime/vm/parser_test.cc
@@ -263,18 +263,20 @@
       "::.main_f\n"
       " 0 ContextVar    level=0   begin=14  end=28  name=value\n"
       " 1 StackVar      scope=1   begin=16  end=28  name=param\n"
+      " 2 CurrentCtx    scope=0   begin=0   end=0"
+      "   name=:current_context_var\n"
 
       // Closure call saves current context.
       "(dynamic, dynamic) => int.call\n"
       " 0 StackVar      scope=1   begin=0   end=0   name=this\n"
-      " 1 SavedCurrentCtx scope=0   begin=0   end=0"
-      "   name=:saved_current_context_var\n"
+      " 1 CurrentCtx    scope=0   begin=0   end=0"
+      "   name=:current_context_var\n"
 
       // function main uses one ctx var at (1); saves caller ctx.
       "::.main\n"
       " 0 ContextLevel  level=1   scope=1   begin=2   end=37\n"
-      " 1 SavedEntryCtx scope=0   begin=0   end=0"
-      "   name=:saved_entry_context_var\n"
+      " 1 CurrentCtx    scope=0   begin=0   end=0"
+      "   name=:current_context_var\n"
       " 2 ContextVar    level=1   begin=7   end=37  name=value\n"
       " 3 StackVar      scope=2   begin=12  end=37  name=f\n",
       CaptureVarsAtLine(lib, "main", 4));
@@ -300,34 +302,38 @@
       // function.
       "::.a_b_c\n"
       " 0 ContextVar    level=0   begin=20  end=30  name=value\n"
+      " 1 CurrentCtx    scope=0   begin=0   end=0"
+      "   name=:current_context_var\n"
 
       // Closure call saves current context.
       "(dynamic) => int.call\n"
       " 0 StackVar      scope=1   begin=0   end=0   name=this\n"
-      " 1 SavedCurrentCtx scope=0   begin=0   end=0"
-      "   name=:saved_current_context_var\n"
+      " 1 CurrentCtx    scope=0   begin=0   end=0"
+      "   name=:current_context_var\n"
 
       // Middle function saves the entry context.  Notice that this
       // happens here and not in the outermost function.  We always
       // save the entry context at the last possible moment.
       "::.a_b\n"
       " 0 ContextLevel  level=1   scope=1   begin=8   end=38\n"
-      " 1 SavedEntryCtx scope=0   begin=0   end=0"
-      "   name=:saved_entry_context_var\n"
+      " 1 CurrentCtx    scope=0   begin=0   end=0"
+      "   name=:current_context_var\n"
       " 2 ContextVar    level=1   begin=13  end=38  name=value\n"
       " 3 StackVar      scope=2   begin=18  end=38  name=c\n"
 
       // Closure call saves current context.
       "(dynamic) => int.call\n"
       " 0 StackVar      scope=1   begin=0   end=0   name=this\n"
-      " 1 SavedCurrentCtx scope=0   begin=0   end=0"
-      "   name=:saved_current_context_var\n"
+      " 1 CurrentCtx    scope=0   begin=0   end=0"
+      "   name=:current_context_var\n"
 
       // Outermost function neglects to save the entry context.  We
       // don't save the entry context if the function has no captured
       // variables.
       "::.a\n"
-      " 0 StackVar      scope=2   begin=6   end=46  name=b\n",
+      " 0 CurrentCtx    scope=0   begin=0   end=0"
+      "   name=:current_context_var\n"
+      " 1 StackVar      scope=2   begin=6   end=46  name=b\n",
       CaptureVarsAtLine(lib, "a", 5));
 }
 
@@ -350,49 +356,54 @@
       "}\n";
   Dart_Handle lib = TestCase::LoadTestScript(kScriptChars, NULL);
   EXPECT_VALID(lib);
+
   EXPECT_STREQ(
       // bb captures only value2 from aa.  No others.
       "::.a_b_aa_bb\n"
       " 0 ContextVar    level=0   begin=32  end=42  name=value2\n"
+      " 1 CurrentCtx    scope=0   begin=0   end=0"
+      "   name=:current_context_var\n"
 
       // Closure call saves current context.
       "(dynamic) => int.call\n"
       " 0 StackVar      scope=1   begin=0   end=0   name=this\n"
-      " 1 SavedCurrentCtx scope=0   begin=0   end=0"
-      "   name=:saved_current_context_var\n"
+      " 1 CurrentCtx    scope=0   begin=0   end=0"
+      "   name=:current_context_var\n"
 
       // aa shares value2. Notice that we save the entry ctx instead
       // of chaining from b.  This keeps us from holding onto closures
       // that we would never access.
       "::.a_b_aa\n"
       " 0 ContextLevel  level=1   scope=1   begin=20  end=50\n"
-      " 1 SavedEntryCtx scope=0   begin=0   end=0"
-      "   name=:saved_entry_context_var\n"
+      " 1 CurrentCtx    scope=0   begin=0   end=0"
+      "   name=:current_context_var\n"
       " 2 ContextVar    level=1   begin=25  end=50  name=value2\n"
       " 3 StackVar      scope=2   begin=30  end=50  name=bb\n"
 
       // Closure call saves current context.
       "(dynamic) => int.call\n"
       " 0 StackVar      scope=1   begin=0   end=0   name=this\n"
-      " 1 SavedCurrentCtx scope=0   begin=0   end=0"
-      "   name=:saved_current_context_var\n"
+      " 1 CurrentCtx    scope=0   begin=0   end=0"
+      "   name=:current_context_var\n"
 
       // b captures value1 from a.
       "::.a_b\n"
       " 0 ContextVar    level=0   begin=14  end=60  name=value1\n"
-      " 1 StackVar      scope=2   begin=18  end=60  name=aa\n"
+      " 1 CurrentCtx    scope=0   begin=0   end=0"
+      "   name=:current_context_var\n"
+      " 2 StackVar      scope=2   begin=18  end=60  name=aa\n"
 
       // Closure call saves current context.
       "(dynamic) => int.call\n"
       " 0 StackVar      scope=1   begin=0   end=0   name=this\n"
-      " 1 SavedCurrentCtx scope=0   begin=0   end=0"
-      "   name=:saved_current_context_var\n"
+      " 1 CurrentCtx    scope=0   begin=0   end=0"
+      "   name=:current_context_var\n"
 
       // a shares value1, saves entry ctx.
       "::.a\n"
       " 0 ContextLevel  level=1   scope=1   begin=2   end=68\n"
-      " 1 SavedEntryCtx scope=0   begin=0   end=0"
-      "   name=:saved_entry_context_var\n"
+      " 1 CurrentCtx    scope=0   begin=0   end=0"
+      "   name=:current_context_var\n"
       " 2 ContextVar    level=1   begin=7   end=68  name=value1\n"
       " 3 StackVar      scope=2   begin=12  end=68  name=b\n",
       CaptureVarsAtLine(lib, "a", 7));
@@ -432,21 +443,25 @@
       "::.doIt_<anonymous closure>\n"
       " 0 ContextLevel  level=1   scope=1   begin=41  end=62\n"
       " 1 ContextVar    level=1   begin=42  end=62  name=y\n"
-      " 2 SavedEntryCtx scope=0   begin=0   end=0"
-      "   name=:saved_entry_context_var\n"
+      " 2 CurrentCtx    scope=0   begin=0   end=0"
+      "   name=:current_context_var\n"
 
       // Closure call saves current context.
       "(dynamic, dynamic) => dynamic.call\n"
       " 0 StackVar      scope=1   begin=0   end=0   name=this\n"
-      " 1 SavedCurrentCtx scope=0   begin=0   end=0"
-      "   name=:saved_current_context_var\n"
+      " 1 CurrentCtx    scope=0   begin=0   end=0"
+      "   name=:current_context_var\n"
 
       "X.onX\n"
       " 0 StackVar      scope=1   begin=0   end=0   name=this\n"
+      " 1 CurrentCtx    scope=0   begin=0   end=0"
+      "   name=:current_context_var\n"
 
       // No context is saved here since no vars are captured.
       "::.doIt\n"
-      " 0 StackVar      scope=2   begin=29  end=77  name=x\n",
+      " 0 CurrentCtx    scope=0   begin=0   end=0"
+      "   name=:current_context_var\n"
+      " 1 StackVar      scope=2   begin=29  end=77  name=x\n",
       CaptureVarsAtLine(lib, "doIt", 12));
 }
 
@@ -473,18 +488,20 @@
       // inner function captures variable value.  That's fine.
       "::.outer_inner\n"
       " 0 ContextVar    level=0   begin=32  end=42  name=value\n"
+      " 1 CurrentCtx    scope=0   begin=0   end=0"
+      "   name=:current_context_var\n"
 
       // Closure call saves current context.
       "(dynamic) => int.call\n"
       " 0 StackVar      scope=1   begin=0   end=0   name=this\n"
-      " 1 SavedCurrentCtx scope=0   begin=0   end=0"
-      "   name=:saved_current_context_var\n"
+      " 1 CurrentCtx    scope=0   begin=0   end=0"
+      "   name=:current_context_var\n"
 
       // The outer function saves the entry context, even though the
       // captured variable is in a loop.  Good.
       "::.outer\n"
-      " 0 SavedEntryCtx scope=0   begin=0   end=0"
-      "   name=:saved_entry_context_var\n"
+      " 0 CurrentCtx    scope=0   begin=0   end=0"
+      "   name=:current_context_var\n"
       " 1 StackVar      scope=3   begin=9   end=50  name=i\n"
       " 2 ContextLevel  level=1   scope=4   begin=20  end=50\n"
       " 3 ContextVar    level=1   begin=23  end=50  name=value\n"
@@ -514,28 +531,32 @@
   EXPECT_STREQ(
       "::.a_b_c\n"
       " 0 ContextVar    level=0   begin=48  end=60  name=x\n"
+      " 1 CurrentCtx    scope=0   begin=0   end=0"
+      "   name=:current_context_var\n"
       "(dynamic) => int.call\n"
       " 0 StackVar      scope=1   begin=0   end=0   name=this\n"
-      " 1 SavedCurrentCtx scope=0   begin=0   end=0"
-      "   name=:saved_current_context_var\n"
+      " 1 CurrentCtx    scope=0   begin=0   end=0"
+      "   name=:current_context_var\n"
 
       // Doesn't save the entry context.  Chains to parent instead.
       "::.a_b\n"
       " 0 ContextVar    level=0   begin=12  end=68  name=x\n"
-      " 1 StackVar      scope=2   begin=46  end=68  name=c\n"
-      " 2 ContextLevel  level=1   scope=3   begin=18  end=46\n"
-      " 3 ContextVar    level=1   begin=19  end=46  name=i\n"
-      " 4 StackVar      scope=4   begin=32  end=46  name=d\n"
+      " 1 CurrentCtx    scope=0   begin=0   end=0"
+      "   name=:current_context_var\n"
+      " 2 StackVar      scope=2   begin=46  end=68  name=c\n"
+      " 3 ContextLevel  level=1   scope=3   begin=18  end=46\n"
+      " 4 ContextVar    level=1   begin=19  end=46  name=i\n"
+      " 5 StackVar      scope=4   begin=32  end=46  name=d\n"
 
       "(dynamic) => dynamic.call\n"
       " 0 StackVar      scope=1   begin=0   end=0   name=this\n"
-      " 1 SavedCurrentCtx scope=0   begin=0   end=0"
-      "   name=:saved_current_context_var\n"
+      " 1 CurrentCtx    scope=0   begin=0   end=0"
+      "   name=:current_context_var\n"
 
       "::.a\n"
       " 0 ContextLevel  level=1   scope=1   begin=1   end=76\n"
-      " 1 SavedEntryCtx scope=0   begin=0   end=0"
-      "   name=:saved_entry_context_var\n"
+      " 1 CurrentCtx    scope=0   begin=0   end=0"
+      "   name=:current_context_var\n"
       " 2 ContextVar    level=1   begin=6   end=76  name=x\n"
       " 3 StackVar      scope=2   begin=11  end=76  name=b\n",
       CaptureVarsAtLine(lib, "a", 10));
diff --git a/runtime/vm/raw_object.h b/runtime/vm/raw_object.h
index c59095d2..8e221e9 100644
--- a/runtime/vm/raw_object.h
+++ b/runtime/vm/raw_object.h
@@ -1059,7 +1059,6 @@
     kStackVar = 1,
     kContextVar,
     kContextLevel,
-    kSavedEntryContext,
     kSavedCurrentContext
   };
 
diff --git a/runtime/vm/regexp.cc b/runtime/vm/regexp.cc
new file mode 100644
index 0000000..534e0c5
--- /dev/null
+++ b/runtime/vm/regexp.cc
@@ -0,0 +1,5438 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for 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/regexp.h"
+
+// SNIP
+
+namespace dart {
+
+// SNIP
+
+// -------------------------------------------------------------------
+// Implementation of the Irregexp regular expression engine.
+//
+// The Irregexp regular expression engine is intended to be a complete
+// implementation of ECMAScript regular expressions.  It generates either
+// bytecodes or native code.
+
+//   The Irregexp regexp engine is structured in three steps.
+//   1) The parser generates an abstract syntax tree.  See ast.cc.
+//   2) From the AST a node network is created.  The nodes are all
+//      subclasses of RegExpNode.  The nodes represent states when
+//      executing a regular expression.  Several optimizations are
+//      performed on the node network.
+//   3) From the nodes we generate either byte codes or native code
+//      that can actually execute the regular expression (perform
+//      the search).  The code generation step is described in more
+//      detail below.
+
+// Code generation.
+//
+//   The nodes are divided into four main categories.
+//   * Choice nodes
+//        These represent places where the regular expression can
+//        match in more than one way.  For example on entry to an
+//        alternation (foo|bar) or a repetition (*, +, ? or {}).
+//   * Action nodes
+//        These represent places where some action should be
+//        performed.  Examples include recording the current position
+//        in the input string to a register (in order to implement
+//        captures) or other actions on register for example in order
+//        to implement the counters needed for {} repetitions.
+//   * Matching nodes
+//        These attempt to match some element part of the input string.
+//        Examples of elements include character classes, plain strings
+//        or back references.
+//   * End nodes
+//        These are used to implement the actions required on finding
+//        a successful match or failing to find a match.
+//
+//   The code generated (whether as byte codes or native code) maintains
+//   some state as it runs.  This consists of the following elements:
+//
+//   * The capture registers.  Used for string captures.
+//   * Other registers.  Used for counters etc.
+//   * The current position.
+//   * The stack of backtracking information.  Used when a matching node
+//     fails to find a match and needs to try an alternative.
+//
+// Conceptual regular expression execution model:
+//
+//   There is a simple conceptual model of regular expression execution
+//   which will be presented first.  The actual code generated is a more
+//   efficient simulation of the simple conceptual model:
+//
+//   * Choice nodes are implemented as follows:
+//     For each choice except the last {
+//       push current position
+//       push backtrack code location
+//       <generate code to test for choice>
+//       backtrack code location:
+//       pop current position
+//     }
+//     <generate code to test for last choice>
+//
+//   * Actions nodes are generated as follows
+//     <push affected registers on backtrack stack>
+//     <generate code to perform action>
+//     push backtrack code location
+//     <generate code to test for following nodes>
+//     backtrack code location:
+//     <pop affected registers to restore their state>
+//     <pop backtrack location from stack and go to it>
+//
+//   * Matching nodes are generated as follows:
+//     if input string matches at current position
+//       update current position
+//       <generate code to test for following nodes>
+//     else
+//       <pop backtrack location from stack and go to it>
+//
+//   Thus it can be seen that the current position is saved and restored
+//   by the choice nodes, whereas the registers are saved and restored by
+//   by the action nodes that manipulate them.
+//
+//   The other interesting aspect of this model is that nodes are generated
+//   at the point where they are needed by a recursive call to Emit().  If
+//   the node has already been code generated then the Emit() call will
+//   generate a jump to the previously generated code instead.  In order to
+//   limit recursion it is possible for the Emit() function to put the node
+//   on a work list for later generation and instead generate a jump.  The
+//   destination of the jump is resolved later when the code is generated.
+//
+// Actual regular expression code generation.
+//
+//   Code generation is actually more complicated than the above.  In order
+//   to improve the efficiency of the generated code some optimizations are
+//   performed
+//
+//   * Choice nodes have 1-character lookahead.
+//     A choice node looks at the following character and eliminates some of
+//     the choices immediately based on that character.  This is not yet
+//     implemented.
+//   * Simple greedy loops store reduced backtracking information.
+//     A quantifier like /.*foo/m will greedily match the whole input.  It will
+//     then need to backtrack to a point where it can match "foo".  The naive
+//     implementation of this would push each character position onto the
+//     backtracking stack, then pop them off one by one.  This would use space
+//     proportional to the length of the input string.  However since the "."
+//     can only match in one way and always has a constant length (in this case
+//     of 1) it suffices to store the current position on the top of the stack
+//     once.  Matching now becomes merely incrementing the current position and
+//     backtracking becomes decrementing the current position and checking the
+//     result against the stored current position.  This is faster and saves
+//     space.
+//   * The current state is virtualized.
+//     This is used to defer expensive operations until it is clear that they
+//     are needed and to generate code for a node more than once, allowing
+//     specialized an efficient versions of the code to be created. This is
+//     explained in the section below.
+//
+// Execution state virtualization.
+//
+//   Instead of emitting code, nodes that manipulate the state can record their
+//   manipulation in an object called the Trace.  The Trace object can record a
+//   current position offset, an optional backtrack code location on the top of
+//   the virtualized backtrack stack and some register changes.  When a node is
+//   to be emitted it can flush the Trace or update it.  Flushing the Trace
+//   will emit code to bring the actual state into line with the virtual state.
+//   Avoiding flushing the state can postpone some work (e.g. updates of capture
+//   registers).  Postponing work can save time when executing the regular
+//   expression since it may be found that the work never has to be done as a
+//   failure to match can occur.  In addition it is much faster to jump to a
+//   known backtrack code location than it is to pop an unknown backtrack
+//   location from the stack and jump there.
+//
+//   The virtual state found in the Trace affects code generation.  For example
+//   the virtual state contains the difference between the actual current
+//   position and the virtual current position, and matching code needs to use
+//   this offset to attempt a match in the correct location of the input
+//   string.  Therefore code generated for a non-trivial trace is specialized
+//   to that trace.  The code generator therefore has the ability to generate
+//   code for each node several times.  In order to limit the size of the
+//   generated code there is an arbitrary limit on how many specialized sets of
+//   code may be generated for a given node.  If the limit is reached, the
+//   trace is flushed and a generic version of the code for a node is emitted.
+//   This is subsequently used for that node.  The code emitted for non-generic
+//   trace is not recorded in the node and so it cannot currently be reused in
+//   the event that code generation is requested for an identical trace.
+
+
+void RegExpTree::AppendToText(RegExpText* text, Zone* zone) {
+  UNREACHABLE();
+}
+
+
+void RegExpAtom::AppendToText(RegExpText* text, Zone* zone) {
+  text->AddElement(TextElement::Atom(this), zone);
+}
+
+
+void RegExpCharacterClass::AppendToText(RegExpText* text, Zone* zone) {
+  text->AddElement(TextElement::CharClass(this), zone);
+}
+
+
+void RegExpText::AppendToText(RegExpText* text, Zone* zone) {
+  for (int i = 0; i < elements()->length(); i++)
+    text->AddElement(elements()->at(i), zone);
+}
+
+
+TextElement TextElement::Atom(RegExpAtom* atom) {
+  return TextElement(ATOM, atom);
+}
+
+
+TextElement TextElement::CharClass(RegExpCharacterClass* char_class) {
+  return TextElement(CHAR_CLASS, char_class);
+}
+
+
+int TextElement::length() const {
+  switch (text_type()) {
+    case ATOM:
+      return atom()->length();
+
+    case CHAR_CLASS:
+      return 1;
+  }
+  UNREACHABLE();
+  return 0;
+}
+
+
+DispatchTable* ChoiceNode::GetTable(bool ignore_case) {
+  if (table_ == NULL) {
+    table_ = new(zone()) DispatchTable(zone());
+    DispatchTableConstructor cons(table_, ignore_case, zone());
+    cons.BuildTable(this);
+  }
+  return table_;
+}
+
+
+class FrequencyCollator {
+ public:
+  FrequencyCollator() : total_samples_(0) {
+    for (int i = 0; i < RegExpMacroAssembler::kTableSize; i++) {
+      frequencies_[i] = CharacterFrequency(i);
+    }
+  }
+
+  void CountCharacter(int character) {
+    int index = (character & RegExpMacroAssembler::kTableMask);
+    frequencies_[index].Increment();
+    total_samples_++;
+  }
+
+  // Does not measure in percent, but rather per-128 (the table size from the
+  // regexp macro assembler).
+  int Frequency(int in_character) {
+    DCHECK((in_character & RegExpMacroAssembler::kTableMask) == in_character);
+    if (total_samples_ < 1) return 1;  // Division by zero.
+    int freq_in_per128 =
+        (frequencies_[in_character].counter() * 128) / total_samples_;
+    return freq_in_per128;
+  }
+
+ private:
+  class CharacterFrequency {
+   public:
+    CharacterFrequency() : counter_(0), character_(-1) { }
+    explicit CharacterFrequency(int character)
+        : counter_(0), character_(character) { }
+
+    void Increment() { counter_++; }
+    int counter() { return counter_; }
+    int character() { return character_; }
+
+   private:
+    int counter_;
+    int character_;
+  };
+
+
+ private:
+  CharacterFrequency frequencies_[RegExpMacroAssembler::kTableSize];
+  int total_samples_;
+};
+
+
+class RegExpCompiler {
+ public:
+  RegExpCompiler(int capture_count, bool ignore_case, bool is_one_byte,
+                 Zone* zone);
+
+  int AllocateRegister() {
+    if (next_register_ >= RegExpMacroAssembler::kMaxRegister) {
+      reg_exp_too_big_ = true;
+      return next_register_;
+    }
+    return next_register_++;
+  }
+
+  RegExpEngine::CompilationResult Assemble(RegExpMacroAssembler* assembler,
+                                           RegExpNode* start,
+                                           int capture_count,
+                                           Handle<String> pattern);
+
+  inline void AddWork(RegExpNode* node) { work_list_->Add(node); }
+
+  static const int kImplementationOffset = 0;
+  static const int kNumberOfRegistersOffset = 0;
+  static const int kCodeOffset = 1;
+
+  RegExpMacroAssembler* macro_assembler() { return macro_assembler_; }
+  EndNode* accept() { return accept_; }
+
+  static const int kMaxRecursion = 100;
+  inline int recursion_depth() { return recursion_depth_; }
+  inline void IncrementRecursionDepth() { recursion_depth_++; }
+  inline void DecrementRecursionDepth() { recursion_depth_--; }
+
+  void SetRegExpTooBig() { reg_exp_too_big_ = true; }
+
+  inline bool ignore_case() { return ignore_case_; }
+  inline bool one_byte() { return one_byte_; }
+  FrequencyCollator* frequency_collator() { return &frequency_collator_; }
+
+  int current_expansion_factor() { return current_expansion_factor_; }
+  void set_current_expansion_factor(int value) {
+    current_expansion_factor_ = value;
+  }
+
+  Zone* zone() const { return zone_; }
+
+  static const int kNoRegister = -1;
+
+ private:
+  EndNode* accept_;
+  int next_register_;
+  List<RegExpNode*>* work_list_;
+  int recursion_depth_;
+  RegExpMacroAssembler* macro_assembler_;
+  bool ignore_case_;
+  bool one_byte_;
+  bool reg_exp_too_big_;
+  int current_expansion_factor_;
+  FrequencyCollator frequency_collator_;
+  Zone* zone_;
+};
+
+
+class RecursionCheck {
+ public:
+  explicit RecursionCheck(RegExpCompiler* compiler) : compiler_(compiler) {
+    compiler->IncrementRecursionDepth();
+  }
+  ~RecursionCheck() { compiler_->DecrementRecursionDepth(); }
+ private:
+  RegExpCompiler* compiler_;
+};
+
+
+static RegExpEngine::CompilationResult IrregexpRegExpTooBig(Isolate* isolate) {
+  return RegExpEngine::CompilationResult(isolate, "RegExp too big");
+}
+
+
+// Attempts to compile the regexp using an Irregexp code generator.  Returns
+// a fixed array or a null handle depending on whether it succeeded.
+RegExpCompiler::RegExpCompiler(int capture_count, bool ignore_case,
+                               bool one_byte, Zone* zone)
+    : next_register_(2 * (capture_count + 1)),
+      work_list_(NULL),
+      recursion_depth_(0),
+      ignore_case_(ignore_case),
+      one_byte_(one_byte),
+      reg_exp_too_big_(false),
+      current_expansion_factor_(1),
+      frequency_collator_(),
+      zone_(zone) {
+  accept_ = new(zone) EndNode(EndNode::ACCEPT, zone);
+  DCHECK(next_register_ - 1 <= RegExpMacroAssembler::kMaxRegister);
+}
+
+
+RegExpEngine::CompilationResult RegExpCompiler::Assemble(
+    RegExpMacroAssembler* macro_assembler,
+    RegExpNode* start,
+    int capture_count,
+    Handle<String> pattern) {
+  Heap* heap = pattern->GetHeap();
+
+  bool use_slow_safe_regexp_compiler = false;
+  if (heap->total_regexp_code_generated() >
+          RegExpImpl::kRegWxpCompiledLimit &&
+      heap->isolate()->memory_allocator()->SizeExecutable() >
+          RegExpImpl::kRegExpExecutableMemoryLimit) {
+    use_slow_safe_regexp_compiler = true;
+  }
+
+  macro_assembler->set_slow_safe(use_slow_safe_regexp_compiler);
+
+#ifdef DEBUG
+  if (FLAG_trace_regexp_assembler)
+    macro_assembler_ = new RegExpMacroAssemblerTracer(macro_assembler);
+  else
+#endif
+    macro_assembler_ = macro_assembler;
+
+  List <RegExpNode*> work_list(0);
+  work_list_ = &work_list;
+  Label fail;
+  macro_assembler_->PushBacktrack(&fail);
+  Trace new_trace;
+  start->Emit(this, &new_trace);
+  macro_assembler_->Bind(&fail);
+  macro_assembler_->Fail();
+  while (!work_list.is_empty()) {
+    work_list.RemoveLast()->Emit(this, &new_trace);
+  }
+  if (reg_exp_too_big_) return IrregexpRegExpTooBig(zone_->isolate());
+
+  Handle<HeapObject> code = macro_assembler_->GetCode(pattern);
+  heap->IncreaseTotalRegexpCodeGenerated(code->Size());
+  work_list_ = NULL;
+#ifdef DEBUG
+  if (FLAG_print_code) {
+    CodeTracer::Scope trace_scope(heap->isolate()->GetCodeTracer());
+    OFStream os(trace_scope.file());
+    Handle<Code>::cast(code)->Disassemble(pattern->ToCString().get(), os);
+  }
+  if (FLAG_trace_regexp_assembler) {
+    delete macro_assembler_;
+  }
+#endif
+  return RegExpEngine::CompilationResult(*code, next_register_);
+}
+
+
+bool Trace::DeferredAction::Mentions(int that) {
+  if (action_type() == ActionNode::CLEAR_CAPTURES) {
+    Interval range = static_cast<DeferredClearCaptures*>(this)->range();
+    return range.Contains(that);
+  } else {
+    return reg() == that;
+  }
+}
+
+
+bool Trace::mentions_reg(int reg) {
+  for (DeferredAction* action = actions_;
+       action != NULL;
+       action = action->next()) {
+    if (action->Mentions(reg))
+      return true;
+  }
+  return false;
+}
+
+
+bool Trace::GetStoredPosition(int reg, int* cp_offset) {
+  DCHECK_EQ(0, *cp_offset);
+  for (DeferredAction* action = actions_;
+       action != NULL;
+       action = action->next()) {
+    if (action->Mentions(reg)) {
+      if (action->action_type() == ActionNode::STORE_POSITION) {
+        *cp_offset = static_cast<DeferredCapture*>(action)->cp_offset();
+        return true;
+      } else {
+        return false;
+      }
+    }
+  }
+  return false;
+}
+
+
+int Trace::FindAffectedRegisters(OutSet* affected_registers,
+                                 Zone* zone) {
+  int max_register = RegExpCompiler::kNoRegister;
+  for (DeferredAction* action = actions_;
+       action != NULL;
+       action = action->next()) {
+    if (action->action_type() == ActionNode::CLEAR_CAPTURES) {
+      Interval range = static_cast<DeferredClearCaptures*>(action)->range();
+      for (int i = range.from(); i <= range.to(); i++)
+        affected_registers->Set(i, zone);
+      if (range.to() > max_register) max_register = range.to();
+    } else {
+      affected_registers->Set(action->reg(), zone);
+      if (action->reg() > max_register) max_register = action->reg();
+    }
+  }
+  return max_register;
+}
+
+
+void Trace::RestoreAffectedRegisters(RegExpMacroAssembler* assembler,
+                                     int max_register,
+                                     const OutSet& registers_to_pop,
+                                     const OutSet& registers_to_clear) {
+  for (int reg = max_register; reg >= 0; reg--) {
+    if (registers_to_pop.Get(reg)) {
+      assembler->PopRegister(reg);
+    } else if (registers_to_clear.Get(reg)) {
+      int clear_to = reg;
+      while (reg > 0 && registers_to_clear.Get(reg - 1)) {
+        reg--;
+      }
+      assembler->ClearRegisters(reg, clear_to);
+    }
+  }
+}
+
+
+void Trace::PerformDeferredActions(RegExpMacroAssembler* assembler,
+                                   int max_register,
+                                   const OutSet& affected_registers,
+                                   OutSet* registers_to_pop,
+                                   OutSet* registers_to_clear,
+                                   Zone* zone) {
+  // The "+1" is to avoid a push_limit of zero if stack_limit_slack() is 1.
+  const int push_limit = (assembler->stack_limit_slack() + 1) / 2;
+
+  // Count pushes performed to force a stack limit check occasionally.
+  int pushes = 0;
+
+  for (int reg = 0; reg <= max_register; reg++) {
+    if (!affected_registers.Get(reg)) {
+      continue;
+    }
+
+    // The chronologically first deferred action in the trace
+    // is used to infer the action needed to restore a register
+    // to its previous state (or not, if it's safe to ignore it).
+    enum DeferredActionUndoType { IGNORE, RESTORE, CLEAR };
+    DeferredActionUndoType undo_action = IGNORE;
+
+    int value = 0;
+    bool absolute = false;
+    bool clear = false;
+    int store_position = -1;
+    // This is a little tricky because we are scanning the actions in reverse
+    // historical order (newest first).
+    for (DeferredAction* action = actions_;
+         action != NULL;
+         action = action->next()) {
+      if (action->Mentions(reg)) {
+        switch (action->action_type()) {
+          case ActionNode::SET_REGISTER: {
+            Trace::DeferredSetRegister* psr =
+                static_cast<Trace::DeferredSetRegister*>(action);
+            if (!absolute) {
+              value += psr->value();
+              absolute = true;
+            }
+            // SET_REGISTER is currently only used for newly introduced loop
+            // counters. They can have a significant previous value if they
+            // occour in a loop. TODO(lrn): Propagate this information, so
+            // we can set undo_action to IGNORE if we know there is no value to
+            // restore.
+            undo_action = RESTORE;
+            DCHECK_EQ(store_position, -1);
+            DCHECK(!clear);
+            break;
+          }
+          case ActionNode::INCREMENT_REGISTER:
+            if (!absolute) {
+              value++;
+            }
+            DCHECK_EQ(store_position, -1);
+            DCHECK(!clear);
+            undo_action = RESTORE;
+            break;
+          case ActionNode::STORE_POSITION: {
+            Trace::DeferredCapture* pc =
+                static_cast<Trace::DeferredCapture*>(action);
+            if (!clear && store_position == -1) {
+              store_position = pc->cp_offset();
+            }
+
+            // For captures we know that stores and clears alternate.
+            // Other register, are never cleared, and if the occur
+            // inside a loop, they might be assigned more than once.
+            if (reg <= 1) {
+              // Registers zero and one, aka "capture zero", is
+              // always set correctly if we succeed. There is no
+              // need to undo a setting on backtrack, because we
+              // will set it again or fail.
+              undo_action = IGNORE;
+            } else {
+              undo_action = pc->is_capture() ? CLEAR : RESTORE;
+            }
+            DCHECK(!absolute);
+            DCHECK_EQ(value, 0);
+            break;
+          }
+          case ActionNode::CLEAR_CAPTURES: {
+            // Since we're scanning in reverse order, if we've already
+            // set the position we have to ignore historically earlier
+            // clearing operations.
+            if (store_position == -1) {
+              clear = true;
+            }
+            undo_action = RESTORE;
+            DCHECK(!absolute);
+            DCHECK_EQ(value, 0);
+            break;
+          }
+          default:
+            UNREACHABLE();
+            break;
+        }
+      }
+    }
+    // Prepare for the undo-action (e.g., push if it's going to be popped).
+    if (undo_action == RESTORE) {
+      pushes++;
+      RegExpMacroAssembler::StackCheckFlag stack_check =
+          RegExpMacroAssembler::kNoStackLimitCheck;
+      if (pushes == push_limit) {
+        stack_check = RegExpMacroAssembler::kCheckStackLimit;
+        pushes = 0;
+      }
+
+      assembler->PushRegister(reg, stack_check);
+      registers_to_pop->Set(reg, zone);
+    } else if (undo_action == CLEAR) {
+      registers_to_clear->Set(reg, zone);
+    }
+    // Perform the chronologically last action (or accumulated increment)
+    // for the register.
+    if (store_position != -1) {
+      assembler->WriteCurrentPositionToRegister(reg, store_position);
+    } else if (clear) {
+      assembler->ClearRegisters(reg, reg);
+    } else if (absolute) {
+      assembler->SetRegister(reg, value);
+    } else if (value != 0) {
+      assembler->AdvanceRegister(reg, value);
+    }
+  }
+}
+
+
+// This is called as we come into a loop choice node and some other tricky
+// nodes.  It normalizes the state of the code generator to ensure we can
+// generate generic code.
+void Trace::Flush(RegExpCompiler* compiler, RegExpNode* successor) {
+  RegExpMacroAssembler* assembler = compiler->macro_assembler();
+
+  DCHECK(!is_trivial());
+
+  if (actions_ == NULL && backtrack() == NULL) {
+    // Here we just have some deferred cp advances to fix and we are back to
+    // a normal situation.  We may also have to forget some information gained
+    // through a quick check that was already performed.
+    if (cp_offset_ != 0) assembler->AdvanceCurrentPosition(cp_offset_);
+    // Create a new trivial state and generate the node with that.
+    Trace new_state;
+    successor->Emit(compiler, &new_state);
+    return;
+  }
+
+  // Generate deferred actions here along with code to undo them again.
+  OutSet affected_registers;
+
+  if (backtrack() != NULL) {
+    // Here we have a concrete backtrack location.  These are set up by choice
+    // nodes and so they indicate that we have a deferred save of the current
+    // position which we may need to emit here.
+    assembler->PushCurrentPosition();
+  }
+
+  int max_register = FindAffectedRegisters(&affected_registers,
+                                           compiler->zone());
+  OutSet registers_to_pop;
+  OutSet registers_to_clear;
+  PerformDeferredActions(assembler,
+                         max_register,
+                         affected_registers,
+                         &registers_to_pop,
+                         &registers_to_clear,
+                         compiler->zone());
+  if (cp_offset_ != 0) {
+    assembler->AdvanceCurrentPosition(cp_offset_);
+  }
+
+  // Create a new trivial state and generate the node with that.
+  Label undo;
+  assembler->PushBacktrack(&undo);
+  Trace new_state;
+  successor->Emit(compiler, &new_state);
+
+  // On backtrack we need to restore state.
+  assembler->Bind(&undo);
+  RestoreAffectedRegisters(assembler,
+                           max_register,
+                           registers_to_pop,
+                           registers_to_clear);
+  if (backtrack() == NULL) {
+    assembler->Backtrack();
+  } else {
+    assembler->PopCurrentPosition();
+    assembler->GoTo(backtrack());
+  }
+}
+
+
+void NegativeSubmatchSuccess::Emit(RegExpCompiler* compiler, Trace* trace) {
+  RegExpMacroAssembler* assembler = compiler->macro_assembler();
+
+  // Omit flushing the trace. We discard the entire stack frame anyway.
+
+  if (!label()->is_bound()) {
+    // We are completely independent of the trace, since we ignore it,
+    // so this code can be used as the generic version.
+    assembler->Bind(label());
+  }
+
+  // Throw away everything on the backtrack stack since the start
+  // of the negative submatch and restore the character position.
+  assembler->ReadCurrentPositionFromRegister(current_position_register_);
+  assembler->ReadStackPointerFromRegister(stack_pointer_register_);
+  if (clear_capture_count_ > 0) {
+    // Clear any captures that might have been performed during the success
+    // of the body of the negative look-ahead.
+    int clear_capture_end = clear_capture_start_ + clear_capture_count_ - 1;
+    assembler->ClearRegisters(clear_capture_start_, clear_capture_end);
+  }
+  // Now that we have unwound the stack we find at the top of the stack the
+  // backtrack that the BeginSubmatch node got.
+  assembler->Backtrack();
+}
+
+
+void EndNode::Emit(RegExpCompiler* compiler, Trace* trace) {
+  if (!trace->is_trivial()) {
+    trace->Flush(compiler, this);
+    return;
+  }
+  RegExpMacroAssembler* assembler = compiler->macro_assembler();
+  if (!label()->is_bound()) {
+    assembler->Bind(label());
+  }
+  switch (action_) {
+    case ACCEPT:
+      assembler->Succeed();
+      return;
+    case BACKTRACK:
+      assembler->GoTo(trace->backtrack());
+      return;
+    case NEGATIVE_SUBMATCH_SUCCESS:
+      // This case is handled in a different virtual method.
+      UNREACHABLE();
+  }
+  UNIMPLEMENTED();
+}
+
+
+void GuardedAlternative::AddGuard(Guard* guard, Zone* zone) {
+  if (guards_ == NULL)
+    guards_ = new(zone) ZoneList<Guard*>(1, zone);
+  guards_->Add(guard, zone);
+}
+
+
+ActionNode* ActionNode::SetRegister(int reg,
+                                    int val,
+                                    RegExpNode* on_success) {
+  ActionNode* result =
+      new(on_success->zone()) ActionNode(SET_REGISTER, on_success);
+  result->data_.u_store_register.reg = reg;
+  result->data_.u_store_register.value = val;
+  return result;
+}
+
+
+ActionNode* ActionNode::IncrementRegister(int reg, RegExpNode* on_success) {
+  ActionNode* result =
+      new(on_success->zone()) ActionNode(INCREMENT_REGISTER, on_success);
+  result->data_.u_increment_register.reg = reg;
+  return result;
+}
+
+
+ActionNode* ActionNode::StorePosition(int reg,
+                                      bool is_capture,
+                                      RegExpNode* on_success) {
+  ActionNode* result =
+      new(on_success->zone()) ActionNode(STORE_POSITION, on_success);
+  result->data_.u_position_register.reg = reg;
+  result->data_.u_position_register.is_capture = is_capture;
+  return result;
+}
+
+
+ActionNode* ActionNode::ClearCaptures(Interval range,
+                                      RegExpNode* on_success) {
+  ActionNode* result =
+      new(on_success->zone()) ActionNode(CLEAR_CAPTURES, on_success);
+  result->data_.u_clear_captures.range_from = range.from();
+  result->data_.u_clear_captures.range_to = range.to();
+  return result;
+}
+
+
+ActionNode* ActionNode::BeginSubmatch(int stack_reg,
+                                      int position_reg,
+                                      RegExpNode* on_success) {
+  ActionNode* result =
+      new(on_success->zone()) ActionNode(BEGIN_SUBMATCH, on_success);
+  result->data_.u_submatch.stack_pointer_register = stack_reg;
+  result->data_.u_submatch.current_position_register = position_reg;
+  return result;
+}
+
+
+ActionNode* ActionNode::PositiveSubmatchSuccess(int stack_reg,
+                                                int position_reg,
+                                                int clear_register_count,
+                                                int clear_register_from,
+                                                RegExpNode* on_success) {
+  ActionNode* result =
+      new(on_success->zone()) ActionNode(POSITIVE_SUBMATCH_SUCCESS, on_success);
+  result->data_.u_submatch.stack_pointer_register = stack_reg;
+  result->data_.u_submatch.current_position_register = position_reg;
+  result->data_.u_submatch.clear_register_count = clear_register_count;
+  result->data_.u_submatch.clear_register_from = clear_register_from;
+  return result;
+}
+
+
+ActionNode* ActionNode::EmptyMatchCheck(int start_register,
+                                        int repetition_register,
+                                        int repetition_limit,
+                                        RegExpNode* on_success) {
+  ActionNode* result =
+      new(on_success->zone()) ActionNode(EMPTY_MATCH_CHECK, on_success);
+  result->data_.u_empty_match_check.start_register = start_register;
+  result->data_.u_empty_match_check.repetition_register = repetition_register;
+  result->data_.u_empty_match_check.repetition_limit = repetition_limit;
+  return result;
+}
+
+
+#define DEFINE_ACCEPT(Type)                                          \
+  void Type##Node::Accept(NodeVisitor* visitor) {                    \
+    visitor->Visit##Type(this);                                      \
+  }
+FOR_EACH_NODE_TYPE(DEFINE_ACCEPT)
+#undef DEFINE_ACCEPT
+
+
+void LoopChoiceNode::Accept(NodeVisitor* visitor) {
+  visitor->VisitLoopChoice(this);
+}
+
+
+// -------------------------------------------------------------------
+// Emit code.
+
+
+void ChoiceNode::GenerateGuard(RegExpMacroAssembler* macro_assembler,
+                               Guard* guard,
+                               Trace* trace) {
+  switch (guard->op()) {
+    case Guard::LT:
+      DCHECK(!trace->mentions_reg(guard->reg()));
+      macro_assembler->IfRegisterGE(guard->reg(),
+                                    guard->value(),
+                                    trace->backtrack());
+      break;
+    case Guard::GEQ:
+      DCHECK(!trace->mentions_reg(guard->reg()));
+      macro_assembler->IfRegisterLT(guard->reg(),
+                                    guard->value(),
+                                    trace->backtrack());
+      break;
+  }
+}
+
+
+// Returns the number of characters in the equivalence class, omitting those
+// that cannot occur in the source string because it is ASCII.
+static int GetCaseIndependentLetters(Isolate* isolate, uc16 character,
+                                     bool one_byte_subject,
+                                     unibrow::uchar* letters) {
+  int length =
+      isolate->jsregexp_uncanonicalize()->get(character, '\0', letters);
+  // Unibrow returns 0 or 1 for characters where case independence is
+  // trivial.
+  if (length == 0) {
+    letters[0] = character;
+    length = 1;
+  }
+  if (!one_byte_subject || character <= String::kMaxOneByteCharCode) {
+    return length;
+  }
+
+  // The standard requires that non-ASCII characters cannot have ASCII
+  // character codes in their equivalence class.
+  // TODO(dcarney): issue 3550 this is not actually true for Latin1 anymore,
+  // is it?  For example, \u00C5 is equivalent to \u212B.
+  return 0;
+}
+
+
+static inline bool EmitSimpleCharacter(Isolate* isolate,
+                                       RegExpCompiler* compiler,
+                                       uc16 c,
+                                       Label* on_failure,
+                                       int cp_offset,
+                                       bool check,
+                                       bool preloaded) {
+  RegExpMacroAssembler* assembler = compiler->macro_assembler();
+  bool bound_checked = false;
+  if (!preloaded) {
+    assembler->LoadCurrentCharacter(
+        cp_offset,
+        on_failure,
+        check);
+    bound_checked = true;
+  }
+  assembler->CheckNotCharacter(c, on_failure);
+  return bound_checked;
+}
+
+
+// Only emits non-letters (things that don't have case).  Only used for case
+// independent matches.
+static inline bool EmitAtomNonLetter(Isolate* isolate,
+                                     RegExpCompiler* compiler,
+                                     uc16 c,
+                                     Label* on_failure,
+                                     int cp_offset,
+                                     bool check,
+                                     bool preloaded) {
+  RegExpMacroAssembler* macro_assembler = compiler->macro_assembler();
+  bool one_byte = compiler->one_byte();
+  unibrow::uchar chars[unibrow::Ecma262UnCanonicalize::kMaxWidth];
+  int length = GetCaseIndependentLetters(isolate, c, one_byte, chars);
+  if (length < 1) {
+    // This can't match.  Must be an one-byte subject and a non-one-byte
+    // character.  We do not need to do anything since the one-byte pass
+    // already handled this.
+    return false;  // Bounds not checked.
+  }
+  bool checked = false;
+  // We handle the length > 1 case in a later pass.
+  if (length == 1) {
+    if (one_byte && c > String::kMaxOneByteCharCodeU) {
+      // Can't match - see above.
+      return false;  // Bounds not checked.
+    }
+    if (!preloaded) {
+      macro_assembler->LoadCurrentCharacter(cp_offset, on_failure, check);
+      checked = check;
+    }
+    macro_assembler->CheckNotCharacter(c, on_failure);
+  }
+  return checked;
+}
+
+
+static bool ShortCutEmitCharacterPair(RegExpMacroAssembler* macro_assembler,
+                                      bool one_byte, uc16 c1, uc16 c2,
+                                      Label* on_failure) {
+  uc16 char_mask;
+  if (one_byte) {
+    char_mask = String::kMaxOneByteCharCode;
+  } else {
+    char_mask = String::kMaxUtf16CodeUnit;
+  }
+  uc16 exor = c1 ^ c2;
+  // Check whether exor has only one bit set.
+  if (((exor - 1) & exor) == 0) {
+    // If c1 and c2 differ only by one bit.
+    // Ecma262UnCanonicalize always gives the highest number last.
+    DCHECK(c2 > c1);
+    uc16 mask = char_mask ^ exor;
+    macro_assembler->CheckNotCharacterAfterAnd(c1, mask, on_failure);
+    return true;
+  }
+  DCHECK(c2 > c1);
+  uc16 diff = c2 - c1;
+  if (((diff - 1) & diff) == 0 && c1 >= diff) {
+    // If the characters differ by 2^n but don't differ by one bit then
+    // subtract the difference from the found character, then do the or
+    // trick.  We avoid the theoretical case where negative numbers are
+    // involved in order to simplify code generation.
+    uc16 mask = char_mask ^ diff;
+    macro_assembler->CheckNotCharacterAfterMinusAnd(c1 - diff,
+                                                    diff,
+                                                    mask,
+                                                    on_failure);
+    return true;
+  }
+  return false;
+}
+
+
+typedef bool EmitCharacterFunction(Isolate* isolate,
+                                   RegExpCompiler* compiler,
+                                   uc16 c,
+                                   Label* on_failure,
+                                   int cp_offset,
+                                   bool check,
+                                   bool preloaded);
+
+// Only emits letters (things that have case).  Only used for case independent
+// matches.
+static inline bool EmitAtomLetter(Isolate* isolate,
+                                  RegExpCompiler* compiler,
+                                  uc16 c,
+                                  Label* on_failure,
+                                  int cp_offset,
+                                  bool check,
+                                  bool preloaded) {
+  RegExpMacroAssembler* macro_assembler = compiler->macro_assembler();
+  bool one_byte = compiler->one_byte();
+  unibrow::uchar chars[unibrow::Ecma262UnCanonicalize::kMaxWidth];
+  int length = GetCaseIndependentLetters(isolate, c, one_byte, chars);
+  if (length <= 1) return false;
+  // We may not need to check against the end of the input string
+  // if this character lies before a character that matched.
+  if (!preloaded) {
+    macro_assembler->LoadCurrentCharacter(cp_offset, on_failure, check);
+  }
+  Label ok;
+  DCHECK(unibrow::Ecma262UnCanonicalize::kMaxWidth == 4);
+  switch (length) {
+    case 2: {
+      if (ShortCutEmitCharacterPair(macro_assembler, one_byte, chars[0],
+                                    chars[1], on_failure)) {
+      } else {
+        macro_assembler->CheckCharacter(chars[0], &ok);
+        macro_assembler->CheckNotCharacter(chars[1], on_failure);
+        macro_assembler->Bind(&ok);
+      }
+      break;
+    }
+    case 4:
+      macro_assembler->CheckCharacter(chars[3], &ok);
+      // Fall through!
+    case 3:
+      macro_assembler->CheckCharacter(chars[0], &ok);
+      macro_assembler->CheckCharacter(chars[1], &ok);
+      macro_assembler->CheckNotCharacter(chars[2], on_failure);
+      macro_assembler->Bind(&ok);
+      break;
+    default:
+      UNREACHABLE();
+      break;
+  }
+  return true;
+}
+
+
+static void EmitBoundaryTest(RegExpMacroAssembler* masm,
+                             int border,
+                             Label* fall_through,
+                             Label* above_or_equal,
+                             Label* below) {
+  if (below != fall_through) {
+    masm->CheckCharacterLT(border, below);
+    if (above_or_equal != fall_through) masm->GoTo(above_or_equal);
+  } else {
+    masm->CheckCharacterGT(border - 1, above_or_equal);
+  }
+}
+
+
+static void EmitDoubleBoundaryTest(RegExpMacroAssembler* masm,
+                                   int first,
+                                   int last,
+                                   Label* fall_through,
+                                   Label* in_range,
+                                   Label* out_of_range) {
+  if (in_range == fall_through) {
+    if (first == last) {
+      masm->CheckNotCharacter(first, out_of_range);
+    } else {
+      masm->CheckCharacterNotInRange(first, last, out_of_range);
+    }
+  } else {
+    if (first == last) {
+      masm->CheckCharacter(first, in_range);
+    } else {
+      masm->CheckCharacterInRange(first, last, in_range);
+    }
+    if (out_of_range != fall_through) masm->GoTo(out_of_range);
+  }
+}
+
+
+// even_label is for ranges[i] to ranges[i + 1] where i - start_index is even.
+// odd_label is for ranges[i] to ranges[i + 1] where i - start_index is odd.
+static void EmitUseLookupTable(
+    RegExpMacroAssembler* masm,
+    ZoneList<int>* ranges,
+    int start_index,
+    int end_index,
+    int min_char,
+    Label* fall_through,
+    Label* even_label,
+    Label* odd_label) {
+  static const int kSize = RegExpMacroAssembler::kTableSize;
+  static const int kMask = RegExpMacroAssembler::kTableMask;
+
+  int base = (min_char & ~kMask);
+  USE(base);
+
+  // Assert that everything is on one kTableSize page.
+  for (int i = start_index; i <= end_index; i++) {
+    DCHECK_EQ(ranges->at(i) & ~kMask, base);
+  }
+  DCHECK(start_index == 0 || (ranges->at(start_index - 1) & ~kMask) <= base);
+
+  char templ[kSize];
+  Label* on_bit_set;
+  Label* on_bit_clear;
+  int bit;
+  if (even_label == fall_through) {
+    on_bit_set = odd_label;
+    on_bit_clear = even_label;
+    bit = 1;
+  } else {
+    on_bit_set = even_label;
+    on_bit_clear = odd_label;
+    bit = 0;
+  }
+  for (int i = 0; i < (ranges->at(start_index) & kMask) && i < kSize; i++) {
+    templ[i] = bit;
+  }
+  int j = 0;
+  bit ^= 1;
+  for (int i = start_index; i < end_index; i++) {
+    for (j = (ranges->at(i) & kMask); j < (ranges->at(i + 1) & kMask); j++) {
+      templ[j] = bit;
+    }
+    bit ^= 1;
+  }
+  for (int i = j; i < kSize; i++) {
+    templ[i] = bit;
+  }
+  Factory* factory = masm->zone()->isolate()->factory();
+  // TODO(erikcorry): Cache these.
+  Handle<ByteArray> ba = factory->NewByteArray(kSize, TENURED);
+  for (int i = 0; i < kSize; i++) {
+    ba->set(i, templ[i]);
+  }
+  masm->CheckBitInTable(ba, on_bit_set);
+  if (on_bit_clear != fall_through) masm->GoTo(on_bit_clear);
+}
+
+
+static void CutOutRange(RegExpMacroAssembler* masm,
+                        ZoneList<int>* ranges,
+                        int start_index,
+                        int end_index,
+                        int cut_index,
+                        Label* even_label,
+                        Label* odd_label) {
+  bool odd = (((cut_index - start_index) & 1) == 1);
+  Label* in_range_label = odd ? odd_label : even_label;
+  Label dummy;
+  EmitDoubleBoundaryTest(masm,
+                         ranges->at(cut_index),
+                         ranges->at(cut_index + 1) - 1,
+                         &dummy,
+                         in_range_label,
+                         &dummy);
+  DCHECK(!dummy.is_linked());
+  // Cut out the single range by rewriting the array.  This creates a new
+  // range that is a merger of the two ranges on either side of the one we
+  // are cutting out.  The oddity of the labels is preserved.
+  for (int j = cut_index; j > start_index; j--) {
+    ranges->at(j) = ranges->at(j - 1);
+  }
+  for (int j = cut_index + 1; j < end_index; j++) {
+    ranges->at(j) = ranges->at(j + 1);
+  }
+}
+
+
+// Unicode case.  Split the search space into kSize spaces that are handled
+// with recursion.
+static void SplitSearchSpace(ZoneList<int>* ranges,
+                             int start_index,
+                             int end_index,
+                             int* new_start_index,
+                             int* new_end_index,
+                             int* border) {
+  static const int kSize = RegExpMacroAssembler::kTableSize;
+  static const int kMask = RegExpMacroAssembler::kTableMask;
+
+  int first = ranges->at(start_index);
+  int last = ranges->at(end_index) - 1;
+
+  *new_start_index = start_index;
+  *border = (ranges->at(start_index) & ~kMask) + kSize;
+  while (*new_start_index < end_index) {
+    if (ranges->at(*new_start_index) > *border) break;
+    (*new_start_index)++;
+  }
+  // new_start_index is the index of the first edge that is beyond the
+  // current kSize space.
+
+  // For very large search spaces we do a binary chop search of the non-Latin1
+  // space instead of just going to the end of the current kSize space.  The
+  // heuristics are complicated a little by the fact that any 128-character
+  // encoding space can be quickly tested with a table lookup, so we don't
+  // wish to do binary chop search at a smaller granularity than that.  A
+  // 128-character space can take up a lot of space in the ranges array if,
+  // for example, we only want to match every second character (eg. the lower
+  // case characters on some Unicode pages).
+  int binary_chop_index = (end_index + start_index) / 2;
+  // The first test ensures that we get to the code that handles the Latin1
+  // range with a single not-taken branch, speeding up this important
+  // character range (even non-Latin1 charset-based text has spaces and
+  // punctuation).
+  if (*border - 1 > String::kMaxOneByteCharCode &&  // Latin1 case.
+      end_index - start_index > (*new_start_index - start_index) * 2 &&
+      last - first > kSize * 2 && binary_chop_index > *new_start_index &&
+      ranges->at(binary_chop_index) >= first + 2 * kSize) {
+    int scan_forward_for_section_border = binary_chop_index;;
+    int new_border = (ranges->at(binary_chop_index) | kMask) + 1;
+
+    while (scan_forward_for_section_border < end_index) {
+      if (ranges->at(scan_forward_for_section_border) > new_border) {
+        *new_start_index = scan_forward_for_section_border;
+        *border = new_border;
+        break;
+      }
+      scan_forward_for_section_border++;
+    }
+  }
+
+  DCHECK(*new_start_index > start_index);
+  *new_end_index = *new_start_index - 1;
+  if (ranges->at(*new_end_index) == *border) {
+    (*new_end_index)--;
+  }
+  if (*border >= ranges->at(end_index)) {
+    *border = ranges->at(end_index);
+    *new_start_index = end_index;  // Won't be used.
+    *new_end_index = end_index - 1;
+  }
+}
+
+
+// Gets a series of segment boundaries representing a character class.  If the
+// character is in the range between an even and an odd boundary (counting from
+// start_index) then go to even_label, otherwise go to odd_label.  We already
+// know that the character is in the range of min_char to max_char inclusive.
+// Either label can be NULL indicating backtracking.  Either label can also be
+// equal to the fall_through label.
+static void GenerateBranches(RegExpMacroAssembler* masm,
+                             ZoneList<int>* ranges,
+                             int start_index,
+                             int end_index,
+                             uc16 min_char,
+                             uc16 max_char,
+                             Label* fall_through,
+                             Label* even_label,
+                             Label* odd_label) {
+  int first = ranges->at(start_index);
+  int last = ranges->at(end_index) - 1;
+
+  DCHECK_LT(min_char, first);
+
+  // Just need to test if the character is before or on-or-after
+  // a particular character.
+  if (start_index == end_index) {
+    EmitBoundaryTest(masm, first, fall_through, even_label, odd_label);
+    return;
+  }
+
+  // Another almost trivial case:  There is one interval in the middle that is
+  // different from the end intervals.
+  if (start_index + 1 == end_index) {
+    EmitDoubleBoundaryTest(
+        masm, first, last, fall_through, even_label, odd_label);
+    return;
+  }
+
+  // It's not worth using table lookup if there are very few intervals in the
+  // character class.
+  if (end_index - start_index <= 6) {
+    // It is faster to test for individual characters, so we look for those
+    // first, then try arbitrary ranges in the second round.
+    static int kNoCutIndex = -1;
+    int cut = kNoCutIndex;
+    for (int i = start_index; i < end_index; i++) {
+      if (ranges->at(i) == ranges->at(i + 1) - 1) {
+        cut = i;
+        break;
+      }
+    }
+    if (cut == kNoCutIndex) cut = start_index;
+    CutOutRange(
+        masm, ranges, start_index, end_index, cut, even_label, odd_label);
+    DCHECK_GE(end_index - start_index, 2);
+    GenerateBranches(masm,
+                     ranges,
+                     start_index + 1,
+                     end_index - 1,
+                     min_char,
+                     max_char,
+                     fall_through,
+                     even_label,
+                     odd_label);
+    return;
+  }
+
+  // If there are a lot of intervals in the regexp, then we will use tables to
+  // determine whether the character is inside or outside the character class.
+  static const int kBits = RegExpMacroAssembler::kTableSizeBits;
+
+  if ((max_char >> kBits) == (min_char >> kBits)) {
+    EmitUseLookupTable(masm,
+                       ranges,
+                       start_index,
+                       end_index,
+                       min_char,
+                       fall_through,
+                       even_label,
+                       odd_label);
+    return;
+  }
+
+  if ((min_char >> kBits) != (first >> kBits)) {
+    masm->CheckCharacterLT(first, odd_label);
+    GenerateBranches(masm,
+                     ranges,
+                     start_index + 1,
+                     end_index,
+                     first,
+                     max_char,
+                     fall_through,
+                     odd_label,
+                     even_label);
+    return;
+  }
+
+  int new_start_index = 0;
+  int new_end_index = 0;
+  int border = 0;
+
+  SplitSearchSpace(ranges,
+                   start_index,
+                   end_index,
+                   &new_start_index,
+                   &new_end_index,
+                   &border);
+
+  Label handle_rest;
+  Label* above = &handle_rest;
+  if (border == last + 1) {
+    // We didn't find any section that started after the limit, so everything
+    // above the border is one of the terminal labels.
+    above = (end_index & 1) != (start_index & 1) ? odd_label : even_label;
+    DCHECK(new_end_index == end_index - 1);
+  }
+
+  DCHECK_LE(start_index, new_end_index);
+  DCHECK_LE(new_start_index, end_index);
+  DCHECK_LT(start_index, new_start_index);
+  DCHECK_LT(new_end_index, end_index);
+  DCHECK(new_end_index + 1 == new_start_index ||
+         (new_end_index + 2 == new_start_index &&
+          border == ranges->at(new_end_index + 1)));
+  DCHECK_LT(min_char, border - 1);
+  DCHECK_LT(border, max_char);
+  DCHECK_LT(ranges->at(new_end_index), border);
+  DCHECK(border < ranges->at(new_start_index) ||
+         (border == ranges->at(new_start_index) &&
+          new_start_index == end_index &&
+          new_end_index == end_index - 1 &&
+          border == last + 1));
+  DCHECK(new_start_index == 0 || border >= ranges->at(new_start_index - 1));
+
+  masm->CheckCharacterGT(border - 1, above);
+  Label dummy;
+  GenerateBranches(masm,
+                   ranges,
+                   start_index,
+                   new_end_index,
+                   min_char,
+                   border - 1,
+                   &dummy,
+                   even_label,
+                   odd_label);
+  if (handle_rest.is_linked()) {
+    masm->Bind(&handle_rest);
+    bool flip = (new_start_index & 1) != (start_index & 1);
+    GenerateBranches(masm,
+                     ranges,
+                     new_start_index,
+                     end_index,
+                     border,
+                     max_char,
+                     &dummy,
+                     flip ? odd_label : even_label,
+                     flip ? even_label : odd_label);
+  }
+}
+
+
+static void EmitCharClass(RegExpMacroAssembler* macro_assembler,
+                          RegExpCharacterClass* cc, bool one_byte,
+                          Label* on_failure, int cp_offset, bool check_offset,
+                          bool preloaded, Zone* zone) {
+  ZoneList<CharacterRange>* ranges = cc->ranges(zone);
+  if (!CharacterRange::IsCanonical(ranges)) {
+    CharacterRange::Canonicalize(ranges);
+  }
+
+  int max_char;
+  if (one_byte) {
+    max_char = String::kMaxOneByteCharCode;
+  } else {
+    max_char = String::kMaxUtf16CodeUnit;
+  }
+
+  int range_count = ranges->length();
+
+  int last_valid_range = range_count - 1;
+  while (last_valid_range >= 0) {
+    CharacterRange& range = ranges->at(last_valid_range);
+    if (range.from() <= max_char) {
+      break;
+    }
+    last_valid_range--;
+  }
+
+  if (last_valid_range < 0) {
+    if (!cc->is_negated()) {
+      macro_assembler->GoTo(on_failure);
+    }
+    if (check_offset) {
+      macro_assembler->CheckPosition(cp_offset, on_failure);
+    }
+    return;
+  }
+
+  if (last_valid_range == 0 &&
+      ranges->at(0).IsEverything(max_char)) {
+    if (cc->is_negated()) {
+      macro_assembler->GoTo(on_failure);
+    } else {
+      // This is a common case hit by non-anchored expressions.
+      if (check_offset) {
+        macro_assembler->CheckPosition(cp_offset, on_failure);
+      }
+    }
+    return;
+  }
+  if (last_valid_range == 0 &&
+      !cc->is_negated() &&
+      ranges->at(0).IsEverything(max_char)) {
+    // This is a common case hit by non-anchored expressions.
+    if (check_offset) {
+      macro_assembler->CheckPosition(cp_offset, on_failure);
+    }
+    return;
+  }
+
+  if (!preloaded) {
+    macro_assembler->LoadCurrentCharacter(cp_offset, on_failure, check_offset);
+  }
+
+  if (cc->is_standard(zone) &&
+        macro_assembler->CheckSpecialCharacterClass(cc->standard_type(),
+                                                    on_failure)) {
+      return;
+  }
+
+
+  // A new list with ascending entries.  Each entry is a code unit
+  // where there is a boundary between code units that are part of
+  // the class and code units that are not.  Normally we insert an
+  // entry at zero which goes to the failure label, but if there
+  // was already one there we fall through for success on that entry.
+  // Subsequent entries have alternating meaning (success/failure).
+  ZoneList<int>* range_boundaries =
+      new(zone) ZoneList<int>(last_valid_range, zone);
+
+  bool zeroth_entry_is_failure = !cc->is_negated();
+
+  for (int i = 0; i <= last_valid_range; i++) {
+    CharacterRange& range = ranges->at(i);
+    if (range.from() == 0) {
+      DCHECK_EQ(i, 0);
+      zeroth_entry_is_failure = !zeroth_entry_is_failure;
+    } else {
+      range_boundaries->Add(range.from(), zone);
+    }
+    range_boundaries->Add(range.to() + 1, zone);
+  }
+  int end_index = range_boundaries->length() - 1;
+  if (range_boundaries->at(end_index) > max_char) {
+    end_index--;
+  }
+
+  Label fall_through;
+  GenerateBranches(macro_assembler,
+                   range_boundaries,
+                   0,  // start_index.
+                   end_index,
+                   0,  // min_char.
+                   max_char,
+                   &fall_through,
+                   zeroth_entry_is_failure ? &fall_through : on_failure,
+                   zeroth_entry_is_failure ? on_failure : &fall_through);
+  macro_assembler->Bind(&fall_through);
+}
+
+
+RegExpNode::~RegExpNode() {
+}
+
+
+RegExpNode::LimitResult RegExpNode::LimitVersions(RegExpCompiler* compiler,
+                                                  Trace* trace) {
+  // If we are generating a greedy loop then don't stop and don't reuse code.
+  if (trace->stop_node() != NULL) {
+    return CONTINUE;
+  }
+
+  RegExpMacroAssembler* macro_assembler = compiler->macro_assembler();
+  if (trace->is_trivial()) {
+    if (label_.is_bound()) {
+      // We are being asked to generate a generic version, but that's already
+      // been done so just go to it.
+      macro_assembler->GoTo(&label_);
+      return DONE;
+    }
+    if (compiler->recursion_depth() >= RegExpCompiler::kMaxRecursion) {
+      // To avoid too deep recursion we push the node to the work queue and just
+      // generate a goto here.
+      compiler->AddWork(this);
+      macro_assembler->GoTo(&label_);
+      return DONE;
+    }
+    // Generate generic version of the node and bind the label for later use.
+    macro_assembler->Bind(&label_);
+    return CONTINUE;
+  }
+
+  // We are being asked to make a non-generic version.  Keep track of how many
+  // non-generic versions we generate so as not to overdo it.
+  trace_count_++;
+  if (FLAG_regexp_optimization &&
+      trace_count_ < kMaxCopiesCodeGenerated &&
+      compiler->recursion_depth() <= RegExpCompiler::kMaxRecursion) {
+    return CONTINUE;
+  }
+
+  // If we get here code has been generated for this node too many times or
+  // recursion is too deep.  Time to switch to a generic version.  The code for
+  // generic versions above can handle deep recursion properly.
+  trace->Flush(compiler, this);
+  return DONE;
+}
+
+
+int ActionNode::EatsAtLeast(int still_to_find,
+                            int budget,
+                            bool not_at_start) {
+  if (budget <= 0) return 0;
+  if (action_type_ == POSITIVE_SUBMATCH_SUCCESS) return 0;  // Rewinds input!
+  return on_success()->EatsAtLeast(still_to_find,
+                                   budget - 1,
+                                   not_at_start);
+}
+
+
+void ActionNode::FillInBMInfo(int offset,
+                              int budget,
+                              BoyerMooreLookahead* bm,
+                              bool not_at_start) {
+  if (action_type_ == BEGIN_SUBMATCH) {
+    bm->SetRest(offset);
+  } else if (action_type_ != POSITIVE_SUBMATCH_SUCCESS) {
+    on_success()->FillInBMInfo(offset, budget - 1, bm, not_at_start);
+  }
+  SaveBMInfo(bm, not_at_start, offset);
+}
+
+
+int AssertionNode::EatsAtLeast(int still_to_find,
+                               int budget,
+                               bool not_at_start) {
+  if (budget <= 0) return 0;
+  // If we know we are not at the start and we are asked "how many characters
+  // will you match if you succeed?" then we can answer anything since false
+  // implies false.  So lets just return the max answer (still_to_find) since
+  // that won't prevent us from preloading a lot of characters for the other
+  // branches in the node graph.
+  if (assertion_type() == AT_START && not_at_start) return still_to_find;
+  return on_success()->EatsAtLeast(still_to_find,
+                                   budget - 1,
+                                   not_at_start);
+}
+
+
+void AssertionNode::FillInBMInfo(int offset,
+                                 int budget,
+                                 BoyerMooreLookahead* bm,
+                                 bool not_at_start) {
+  // Match the behaviour of EatsAtLeast on this node.
+  if (assertion_type() == AT_START && not_at_start) return;
+  on_success()->FillInBMInfo(offset, budget - 1, bm, not_at_start);
+  SaveBMInfo(bm, not_at_start, offset);
+}
+
+
+int BackReferenceNode::EatsAtLeast(int still_to_find,
+                                   int budget,
+                                   bool not_at_start) {
+  if (budget <= 0) return 0;
+  return on_success()->EatsAtLeast(still_to_find,
+                                   budget - 1,
+                                   not_at_start);
+}
+
+
+int TextNode::EatsAtLeast(int still_to_find,
+                          int budget,
+                          bool not_at_start) {
+  int answer = Length();
+  if (answer >= still_to_find) return answer;
+  if (budget <= 0) return answer;
+  // We are not at start after this node so we set the last argument to 'true'.
+  return answer + on_success()->EatsAtLeast(still_to_find - answer,
+                                            budget - 1,
+                                            true);
+}
+
+
+int NegativeLookaheadChoiceNode::EatsAtLeast(int still_to_find,
+                                             int budget,
+                                             bool not_at_start) {
+  if (budget <= 0) return 0;
+  // Alternative 0 is the negative lookahead, alternative 1 is what comes
+  // afterwards.
+  RegExpNode* node = alternatives_->at(1).node();
+  return node->EatsAtLeast(still_to_find, budget - 1, not_at_start);
+}
+
+
+void NegativeLookaheadChoiceNode::GetQuickCheckDetails(
+    QuickCheckDetails* details,
+    RegExpCompiler* compiler,
+    int filled_in,
+    bool not_at_start) {
+  // Alternative 0 is the negative lookahead, alternative 1 is what comes
+  // afterwards.
+  RegExpNode* node = alternatives_->at(1).node();
+  return node->GetQuickCheckDetails(details, compiler, filled_in, not_at_start);
+}
+
+
+int ChoiceNode::EatsAtLeastHelper(int still_to_find,
+                                  int budget,
+                                  RegExpNode* ignore_this_node,
+                                  bool not_at_start) {
+  if (budget <= 0) return 0;
+  int min = 100;
+  int choice_count = alternatives_->length();
+  budget = (budget - 1) / choice_count;
+  for (int i = 0; i < choice_count; i++) {
+    RegExpNode* node = alternatives_->at(i).node();
+    if (node == ignore_this_node) continue;
+    int node_eats_at_least =
+        node->EatsAtLeast(still_to_find, budget, not_at_start);
+    if (node_eats_at_least < min) min = node_eats_at_least;
+    if (min == 0) return 0;
+  }
+  return min;
+}
+
+
+int LoopChoiceNode::EatsAtLeast(int still_to_find,
+                                int budget,
+                                bool not_at_start) {
+  return EatsAtLeastHelper(still_to_find,
+                           budget - 1,
+                           loop_node_,
+                           not_at_start);
+}
+
+
+int ChoiceNode::EatsAtLeast(int still_to_find,
+                            int budget,
+                            bool not_at_start) {
+  return EatsAtLeastHelper(still_to_find,
+                           budget,
+                           NULL,
+                           not_at_start);
+}
+
+
+// Takes the left-most 1-bit and smears it out, setting all bits to its right.
+static inline uint32_t SmearBitsRight(uint32_t v) {
+  v |= v >> 1;
+  v |= v >> 2;
+  v |= v >> 4;
+  v |= v >> 8;
+  v |= v >> 16;
+  return v;
+}
+
+
+bool QuickCheckDetails::Rationalize(bool asc) {
+  bool found_useful_op = false;
+  uint32_t char_mask;
+  if (asc) {
+    char_mask = String::kMaxOneByteCharCode;
+  } else {
+    char_mask = String::kMaxUtf16CodeUnit;
+  }
+  mask_ = 0;
+  value_ = 0;
+  int char_shift = 0;
+  for (int i = 0; i < characters_; i++) {
+    Position* pos = &positions_[i];
+    if ((pos->mask & String::kMaxOneByteCharCode) != 0) {
+      found_useful_op = true;
+    }
+    mask_ |= (pos->mask & char_mask) << char_shift;
+    value_ |= (pos->value & char_mask) << char_shift;
+    char_shift += asc ? 8 : 16;
+  }
+  return found_useful_op;
+}
+
+
+bool RegExpNode::EmitQuickCheck(RegExpCompiler* compiler,
+                                Trace* bounds_check_trace,
+                                Trace* trace,
+                                bool preload_has_checked_bounds,
+                                Label* on_possible_success,
+                                QuickCheckDetails* details,
+                                bool fall_through_on_failure) {
+  if (details->characters() == 0) return false;
+  GetQuickCheckDetails(
+      details, compiler, 0, trace->at_start() == Trace::FALSE_VALUE);
+  if (details->cannot_match()) return false;
+  if (!details->Rationalize(compiler->one_byte())) return false;
+  DCHECK(details->characters() == 1 ||
+         compiler->macro_assembler()->CanReadUnaligned());
+  uint32_t mask = details->mask();
+  uint32_t value = details->value();
+
+  RegExpMacroAssembler* assembler = compiler->macro_assembler();
+
+  if (trace->characters_preloaded() != details->characters()) {
+    DCHECK(trace->cp_offset() == bounds_check_trace->cp_offset());
+    // We are attempting to preload the minimum number of characters
+    // any choice would eat, so if the bounds check fails, then none of the
+    // choices can succeed, so we can just immediately backtrack, rather
+    // than go to the next choice.
+    assembler->LoadCurrentCharacter(trace->cp_offset(),
+                                    bounds_check_trace->backtrack(),
+                                    !preload_has_checked_bounds,
+                                    details->characters());
+  }
+
+
+  bool need_mask = true;
+
+  if (details->characters() == 1) {
+    // If number of characters preloaded is 1 then we used a byte or 16 bit
+    // load so the value is already masked down.
+    uint32_t char_mask;
+    if (compiler->one_byte()) {
+      char_mask = String::kMaxOneByteCharCode;
+    } else {
+      char_mask = String::kMaxUtf16CodeUnit;
+    }
+    if ((mask & char_mask) == char_mask) need_mask = false;
+    mask &= char_mask;
+  } else {
+    // For 2-character preloads in one-byte mode or 1-character preloads in
+    // two-byte mode we also use a 16 bit load with zero extend.
+    if (details->characters() == 2 && compiler->one_byte()) {
+      if ((mask & 0xffff) == 0xffff) need_mask = false;
+    } else if (details->characters() == 1 && !compiler->one_byte()) {
+      if ((mask & 0xffff) == 0xffff) need_mask = false;
+    } else {
+      if (mask == 0xffffffff) need_mask = false;
+    }
+  }
+
+  if (fall_through_on_failure) {
+    if (need_mask) {
+      assembler->CheckCharacterAfterAnd(value, mask, on_possible_success);
+    } else {
+      assembler->CheckCharacter(value, on_possible_success);
+    }
+  } else {
+    if (need_mask) {
+      assembler->CheckNotCharacterAfterAnd(value, mask, trace->backtrack());
+    } else {
+      assembler->CheckNotCharacter(value, trace->backtrack());
+    }
+  }
+  return true;
+}
+
+
+// Here is the meat of GetQuickCheckDetails (see also the comment on the
+// super-class in the .h file).
+//
+// We iterate along the text object, building up for each character a
+// mask and value that can be used to test for a quick failure to match.
+// The masks and values for the positions will be combined into a single
+// machine word for the current character width in order to be used in
+// generating a quick check.
+void TextNode::GetQuickCheckDetails(QuickCheckDetails* details,
+                                    RegExpCompiler* compiler,
+                                    int characters_filled_in,
+                                    bool not_at_start) {
+  Isolate* isolate = compiler->macro_assembler()->zone()->isolate();
+  DCHECK(characters_filled_in < details->characters());
+  int characters = details->characters();
+  int char_mask;
+  if (compiler->one_byte()) {
+    char_mask = String::kMaxOneByteCharCode;
+  } else {
+    char_mask = String::kMaxUtf16CodeUnit;
+  }
+  for (int k = 0; k < elms_->length(); k++) {
+    TextElement elm = elms_->at(k);
+    if (elm.text_type() == TextElement::ATOM) {
+      Vector<const uc16> quarks = elm.atom()->data();
+      for (int i = 0; i < characters && i < quarks.length(); i++) {
+        QuickCheckDetails::Position* pos =
+            details->positions(characters_filled_in);
+        uc16 c = quarks[i];
+        if (c > char_mask) {
+          // If we expect a non-Latin1 character from an one-byte string,
+          // there is no way we can match. Not even case-independent
+          // matching can turn an Latin1 character into non-Latin1 or
+          // vice versa.
+          // TODO(dcarney): issue 3550.  Verify that this works as expected.
+          // For example, \u0178 is uppercase of \u00ff (y-umlaut).
+          details->set_cannot_match();
+          pos->determines_perfectly = false;
+          return;
+        }
+        if (compiler->ignore_case()) {
+          unibrow::uchar chars[unibrow::Ecma262UnCanonicalize::kMaxWidth];
+          int length = GetCaseIndependentLetters(isolate, c,
+                                                 compiler->one_byte(), chars);
+          DCHECK(length != 0);  // Can only happen if c > char_mask (see above).
+          if (length == 1) {
+            // This letter has no case equivalents, so it's nice and simple
+            // and the mask-compare will determine definitely whether we have
+            // a match at this character position.
+            pos->mask = char_mask;
+            pos->value = c;
+            pos->determines_perfectly = true;
+          } else {
+            uint32_t common_bits = char_mask;
+            uint32_t bits = chars[0];
+            for (int j = 1; j < length; j++) {
+              uint32_t differing_bits = ((chars[j] & common_bits) ^ bits);
+              common_bits ^= differing_bits;
+              bits &= common_bits;
+            }
+            // If length is 2 and common bits has only one zero in it then
+            // our mask and compare instruction will determine definitely
+            // whether we have a match at this character position.  Otherwise
+            // it can only be an approximate check.
+            uint32_t one_zero = (common_bits | ~char_mask);
+            if (length == 2 && ((~one_zero) & ((~one_zero) - 1)) == 0) {
+              pos->determines_perfectly = true;
+            }
+            pos->mask = common_bits;
+            pos->value = bits;
+          }
+        } else {
+          // Don't ignore case.  Nice simple case where the mask-compare will
+          // determine definitely whether we have a match at this character
+          // position.
+          pos->mask = char_mask;
+          pos->value = c;
+          pos->determines_perfectly = true;
+        }
+        characters_filled_in++;
+        DCHECK(characters_filled_in <= details->characters());
+        if (characters_filled_in == details->characters()) {
+          return;
+        }
+      }
+    } else {
+      QuickCheckDetails::Position* pos =
+          details->positions(characters_filled_in);
+      RegExpCharacterClass* tree = elm.char_class();
+      ZoneList<CharacterRange>* ranges = tree->ranges(zone());
+      if (tree->is_negated()) {
+        // A quick check uses multi-character mask and compare.  There is no
+        // useful way to incorporate a negative char class into this scheme
+        // so we just conservatively create a mask and value that will always
+        // succeed.
+        pos->mask = 0;
+        pos->value = 0;
+      } else {
+        int first_range = 0;
+        while (ranges->at(first_range).from() > char_mask) {
+          first_range++;
+          if (first_range == ranges->length()) {
+            details->set_cannot_match();
+            pos->determines_perfectly = false;
+            return;
+          }
+        }
+        CharacterRange range = ranges->at(first_range);
+        uc16 from = range.from();
+        uc16 to = range.to();
+        if (to > char_mask) {
+          to = char_mask;
+        }
+        uint32_t differing_bits = (from ^ to);
+        // A mask and compare is only perfect if the differing bits form a
+        // number like 00011111 with one single block of trailing 1s.
+        if ((differing_bits & (differing_bits + 1)) == 0 &&
+             from + differing_bits == to) {
+          pos->determines_perfectly = true;
+        }
+        uint32_t common_bits = ~SmearBitsRight(differing_bits);
+        uint32_t bits = (from & common_bits);
+        for (int i = first_range + 1; i < ranges->length(); i++) {
+          CharacterRange range = ranges->at(i);
+          uc16 from = range.from();
+          uc16 to = range.to();
+          if (from > char_mask) continue;
+          if (to > char_mask) to = char_mask;
+          // Here we are combining more ranges into the mask and compare
+          // value.  With each new range the mask becomes more sparse and
+          // so the chances of a false positive rise.  A character class
+          // with multiple ranges is assumed never to be equivalent to a
+          // mask and compare operation.
+          pos->determines_perfectly = false;
+          uint32_t new_common_bits = (from ^ to);
+          new_common_bits = ~SmearBitsRight(new_common_bits);
+          common_bits &= new_common_bits;
+          bits &= new_common_bits;
+          uint32_t differing_bits = (from & common_bits) ^ bits;
+          common_bits ^= differing_bits;
+          bits &= common_bits;
+        }
+        pos->mask = common_bits;
+        pos->value = bits;
+      }
+      characters_filled_in++;
+      DCHECK(characters_filled_in <= details->characters());
+      if (characters_filled_in == details->characters()) {
+        return;
+      }
+    }
+  }
+  DCHECK(characters_filled_in != details->characters());
+  if (!details->cannot_match()) {
+    on_success()-> GetQuickCheckDetails(details,
+                                        compiler,
+                                        characters_filled_in,
+                                        true);
+  }
+}
+
+
+void QuickCheckDetails::Clear() {
+  for (int i = 0; i < characters_; i++) {
+    positions_[i].mask = 0;
+    positions_[i].value = 0;
+    positions_[i].determines_perfectly = false;
+  }
+  characters_ = 0;
+}
+
+
+void QuickCheckDetails::Advance(int by, bool one_byte) {
+  DCHECK(by >= 0);
+  if (by >= characters_) {
+    Clear();
+    return;
+  }
+  for (int i = 0; i < characters_ - by; i++) {
+    positions_[i] = positions_[by + i];
+  }
+  for (int i = characters_ - by; i < characters_; i++) {
+    positions_[i].mask = 0;
+    positions_[i].value = 0;
+    positions_[i].determines_perfectly = false;
+  }
+  characters_ -= by;
+  // We could change mask_ and value_ here but we would never advance unless
+  // they had already been used in a check and they won't be used again because
+  // it would gain us nothing.  So there's no point.
+}
+
+
+void QuickCheckDetails::Merge(QuickCheckDetails* other, int from_index) {
+  DCHECK(characters_ == other->characters_);
+  if (other->cannot_match_) {
+    return;
+  }
+  if (cannot_match_) {
+    *this = *other;
+    return;
+  }
+  for (int i = from_index; i < characters_; i++) {
+    QuickCheckDetails::Position* pos = positions(i);
+    QuickCheckDetails::Position* other_pos = other->positions(i);
+    if (pos->mask != other_pos->mask ||
+        pos->value != other_pos->value ||
+        !other_pos->determines_perfectly) {
+      // Our mask-compare operation will be approximate unless we have the
+      // exact same operation on both sides of the alternation.
+      pos->determines_perfectly = false;
+    }
+    pos->mask &= other_pos->mask;
+    pos->value &= pos->mask;
+    other_pos->value &= pos->mask;
+    uc16 differing_bits = (pos->value ^ other_pos->value);
+    pos->mask &= ~differing_bits;
+    pos->value &= pos->mask;
+  }
+}
+
+
+class VisitMarker {
+ public:
+  explicit VisitMarker(NodeInfo* info) : info_(info) {
+    DCHECK(!info->visited);
+    info->visited = true;
+  }
+  ~VisitMarker() {
+    info_->visited = false;
+  }
+ private:
+  NodeInfo* info_;
+};
+
+
+RegExpNode* SeqRegExpNode::FilterOneByte(int depth, bool ignore_case) {
+  if (info()->replacement_calculated) return replacement();
+  if (depth < 0) return this;
+  DCHECK(!info()->visited);
+  VisitMarker marker(info());
+  return FilterSuccessor(depth - 1, ignore_case);
+}
+
+
+RegExpNode* SeqRegExpNode::FilterSuccessor(int depth, bool ignore_case) {
+  RegExpNode* next = on_success_->FilterOneByte(depth - 1, ignore_case);
+  if (next == NULL) return set_replacement(NULL);
+  on_success_ = next;
+  return set_replacement(this);
+}
+
+
+// We need to check for the following characters: 0x39c 0x3bc 0x178.
+static inline bool RangeContainsLatin1Equivalents(CharacterRange range) {
+  // TODO(dcarney): this could be a lot more efficient.
+  return range.Contains(0x39c) ||
+      range.Contains(0x3bc) || range.Contains(0x178);
+}
+
+
+static bool RangesContainLatin1Equivalents(ZoneList<CharacterRange>* ranges) {
+  for (int i = 0; i < ranges->length(); i++) {
+    // TODO(dcarney): this could be a lot more efficient.
+    if (RangeContainsLatin1Equivalents(ranges->at(i))) return true;
+  }
+  return false;
+}
+
+
+RegExpNode* TextNode::FilterOneByte(int depth, bool ignore_case) {
+  if (info()->replacement_calculated) return replacement();
+  if (depth < 0) return this;
+  DCHECK(!info()->visited);
+  VisitMarker marker(info());
+  int element_count = elms_->length();
+  for (int i = 0; i < element_count; i++) {
+    TextElement elm = elms_->at(i);
+    if (elm.text_type() == TextElement::ATOM) {
+      Vector<const uc16> quarks = elm.atom()->data();
+      for (int j = 0; j < quarks.length(); j++) {
+        uint16_t c = quarks[j];
+        if (c <= String::kMaxOneByteCharCode) continue;
+        if (!ignore_case) return set_replacement(NULL);
+        // Here, we need to check for characters whose upper and lower cases
+        // are outside the Latin-1 range.
+        uint16_t converted = unibrow::Latin1::ConvertNonLatin1ToLatin1(c);
+        // Character is outside Latin-1 completely
+        if (converted == 0) return set_replacement(NULL);
+        // Convert quark to Latin-1 in place.
+        uint16_t* copy = const_cast<uint16_t*>(quarks.start());
+        copy[j] = converted;
+      }
+    } else {
+      DCHECK(elm.text_type() == TextElement::CHAR_CLASS);
+      RegExpCharacterClass* cc = elm.char_class();
+      ZoneList<CharacterRange>* ranges = cc->ranges(zone());
+      if (!CharacterRange::IsCanonical(ranges)) {
+        CharacterRange::Canonicalize(ranges);
+      }
+      // Now they are in order so we only need to look at the first.
+      int range_count = ranges->length();
+      if (cc->is_negated()) {
+        if (range_count != 0 &&
+            ranges->at(0).from() == 0 &&
+            ranges->at(0).to() >= String::kMaxOneByteCharCode) {
+          // This will be handled in a later filter.
+          if (ignore_case && RangesContainLatin1Equivalents(ranges)) continue;
+          return set_replacement(NULL);
+        }
+      } else {
+        if (range_count == 0 ||
+            ranges->at(0).from() > String::kMaxOneByteCharCode) {
+          // This will be handled in a later filter.
+          if (ignore_case && RangesContainLatin1Equivalents(ranges)) continue;
+          return set_replacement(NULL);
+        }
+      }
+    }
+  }
+  return FilterSuccessor(depth - 1, ignore_case);
+}
+
+
+RegExpNode* LoopChoiceNode::FilterOneByte(int depth, bool ignore_case) {
+  if (info()->replacement_calculated) return replacement();
+  if (depth < 0) return this;
+  if (info()->visited) return this;
+  {
+    VisitMarker marker(info());
+
+    RegExpNode* continue_replacement =
+        continue_node_->FilterOneByte(depth - 1, ignore_case);
+    // If we can't continue after the loop then there is no sense in doing the
+    // loop.
+    if (continue_replacement == NULL) return set_replacement(NULL);
+  }
+
+  return ChoiceNode::FilterOneByte(depth - 1, ignore_case);
+}
+
+
+RegExpNode* ChoiceNode::FilterOneByte(int depth, bool ignore_case) {
+  if (info()->replacement_calculated) return replacement();
+  if (depth < 0) return this;
+  if (info()->visited) return this;
+  VisitMarker marker(info());
+  int choice_count = alternatives_->length();
+
+  for (int i = 0; i < choice_count; i++) {
+    GuardedAlternative alternative = alternatives_->at(i);
+    if (alternative.guards() != NULL && alternative.guards()->length() != 0) {
+      set_replacement(this);
+      return this;
+    }
+  }
+
+  int surviving = 0;
+  RegExpNode* survivor = NULL;
+  for (int i = 0; i < choice_count; i++) {
+    GuardedAlternative alternative = alternatives_->at(i);
+    RegExpNode* replacement =
+        alternative.node()->FilterOneByte(depth - 1, ignore_case);
+    DCHECK(replacement != this);  // No missing EMPTY_MATCH_CHECK.
+    if (replacement != NULL) {
+      alternatives_->at(i).set_node(replacement);
+      surviving++;
+      survivor = replacement;
+    }
+  }
+  if (surviving < 2) return set_replacement(survivor);
+
+  set_replacement(this);
+  if (surviving == choice_count) {
+    return this;
+  }
+  // Only some of the nodes survived the filtering.  We need to rebuild the
+  // alternatives list.
+  ZoneList<GuardedAlternative>* new_alternatives =
+      new(zone()) ZoneList<GuardedAlternative>(surviving, zone());
+  for (int i = 0; i < choice_count; i++) {
+    RegExpNode* replacement =
+        alternatives_->at(i).node()->FilterOneByte(depth - 1, ignore_case);
+    if (replacement != NULL) {
+      alternatives_->at(i).set_node(replacement);
+      new_alternatives->Add(alternatives_->at(i), zone());
+    }
+  }
+  alternatives_ = new_alternatives;
+  return this;
+}
+
+
+RegExpNode* NegativeLookaheadChoiceNode::FilterOneByte(int depth,
+                                                       bool ignore_case) {
+  if (info()->replacement_calculated) return replacement();
+  if (depth < 0) return this;
+  if (info()->visited) return this;
+  VisitMarker marker(info());
+  // Alternative 0 is the negative lookahead, alternative 1 is what comes
+  // afterwards.
+  RegExpNode* node = alternatives_->at(1).node();
+  RegExpNode* replacement = node->FilterOneByte(depth - 1, ignore_case);
+  if (replacement == NULL) return set_replacement(NULL);
+  alternatives_->at(1).set_node(replacement);
+
+  RegExpNode* neg_node = alternatives_->at(0).node();
+  RegExpNode* neg_replacement = neg_node->FilterOneByte(depth - 1, ignore_case);
+  // If the negative lookahead is always going to fail then
+  // we don't need to check it.
+  if (neg_replacement == NULL) return set_replacement(replacement);
+  alternatives_->at(0).set_node(neg_replacement);
+  return set_replacement(this);
+}
+
+
+void LoopChoiceNode::GetQuickCheckDetails(QuickCheckDetails* details,
+                                          RegExpCompiler* compiler,
+                                          int characters_filled_in,
+                                          bool not_at_start) {
+  if (body_can_be_zero_length_ || info()->visited) return;
+  VisitMarker marker(info());
+  return ChoiceNode::GetQuickCheckDetails(details,
+                                          compiler,
+                                          characters_filled_in,
+                                          not_at_start);
+}
+
+
+void LoopChoiceNode::FillInBMInfo(int offset,
+                                  int budget,
+                                  BoyerMooreLookahead* bm,
+                                  bool not_at_start) {
+  if (body_can_be_zero_length_ || budget <= 0) {
+    bm->SetRest(offset);
+    SaveBMInfo(bm, not_at_start, offset);
+    return;
+  }
+  ChoiceNode::FillInBMInfo(offset, budget - 1, bm, not_at_start);
+  SaveBMInfo(bm, not_at_start, offset);
+}
+
+
+void ChoiceNode::GetQuickCheckDetails(QuickCheckDetails* details,
+                                      RegExpCompiler* compiler,
+                                      int characters_filled_in,
+                                      bool not_at_start) {
+  not_at_start = (not_at_start || not_at_start_);
+  int choice_count = alternatives_->length();
+  DCHECK(choice_count > 0);
+  alternatives_->at(0).node()->GetQuickCheckDetails(details,
+                                                    compiler,
+                                                    characters_filled_in,
+                                                    not_at_start);
+  for (int i = 1; i < choice_count; i++) {
+    QuickCheckDetails new_details(details->characters());
+    RegExpNode* node = alternatives_->at(i).node();
+    node->GetQuickCheckDetails(&new_details, compiler,
+                               characters_filled_in,
+                               not_at_start);
+    // Here we merge the quick match details of the two branches.
+    details->Merge(&new_details, characters_filled_in);
+  }
+}
+
+
+// Check for [0-9A-Z_a-z].
+static void EmitWordCheck(RegExpMacroAssembler* assembler,
+                          Label* word,
+                          Label* non_word,
+                          bool fall_through_on_word) {
+  if (assembler->CheckSpecialCharacterClass(
+          fall_through_on_word ? 'w' : 'W',
+          fall_through_on_word ? non_word : word)) {
+    // Optimized implementation available.
+    return;
+  }
+  assembler->CheckCharacterGT('z', non_word);
+  assembler->CheckCharacterLT('0', non_word);
+  assembler->CheckCharacterGT('a' - 1, word);
+  assembler->CheckCharacterLT('9' + 1, word);
+  assembler->CheckCharacterLT('A', non_word);
+  assembler->CheckCharacterLT('Z' + 1, word);
+  if (fall_through_on_word) {
+    assembler->CheckNotCharacter('_', non_word);
+  } else {
+    assembler->CheckCharacter('_', word);
+  }
+}
+
+
+// Emit the code to check for a ^ in multiline mode (1-character lookbehind
+// that matches newline or the start of input).
+static void EmitHat(RegExpCompiler* compiler,
+                    RegExpNode* on_success,
+                    Trace* trace) {
+  RegExpMacroAssembler* assembler = compiler->macro_assembler();
+  // We will be loading the previous character into the current character
+  // register.
+  Trace new_trace(*trace);
+  new_trace.InvalidateCurrentCharacter();
+
+  Label ok;
+  if (new_trace.cp_offset() == 0) {
+    // The start of input counts as a newline in this context, so skip to
+    // ok if we are at the start.
+    assembler->CheckAtStart(&ok);
+  }
+  // We already checked that we are not at the start of input so it must be
+  // OK to load the previous character.
+  assembler->LoadCurrentCharacter(new_trace.cp_offset() -1,
+                                  new_trace.backtrack(),
+                                  false);
+  if (!assembler->CheckSpecialCharacterClass('n',
+                                             new_trace.backtrack())) {
+    // Newline means \n, \r, 0x2028 or 0x2029.
+    if (!compiler->one_byte()) {
+      assembler->CheckCharacterAfterAnd(0x2028, 0xfffe, &ok);
+    }
+    assembler->CheckCharacter('\n', &ok);
+    assembler->CheckNotCharacter('\r', new_trace.backtrack());
+  }
+  assembler->Bind(&ok);
+  on_success->Emit(compiler, &new_trace);
+}
+
+
+// Emit the code to handle \b and \B (word-boundary or non-word-boundary).
+void AssertionNode::EmitBoundaryCheck(RegExpCompiler* compiler, Trace* trace) {
+  RegExpMacroAssembler* assembler = compiler->macro_assembler();
+  Trace::TriBool next_is_word_character = Trace::UNKNOWN;
+  bool not_at_start = (trace->at_start() == Trace::FALSE_VALUE);
+  BoyerMooreLookahead* lookahead = bm_info(not_at_start);
+  if (lookahead == NULL) {
+    int eats_at_least =
+        Min(kMaxLookaheadForBoyerMoore, EatsAtLeast(kMaxLookaheadForBoyerMoore,
+                                                    kRecursionBudget,
+                                                    not_at_start));
+    if (eats_at_least >= 1) {
+      BoyerMooreLookahead* bm =
+          new(zone()) BoyerMooreLookahead(eats_at_least, compiler, zone());
+      FillInBMInfo(0, kRecursionBudget, bm, not_at_start);
+      if (bm->at(0)->is_non_word())
+        next_is_word_character = Trace::FALSE_VALUE;
+      if (bm->at(0)->is_word()) next_is_word_character = Trace::TRUE_VALUE;
+    }
+  } else {
+    if (lookahead->at(0)->is_non_word())
+      next_is_word_character = Trace::FALSE_VALUE;
+    if (lookahead->at(0)->is_word())
+      next_is_word_character = Trace::TRUE_VALUE;
+  }
+  bool at_boundary = (assertion_type_ == AssertionNode::AT_BOUNDARY);
+  if (next_is_word_character == Trace::UNKNOWN) {
+    Label before_non_word;
+    Label before_word;
+    if (trace->characters_preloaded() != 1) {
+      assembler->LoadCurrentCharacter(trace->cp_offset(), &before_non_word);
+    }
+    // Fall through on non-word.
+    EmitWordCheck(assembler, &before_word, &before_non_word, false);
+    // Next character is not a word character.
+    assembler->Bind(&before_non_word);
+    Label ok;
+    BacktrackIfPrevious(compiler, trace, at_boundary ? kIsNonWord : kIsWord);
+    assembler->GoTo(&ok);
+
+    assembler->Bind(&before_word);
+    BacktrackIfPrevious(compiler, trace, at_boundary ? kIsWord : kIsNonWord);
+    assembler->Bind(&ok);
+  } else if (next_is_word_character == Trace::TRUE_VALUE) {
+    BacktrackIfPrevious(compiler, trace, at_boundary ? kIsWord : kIsNonWord);
+  } else {
+    DCHECK(next_is_word_character == Trace::FALSE_VALUE);
+    BacktrackIfPrevious(compiler, trace, at_boundary ? kIsNonWord : kIsWord);
+  }
+}
+
+
+void AssertionNode::BacktrackIfPrevious(
+    RegExpCompiler* compiler,
+    Trace* trace,
+    AssertionNode::IfPrevious backtrack_if_previous) {
+  RegExpMacroAssembler* assembler = compiler->macro_assembler();
+  Trace new_trace(*trace);
+  new_trace.InvalidateCurrentCharacter();
+
+  Label fall_through, dummy;
+
+  Label* non_word = backtrack_if_previous == kIsNonWord ?
+                    new_trace.backtrack() :
+                    &fall_through;
+  Label* word = backtrack_if_previous == kIsNonWord ?
+                &fall_through :
+                new_trace.backtrack();
+
+  if (new_trace.cp_offset() == 0) {
+    // The start of input counts as a non-word character, so the question is
+    // decided if we are at the start.
+    assembler->CheckAtStart(non_word);
+  }
+  // We already checked that we are not at the start of input so it must be
+  // OK to load the previous character.
+  assembler->LoadCurrentCharacter(new_trace.cp_offset() - 1, &dummy, false);
+  EmitWordCheck(assembler, word, non_word, backtrack_if_previous == kIsNonWord);
+
+  assembler->Bind(&fall_through);
+  on_success()->Emit(compiler, &new_trace);
+}
+
+
+void AssertionNode::GetQuickCheckDetails(QuickCheckDetails* details,
+                                         RegExpCompiler* compiler,
+                                         int filled_in,
+                                         bool not_at_start) {
+  if (assertion_type_ == AT_START && not_at_start) {
+    details->set_cannot_match();
+    return;
+  }
+  return on_success()->GetQuickCheckDetails(details,
+                                            compiler,
+                                            filled_in,
+                                            not_at_start);
+}
+
+
+void AssertionNode::Emit(RegExpCompiler* compiler, Trace* trace) {
+  RegExpMacroAssembler* assembler = compiler->macro_assembler();
+  switch (assertion_type_) {
+    case AT_END: {
+      Label ok;
+      assembler->CheckPosition(trace->cp_offset(), &ok);
+      assembler->GoTo(trace->backtrack());
+      assembler->Bind(&ok);
+      break;
+    }
+    case AT_START: {
+      if (trace->at_start() == Trace::FALSE_VALUE) {
+        assembler->GoTo(trace->backtrack());
+        return;
+      }
+      if (trace->at_start() == Trace::UNKNOWN) {
+        assembler->CheckNotAtStart(trace->backtrack());
+        Trace at_start_trace = *trace;
+        at_start_trace.set_at_start(true);
+        on_success()->Emit(compiler, &at_start_trace);
+        return;
+      }
+    }
+    break;
+    case AFTER_NEWLINE:
+      EmitHat(compiler, on_success(), trace);
+      return;
+    case AT_BOUNDARY:
+    case AT_NON_BOUNDARY: {
+      EmitBoundaryCheck(compiler, trace);
+      return;
+    }
+  }
+  on_success()->Emit(compiler, trace);
+}
+
+
+static bool DeterminedAlready(QuickCheckDetails* quick_check, int offset) {
+  if (quick_check == NULL) return false;
+  if (offset >= quick_check->characters()) return false;
+  return quick_check->positions(offset)->determines_perfectly;
+}
+
+
+static void UpdateBoundsCheck(int index, int* checked_up_to) {
+  if (index > *checked_up_to) {
+    *checked_up_to = index;
+  }
+}
+
+
+// We call this repeatedly to generate code for each pass over the text node.
+// The passes are in increasing order of difficulty because we hope one
+// of the first passes will fail in which case we are saved the work of the
+// later passes.  for example for the case independent regexp /%[asdfghjkl]a/
+// we will check the '%' in the first pass, the case independent 'a' in the
+// second pass and the character class in the last pass.
+//
+// The passes are done from right to left, so for example to test for /bar/
+// we will first test for an 'r' with offset 2, then an 'a' with offset 1
+// and then a 'b' with offset 0.  This means we can avoid the end-of-input
+// bounds check most of the time.  In the example we only need to check for
+// end-of-input when loading the putative 'r'.
+//
+// A slight complication involves the fact that the first character may already
+// be fetched into a register by the previous node.  In this case we want to
+// do the test for that character first.  We do this in separate passes.  The
+// 'preloaded' argument indicates that we are doing such a 'pass'.  If such a
+// pass has been performed then subsequent passes will have true in
+// first_element_checked to indicate that that character does not need to be
+// checked again.
+//
+// In addition to all this we are passed a Trace, which can
+// contain an AlternativeGeneration object.  In this AlternativeGeneration
+// object we can see details of any quick check that was already passed in
+// order to get to the code we are now generating.  The quick check can involve
+// loading characters, which means we do not need to recheck the bounds
+// up to the limit the quick check already checked.  In addition the quick
+// check can have involved a mask and compare operation which may simplify
+// or obviate the need for further checks at some character positions.
+void TextNode::TextEmitPass(RegExpCompiler* compiler,
+                            TextEmitPassType pass,
+                            bool preloaded,
+                            Trace* trace,
+                            bool first_element_checked,
+                            int* checked_up_to) {
+  RegExpMacroAssembler* assembler = compiler->macro_assembler();
+  Isolate* isolate = assembler->zone()->isolate();
+  bool one_byte = compiler->one_byte();
+  Label* backtrack = trace->backtrack();
+  QuickCheckDetails* quick_check = trace->quick_check_performed();
+  int element_count = elms_->length();
+  for (int i = preloaded ? 0 : element_count - 1; i >= 0; i--) {
+    TextElement elm = elms_->at(i);
+    int cp_offset = trace->cp_offset() + elm.cp_offset();
+    if (elm.text_type() == TextElement::ATOM) {
+      Vector<const uc16> quarks = elm.atom()->data();
+      for (int j = preloaded ? 0 : quarks.length() - 1; j >= 0; j--) {
+        if (first_element_checked && i == 0 && j == 0) continue;
+        if (DeterminedAlready(quick_check, elm.cp_offset() + j)) continue;
+        EmitCharacterFunction* emit_function = NULL;
+        switch (pass) {
+          case NON_LATIN1_MATCH:
+            DCHECK(one_byte);
+            if (quarks[j] > String::kMaxOneByteCharCode) {
+              assembler->GoTo(backtrack);
+              return;
+            }
+            break;
+          case NON_LETTER_CHARACTER_MATCH:
+            emit_function = &EmitAtomNonLetter;
+            break;
+          case SIMPLE_CHARACTER_MATCH:
+            emit_function = &EmitSimpleCharacter;
+            break;
+          case CASE_CHARACTER_MATCH:
+            emit_function = &EmitAtomLetter;
+            break;
+          default:
+            break;
+        }
+        if (emit_function != NULL) {
+          bool bound_checked = emit_function(isolate,
+                                             compiler,
+                                             quarks[j],
+                                             backtrack,
+                                             cp_offset + j,
+                                             *checked_up_to < cp_offset + j,
+                                             preloaded);
+          if (bound_checked) UpdateBoundsCheck(cp_offset + j, checked_up_to);
+        }
+      }
+    } else {
+      DCHECK_EQ(TextElement::CHAR_CLASS, elm.text_type());
+      if (pass == CHARACTER_CLASS_MATCH) {
+        if (first_element_checked && i == 0) continue;
+        if (DeterminedAlready(quick_check, elm.cp_offset())) continue;
+        RegExpCharacterClass* cc = elm.char_class();
+        EmitCharClass(assembler, cc, one_byte, backtrack, cp_offset,
+                      *checked_up_to < cp_offset, preloaded, zone());
+        UpdateBoundsCheck(cp_offset, checked_up_to);
+      }
+    }
+  }
+}
+
+
+int TextNode::Length() {
+  TextElement elm = elms_->last();
+  DCHECK(elm.cp_offset() >= 0);
+  return elm.cp_offset() + elm.length();
+}
+
+
+bool TextNode::SkipPass(int int_pass, bool ignore_case) {
+  TextEmitPassType pass = static_cast<TextEmitPassType>(int_pass);
+  if (ignore_case) {
+    return pass == SIMPLE_CHARACTER_MATCH;
+  } else {
+    return pass == NON_LETTER_CHARACTER_MATCH || pass == CASE_CHARACTER_MATCH;
+  }
+}
+
+
+// This generates the code to match a text node.  A text node can contain
+// straight character sequences (possibly to be matched in a case-independent
+// way) and character classes.  For efficiency we do not do this in a single
+// pass from left to right.  Instead we pass over the text node several times,
+// emitting code for some character positions every time.  See the comment on
+// TextEmitPass for details.
+void TextNode::Emit(RegExpCompiler* compiler, Trace* trace) {
+  LimitResult limit_result = LimitVersions(compiler, trace);
+  if (limit_result == DONE) return;
+  DCHECK(limit_result == CONTINUE);
+
+  if (trace->cp_offset() + Length() > RegExpMacroAssembler::kMaxCPOffset) {
+    compiler->SetRegExpTooBig();
+    return;
+  }
+
+  if (compiler->one_byte()) {
+    int dummy = 0;
+    TextEmitPass(compiler, NON_LATIN1_MATCH, false, trace, false, &dummy);
+  }
+
+  bool first_elt_done = false;
+  int bound_checked_to = trace->cp_offset() - 1;
+  bound_checked_to += trace->bound_checked_up_to();
+
+  // If a character is preloaded into the current character register then
+  // check that now.
+  if (trace->characters_preloaded() == 1) {
+    for (int pass = kFirstRealPass; pass <= kLastPass; pass++) {
+      if (!SkipPass(pass, compiler->ignore_case())) {
+        TextEmitPass(compiler,
+                     static_cast<TextEmitPassType>(pass),
+                     true,
+                     trace,
+                     false,
+                     &bound_checked_to);
+      }
+    }
+    first_elt_done = true;
+  }
+
+  for (int pass = kFirstRealPass; pass <= kLastPass; pass++) {
+    if (!SkipPass(pass, compiler->ignore_case())) {
+      TextEmitPass(compiler,
+                   static_cast<TextEmitPassType>(pass),
+                   false,
+                   trace,
+                   first_elt_done,
+                   &bound_checked_to);
+    }
+  }
+
+  Trace successor_trace(*trace);
+  successor_trace.set_at_start(false);
+  successor_trace.AdvanceCurrentPositionInTrace(Length(), compiler);
+  RecursionCheck rc(compiler);
+  on_success()->Emit(compiler, &successor_trace);
+}
+
+
+void Trace::InvalidateCurrentCharacter() {
+  characters_preloaded_ = 0;
+}
+
+
+void Trace::AdvanceCurrentPositionInTrace(int by, RegExpCompiler* compiler) {
+  DCHECK(by > 0);
+  // We don't have an instruction for shifting the current character register
+  // down or for using a shifted value for anything so lets just forget that
+  // we preloaded any characters into it.
+  characters_preloaded_ = 0;
+  // Adjust the offsets of the quick check performed information.  This
+  // information is used to find out what we already determined about the
+  // characters by means of mask and compare.
+  quick_check_performed_.Advance(by, compiler->one_byte());
+  cp_offset_ += by;
+  if (cp_offset_ > RegExpMacroAssembler::kMaxCPOffset) {
+    compiler->SetRegExpTooBig();
+    cp_offset_ = 0;
+  }
+  bound_checked_up_to_ = Max(0, bound_checked_up_to_ - by);
+}
+
+
+void TextNode::MakeCaseIndependent(bool is_one_byte) {
+  int element_count = elms_->length();
+  for (int i = 0; i < element_count; i++) {
+    TextElement elm = elms_->at(i);
+    if (elm.text_type() == TextElement::CHAR_CLASS) {
+      RegExpCharacterClass* cc = elm.char_class();
+      // None of the standard character classes is different in the case
+      // independent case and it slows us down if we don't know that.
+      if (cc->is_standard(zone())) continue;
+      ZoneList<CharacterRange>* ranges = cc->ranges(zone());
+      int range_count = ranges->length();
+      for (int j = 0; j < range_count; j++) {
+        ranges->at(j).AddCaseEquivalents(ranges, is_one_byte, zone());
+      }
+    }
+  }
+}
+
+
+int TextNode::GreedyLoopTextLength() {
+  TextElement elm = elms_->at(elms_->length() - 1);
+  return elm.cp_offset() + elm.length();
+}
+
+
+RegExpNode* TextNode::GetSuccessorOfOmnivorousTextNode(
+    RegExpCompiler* compiler) {
+  if (elms_->length() != 1) return NULL;
+  TextElement elm = elms_->at(0);
+  if (elm.text_type() != TextElement::CHAR_CLASS) return NULL;
+  RegExpCharacterClass* node = elm.char_class();
+  ZoneList<CharacterRange>* ranges = node->ranges(zone());
+  if (!CharacterRange::IsCanonical(ranges)) {
+    CharacterRange::Canonicalize(ranges);
+  }
+  if (node->is_negated()) {
+    return ranges->length() == 0 ? on_success() : NULL;
+  }
+  if (ranges->length() != 1) return NULL;
+  uint32_t max_char;
+  if (compiler->one_byte()) {
+    max_char = String::kMaxOneByteCharCode;
+  } else {
+    max_char = String::kMaxUtf16CodeUnit;
+  }
+  return ranges->at(0).IsEverything(max_char) ? on_success() : NULL;
+}
+
+
+// Finds the fixed match length of a sequence of nodes that goes from
+// this alternative and back to this choice node.  If there are variable
+// length nodes or other complications in the way then return a sentinel
+// value indicating that a greedy loop cannot be constructed.
+int ChoiceNode::GreedyLoopTextLengthForAlternative(
+    GuardedAlternative* alternative) {
+  int length = 0;
+  RegExpNode* node = alternative->node();
+  // Later we will generate code for all these text nodes using recursion
+  // so we have to limit the max number.
+  int recursion_depth = 0;
+  while (node != this) {
+    if (recursion_depth++ > RegExpCompiler::kMaxRecursion) {
+      return kNodeIsTooComplexForGreedyLoops;
+    }
+    int node_length = node->GreedyLoopTextLength();
+    if (node_length == kNodeIsTooComplexForGreedyLoops) {
+      return kNodeIsTooComplexForGreedyLoops;
+    }
+    length += node_length;
+    SeqRegExpNode* seq_node = static_cast<SeqRegExpNode*>(node);
+    node = seq_node->on_success();
+  }
+  return length;
+}
+
+
+void LoopChoiceNode::AddLoopAlternative(GuardedAlternative alt) {
+  DCHECK_EQ(loop_node_, NULL);
+  AddAlternative(alt);
+  loop_node_ = alt.node();
+}
+
+
+void LoopChoiceNode::AddContinueAlternative(GuardedAlternative alt) {
+  DCHECK_EQ(continue_node_, NULL);
+  AddAlternative(alt);
+  continue_node_ = alt.node();
+}
+
+
+void LoopChoiceNode::Emit(RegExpCompiler* compiler, Trace* trace) {
+  RegExpMacroAssembler* macro_assembler = compiler->macro_assembler();
+  if (trace->stop_node() == this) {
+    // Back edge of greedy optimized loop node graph.
+    int text_length =
+        GreedyLoopTextLengthForAlternative(&(alternatives_->at(0)));
+    DCHECK(text_length != kNodeIsTooComplexForGreedyLoops);
+    // Update the counter-based backtracking info on the stack.  This is an
+    // optimization for greedy loops (see below).
+    DCHECK(trace->cp_offset() == text_length);
+    macro_assembler->AdvanceCurrentPosition(text_length);
+    macro_assembler->GoTo(trace->loop_label());
+    return;
+  }
+  DCHECK(trace->stop_node() == NULL);
+  if (!trace->is_trivial()) {
+    trace->Flush(compiler, this);
+    return;
+  }
+  ChoiceNode::Emit(compiler, trace);
+}
+
+
+int ChoiceNode::CalculatePreloadCharacters(RegExpCompiler* compiler,
+                                           int eats_at_least) {
+  int preload_characters = Min(4, eats_at_least);
+  if (compiler->macro_assembler()->CanReadUnaligned()) {
+    bool one_byte = compiler->one_byte();
+    if (one_byte) {
+      if (preload_characters > 4) preload_characters = 4;
+      // We can't preload 3 characters because there is no machine instruction
+      // to do that.  We can't just load 4 because we could be reading
+      // beyond the end of the string, which could cause a memory fault.
+      if (preload_characters == 3) preload_characters = 2;
+    } else {
+      if (preload_characters > 2) preload_characters = 2;
+    }
+  } else {
+    if (preload_characters > 1) preload_characters = 1;
+  }
+  return preload_characters;
+}
+
+
+// This class is used when generating the alternatives in a choice node.  It
+// records the way the alternative is being code generated.
+class AlternativeGeneration: public Malloced {
+ public:
+  AlternativeGeneration()
+      : possible_success(),
+        expects_preload(false),
+        after(),
+        quick_check_details() { }
+  Label possible_success;
+  bool expects_preload;
+  Label after;
+  QuickCheckDetails quick_check_details;
+};
+
+
+// Creates a list of AlternativeGenerations.  If the list has a reasonable
+// size then it is on the stack, otherwise the excess is on the heap.
+class AlternativeGenerationList {
+ public:
+  AlternativeGenerationList(int count, Zone* zone)
+      : alt_gens_(count, zone) {
+    for (int i = 0; i < count && i < kAFew; i++) {
+      alt_gens_.Add(a_few_alt_gens_ + i, zone);
+    }
+    for (int i = kAFew; i < count; i++) {
+      alt_gens_.Add(new AlternativeGeneration(), zone);
+    }
+  }
+  ~AlternativeGenerationList() {
+    for (int i = kAFew; i < alt_gens_.length(); i++) {
+      delete alt_gens_[i];
+      alt_gens_[i] = NULL;
+    }
+  }
+
+  AlternativeGeneration* at(int i) {
+    return alt_gens_[i];
+  }
+
+ private:
+  static const int kAFew = 10;
+  ZoneList<AlternativeGeneration*> alt_gens_;
+  AlternativeGeneration a_few_alt_gens_[kAFew];
+};
+
+
+// The '2' variant is has inclusive from and exclusive to.
+// This covers \s as defined in ECMA-262 5.1, 15.10.2.12,
+// which include WhiteSpace (7.2) or LineTerminator (7.3) values.
+static const int kSpaceRanges[] = { '\t', '\r' + 1, ' ', ' ' + 1,
+    0x00A0, 0x00A1, 0x1680, 0x1681, 0x180E, 0x180F, 0x2000, 0x200B,
+    0x2028, 0x202A, 0x202F, 0x2030, 0x205F, 0x2060, 0x3000, 0x3001,
+    0xFEFF, 0xFF00, 0x10000 };
+static const int kSpaceRangeCount = arraysize(kSpaceRanges);
+
+static const int kWordRanges[] = {
+    '0', '9' + 1, 'A', 'Z' + 1, '_', '_' + 1, 'a', 'z' + 1, 0x10000 };
+static const int kWordRangeCount = arraysize(kWordRanges);
+static const int kDigitRanges[] = { '0', '9' + 1, 0x10000 };
+static const int kDigitRangeCount = arraysize(kDigitRanges);
+static const int kSurrogateRanges[] = { 0xd800, 0xe000, 0x10000 };
+static const int kSurrogateRangeCount = arraysize(kSurrogateRanges);
+static const int kLineTerminatorRanges[] = { 0x000A, 0x000B, 0x000D, 0x000E,
+    0x2028, 0x202A, 0x10000 };
+static const int kLineTerminatorRangeCount = arraysize(kLineTerminatorRanges);
+
+
+void BoyerMoorePositionInfo::Set(int character) {
+  SetInterval(Interval(character, character));
+}
+
+
+void BoyerMoorePositionInfo::SetInterval(const Interval& interval) {
+  s_ = AddRange(s_, kSpaceRanges, kSpaceRangeCount, interval);
+  w_ = AddRange(w_, kWordRanges, kWordRangeCount, interval);
+  d_ = AddRange(d_, kDigitRanges, kDigitRangeCount, interval);
+  surrogate_ =
+      AddRange(surrogate_, kSurrogateRanges, kSurrogateRangeCount, interval);
+  if (interval.to() - interval.from() >= kMapSize - 1) {
+    if (map_count_ != kMapSize) {
+      map_count_ = kMapSize;
+      for (int i = 0; i < kMapSize; i++) map_->at(i) = true;
+    }
+    return;
+  }
+  for (int i = interval.from(); i <= interval.to(); i++) {
+    int mod_character = (i & kMask);
+    if (!map_->at(mod_character)) {
+      map_count_++;
+      map_->at(mod_character) = true;
+    }
+    if (map_count_ == kMapSize) return;
+  }
+}
+
+
+void BoyerMoorePositionInfo::SetAll() {
+  s_ = w_ = d_ = kLatticeUnknown;
+  if (map_count_ != kMapSize) {
+    map_count_ = kMapSize;
+    for (int i = 0; i < kMapSize; i++) map_->at(i) = true;
+  }
+}
+
+
+BoyerMooreLookahead::BoyerMooreLookahead(
+    int length, RegExpCompiler* compiler, Zone* zone)
+    : length_(length),
+      compiler_(compiler) {
+  if (compiler->one_byte()) {
+    max_char_ = String::kMaxOneByteCharCode;
+  } else {
+    max_char_ = String::kMaxUtf16CodeUnit;
+  }
+  bitmaps_ = new(zone) ZoneList<BoyerMoorePositionInfo*>(length, zone);
+  for (int i = 0; i < length; i++) {
+    bitmaps_->Add(new(zone) BoyerMoorePositionInfo(zone), zone);
+  }
+}
+
+
+// Find the longest range of lookahead that has the fewest number of different
+// characters that can occur at a given position.  Since we are optimizing two
+// different parameters at once this is a tradeoff.
+bool BoyerMooreLookahead::FindWorthwhileInterval(int* from, int* to) {
+  int biggest_points = 0;
+  // If more than 32 characters out of 128 can occur it is unlikely that we can
+  // be lucky enough to step forwards much of the time.
+  const int kMaxMax = 32;
+  for (int max_number_of_chars = 4;
+       max_number_of_chars < kMaxMax;
+       max_number_of_chars *= 2) {
+    biggest_points =
+        FindBestInterval(max_number_of_chars, biggest_points, from, to);
+  }
+  if (biggest_points == 0) return false;
+  return true;
+}
+
+
+// Find the highest-points range between 0 and length_ where the character
+// information is not too vague.  'Too vague' means that there are more than
+// max_number_of_chars that can occur at this position.  Calculates the number
+// of points as the product of width-of-the-range and
+// probability-of-finding-one-of-the-characters, where the probability is
+// calculated using the frequency distribution of the sample subject string.
+int BoyerMooreLookahead::FindBestInterval(
+    int max_number_of_chars, int old_biggest_points, int* from, int* to) {
+  int biggest_points = old_biggest_points;
+  static const int kSize = RegExpMacroAssembler::kTableSize;
+  for (int i = 0; i < length_; ) {
+    while (i < length_ && Count(i) > max_number_of_chars) i++;
+    if (i == length_) break;
+    int remembered_from = i;
+    bool union_map[kSize];
+    for (int j = 0; j < kSize; j++) union_map[j] = false;
+    while (i < length_ && Count(i) <= max_number_of_chars) {
+      BoyerMoorePositionInfo* map = bitmaps_->at(i);
+      for (int j = 0; j < kSize; j++) union_map[j] |= map->at(j);
+      i++;
+    }
+    int frequency = 0;
+    for (int j = 0; j < kSize; j++) {
+      if (union_map[j]) {
+        // Add 1 to the frequency to give a small per-character boost for
+        // the cases where our sampling is not good enough and many
+        // characters have a frequency of zero.  This means the frequency
+        // can theoretically be up to 2*kSize though we treat it mostly as
+        // a fraction of kSize.
+        frequency += compiler_->frequency_collator()->Frequency(j) + 1;
+      }
+    }
+    // We use the probability of skipping times the distance we are skipping to
+    // judge the effectiveness of this.  Actually we have a cut-off:  By
+    // dividing by 2 we switch off the skipping if the probability of skipping
+    // is less than 50%.  This is because the multibyte mask-and-compare
+    // skipping in quickcheck is more likely to do well on this case.
+    bool in_quickcheck_range =
+        ((i - remembered_from < 4) ||
+         (compiler_->one_byte() ? remembered_from <= 4 : remembered_from <= 2));
+    // Called 'probability' but it is only a rough estimate and can actually
+    // be outside the 0-kSize range.
+    int probability = (in_quickcheck_range ? kSize / 2 : kSize) - frequency;
+    int points = (i - remembered_from) * probability;
+    if (points > biggest_points) {
+      *from = remembered_from;
+      *to = i - 1;
+      biggest_points = points;
+    }
+  }
+  return biggest_points;
+}
+
+
+// Take all the characters that will not prevent a successful match if they
+// occur in the subject string in the range between min_lookahead and
+// max_lookahead (inclusive) measured from the current position.  If the
+// character at max_lookahead offset is not one of these characters, then we
+// can safely skip forwards by the number of characters in the range.
+int BoyerMooreLookahead::GetSkipTable(int min_lookahead,
+                                      int max_lookahead,
+                                      Handle<ByteArray> boolean_skip_table) {
+  const int kSize = RegExpMacroAssembler::kTableSize;
+
+  const int kSkipArrayEntry = 0;
+  const int kDontSkipArrayEntry = 1;
+
+  for (int i = 0; i < kSize; i++) {
+    boolean_skip_table->set(i, kSkipArrayEntry);
+  }
+  int skip = max_lookahead + 1 - min_lookahead;
+
+  for (int i = max_lookahead; i >= min_lookahead; i--) {
+    BoyerMoorePositionInfo* map = bitmaps_->at(i);
+    for (int j = 0; j < kSize; j++) {
+      if (map->at(j)) {
+        boolean_skip_table->set(j, kDontSkipArrayEntry);
+      }
+    }
+  }
+
+  return skip;
+}
+
+
+// See comment above on the implementation of GetSkipTable.
+void BoyerMooreLookahead::EmitSkipInstructions(RegExpMacroAssembler* masm) {
+  const int kSize = RegExpMacroAssembler::kTableSize;
+
+  int min_lookahead = 0;
+  int max_lookahead = 0;
+
+  if (!FindWorthwhileInterval(&min_lookahead, &max_lookahead)) return;
+
+  bool found_single_character = false;
+  int single_character = 0;
+  for (int i = max_lookahead; i >= min_lookahead; i--) {
+    BoyerMoorePositionInfo* map = bitmaps_->at(i);
+    if (map->map_count() > 1 ||
+        (found_single_character && map->map_count() != 0)) {
+      found_single_character = false;
+      break;
+    }
+    for (int j = 0; j < kSize; j++) {
+      if (map->at(j)) {
+        found_single_character = true;
+        single_character = j;
+        break;
+      }
+    }
+  }
+
+  int lookahead_width = max_lookahead + 1 - min_lookahead;
+
+  if (found_single_character && lookahead_width == 1 && max_lookahead < 3) {
+    // The mask-compare can probably handle this better.
+    return;
+  }
+
+  if (found_single_character) {
+    Label cont, again;
+    masm->Bind(&again);
+    masm->LoadCurrentCharacter(max_lookahead, &cont, true);
+    if (max_char_ > kSize) {
+      masm->CheckCharacterAfterAnd(single_character,
+                                   RegExpMacroAssembler::kTableMask,
+                                   &cont);
+    } else {
+      masm->CheckCharacter(single_character, &cont);
+    }
+    masm->AdvanceCurrentPosition(lookahead_width);
+    masm->GoTo(&again);
+    masm->Bind(&cont);
+    return;
+  }
+
+  Factory* factory = masm->zone()->isolate()->factory();
+  Handle<ByteArray> boolean_skip_table = factory->NewByteArray(kSize, TENURED);
+  int skip_distance = GetSkipTable(
+      min_lookahead, max_lookahead, boolean_skip_table);
+  DCHECK(skip_distance != 0);
+
+  Label cont, again;
+  masm->Bind(&again);
+  masm->LoadCurrentCharacter(max_lookahead, &cont, true);
+  masm->CheckBitInTable(boolean_skip_table, &cont);
+  masm->AdvanceCurrentPosition(skip_distance);
+  masm->GoTo(&again);
+  masm->Bind(&cont);
+}
+
+
+/* Code generation for choice nodes.
+ *
+ * We generate quick checks that do a mask and compare to eliminate a
+ * choice.  If the quick check succeeds then it jumps to the continuation to
+ * do slow checks and check subsequent nodes.  If it fails (the common case)
+ * it falls through to the next choice.
+ *
+ * Here is the desired flow graph.  Nodes directly below each other imply
+ * fallthrough.  Alternatives 1 and 2 have quick checks.  Alternative
+ * 3 doesn't have a quick check so we have to call the slow check.
+ * Nodes are marked Qn for quick checks and Sn for slow checks.  The entire
+ * regexp continuation is generated directly after the Sn node, up to the
+ * next GoTo if we decide to reuse some already generated code.  Some
+ * nodes expect preload_characters to be preloaded into the current
+ * character register.  R nodes do this preloading.  Vertices are marked
+ * F for failures and S for success (possible success in the case of quick
+ * nodes).  L, V, < and > are used as arrow heads.
+ *
+ * ----------> R
+ *             |
+ *             V
+ *            Q1 -----> S1
+ *             |   S   /
+ *            F|      /
+ *             |    F/
+ *             |    /
+ *             |   R
+ *             |  /
+ *             V L
+ *            Q2 -----> S2
+ *             |   S   /
+ *            F|      /
+ *             |    F/
+ *             |    /
+ *             |   R
+ *             |  /
+ *             V L
+ *            S3
+ *             |
+ *            F|
+ *             |
+ *             R
+ *             |
+ * backtrack   V
+ * <----------Q4
+ *   \    F    |
+ *    \        |S
+ *     \   F   V
+ *      \-----S4
+ *
+ * For greedy loops we push the current position, then generate the code that
+ * eats the input specially in EmitGreedyLoop.  The other choice (the
+ * continuation) is generated by the normal code in EmitChoices, and steps back
+ * in the input to the starting position when it fails to match.  The loop code
+ * looks like this (U is the unwind code that steps back in the greedy loop).
+ *
+ *              _____
+ *             /     \
+ *             V     |
+ * ----------> S1    |
+ *            /|     |
+ *           / |S    |
+ *         F/  \_____/
+ *         /
+ *        |<-----
+ *        |      \
+ *        V       |S
+ *        Q2 ---> U----->backtrack
+ *        |  F   /
+ *       S|     /
+ *        V  F /
+ *        S2--/
+ */
+
+GreedyLoopState::GreedyLoopState(bool not_at_start) {
+  counter_backtrack_trace_.set_backtrack(&label_);
+  if (not_at_start) counter_backtrack_trace_.set_at_start(false);
+}
+
+
+void ChoiceNode::AssertGuardsMentionRegisters(Trace* trace) {
+#ifdef DEBUG
+  int choice_count = alternatives_->length();
+  for (int i = 0; i < choice_count - 1; i++) {
+    GuardedAlternative alternative = alternatives_->at(i);
+    ZoneList<Guard*>* guards = alternative.guards();
+    int guard_count = (guards == NULL) ? 0 : guards->length();
+    for (int j = 0; j < guard_count; j++) {
+      DCHECK(!trace->mentions_reg(guards->at(j)->reg()));
+    }
+  }
+#endif
+}
+
+
+void ChoiceNode::SetUpPreLoad(RegExpCompiler* compiler,
+                              Trace* current_trace,
+                              PreloadState* state) {
+    if (state->eats_at_least_ == PreloadState::kEatsAtLeastNotYetInitialized) {
+      // Save some time by looking at most one machine word ahead.
+      state->eats_at_least_ =
+          EatsAtLeast(compiler->one_byte() ? 4 : 2, kRecursionBudget,
+                      current_trace->at_start() == Trace::FALSE_VALUE);
+    }
+    state->preload_characters_ =
+        CalculatePreloadCharacters(compiler, state->eats_at_least_);
+
+    state->preload_is_current_ =
+        (current_trace->characters_preloaded() == state->preload_characters_);
+    state->preload_has_checked_bounds_ = state->preload_is_current_;
+}
+
+
+void ChoiceNode::Emit(RegExpCompiler* compiler, Trace* trace) {
+  int choice_count = alternatives_->length();
+
+  AssertGuardsMentionRegisters(trace);
+
+  LimitResult limit_result = LimitVersions(compiler, trace);
+  if (limit_result == DONE) return;
+  DCHECK(limit_result == CONTINUE);
+
+  // For loop nodes we already flushed (see LoopChoiceNode::Emit), but for
+  // other choice nodes we only flush if we are out of code size budget.
+  if (trace->flush_budget() == 0 && trace->actions() != NULL) {
+    trace->Flush(compiler, this);
+    return;
+  }
+
+  RecursionCheck rc(compiler);
+
+  PreloadState preload;
+  preload.init();
+  GreedyLoopState greedy_loop_state(not_at_start());
+
+  int text_length = GreedyLoopTextLengthForAlternative(&alternatives_->at(0));
+  AlternativeGenerationList alt_gens(choice_count, zone());
+
+  if (choice_count > 1 && text_length != kNodeIsTooComplexForGreedyLoops) {
+    trace = EmitGreedyLoop(compiler,
+                           trace,
+                           &alt_gens,
+                           &preload,
+                           &greedy_loop_state,
+                           text_length);
+  } else {
+    // TODO(erikcorry): Delete this.  We don't need this label, but it makes us
+    // match the traces produced pre-cleanup.
+    Label second_choice;
+    compiler->macro_assembler()->Bind(&second_choice);
+
+    preload.eats_at_least_ = EmitOptimizedUnanchoredSearch(compiler, trace);
+
+    EmitChoices(compiler,
+                &alt_gens,
+                0,
+                trace,
+                &preload);
+  }
+
+  // At this point we need to generate slow checks for the alternatives where
+  // the quick check was inlined.  We can recognize these because the associated
+  // label was bound.
+  int new_flush_budget = trace->flush_budget() / choice_count;
+  for (int i = 0; i < choice_count; i++) {
+    AlternativeGeneration* alt_gen = alt_gens.at(i);
+    Trace new_trace(*trace);
+    // If there are actions to be flushed we have to limit how many times
+    // they are flushed.  Take the budget of the parent trace and distribute
+    // it fairly amongst the children.
+    if (new_trace.actions() != NULL) {
+      new_trace.set_flush_budget(new_flush_budget);
+    }
+    bool next_expects_preload =
+        i == choice_count - 1 ? false : alt_gens.at(i + 1)->expects_preload;
+    EmitOutOfLineContinuation(compiler,
+                              &new_trace,
+                              alternatives_->at(i),
+                              alt_gen,
+                              preload.preload_characters_,
+                              next_expects_preload);
+  }
+}
+
+
+Trace* ChoiceNode::EmitGreedyLoop(RegExpCompiler* compiler,
+                                  Trace* trace,
+                                  AlternativeGenerationList* alt_gens,
+                                  PreloadState* preload,
+                                  GreedyLoopState* greedy_loop_state,
+                                  int text_length) {
+  RegExpMacroAssembler* macro_assembler = compiler->macro_assembler();
+  // Here we have special handling for greedy loops containing only text nodes
+  // and other simple nodes.  These are handled by pushing the current
+  // position on the stack and then incrementing the current position each
+  // time around the switch.  On backtrack we decrement the current position
+  // and check it against the pushed value.  This avoids pushing backtrack
+  // information for each iteration of the loop, which could take up a lot of
+  // space.
+  DCHECK(trace->stop_node() == NULL);
+  macro_assembler->PushCurrentPosition();
+  Label greedy_match_failed;
+  Trace greedy_match_trace;
+  if (not_at_start()) greedy_match_trace.set_at_start(false);
+  greedy_match_trace.set_backtrack(&greedy_match_failed);
+  Label loop_label;
+  macro_assembler->Bind(&loop_label);
+  greedy_match_trace.set_stop_node(this);
+  greedy_match_trace.set_loop_label(&loop_label);
+  alternatives_->at(0).node()->Emit(compiler, &greedy_match_trace);
+  macro_assembler->Bind(&greedy_match_failed);
+
+  Label second_choice;  // For use in greedy matches.
+  macro_assembler->Bind(&second_choice);
+
+  Trace* new_trace = greedy_loop_state->counter_backtrack_trace();
+
+  EmitChoices(compiler,
+              alt_gens,
+              1,
+              new_trace,
+              preload);
+
+  macro_assembler->Bind(greedy_loop_state->label());
+  // If we have unwound to the bottom then backtrack.
+  macro_assembler->CheckGreedyLoop(trace->backtrack());
+  // Otherwise try the second priority at an earlier position.
+  macro_assembler->AdvanceCurrentPosition(-text_length);
+  macro_assembler->GoTo(&second_choice);
+  return new_trace;
+}
+
+int ChoiceNode::EmitOptimizedUnanchoredSearch(RegExpCompiler* compiler,
+                                              Trace* trace) {
+  int eats_at_least = PreloadState::kEatsAtLeastNotYetInitialized;
+  if (alternatives_->length() != 2) return eats_at_least;
+
+  GuardedAlternative alt1 = alternatives_->at(1);
+  if (alt1.guards() != NULL && alt1.guards()->length() != 0) {
+    return eats_at_least;
+  }
+  RegExpNode* eats_anything_node = alt1.node();
+  if (eats_anything_node->GetSuccessorOfOmnivorousTextNode(compiler) != this) {
+    return eats_at_least;
+  }
+
+  // Really we should be creating a new trace when we execute this function,
+  // but there is no need, because the code it generates cannot backtrack, and
+  // we always arrive here with a trivial trace (since it's the entry to a
+  // loop.  That also implies that there are no preloaded characters, which is
+  // good, because it means we won't be violating any assumptions by
+  // overwriting those characters with new load instructions.
+  DCHECK(trace->is_trivial());
+
+  RegExpMacroAssembler* macro_assembler = compiler->macro_assembler();
+  // At this point we know that we are at a non-greedy loop that will eat
+  // any character one at a time.  Any non-anchored regexp has such a
+  // loop prepended to it in order to find where it starts.  We look for
+  // a pattern of the form ...abc... where we can look 6 characters ahead
+  // and step forwards 3 if the character is not one of abc.  Abc need
+  // not be atoms, they can be any reasonably limited character class or
+  // small alternation.
+  BoyerMooreLookahead* bm = bm_info(false);
+  if (bm == NULL) {
+    eats_at_least = Min(kMaxLookaheadForBoyerMoore,
+                        EatsAtLeast(kMaxLookaheadForBoyerMoore,
+                                    kRecursionBudget,
+                                    false));
+    if (eats_at_least >= 1) {
+      bm = new(zone()) BoyerMooreLookahead(eats_at_least,
+                                           compiler,
+                                           zone());
+      GuardedAlternative alt0 = alternatives_->at(0);
+      alt0.node()->FillInBMInfo(0, kRecursionBudget, bm, false);
+    }
+  }
+  if (bm != NULL) {
+    bm->EmitSkipInstructions(macro_assembler);
+  }
+  return eats_at_least;
+}
+
+
+void ChoiceNode::EmitChoices(RegExpCompiler* compiler,
+                             AlternativeGenerationList* alt_gens,
+                             int first_choice,
+                             Trace* trace,
+                             PreloadState* preload) {
+  RegExpMacroAssembler* macro_assembler = compiler->macro_assembler();
+  SetUpPreLoad(compiler, trace, preload);
+
+  // For now we just call all choices one after the other.  The idea ultimately
+  // is to use the Dispatch table to try only the relevant ones.
+  int choice_count = alternatives_->length();
+
+  int new_flush_budget = trace->flush_budget() / choice_count;
+
+  for (int i = first_choice; i < choice_count; i++) {
+    bool is_last = i == choice_count - 1;
+    bool fall_through_on_failure = !is_last;
+    GuardedAlternative alternative = alternatives_->at(i);
+    AlternativeGeneration* alt_gen = alt_gens->at(i);
+    alt_gen->quick_check_details.set_characters(preload->preload_characters_);
+    ZoneList<Guard*>* guards = alternative.guards();
+    int guard_count = (guards == NULL) ? 0 : guards->length();
+    Trace new_trace(*trace);
+    new_trace.set_characters_preloaded(preload->preload_is_current_ ?
+                                         preload->preload_characters_ :
+                                         0);
+    if (preload->preload_has_checked_bounds_) {
+      new_trace.set_bound_checked_up_to(preload->preload_characters_);
+    }
+    new_trace.quick_check_performed()->Clear();
+    if (not_at_start_) new_trace.set_at_start(Trace::FALSE_VALUE);
+    if (!is_last) {
+      new_trace.set_backtrack(&alt_gen->after);
+    }
+    alt_gen->expects_preload = preload->preload_is_current_;
+    bool generate_full_check_inline = false;
+    if (FLAG_regexp_optimization &&
+        try_to_emit_quick_check_for_alternative(i == 0) &&
+        alternative.node()->EmitQuickCheck(compiler,
+                                           trace,
+                                           &new_trace,
+                                           preload->preload_has_checked_bounds_,
+                                           &alt_gen->possible_success,
+                                           &alt_gen->quick_check_details,
+                                           fall_through_on_failure)) {
+      // Quick check was generated for this choice.
+      preload->preload_is_current_ = true;
+      preload->preload_has_checked_bounds_ = true;
+      // If we generated the quick check to fall through on possible success,
+      // we now need to generate the full check inline.
+      if (!fall_through_on_failure) {
+        macro_assembler->Bind(&alt_gen->possible_success);
+        new_trace.set_quick_check_performed(&alt_gen->quick_check_details);
+        new_trace.set_characters_preloaded(preload->preload_characters_);
+        new_trace.set_bound_checked_up_to(preload->preload_characters_);
+        generate_full_check_inline = true;
+      }
+    } else if (alt_gen->quick_check_details.cannot_match()) {
+      if (!fall_through_on_failure) {
+        macro_assembler->GoTo(trace->backtrack());
+      }
+      continue;
+    } else {
+      // No quick check was generated.  Put the full code here.
+      // If this is not the first choice then there could be slow checks from
+      // previous cases that go here when they fail.  There's no reason to
+      // insist that they preload characters since the slow check we are about
+      // to generate probably can't use it.
+      if (i != first_choice) {
+        alt_gen->expects_preload = false;
+        new_trace.InvalidateCurrentCharacter();
+      }
+      generate_full_check_inline = true;
+    }
+    if (generate_full_check_inline) {
+      if (new_trace.actions() != NULL) {
+        new_trace.set_flush_budget(new_flush_budget);
+      }
+      for (int j = 0; j < guard_count; j++) {
+        GenerateGuard(macro_assembler, guards->at(j), &new_trace);
+      }
+      alternative.node()->Emit(compiler, &new_trace);
+      preload->preload_is_current_ = false;
+    }
+    macro_assembler->Bind(&alt_gen->after);
+  }
+}
+
+
+void ChoiceNode::EmitOutOfLineContinuation(RegExpCompiler* compiler,
+                                           Trace* trace,
+                                           GuardedAlternative alternative,
+                                           AlternativeGeneration* alt_gen,
+                                           int preload_characters,
+                                           bool next_expects_preload) {
+  if (!alt_gen->possible_success.is_linked()) return;
+
+  RegExpMacroAssembler* macro_assembler = compiler->macro_assembler();
+  macro_assembler->Bind(&alt_gen->possible_success);
+  Trace out_of_line_trace(*trace);
+  out_of_line_trace.set_characters_preloaded(preload_characters);
+  out_of_line_trace.set_quick_check_performed(&alt_gen->quick_check_details);
+  if (not_at_start_) out_of_line_trace.set_at_start(Trace::FALSE_VALUE);
+  ZoneList<Guard*>* guards = alternative.guards();
+  int guard_count = (guards == NULL) ? 0 : guards->length();
+  if (next_expects_preload) {
+    Label reload_current_char;
+    out_of_line_trace.set_backtrack(&reload_current_char);
+    for (int j = 0; j < guard_count; j++) {
+      GenerateGuard(macro_assembler, guards->at(j), &out_of_line_trace);
+    }
+    alternative.node()->Emit(compiler, &out_of_line_trace);
+    macro_assembler->Bind(&reload_current_char);
+    // Reload the current character, since the next quick check expects that.
+    // We don't need to check bounds here because we only get into this
+    // code through a quick check which already did the checked load.
+    macro_assembler->LoadCurrentCharacter(trace->cp_offset(),
+                                          NULL,
+                                          false,
+                                          preload_characters);
+    macro_assembler->GoTo(&(alt_gen->after));
+  } else {
+    out_of_line_trace.set_backtrack(&(alt_gen->after));
+    for (int j = 0; j < guard_count; j++) {
+      GenerateGuard(macro_assembler, guards->at(j), &out_of_line_trace);
+    }
+    alternative.node()->Emit(compiler, &out_of_line_trace);
+  }
+}
+
+
+void ActionNode::Emit(RegExpCompiler* compiler, Trace* trace) {
+  RegExpMacroAssembler* assembler = compiler->macro_assembler();
+  LimitResult limit_result = LimitVersions(compiler, trace);
+  if (limit_result == DONE) return;
+  DCHECK(limit_result == CONTINUE);
+
+  RecursionCheck rc(compiler);
+
+  switch (action_type_) {
+    case STORE_POSITION: {
+      Trace::DeferredCapture
+          new_capture(data_.u_position_register.reg,
+                      data_.u_position_register.is_capture,
+                      trace);
+      Trace new_trace = *trace;
+      new_trace.add_action(&new_capture);
+      on_success()->Emit(compiler, &new_trace);
+      break;
+    }
+    case INCREMENT_REGISTER: {
+      Trace::DeferredIncrementRegister
+          new_increment(data_.u_increment_register.reg);
+      Trace new_trace = *trace;
+      new_trace.add_action(&new_increment);
+      on_success()->Emit(compiler, &new_trace);
+      break;
+    }
+    case SET_REGISTER: {
+      Trace::DeferredSetRegister
+          new_set(data_.u_store_register.reg, data_.u_store_register.value);
+      Trace new_trace = *trace;
+      new_trace.add_action(&new_set);
+      on_success()->Emit(compiler, &new_trace);
+      break;
+    }
+    case CLEAR_CAPTURES: {
+      Trace::DeferredClearCaptures
+        new_capture(Interval(data_.u_clear_captures.range_from,
+                             data_.u_clear_captures.range_to));
+      Trace new_trace = *trace;
+      new_trace.add_action(&new_capture);
+      on_success()->Emit(compiler, &new_trace);
+      break;
+    }
+    case BEGIN_SUBMATCH:
+      if (!trace->is_trivial()) {
+        trace->Flush(compiler, this);
+      } else {
+        assembler->WriteCurrentPositionToRegister(
+            data_.u_submatch.current_position_register, 0);
+        assembler->WriteStackPointerToRegister(
+            data_.u_submatch.stack_pointer_register);
+        on_success()->Emit(compiler, trace);
+      }
+      break;
+    case EMPTY_MATCH_CHECK: {
+      int start_pos_reg = data_.u_empty_match_check.start_register;
+      int stored_pos = 0;
+      int rep_reg = data_.u_empty_match_check.repetition_register;
+      bool has_minimum = (rep_reg != RegExpCompiler::kNoRegister);
+      bool know_dist = trace->GetStoredPosition(start_pos_reg, &stored_pos);
+      if (know_dist && !has_minimum && stored_pos == trace->cp_offset()) {
+        // If we know we haven't advanced and there is no minimum we
+        // can just backtrack immediately.
+        assembler->GoTo(trace->backtrack());
+      } else if (know_dist && stored_pos < trace->cp_offset()) {
+        // If we know we've advanced we can generate the continuation
+        // immediately.
+        on_success()->Emit(compiler, trace);
+      } else if (!trace->is_trivial()) {
+        trace->Flush(compiler, this);
+      } else {
+        Label skip_empty_check;
+        // If we have a minimum number of repetitions we check the current
+        // number first and skip the empty check if it's not enough.
+        if (has_minimum) {
+          int limit = data_.u_empty_match_check.repetition_limit;
+          assembler->IfRegisterLT(rep_reg, limit, &skip_empty_check);
+        }
+        // If the match is empty we bail out, otherwise we fall through
+        // to the on-success continuation.
+        assembler->IfRegisterEqPos(data_.u_empty_match_check.start_register,
+                                   trace->backtrack());
+        assembler->Bind(&skip_empty_check);
+        on_success()->Emit(compiler, trace);
+      }
+      break;
+    }
+    case POSITIVE_SUBMATCH_SUCCESS: {
+      if (!trace->is_trivial()) {
+        trace->Flush(compiler, this);
+        return;
+      }
+      assembler->ReadCurrentPositionFromRegister(
+          data_.u_submatch.current_position_register);
+      assembler->ReadStackPointerFromRegister(
+          data_.u_submatch.stack_pointer_register);
+      int clear_register_count = data_.u_submatch.clear_register_count;
+      if (clear_register_count == 0) {
+        on_success()->Emit(compiler, trace);
+        return;
+      }
+      int clear_registers_from = data_.u_submatch.clear_register_from;
+      Label clear_registers_backtrack;
+      Trace new_trace = *trace;
+      new_trace.set_backtrack(&clear_registers_backtrack);
+      on_success()->Emit(compiler, &new_trace);
+
+      assembler->Bind(&clear_registers_backtrack);
+      int clear_registers_to = clear_registers_from + clear_register_count - 1;
+      assembler->ClearRegisters(clear_registers_from, clear_registers_to);
+
+      DCHECK(trace->backtrack() == NULL);
+      assembler->Backtrack();
+      return;
+    }
+    default:
+      UNREACHABLE();
+  }
+}
+
+
+void BackReferenceNode::Emit(RegExpCompiler* compiler, Trace* trace) {
+  RegExpMacroAssembler* assembler = compiler->macro_assembler();
+  if (!trace->is_trivial()) {
+    trace->Flush(compiler, this);
+    return;
+  }
+
+  LimitResult limit_result = LimitVersions(compiler, trace);
+  if (limit_result == DONE) return;
+  DCHECK(limit_result == CONTINUE);
+
+  RecursionCheck rc(compiler);
+
+  DCHECK_EQ(start_reg_ + 1, end_reg_);
+  if (compiler->ignore_case()) {
+    assembler->CheckNotBackReferenceIgnoreCase(start_reg_,
+                                               trace->backtrack());
+  } else {
+    assembler->CheckNotBackReference(start_reg_, trace->backtrack());
+  }
+  on_success()->Emit(compiler, trace);
+}
+
+
+// -------------------------------------------------------------------
+// Dot/dotty output
+
+
+#ifdef DEBUG
+
+
+class DotPrinter: public NodeVisitor {
+ public:
+  DotPrinter(OStream& os, bool ignore_case)  // NOLINT
+      : os_(os),
+        ignore_case_(ignore_case) {}
+  void PrintNode(const char* label, RegExpNode* node);
+  void Visit(RegExpNode* node);
+  void PrintAttributes(RegExpNode* from);
+  void PrintOnFailure(RegExpNode* from, RegExpNode* to);
+#define DECLARE_VISIT(Type)                                          \
+  virtual void Visit##Type(Type##Node* that);
+FOR_EACH_NODE_TYPE(DECLARE_VISIT)
+#undef DECLARE_VISIT
+ private:
+  OStream& os_;
+  bool ignore_case_;
+};
+
+
+void DotPrinter::PrintNode(const char* label, RegExpNode* node) {
+  os_ << "digraph G {\n  graph [label=\"";
+  for (int i = 0; label[i]; i++) {
+    switch (label[i]) {
+      case '\\':
+        os_ << "\\\\";
+        break;
+      case '"':
+        os_ << "\"";
+        break;
+      default:
+        os_ << label[i];
+        break;
+    }
+  }
+  os_ << "\"];\n";
+  Visit(node);
+  os_ << "}" << endl;
+}
+
+
+void DotPrinter::Visit(RegExpNode* node) {
+  if (node->info()->visited) return;
+  node->info()->visited = true;
+  node->Accept(this);
+}
+
+
+void DotPrinter::PrintOnFailure(RegExpNode* from, RegExpNode* on_failure) {
+  os_ << "  n" << from << " -> n" << on_failure << " [style=dotted];\n";
+  Visit(on_failure);
+}
+
+
+class TableEntryBodyPrinter {
+ public:
+  TableEntryBodyPrinter(OStream& os, ChoiceNode* choice)  // NOLINT
+      : os_(os),
+        choice_(choice) {}
+  void Call(uc16 from, DispatchTable::Entry entry) {
+    OutSet* out_set = entry.out_set();
+    for (unsigned i = 0; i < OutSet::kFirstLimit; i++) {
+      if (out_set->Get(i)) {
+        os_ << "    n" << choice() << ":s" << from << "o" << i << " -> n"
+            << choice()->alternatives()->at(i).node() << ";\n";
+      }
+    }
+  }
+ private:
+  ChoiceNode* choice() { return choice_; }
+  OStream& os_;
+  ChoiceNode* choice_;
+};
+
+
+class TableEntryHeaderPrinter {
+ public:
+  explicit TableEntryHeaderPrinter(OStream& os)  // NOLINT
+      : first_(true),
+        os_(os) {}
+  void Call(uc16 from, DispatchTable::Entry entry) {
+    if (first_) {
+      first_ = false;
+    } else {
+      os_ << "|";
+    }
+    os_ << "{\\" << AsUC16(from) << "-\\" << AsUC16(entry.to()) << "|{";
+    OutSet* out_set = entry.out_set();
+    int priority = 0;
+    for (unsigned i = 0; i < OutSet::kFirstLimit; i++) {
+      if (out_set->Get(i)) {
+        if (priority > 0) os_ << "|";
+        os_ << "<s" << from << "o" << i << "> " << priority;
+        priority++;
+      }
+    }
+    os_ << "}}";
+  }
+
+ private:
+  bool first_;
+  OStream& os_;
+};
+
+
+class AttributePrinter {
+ public:
+  explicit AttributePrinter(OStream& os)  // NOLINT
+      : os_(os),
+        first_(true) {}
+  void PrintSeparator() {
+    if (first_) {
+      first_ = false;
+    } else {
+      os_ << "|";
+    }
+  }
+  void PrintBit(const char* name, bool value) {
+    if (!value) return;
+    PrintSeparator();
+    os_ << "{" << name << "}";
+  }
+  void PrintPositive(const char* name, int value) {
+    if (value < 0) return;
+    PrintSeparator();
+    os_ << "{" << name << "|" << value << "}";
+  }
+
+ private:
+  OStream& os_;
+  bool first_;
+};
+
+
+void DotPrinter::PrintAttributes(RegExpNode* that) {
+  os_ << "  a" << that << " [shape=Mrecord, color=grey, fontcolor=grey, "
+      << "margin=0.1, fontsize=10, label=\"{";
+  AttributePrinter printer(os_);
+  NodeInfo* info = that->info();
+  printer.PrintBit("NI", info->follows_newline_interest);
+  printer.PrintBit("WI", info->follows_word_interest);
+  printer.PrintBit("SI", info->follows_start_interest);
+  Label* label = that->label();
+  if (label->is_bound())
+    printer.PrintPositive("@", label->pos());
+  os_ << "}\"];\n"
+      << "  a" << that << " -> n" << that
+      << " [style=dashed, color=grey, arrowhead=none];\n";
+}
+
+
+static const bool kPrintDispatchTable = false;
+void DotPrinter::VisitChoice(ChoiceNode* that) {
+  if (kPrintDispatchTable) {
+    os_ << "  n" << that << " [shape=Mrecord, label=\"";
+    TableEntryHeaderPrinter header_printer(os_);
+    that->GetTable(ignore_case_)->ForEach(&header_printer);
+    os_ << "\"]\n";
+    PrintAttributes(that);
+    TableEntryBodyPrinter body_printer(os_, that);
+    that->GetTable(ignore_case_)->ForEach(&body_printer);
+  } else {
+    os_ << "  n" << that << " [shape=Mrecord, label=\"?\"];\n";
+    for (int i = 0; i < that->alternatives()->length(); i++) {
+      GuardedAlternative alt = that->alternatives()->at(i);
+      os_ << "  n" << that << " -> n" << alt.node();
+    }
+  }
+  for (int i = 0; i < that->alternatives()->length(); i++) {
+    GuardedAlternative alt = that->alternatives()->at(i);
+    alt.node()->Accept(this);
+  }
+}
+
+
+void DotPrinter::VisitText(TextNode* that) {
+  Zone* zone = that->zone();
+  os_ << "  n" << that << " [label=\"";
+  for (int i = 0; i < that->elements()->length(); i++) {
+    if (i > 0) os_ << " ";
+    TextElement elm = that->elements()->at(i);
+    switch (elm.text_type()) {
+      case TextElement::ATOM: {
+        Vector<const uc16> data = elm.atom()->data();
+        for (int i = 0; i < data.length(); i++) {
+          os_ << static_cast<char>(data[i]);
+        }
+        break;
+      }
+      case TextElement::CHAR_CLASS: {
+        RegExpCharacterClass* node = elm.char_class();
+        os_ << "[";
+        if (node->is_negated()) os_ << "^";
+        for (int j = 0; j < node->ranges(zone)->length(); j++) {
+          CharacterRange range = node->ranges(zone)->at(j);
+          os_ << AsUC16(range.from()) << "-" << AsUC16(range.to());
+        }
+        os_ << "]";
+        break;
+      }
+      default:
+        UNREACHABLE();
+    }
+  }
+  os_ << "\", shape=box, peripheries=2];\n";
+  PrintAttributes(that);
+  os_ << "  n" << that << " -> n" << that->on_success() << ";\n";
+  Visit(that->on_success());
+}
+
+
+void DotPrinter::VisitBackReference(BackReferenceNode* that) {
+  os_ << "  n" << that << " [label=\"$" << that->start_register() << "..$"
+      << that->end_register() << "\", shape=doubleoctagon];\n";
+  PrintAttributes(that);
+  os_ << "  n" << that << " -> n" << that->on_success() << ";\n";
+  Visit(that->on_success());
+}
+
+
+void DotPrinter::VisitEnd(EndNode* that) {
+  os_ << "  n" << that << " [style=bold, shape=point];\n";
+  PrintAttributes(that);
+}
+
+
+void DotPrinter::VisitAssertion(AssertionNode* that) {
+  os_ << "  n" << that << " [";
+  switch (that->assertion_type()) {
+    case AssertionNode::AT_END:
+      os_ << "label=\"$\", shape=septagon";
+      break;
+    case AssertionNode::AT_START:
+      os_ << "label=\"^\", shape=septagon";
+      break;
+    case AssertionNode::AT_BOUNDARY:
+      os_ << "label=\"\\b\", shape=septagon";
+      break;
+    case AssertionNode::AT_NON_BOUNDARY:
+      os_ << "label=\"\\B\", shape=septagon";
+      break;
+    case AssertionNode::AFTER_NEWLINE:
+      os_ << "label=\"(?<=\\n)\", shape=septagon";
+      break;
+  }
+  os_ << "];\n";
+  PrintAttributes(that);
+  RegExpNode* successor = that->on_success();
+  os_ << "  n" << that << " -> n" << successor << ";\n";
+  Visit(successor);
+}
+
+
+void DotPrinter::VisitAction(ActionNode* that) {
+  os_ << "  n" << that << " [";
+  switch (that->action_type_) {
+    case ActionNode::SET_REGISTER:
+      os_ << "label=\"$" << that->data_.u_store_register.reg
+          << ":=" << that->data_.u_store_register.value << "\", shape=octagon";
+      break;
+    case ActionNode::INCREMENT_REGISTER:
+      os_ << "label=\"$" << that->data_.u_increment_register.reg
+          << "++\", shape=octagon";
+      break;
+    case ActionNode::STORE_POSITION:
+      os_ << "label=\"$" << that->data_.u_position_register.reg
+          << ":=$pos\", shape=octagon";
+      break;
+    case ActionNode::BEGIN_SUBMATCH:
+      os_ << "label=\"$" << that->data_.u_submatch.current_position_register
+          << ":=$pos,begin\", shape=septagon";
+      break;
+    case ActionNode::POSITIVE_SUBMATCH_SUCCESS:
+      os_ << "label=\"escape\", shape=septagon";
+      break;
+    case ActionNode::EMPTY_MATCH_CHECK:
+      os_ << "label=\"$" << that->data_.u_empty_match_check.start_register
+          << "=$pos?,$" << that->data_.u_empty_match_check.repetition_register
+          << "<" << that->data_.u_empty_match_check.repetition_limit
+          << "?\", shape=septagon";
+      break;
+    case ActionNode::CLEAR_CAPTURES: {
+      os_ << "label=\"clear $" << that->data_.u_clear_captures.range_from
+          << " to $" << that->data_.u_clear_captures.range_to
+          << "\", shape=septagon";
+      break;
+    }
+  }
+  os_ << "];\n";
+  PrintAttributes(that);
+  RegExpNode* successor = that->on_success();
+  os_ << "  n" << that << " -> n" << successor << ";\n";
+  Visit(successor);
+}
+
+
+class DispatchTableDumper {
+ public:
+  explicit DispatchTableDumper(OStream& os) : os_(os) {}
+  void Call(uc16 key, DispatchTable::Entry entry);
+ private:
+  OStream& os_;
+};
+
+
+void DispatchTableDumper::Call(uc16 key, DispatchTable::Entry entry) {
+  os_ << "[" << AsUC16(key) << "-" << AsUC16(entry.to()) << "]: {";
+  OutSet* set = entry.out_set();
+  bool first = true;
+  for (unsigned i = 0; i < OutSet::kFirstLimit; i++) {
+    if (set->Get(i)) {
+      if (first) {
+        first = false;
+      } else {
+        os_ << ", ";
+      }
+      os_ << i;
+    }
+  }
+  os_ << "}\n";
+}
+
+
+void DispatchTable::Dump() {
+  OFStream os(stderr);
+  DispatchTableDumper dumper(os);
+  tree()->ForEach(&dumper);
+}
+
+
+void RegExpEngine::DotPrint(const char* label,
+                            RegExpNode* node,
+                            bool ignore_case) {
+  OFStream os(stdout);
+  DotPrinter printer(os, ignore_case);
+  printer.PrintNode(label, node);
+}
+
+
+#endif  // DEBUG
+
+
+// -------------------------------------------------------------------
+// Tree to graph conversion
+
+RegExpNode* RegExpAtom::ToNode(RegExpCompiler* compiler,
+                               RegExpNode* on_success) {
+  ZoneList<TextElement>* elms =
+      new(compiler->zone()) ZoneList<TextElement>(1, compiler->zone());
+  elms->Add(TextElement::Atom(this), compiler->zone());
+  return new(compiler->zone()) TextNode(elms, on_success);
+}
+
+
+RegExpNode* RegExpText::ToNode(RegExpCompiler* compiler,
+                               RegExpNode* on_success) {
+  return new(compiler->zone()) TextNode(elements(), on_success);
+}
+
+
+static bool CompareInverseRanges(ZoneList<CharacterRange>* ranges,
+                                 const int* special_class,
+                                 int length) {
+  length--;  // Remove final 0x10000.
+  DCHECK(special_class[length] == 0x10000);
+  DCHECK(ranges->length() != 0);
+  DCHECK(length != 0);
+  DCHECK(special_class[0] != 0);
+  if (ranges->length() != (length >> 1) + 1) {
+    return false;
+  }
+  CharacterRange range = ranges->at(0);
+  if (range.from() != 0) {
+    return false;
+  }
+  for (int i = 0; i < length; i += 2) {
+    if (special_class[i] != (range.to() + 1)) {
+      return false;
+    }
+    range = ranges->at((i >> 1) + 1);
+    if (special_class[i+1] != range.from()) {
+      return false;
+    }
+  }
+  if (range.to() != 0xffff) {
+    return false;
+  }
+  return true;
+}
+
+
+static bool CompareRanges(ZoneList<CharacterRange>* ranges,
+                          const int* special_class,
+                          int length) {
+  length--;  // Remove final 0x10000.
+  DCHECK(special_class[length] == 0x10000);
+  if (ranges->length() * 2 != length) {
+    return false;
+  }
+  for (int i = 0; i < length; i += 2) {
+    CharacterRange range = ranges->at(i >> 1);
+    if (range.from() != special_class[i] ||
+        range.to() != special_class[i + 1] - 1) {
+      return false;
+    }
+  }
+  return true;
+}
+
+
+bool RegExpCharacterClass::is_standard(Zone* zone) {
+  // TODO(lrn): Remove need for this function, by not throwing away information
+  // along the way.
+  if (is_negated_) {
+    return false;
+  }
+  if (set_.is_standard()) {
+    return true;
+  }
+  if (CompareRanges(set_.ranges(zone), kSpaceRanges, kSpaceRangeCount)) {
+    set_.set_standard_set_type('s');
+    return true;
+  }
+  if (CompareInverseRanges(set_.ranges(zone), kSpaceRanges, kSpaceRangeCount)) {
+    set_.set_standard_set_type('S');
+    return true;
+  }
+  if (CompareInverseRanges(set_.ranges(zone),
+                           kLineTerminatorRanges,
+                           kLineTerminatorRangeCount)) {
+    set_.set_standard_set_type('.');
+    return true;
+  }
+  if (CompareRanges(set_.ranges(zone),
+                    kLineTerminatorRanges,
+                    kLineTerminatorRangeCount)) {
+    set_.set_standard_set_type('n');
+    return true;
+  }
+  if (CompareRanges(set_.ranges(zone), kWordRanges, kWordRangeCount)) {
+    set_.set_standard_set_type('w');
+    return true;
+  }
+  if (CompareInverseRanges(set_.ranges(zone), kWordRanges, kWordRangeCount)) {
+    set_.set_standard_set_type('W');
+    return true;
+  }
+  return false;
+}
+
+
+RegExpNode* RegExpCharacterClass::ToNode(RegExpCompiler* compiler,
+                                         RegExpNode* on_success) {
+  return new(compiler->zone()) TextNode(this, on_success);
+}
+
+
+RegExpNode* RegExpDisjunction::ToNode(RegExpCompiler* compiler,
+                                      RegExpNode* on_success) {
+  ZoneList<RegExpTree*>* alternatives = this->alternatives();
+  int length = alternatives->length();
+  ChoiceNode* result =
+      new(compiler->zone()) ChoiceNode(length, compiler->zone());
+  for (int i = 0; i < length; i++) {
+    GuardedAlternative alternative(alternatives->at(i)->ToNode(compiler,
+                                                               on_success));
+    result->AddAlternative(alternative);
+  }
+  return result;
+}
+
+
+RegExpNode* RegExpQuantifier::ToNode(RegExpCompiler* compiler,
+                                     RegExpNode* on_success) {
+  return ToNode(min(),
+                max(),
+                is_greedy(),
+                body(),
+                compiler,
+                on_success);
+}
+
+
+// Scoped object to keep track of how much we unroll quantifier loops in the
+// regexp graph generator.
+class RegExpExpansionLimiter {
+ public:
+  static const int kMaxExpansionFactor = 6;
+  RegExpExpansionLimiter(RegExpCompiler* compiler, int factor)
+      : compiler_(compiler),
+        saved_expansion_factor_(compiler->current_expansion_factor()),
+        ok_to_expand_(saved_expansion_factor_ <= kMaxExpansionFactor) {
+    DCHECK(factor > 0);
+    if (ok_to_expand_) {
+      if (factor > kMaxExpansionFactor) {
+        // Avoid integer overflow of the current expansion factor.
+        ok_to_expand_ = false;
+        compiler->set_current_expansion_factor(kMaxExpansionFactor + 1);
+      } else {
+        int new_factor = saved_expansion_factor_ * factor;
+        ok_to_expand_ = (new_factor <= kMaxExpansionFactor);
+        compiler->set_current_expansion_factor(new_factor);
+      }
+    }
+  }
+
+  ~RegExpExpansionLimiter() {
+    compiler_->set_current_expansion_factor(saved_expansion_factor_);
+  }
+
+  bool ok_to_expand() { return ok_to_expand_; }
+
+ private:
+  RegExpCompiler* compiler_;
+  int saved_expansion_factor_;
+  bool ok_to_expand_;
+
+  DISALLOW_IMPLICIT_CONSTRUCTORS(RegExpExpansionLimiter);
+};
+
+
+RegExpNode* RegExpQuantifier::ToNode(int min,
+                                     int max,
+                                     bool is_greedy,
+                                     RegExpTree* body,
+                                     RegExpCompiler* compiler,
+                                     RegExpNode* on_success,
+                                     bool not_at_start) {
+  // x{f, t} becomes this:
+  //
+  //             (r++)<-.
+  //               |     `
+  //               |     (x)
+  //               v     ^
+  //      (r=0)-->(?)---/ [if r < t]
+  //               |
+  //   [if r >= f] \----> ...
+  //
+
+  // 15.10.2.5 RepeatMatcher algorithm.
+  // The parser has already eliminated the case where max is 0.  In the case
+  // where max_match is zero the parser has removed the quantifier if min was
+  // > 0 and removed the atom if min was 0.  See AddQuantifierToAtom.
+
+  // If we know that we cannot match zero length then things are a little
+  // simpler since we don't need to make the special zero length match check
+  // from step 2.1.  If the min and max are small we can unroll a little in
+  // this case.
+  static const int kMaxUnrolledMinMatches = 3;  // Unroll (foo)+ and (foo){3,}
+  static const int kMaxUnrolledMaxMatches = 3;  // Unroll (foo)? and (foo){x,3}
+  if (max == 0) return on_success;  // This can happen due to recursion.
+  bool body_can_be_empty = (body->min_match() == 0);
+  int body_start_reg = RegExpCompiler::kNoRegister;
+  Interval capture_registers = body->CaptureRegisters();
+  bool needs_capture_clearing = !capture_registers.is_empty();
+  Zone* zone = compiler->zone();
+
+  if (body_can_be_empty) {
+    body_start_reg = compiler->AllocateRegister();
+  } else if (FLAG_regexp_optimization && !needs_capture_clearing) {
+    // Only unroll if there are no captures and the body can't be
+    // empty.
+    {
+      RegExpExpansionLimiter limiter(
+          compiler, min + ((max != min) ? 1 : 0));
+      if (min > 0 && min <= kMaxUnrolledMinMatches && limiter.ok_to_expand()) {
+        int new_max = (max == kInfinity) ? max : max - min;
+        // Recurse once to get the loop or optional matches after the fixed
+        // ones.
+        RegExpNode* answer = ToNode(
+            0, new_max, is_greedy, body, compiler, on_success, true);
+        // Unroll the forced matches from 0 to min.  This can cause chains of
+        // TextNodes (which the parser does not generate).  These should be
+        // combined if it turns out they hinder good code generation.
+        for (int i = 0; i < min; i++) {
+          answer = body->ToNode(compiler, answer);
+        }
+        return answer;
+      }
+    }
+    if (max <= kMaxUnrolledMaxMatches && min == 0) {
+      DCHECK(max > 0);  // Due to the 'if' above.
+      RegExpExpansionLimiter limiter(compiler, max);
+      if (limiter.ok_to_expand()) {
+        // Unroll the optional matches up to max.
+        RegExpNode* answer = on_success;
+        for (int i = 0; i < max; i++) {
+          ChoiceNode* alternation = new(zone) ChoiceNode(2, zone);
+          if (is_greedy) {
+            alternation->AddAlternative(
+                GuardedAlternative(body->ToNode(compiler, answer)));
+            alternation->AddAlternative(GuardedAlternative(on_success));
+          } else {
+            alternation->AddAlternative(GuardedAlternative(on_success));
+            alternation->AddAlternative(
+                GuardedAlternative(body->ToNode(compiler, answer)));
+          }
+          answer = alternation;
+          if (not_at_start) alternation->set_not_at_start();
+        }
+        return answer;
+      }
+    }
+  }
+  bool has_min = min > 0;
+  bool has_max = max < RegExpTree::kInfinity;
+  bool needs_counter = has_min || has_max;
+  int reg_ctr = needs_counter
+      ? compiler->AllocateRegister()
+      : RegExpCompiler::kNoRegister;
+  LoopChoiceNode* center = new(zone) LoopChoiceNode(body->min_match() == 0,
+                                                    zone);
+  if (not_at_start) center->set_not_at_start();
+  RegExpNode* loop_return = needs_counter
+      ? static_cast<RegExpNode*>(ActionNode::IncrementRegister(reg_ctr, center))
+      : static_cast<RegExpNode*>(center);
+  if (body_can_be_empty) {
+    // If the body can be empty we need to check if it was and then
+    // backtrack.
+    loop_return = ActionNode::EmptyMatchCheck(body_start_reg,
+                                              reg_ctr,
+                                              min,
+                                              loop_return);
+  }
+  RegExpNode* body_node = body->ToNode(compiler, loop_return);
+  if (body_can_be_empty) {
+    // If the body can be empty we need to store the start position
+    // so we can bail out if it was empty.
+    body_node = ActionNode::StorePosition(body_start_reg, false, body_node);
+  }
+  if (needs_capture_clearing) {
+    // Before entering the body of this loop we need to clear captures.
+    body_node = ActionNode::ClearCaptures(capture_registers, body_node);
+  }
+  GuardedAlternative body_alt(body_node);
+  if (has_max) {
+    Guard* body_guard =
+        new(zone) Guard(reg_ctr, Guard::LT, max);
+    body_alt.AddGuard(body_guard, zone);
+  }
+  GuardedAlternative rest_alt(on_success);
+  if (has_min) {
+    Guard* rest_guard = new(compiler->zone()) Guard(reg_ctr, Guard::GEQ, min);
+    rest_alt.AddGuard(rest_guard, zone);
+  }
+  if (is_greedy) {
+    center->AddLoopAlternative(body_alt);
+    center->AddContinueAlternative(rest_alt);
+  } else {
+    center->AddContinueAlternative(rest_alt);
+    center->AddLoopAlternative(body_alt);
+  }
+  if (needs_counter) {
+    return ActionNode::SetRegister(reg_ctr, 0, center);
+  } else {
+    return center;
+  }
+}
+
+
+RegExpNode* RegExpAssertion::ToNode(RegExpCompiler* compiler,
+                                    RegExpNode* on_success) {
+  NodeInfo info;
+  Zone* zone = compiler->zone();
+
+  switch (assertion_type()) {
+    case START_OF_LINE:
+      return AssertionNode::AfterNewline(on_success);
+    case START_OF_INPUT:
+      return AssertionNode::AtStart(on_success);
+    case BOUNDARY:
+      return AssertionNode::AtBoundary(on_success);
+    case NON_BOUNDARY:
+      return AssertionNode::AtNonBoundary(on_success);
+    case END_OF_INPUT:
+      return AssertionNode::AtEnd(on_success);
+    case END_OF_LINE: {
+      // Compile $ in multiline regexps as an alternation with a positive
+      // lookahead in one side and an end-of-input on the other side.
+      // We need two registers for the lookahead.
+      int stack_pointer_register = compiler->AllocateRegister();
+      int position_register = compiler->AllocateRegister();
+      // The ChoiceNode to distinguish between a newline and end-of-input.
+      ChoiceNode* result = new(zone) ChoiceNode(2, zone);
+      // Create a newline atom.
+      ZoneList<CharacterRange>* newline_ranges =
+          new(zone) ZoneList<CharacterRange>(3, zone);
+      CharacterRange::AddClassEscape('n', newline_ranges, zone);
+      RegExpCharacterClass* newline_atom = new(zone) RegExpCharacterClass('n');
+      TextNode* newline_matcher = new(zone) TextNode(
+         newline_atom,
+         ActionNode::PositiveSubmatchSuccess(stack_pointer_register,
+                                             position_register,
+                                             0,  // No captures inside.
+                                             -1,  // Ignored if no captures.
+                                             on_success));
+      // Create an end-of-input matcher.
+      RegExpNode* end_of_line = ActionNode::BeginSubmatch(
+          stack_pointer_register,
+          position_register,
+          newline_matcher);
+      // Add the two alternatives to the ChoiceNode.
+      GuardedAlternative eol_alternative(end_of_line);
+      result->AddAlternative(eol_alternative);
+      GuardedAlternative end_alternative(AssertionNode::AtEnd(on_success));
+      result->AddAlternative(end_alternative);
+      return result;
+    }
+    default:
+      UNREACHABLE();
+  }
+  return on_success;
+}
+
+
+RegExpNode* RegExpBackReference::ToNode(RegExpCompiler* compiler,
+                                        RegExpNode* on_success) {
+  return new(compiler->zone())
+      BackReferenceNode(RegExpCapture::StartRegister(index()),
+                        RegExpCapture::EndRegister(index()),
+                        on_success);
+}
+
+
+RegExpNode* RegExpEmpty::ToNode(RegExpCompiler* compiler,
+                                RegExpNode* on_success) {
+  return on_success;
+}
+
+
+RegExpNode* RegExpLookahead::ToNode(RegExpCompiler* compiler,
+                                    RegExpNode* on_success) {
+  int stack_pointer_register = compiler->AllocateRegister();
+  int position_register = compiler->AllocateRegister();
+
+  const int registers_per_capture = 2;
+  const int register_of_first_capture = 2;
+  int register_count = capture_count_ * registers_per_capture;
+  int register_start =
+    register_of_first_capture + capture_from_ * registers_per_capture;
+
+  RegExpNode* success;
+  if (is_positive()) {
+    RegExpNode* node = ActionNode::BeginSubmatch(
+        stack_pointer_register,
+        position_register,
+        body()->ToNode(
+            compiler,
+            ActionNode::PositiveSubmatchSuccess(stack_pointer_register,
+                                                position_register,
+                                                register_count,
+                                                register_start,
+                                                on_success)));
+    return node;
+  } else {
+    // We use a ChoiceNode for a negative lookahead because it has most of
+    // the characteristics we need.  It has the body of the lookahead as its
+    // first alternative and the expression after the lookahead of the second
+    // alternative.  If the first alternative succeeds then the
+    // NegativeSubmatchSuccess will unwind the stack including everything the
+    // choice node set up and backtrack.  If the first alternative fails then
+    // the second alternative is tried, which is exactly the desired result
+    // for a negative lookahead.  The NegativeLookaheadChoiceNode is a special
+    // ChoiceNode that knows to ignore the first exit when calculating quick
+    // checks.
+    Zone* zone = compiler->zone();
+
+    GuardedAlternative body_alt(
+        body()->ToNode(
+            compiler,
+            success = new(zone) NegativeSubmatchSuccess(stack_pointer_register,
+                                                        position_register,
+                                                        register_count,
+                                                        register_start,
+                                                        zone)));
+    ChoiceNode* choice_node =
+        new(zone) NegativeLookaheadChoiceNode(body_alt,
+                                              GuardedAlternative(on_success),
+                                              zone);
+    return ActionNode::BeginSubmatch(stack_pointer_register,
+                                     position_register,
+                                     choice_node);
+  }
+}
+
+
+RegExpNode* RegExpCapture::ToNode(RegExpCompiler* compiler,
+                                  RegExpNode* on_success) {
+  return ToNode(body(), index(), compiler, on_success);
+}
+
+
+RegExpNode* RegExpCapture::ToNode(RegExpTree* body,
+                                  int index,
+                                  RegExpCompiler* compiler,
+                                  RegExpNode* on_success) {
+  int start_reg = RegExpCapture::StartRegister(index);
+  int end_reg = RegExpCapture::EndRegister(index);
+  RegExpNode* store_end = ActionNode::StorePosition(end_reg, true, on_success);
+  RegExpNode* body_node = body->ToNode(compiler, store_end);
+  return ActionNode::StorePosition(start_reg, true, body_node);
+}
+
+
+RegExpNode* RegExpAlternative::ToNode(RegExpCompiler* compiler,
+                                      RegExpNode* on_success) {
+  ZoneList<RegExpTree*>* children = nodes();
+  RegExpNode* current = on_success;
+  for (int i = children->length() - 1; i >= 0; i--) {
+    current = children->at(i)->ToNode(compiler, current);
+  }
+  return current;
+}
+
+
+static void AddClass(const int* elmv,
+                     int elmc,
+                     ZoneList<CharacterRange>* ranges,
+                     Zone* zone) {
+  elmc--;
+  DCHECK(elmv[elmc] == 0x10000);
+  for (int i = 0; i < elmc; i += 2) {
+    DCHECK(elmv[i] < elmv[i + 1]);
+    ranges->Add(CharacterRange(elmv[i], elmv[i + 1] - 1), zone);
+  }
+}
+
+
+static void AddClassNegated(const int *elmv,
+                            int elmc,
+                            ZoneList<CharacterRange>* ranges,
+                            Zone* zone) {
+  elmc--;
+  DCHECK(elmv[elmc] == 0x10000);
+  DCHECK(elmv[0] != 0x0000);
+  DCHECK(elmv[elmc-1] != String::kMaxUtf16CodeUnit);
+  uc16 last = 0x0000;
+  for (int i = 0; i < elmc; i += 2) {
+    DCHECK(last <= elmv[i] - 1);
+    DCHECK(elmv[i] < elmv[i + 1]);
+    ranges->Add(CharacterRange(last, elmv[i] - 1), zone);
+    last = elmv[i + 1];
+  }
+  ranges->Add(CharacterRange(last, String::kMaxUtf16CodeUnit), zone);
+}
+
+
+void CharacterRange::AddClassEscape(uc16 type,
+                                    ZoneList<CharacterRange>* ranges,
+                                    Zone* zone) {
+  switch (type) {
+    case 's':
+      AddClass(kSpaceRanges, kSpaceRangeCount, ranges, zone);
+      break;
+    case 'S':
+      AddClassNegated(kSpaceRanges, kSpaceRangeCount, ranges, zone);
+      break;
+    case 'w':
+      AddClass(kWordRanges, kWordRangeCount, ranges, zone);
+      break;
+    case 'W':
+      AddClassNegated(kWordRanges, kWordRangeCount, ranges, zone);
+      break;
+    case 'd':
+      AddClass(kDigitRanges, kDigitRangeCount, ranges, zone);
+      break;
+    case 'D':
+      AddClassNegated(kDigitRanges, kDigitRangeCount, ranges, zone);
+      break;
+    case '.':
+      AddClassNegated(kLineTerminatorRanges,
+                      kLineTerminatorRangeCount,
+                      ranges,
+                      zone);
+      break;
+    // This is not a character range as defined by the spec but a
+    // convenient shorthand for a character class that matches any
+    // character.
+    case '*':
+      ranges->Add(CharacterRange::Everything(), zone);
+      break;
+    // This is the set of characters matched by the $ and ^ symbols
+    // in multiline mode.
+    case 'n':
+      AddClass(kLineTerminatorRanges,
+               kLineTerminatorRangeCount,
+               ranges,
+               zone);
+      break;
+    default:
+      UNREACHABLE();
+  }
+}
+
+
+Vector<const int> CharacterRange::GetWordBounds() {
+  return Vector<const int>(kWordRanges, kWordRangeCount - 1);
+}
+
+
+class CharacterRangeSplitter {
+ public:
+  CharacterRangeSplitter(ZoneList<CharacterRange>** included,
+                         ZoneList<CharacterRange>** excluded,
+                         Zone* zone)
+      : included_(included),
+        excluded_(excluded),
+        zone_(zone) { }
+  void Call(uc16 from, DispatchTable::Entry entry);
+
+  static const int kInBase = 0;
+  static const int kInOverlay = 1;
+
+ private:
+  ZoneList<CharacterRange>** included_;
+  ZoneList<CharacterRange>** excluded_;
+  Zone* zone_;
+};
+
+
+void CharacterRangeSplitter::Call(uc16 from, DispatchTable::Entry entry) {
+  if (!entry.out_set()->Get(kInBase)) return;
+  ZoneList<CharacterRange>** target = entry.out_set()->Get(kInOverlay)
+    ? included_
+    : excluded_;
+  if (*target == NULL) *target = new(zone_) ZoneList<CharacterRange>(2, zone_);
+  (*target)->Add(CharacterRange(entry.from(), entry.to()), zone_);
+}
+
+
+void CharacterRange::Split(ZoneList<CharacterRange>* base,
+                           Vector<const int> overlay,
+                           ZoneList<CharacterRange>** included,
+                           ZoneList<CharacterRange>** excluded,
+                           Zone* zone) {
+  DCHECK_EQ(NULL, *included);
+  DCHECK_EQ(NULL, *excluded);
+  DispatchTable table(zone);
+  for (int i = 0; i < base->length(); i++)
+    table.AddRange(base->at(i), CharacterRangeSplitter::kInBase, zone);
+  for (int i = 0; i < overlay.length(); i += 2) {
+    table.AddRange(CharacterRange(overlay[i], overlay[i + 1] - 1),
+                   CharacterRangeSplitter::kInOverlay, zone);
+  }
+  CharacterRangeSplitter callback(included, excluded, zone);
+  table.ForEach(&callback);
+}
+
+
+void CharacterRange::AddCaseEquivalents(ZoneList<CharacterRange>* ranges,
+                                        bool is_one_byte, Zone* zone) {
+  Isolate* isolate = zone->isolate();
+  uc16 bottom = from();
+  uc16 top = to();
+  if (is_one_byte && !RangeContainsLatin1Equivalents(*this)) {
+    if (bottom > String::kMaxOneByteCharCode) return;
+    if (top > String::kMaxOneByteCharCode) top = String::kMaxOneByteCharCode;
+  }
+  unibrow::uchar chars[unibrow::Ecma262UnCanonicalize::kMaxWidth];
+  if (top == bottom) {
+    // If this is a singleton we just expand the one character.
+    int length = isolate->jsregexp_uncanonicalize()->get(bottom, '\0', chars);
+    for (int i = 0; i < length; i++) {
+      uc32 chr = chars[i];
+      if (chr != bottom) {
+        ranges->Add(CharacterRange::Singleton(chars[i]), zone);
+      }
+    }
+  } else {
+    // If this is a range we expand the characters block by block,
+    // expanding contiguous subranges (blocks) one at a time.
+    // The approach is as follows.  For a given start character we
+    // look up the remainder of the block that contains it (represented
+    // by the end point), for instance we find 'z' if the character
+    // is 'c'.  A block is characterized by the property
+    // that all characters uncanonicalize in the same way, except that
+    // each entry in the result is incremented by the distance from the first
+    // element.  So a-z is a block because 'a' uncanonicalizes to ['a', 'A'] and
+    // the k'th letter uncanonicalizes to ['a' + k, 'A' + k].
+    // Once we've found the end point we look up its uncanonicalization
+    // and produce a range for each element.  For instance for [c-f]
+    // we look up ['z', 'Z'] and produce [c-f] and [C-F].  We then only
+    // add a range if it is not already contained in the input, so [c-f]
+    // will be skipped but [C-F] will be added.  If this range is not
+    // completely contained in a block we do this for all the blocks
+    // covered by the range (handling characters that is not in a block
+    // as a "singleton block").
+    unibrow::uchar range[unibrow::Ecma262UnCanonicalize::kMaxWidth];
+    int pos = bottom;
+    while (pos <= top) {
+      int length = isolate->jsregexp_canonrange()->get(pos, '\0', range);
+      uc16 block_end;
+      if (length == 0) {
+        block_end = pos;
+      } else {
+        DCHECK_EQ(1, length);
+        block_end = range[0];
+      }
+      int end = (block_end > top) ? top : block_end;
+      length = isolate->jsregexp_uncanonicalize()->get(block_end, '\0', range);
+      for (int i = 0; i < length; i++) {
+        uc32 c = range[i];
+        uc16 range_from = c - (block_end - pos);
+        uc16 range_to = c - (block_end - end);
+        if (!(bottom <= range_from && range_to <= top)) {
+          ranges->Add(CharacterRange(range_from, range_to), zone);
+        }
+      }
+      pos = end + 1;
+    }
+  }
+}
+
+
+bool CharacterRange::IsCanonical(ZoneList<CharacterRange>* ranges) {
+  DCHECK_NOT_NULL(ranges);
+  int n = ranges->length();
+  if (n <= 1) return true;
+  int max = ranges->at(0).to();
+  for (int i = 1; i < n; i++) {
+    CharacterRange next_range = ranges->at(i);
+    if (next_range.from() <= max + 1) return false;
+    max = next_range.to();
+  }
+  return true;
+}
+
+
+ZoneList<CharacterRange>* CharacterSet::ranges(Zone* zone) {
+  if (ranges_ == NULL) {
+    ranges_ = new(zone) ZoneList<CharacterRange>(2, zone);
+    CharacterRange::AddClassEscape(standard_set_type_, ranges_, zone);
+  }
+  return ranges_;
+}
+
+
+// Move a number of elements in a zonelist to another position
+// in the same list. Handles overlapping source and target areas.
+static void MoveRanges(ZoneList<CharacterRange>* list,
+                       int from,
+                       int to,
+                       int count) {
+  // Ranges are potentially overlapping.
+  if (from < to) {
+    for (int i = count - 1; i >= 0; i--) {
+      list->at(to + i) = list->at(from + i);
+    }
+  } else {
+    for (int i = 0; i < count; i++) {
+      list->at(to + i) = list->at(from + i);
+    }
+  }
+}
+
+
+static int InsertRangeInCanonicalList(ZoneList<CharacterRange>* list,
+                                      int count,
+                                      CharacterRange insert) {
+  // Inserts a range into list[0..count[, which must be sorted
+  // by from value and non-overlapping and non-adjacent, using at most
+  // list[0..count] for the result. Returns the number of resulting
+  // canonicalized ranges. Inserting a range may collapse existing ranges into
+  // fewer ranges, so the return value can be anything in the range 1..count+1.
+  uc16 from = insert.from();
+  uc16 to = insert.to();
+  int start_pos = 0;
+  int end_pos = count;
+  for (int i = count - 1; i >= 0; i--) {
+    CharacterRange current = list->at(i);
+    if (current.from() > to + 1) {
+      end_pos = i;
+    } else if (current.to() + 1 < from) {
+      start_pos = i + 1;
+      break;
+    }
+  }
+
+  // Inserted range overlaps, or is adjacent to, ranges at positions
+  // [start_pos..end_pos[. Ranges before start_pos or at or after end_pos are
+  // not affected by the insertion.
+  // If start_pos == end_pos, the range must be inserted before start_pos.
+  // if start_pos < end_pos, the entire range from start_pos to end_pos
+  // must be merged with the insert range.
+
+  if (start_pos == end_pos) {
+    // Insert between existing ranges at position start_pos.
+    if (start_pos < count) {
+      MoveRanges(list, start_pos, start_pos + 1, count - start_pos);
+    }
+    list->at(start_pos) = insert;
+    return count + 1;
+  }
+  if (start_pos + 1 == end_pos) {
+    // Replace single existing range at position start_pos.
+    CharacterRange to_replace = list->at(start_pos);
+    int new_from = Min(to_replace.from(), from);
+    int new_to = Max(to_replace.to(), to);
+    list->at(start_pos) = CharacterRange(new_from, new_to);
+    return count;
+  }
+  // Replace a number of existing ranges from start_pos to end_pos - 1.
+  // Move the remaining ranges down.
+
+  int new_from = Min(list->at(start_pos).from(), from);
+  int new_to = Max(list->at(end_pos - 1).to(), to);
+  if (end_pos < count) {
+    MoveRanges(list, end_pos, start_pos + 1, count - end_pos);
+  }
+  list->at(start_pos) = CharacterRange(new_from, new_to);
+  return count - (end_pos - start_pos) + 1;
+}
+
+
+void CharacterSet::Canonicalize() {
+  // Special/default classes are always considered canonical. The result
+  // of calling ranges() will be sorted.
+  if (ranges_ == NULL) return;
+  CharacterRange::Canonicalize(ranges_);
+}
+
+
+void CharacterRange::Canonicalize(ZoneList<CharacterRange>* character_ranges) {
+  if (character_ranges->length() <= 1) return;
+  // Check whether ranges are already canonical (increasing, non-overlapping,
+  // non-adjacent).
+  int n = character_ranges->length();
+  int max = character_ranges->at(0).to();
+  int i = 1;
+  while (i < n) {
+    CharacterRange current = character_ranges->at(i);
+    if (current.from() <= max + 1) {
+      break;
+    }
+    max = current.to();
+    i++;
+  }
+  // Canonical until the i'th range. If that's all of them, we are done.
+  if (i == n) return;
+
+  // The ranges at index i and forward are not canonicalized. Make them so by
+  // doing the equivalent of insertion sort (inserting each into the previous
+  // list, in order).
+  // Notice that inserting a range can reduce the number of ranges in the
+  // result due to combining of adjacent and overlapping ranges.
+  int read = i;  // Range to insert.
+  int num_canonical = i;  // Length of canonicalized part of list.
+  do {
+    num_canonical = InsertRangeInCanonicalList(character_ranges,
+                                               num_canonical,
+                                               character_ranges->at(read));
+    read++;
+  } while (read < n);
+  character_ranges->Rewind(num_canonical);
+
+  DCHECK(CharacterRange::IsCanonical(character_ranges));
+}
+
+
+void CharacterRange::Negate(ZoneList<CharacterRange>* ranges,
+                            ZoneList<CharacterRange>* negated_ranges,
+                            Zone* zone) {
+  DCHECK(CharacterRange::IsCanonical(ranges));
+  DCHECK_EQ(0, negated_ranges->length());
+  int range_count = ranges->length();
+  uc16 from = 0;
+  int i = 0;
+  if (range_count > 0 && ranges->at(0).from() == 0) {
+    from = ranges->at(0).to();
+    i = 1;
+  }
+  while (i < range_count) {
+    CharacterRange range = ranges->at(i);
+    negated_ranges->Add(CharacterRange(from + 1, range.from() - 1), zone);
+    from = range.to();
+    i++;
+  }
+  if (from < String::kMaxUtf16CodeUnit) {
+    negated_ranges->Add(CharacterRange(from + 1, String::kMaxUtf16CodeUnit),
+                        zone);
+  }
+}
+
+
+// -------------------------------------------------------------------
+// Splay tree
+
+
+OutSet* OutSet::Extend(unsigned value, Zone* zone) {
+  if (Get(value))
+    return this;
+  if (successors(zone) != NULL) {
+    for (int i = 0; i < successors(zone)->length(); i++) {
+      OutSet* successor = successors(zone)->at(i);
+      if (successor->Get(value))
+        return successor;
+    }
+  } else {
+    successors_ = new(zone) ZoneList<OutSet*>(2, zone);
+  }
+  OutSet* result = new(zone) OutSet(first_, remaining_);
+  result->Set(value, zone);
+  successors(zone)->Add(result, zone);
+  return result;
+}
+
+
+void OutSet::Set(unsigned value, Zone *zone) {
+  if (value < kFirstLimit) {
+    first_ |= (1 << value);
+  } else {
+    if (remaining_ == NULL)
+      remaining_ = new(zone) ZoneList<unsigned>(1, zone);
+    if (remaining_->is_empty() || !remaining_->Contains(value))
+      remaining_->Add(value, zone);
+  }
+}
+
+
+bool OutSet::Get(unsigned value) const {
+  if (value < kFirstLimit) {
+    return (first_ & (1 << value)) != 0;
+  } else if (remaining_ == NULL) {
+    return false;
+  } else {
+    return remaining_->Contains(value);
+  }
+}
+
+
+const uc16 DispatchTable::Config::kNoKey = unibrow::Utf8::kBadChar;
+
+
+void DispatchTable::AddRange(CharacterRange full_range, int value,
+                             Zone* zone) {
+  CharacterRange current = full_range;
+  if (tree()->is_empty()) {
+    // If this is the first range we just insert into the table.
+    ZoneSplayTree<Config>::Locator loc;
+    DCHECK_RESULT(tree()->Insert(current.from(), &loc));
+    loc.set_value(Entry(current.from(), current.to(),
+                        empty()->Extend(value, zone)));
+    return;
+  }
+  // First see if there is a range to the left of this one that
+  // overlaps.
+  ZoneSplayTree<Config>::Locator loc;
+  if (tree()->FindGreatestLessThan(current.from(), &loc)) {
+    Entry* entry = &loc.value();
+    // If we've found a range that overlaps with this one, and it
+    // starts strictly to the left of this one, we have to fix it
+    // because the following code only handles ranges that start on
+    // or after the start point of the range we're adding.
+    if (entry->from() < current.from() && entry->to() >= current.from()) {
+      // Snap the overlapping range in half around the start point of
+      // the range we're adding.
+      CharacterRange left(entry->from(), current.from() - 1);
+      CharacterRange right(current.from(), entry->to());
+      // The left part of the overlapping range doesn't overlap.
+      // Truncate the whole entry to be just the left part.
+      entry->set_to(left.to());
+      // The right part is the one that overlaps.  We add this part
+      // to the map and let the next step deal with merging it with
+      // the range we're adding.
+      ZoneSplayTree<Config>::Locator loc;
+      DCHECK_RESULT(tree()->Insert(right.from(), &loc));
+      loc.set_value(Entry(right.from(),
+                          right.to(),
+                          entry->out_set()));
+    }
+  }
+  while (current.is_valid()) {
+    if (tree()->FindLeastGreaterThan(current.from(), &loc) &&
+        (loc.value().from() <= current.to()) &&
+        (loc.value().to() >= current.from())) {
+      Entry* entry = &loc.value();
+      // We have overlap.  If there is space between the start point of
+      // the range we're adding and where the overlapping range starts
+      // then we have to add a range covering just that space.
+      if (current.from() < entry->from()) {
+        ZoneSplayTree<Config>::Locator ins;
+        DCHECK_RESULT(tree()->Insert(current.from(), &ins));
+        ins.set_value(Entry(current.from(),
+                            entry->from() - 1,
+                            empty()->Extend(value, zone)));
+        current.set_from(entry->from());
+      }
+      DCHECK_EQ(current.from(), entry->from());
+      // If the overlapping range extends beyond the one we want to add
+      // we have to snap the right part off and add it separately.
+      if (entry->to() > current.to()) {
+        ZoneSplayTree<Config>::Locator ins;
+        DCHECK_RESULT(tree()->Insert(current.to() + 1, &ins));
+        ins.set_value(Entry(current.to() + 1,
+                            entry->to(),
+                            entry->out_set()));
+        entry->set_to(current.to());
+      }
+      DCHECK(entry->to() <= current.to());
+      // The overlapping range is now completely contained by the range
+      // we're adding so we can just update it and move the start point
+      // of the range we're adding just past it.
+      entry->AddValue(value, zone);
+      // Bail out if the last interval ended at 0xFFFF since otherwise
+      // adding 1 will wrap around to 0.
+      if (entry->to() == String::kMaxUtf16CodeUnit)
+        break;
+      DCHECK(entry->to() + 1 > current.from());
+      current.set_from(entry->to() + 1);
+    } else {
+      // There is no overlap so we can just add the range
+      ZoneSplayTree<Config>::Locator ins;
+      DCHECK_RESULT(tree()->Insert(current.from(), &ins));
+      ins.set_value(Entry(current.from(),
+                          current.to(),
+                          empty()->Extend(value, zone)));
+      break;
+    }
+  }
+}
+
+
+OutSet* DispatchTable::Get(uc16 value) {
+  ZoneSplayTree<Config>::Locator loc;
+  if (!tree()->FindGreatestLessThan(value, &loc))
+    return empty();
+  Entry* entry = &loc.value();
+  if (value <= entry->to())
+    return entry->out_set();
+  else
+    return empty();
+}
+
+
+// -------------------------------------------------------------------
+// Analysis
+
+
+void Analysis::EnsureAnalyzed(RegExpNode* that) {
+  StackLimitCheck check(that->zone()->isolate());
+  if (check.HasOverflowed()) {
+    fail("Stack overflow");
+    return;
+  }
+  if (that->info()->been_analyzed || that->info()->being_analyzed)
+    return;
+  that->info()->being_analyzed = true;
+  that->Accept(this);
+  that->info()->being_analyzed = false;
+  that->info()->been_analyzed = true;
+}
+
+
+void Analysis::VisitEnd(EndNode* that) {
+  // nothing to do
+}
+
+
+void TextNode::CalculateOffsets() {
+  int element_count = elements()->length();
+  // Set up the offsets of the elements relative to the start.  This is a fixed
+  // quantity since a TextNode can only contain fixed-width things.
+  int cp_offset = 0;
+  for (int i = 0; i < element_count; i++) {
+    TextElement& elm = elements()->at(i);
+    elm.set_cp_offset(cp_offset);
+    cp_offset += elm.length();
+  }
+}
+
+
+void Analysis::VisitText(TextNode* that) {
+  if (ignore_case_) {
+    that->MakeCaseIndependent(is_one_byte_);
+  }
+  EnsureAnalyzed(that->on_success());
+  if (!has_failed()) {
+    that->CalculateOffsets();
+  }
+}
+
+
+void Analysis::VisitAction(ActionNode* that) {
+  RegExpNode* target = that->on_success();
+  EnsureAnalyzed(target);
+  if (!has_failed()) {
+    // If the next node is interested in what it follows then this node
+    // has to be interested too so it can pass the information on.
+    that->info()->AddFromFollowing(target->info());
+  }
+}
+
+
+void Analysis::VisitChoice(ChoiceNode* that) {
+  NodeInfo* info = that->info();
+  for (int i = 0; i < that->alternatives()->length(); i++) {
+    RegExpNode* node = that->alternatives()->at(i).node();
+    EnsureAnalyzed(node);
+    if (has_failed()) return;
+    // Anything the following nodes need to know has to be known by
+    // this node also, so it can pass it on.
+    info->AddFromFollowing(node->info());
+  }
+}
+
+
+void Analysis::VisitLoopChoice(LoopChoiceNode* that) {
+  NodeInfo* info = that->info();
+  for (int i = 0; i < that->alternatives()->length(); i++) {
+    RegExpNode* node = that->alternatives()->at(i).node();
+    if (node != that->loop_node()) {
+      EnsureAnalyzed(node);
+      if (has_failed()) return;
+      info->AddFromFollowing(node->info());
+    }
+  }
+  // Check the loop last since it may need the value of this node
+  // to get a correct result.
+  EnsureAnalyzed(that->loop_node());
+  if (!has_failed()) {
+    info->AddFromFollowing(that->loop_node()->info());
+  }
+}
+
+
+void Analysis::VisitBackReference(BackReferenceNode* that) {
+  EnsureAnalyzed(that->on_success());
+}
+
+
+void Analysis::VisitAssertion(AssertionNode* that) {
+  EnsureAnalyzed(that->on_success());
+}
+
+
+void BackReferenceNode::FillInBMInfo(int offset,
+                                     int budget,
+                                     BoyerMooreLookahead* bm,
+                                     bool not_at_start) {
+  // Working out the set of characters that a backreference can match is too
+  // hard, so we just say that any character can match.
+  bm->SetRest(offset);
+  SaveBMInfo(bm, not_at_start, offset);
+}
+
+
+STATIC_ASSERT(BoyerMoorePositionInfo::kMapSize ==
+              RegExpMacroAssembler::kTableSize);
+
+
+void ChoiceNode::FillInBMInfo(int offset,
+                              int budget,
+                              BoyerMooreLookahead* bm,
+                              bool not_at_start) {
+  ZoneList<GuardedAlternative>* alts = alternatives();
+  budget = (budget - 1) / alts->length();
+  for (int i = 0; i < alts->length(); i++) {
+    GuardedAlternative& alt = alts->at(i);
+    if (alt.guards() != NULL && alt.guards()->length() != 0) {
+      bm->SetRest(offset);  // Give up trying to fill in info.
+      SaveBMInfo(bm, not_at_start, offset);
+      return;
+    }
+    alt.node()->FillInBMInfo(offset, budget, bm, not_at_start);
+  }
+  SaveBMInfo(bm, not_at_start, offset);
+}
+
+
+void TextNode::FillInBMInfo(int initial_offset,
+                            int budget,
+                            BoyerMooreLookahead* bm,
+                            bool not_at_start) {
+  if (initial_offset >= bm->length()) return;
+  int offset = initial_offset;
+  int max_char = bm->max_char();
+  for (int i = 0; i < elements()->length(); i++) {
+    if (offset >= bm->length()) {
+      if (initial_offset == 0) set_bm_info(not_at_start, bm);
+      return;
+    }
+    TextElement text = elements()->at(i);
+    if (text.text_type() == TextElement::ATOM) {
+      RegExpAtom* atom = text.atom();
+      for (int j = 0; j < atom->length(); j++, offset++) {
+        if (offset >= bm->length()) {
+          if (initial_offset == 0) set_bm_info(not_at_start, bm);
+          return;
+        }
+        uc16 character = atom->data()[j];
+        if (bm->compiler()->ignore_case()) {
+          unibrow::uchar chars[unibrow::Ecma262UnCanonicalize::kMaxWidth];
+          int length = GetCaseIndependentLetters(
+              Isolate::Current(),
+              character,
+              bm->max_char() == String::kMaxOneByteCharCode,
+              chars);
+          for (int j = 0; j < length; j++) {
+            bm->Set(offset, chars[j]);
+          }
+        } else {
+          if (character <= max_char) bm->Set(offset, character);
+        }
+      }
+    } else {
+      DCHECK_EQ(TextElement::CHAR_CLASS, text.text_type());
+      RegExpCharacterClass* char_class = text.char_class();
+      ZoneList<CharacterRange>* ranges = char_class->ranges(zone());
+      if (char_class->is_negated()) {
+        bm->SetAll(offset);
+      } else {
+        for (int k = 0; k < ranges->length(); k++) {
+          CharacterRange& range = ranges->at(k);
+          if (range.from() > max_char) continue;
+          int to = Min(max_char, static_cast<int>(range.to()));
+          bm->SetInterval(offset, Interval(range.from(), to));
+        }
+      }
+      offset++;
+    }
+  }
+  if (offset >= bm->length()) {
+    if (initial_offset == 0) set_bm_info(not_at_start, bm);
+    return;
+  }
+  on_success()->FillInBMInfo(offset,
+                             budget - 1,
+                             bm,
+                             true);  // Not at start after a text node.
+  if (initial_offset == 0) set_bm_info(not_at_start, bm);
+}
+
+
+// -------------------------------------------------------------------
+// Dispatch table construction
+
+
+void DispatchTableConstructor::VisitEnd(EndNode* that) {
+  AddRange(CharacterRange::Everything());
+}
+
+
+void DispatchTableConstructor::BuildTable(ChoiceNode* node) {
+  node->set_being_calculated(true);
+  ZoneList<GuardedAlternative>* alternatives = node->alternatives();
+  for (int i = 0; i < alternatives->length(); i++) {
+    set_choice_index(i);
+    alternatives->at(i).node()->Accept(this);
+  }
+  node->set_being_calculated(false);
+}
+
+
+class AddDispatchRange {
+ public:
+  explicit AddDispatchRange(DispatchTableConstructor* constructor)
+    : constructor_(constructor) { }
+  void Call(uc32 from, DispatchTable::Entry entry);
+ private:
+  DispatchTableConstructor* constructor_;
+};
+
+
+void AddDispatchRange::Call(uc32 from, DispatchTable::Entry entry) {
+  CharacterRange range(from, entry.to());
+  constructor_->AddRange(range);
+}
+
+
+void DispatchTableConstructor::VisitChoice(ChoiceNode* node) {
+  if (node->being_calculated())
+    return;
+  DispatchTable* table = node->GetTable(ignore_case_);
+  AddDispatchRange adder(this);
+  table->ForEach(&adder);
+}
+
+
+void DispatchTableConstructor::VisitBackReference(BackReferenceNode* that) {
+  // TODO(160): Find the node that we refer back to and propagate its start
+  // set back to here.  For now we just accept anything.
+  AddRange(CharacterRange::Everything());
+}
+
+
+void DispatchTableConstructor::VisitAssertion(AssertionNode* that) {
+  RegExpNode* target = that->on_success();
+  target->Accept(this);
+}
+
+
+static int CompareRangeByFrom(const CharacterRange* a,
+                              const CharacterRange* b) {
+  return Compare<uc16>(a->from(), b->from());
+}
+
+
+void DispatchTableConstructor::AddInverse(ZoneList<CharacterRange>* ranges) {
+  ranges->Sort(CompareRangeByFrom);
+  uc16 last = 0;
+  for (int i = 0; i < ranges->length(); i++) {
+    CharacterRange range = ranges->at(i);
+    if (last < range.from())
+      AddRange(CharacterRange(last, range.from() - 1));
+    if (range.to() >= last) {
+      if (range.to() == String::kMaxUtf16CodeUnit) {
+        return;
+      } else {
+        last = range.to() + 1;
+      }
+    }
+  }
+  AddRange(CharacterRange(last, String::kMaxUtf16CodeUnit));
+}
+
+
+void DispatchTableConstructor::VisitText(TextNode* that) {
+  TextElement elm = that->elements()->at(0);
+  switch (elm.text_type()) {
+    case TextElement::ATOM: {
+      uc16 c = elm.atom()->data()[0];
+      AddRange(CharacterRange(c, c));
+      break;
+    }
+    case TextElement::CHAR_CLASS: {
+      RegExpCharacterClass* tree = elm.char_class();
+      ZoneList<CharacterRange>* ranges = tree->ranges(that->zone());
+      if (tree->is_negated()) {
+        AddInverse(ranges);
+      } else {
+        for (int i = 0; i < ranges->length(); i++)
+          AddRange(ranges->at(i));
+      }
+      break;
+    }
+    default: {
+      UNIMPLEMENTED();
+    }
+  }
+}
+
+
+void DispatchTableConstructor::VisitAction(ActionNode* that) {
+  RegExpNode* target = that->on_success();
+  target->Accept(this);
+}
+
+
+RegExpEngine::CompilationResult RegExpEngine::Compile(
+    RegExpCompileData* data, bool ignore_case, bool is_global,
+    bool is_multiline, bool is_sticky, Handle<String> pattern,
+    Handle<String> sample_subject, bool is_one_byte, Zone* zone) {
+  if ((data->capture_count + 1) * 2 - 1 > RegExpMacroAssembler::kMaxRegister) {
+    return IrregexpRegExpTooBig(zone->isolate());
+  }
+  RegExpCompiler compiler(data->capture_count, ignore_case, is_one_byte, zone);
+
+  // Sample some characters from the middle of the string.
+  static const int kSampleSize = 128;
+
+  sample_subject = String::Flatten(sample_subject);
+  int chars_sampled = 0;
+  int half_way = (sample_subject->length() - kSampleSize) / 2;
+  for (int i = Max(0, half_way);
+       i < sample_subject->length() && chars_sampled < kSampleSize;
+       i++, chars_sampled++) {
+    compiler.frequency_collator()->CountCharacter(sample_subject->Get(i));
+  }
+
+  // Wrap the body of the regexp in capture #0.
+  RegExpNode* captured_body = RegExpCapture::ToNode(data->tree,
+                                                    0,
+                                                    &compiler,
+                                                    compiler.accept());
+  RegExpNode* node = captured_body;
+  bool is_end_anchored = data->tree->IsAnchoredAtEnd();
+  bool is_start_anchored = data->tree->IsAnchoredAtStart();
+  int max_length = data->tree->max_match();
+  if (!is_start_anchored && !is_sticky) {
+    // Add a .*? at the beginning, outside the body capture, unless
+    // this expression is anchored at the beginning or sticky.
+    RegExpNode* loop_node =
+        RegExpQuantifier::ToNode(0,
+                                 RegExpTree::kInfinity,
+                                 false,
+                                 new(zone) RegExpCharacterClass('*'),
+                                 &compiler,
+                                 captured_body,
+                                 data->contains_anchor);
+
+    if (data->contains_anchor) {
+      // Unroll loop once, to take care of the case that might start
+      // at the start of input.
+      ChoiceNode* first_step_node = new(zone) ChoiceNode(2, zone);
+      first_step_node->AddAlternative(GuardedAlternative(captured_body));
+      first_step_node->AddAlternative(GuardedAlternative(
+          new(zone) TextNode(new(zone) RegExpCharacterClass('*'), loop_node)));
+      node = first_step_node;
+    } else {
+      node = loop_node;
+    }
+  }
+  if (is_one_byte) {
+    node = node->FilterOneByte(RegExpCompiler::kMaxRecursion, ignore_case);
+    // Do it again to propagate the new nodes to places where they were not
+    // put because they had not been calculated yet.
+    if (node != NULL) {
+      node = node->FilterOneByte(RegExpCompiler::kMaxRecursion, ignore_case);
+    }
+  }
+
+  if (node == NULL) node = new(zone) EndNode(EndNode::BACKTRACK, zone);
+  data->node = node;
+  Analysis analysis(ignore_case, is_one_byte);
+  analysis.EnsureAnalyzed(node);
+  if (analysis.has_failed()) {
+    const char* error_message = analysis.error_message();
+    return CompilationResult(zone->isolate(), error_message);
+  }
+
+  // Create the correct assembler for the architecture.
+#ifndef V8_INTERPRETED_REGEXP
+  // Native regexp implementation.
+
+  NativeRegExpMacroAssembler::Mode mode =
+      is_one_byte ? NativeRegExpMacroAssembler::LATIN1
+                  : NativeRegExpMacroAssembler::UC16;
+
+#if V8_TARGET_ARCH_IA32
+  RegExpMacroAssemblerIA32 macro_assembler(mode, (data->capture_count + 1) * 2,
+                                           zone);
+#elif V8_TARGET_ARCH_X64
+  RegExpMacroAssemblerX64 macro_assembler(mode, (data->capture_count + 1) * 2,
+                                          zone);
+#elif V8_TARGET_ARCH_ARM
+  RegExpMacroAssemblerARM macro_assembler(mode, (data->capture_count + 1) * 2,
+                                          zone);
+#elif V8_TARGET_ARCH_ARM64
+  RegExpMacroAssemblerARM64 macro_assembler(mode, (data->capture_count + 1) * 2,
+                                            zone);
+#elif V8_TARGET_ARCH_MIPS
+  RegExpMacroAssemblerMIPS macro_assembler(mode, (data->capture_count + 1) * 2,
+                                           zone);
+#elif V8_TARGET_ARCH_MIPS64
+  RegExpMacroAssemblerMIPS macro_assembler(mode, (data->capture_count + 1) * 2,
+                                           zone);
+#elif V8_TARGET_ARCH_X87
+  RegExpMacroAssemblerX87 macro_assembler(mode, (data->capture_count + 1) * 2,
+                                          zone);
+#else
+#error "Unsupported architecture"
+#endif
+
+#else  // V8_INTERPRETED_REGEXP
+  // Interpreted regexp implementation.
+  EmbeddedVector<byte, 1024> codes;
+  RegExpMacroAssemblerIrregexp macro_assembler(codes, zone);
+#endif  // V8_INTERPRETED_REGEXP
+
+  // Inserted here, instead of in Assembler, because it depends on information
+  // in the AST that isn't replicated in the Node structure.
+  static const int kMaxBacksearchLimit = 1024;
+  if (is_end_anchored &&
+      !is_start_anchored &&
+      max_length < kMaxBacksearchLimit) {
+    macro_assembler.SetCurrentPositionFromEnd(max_length);
+  }
+
+  if (is_global) {
+    macro_assembler.set_global_mode(
+        (data->tree->min_match() > 0)
+            ? RegExpMacroAssembler::GLOBAL_NO_ZERO_LENGTH_CHECK
+            : RegExpMacroAssembler::GLOBAL);
+  }
+
+  return compiler.Assemble(&macro_assembler,
+                           node,
+                           data->capture_count,
+                           pattern);
+}
+
+}  // namespace dart
diff --git a/runtime/vm/regexp.h b/runtime/vm/regexp.h
new file mode 100644
index 0000000..921ec20
--- /dev/null
+++ b/runtime/vm/regexp.h
@@ -0,0 +1,1466 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+#ifndef VM_REGEXP_H_
+#define VM_REGEXP_H_
+
+// SNIP
+
+namespace dart {
+
+class NodeVisitor;
+class RegExpCompiler;
+class RegExpMacroAssembler;
+class RegExpNode;
+class RegExpTree;
+class BoyerMooreLookahead;
+
+// Represents the location of one element relative to the intersection of
+// two sets. Corresponds to the four areas of a Venn diagram.
+enum ElementInSetsRelation {
+  kInsideNone = 0,
+  kInsideFirst = 1,
+  kInsideSecond = 2,
+  kInsideBoth = 3
+};
+
+
+// Represents code units in the range from from_ to to_, both ends are
+// inclusive.
+class CharacterRange {
+ public:
+  CharacterRange() : from_(0), to_(0) { }
+  // For compatibility with the CHECK_OK macro
+  CharacterRange(void* null) { DCHECK_EQ(NULL, null); }  //NOLINT
+  CharacterRange(uc16 from, uc16 to) : from_(from), to_(to) { }
+  static void AddClassEscape(uc16 type, ZoneList<CharacterRange>* ranges,
+                             Zone* zone);
+  static Vector<const int> GetWordBounds();
+  static inline CharacterRange Singleton(uc16 value) {
+    return CharacterRange(value, value);
+  }
+  static inline CharacterRange Range(uc16 from, uc16 to) {
+    DCHECK(from <= to);
+    return CharacterRange(from, to);
+  }
+  static inline CharacterRange Everything() {
+    return CharacterRange(0, 0xFFFF);
+  }
+  bool Contains(uc16 i) { return from_ <= i && i <= to_; }
+  uc16 from() const { return from_; }
+  void set_from(uc16 value) { from_ = value; }
+  uc16 to() const { return to_; }
+  void set_to(uc16 value) { to_ = value; }
+  bool is_valid() { return from_ <= to_; }
+  bool IsEverything(uc16 max) { return from_ == 0 && to_ >= max; }
+  bool IsSingleton() { return (from_ == to_); }
+  void AddCaseEquivalents(ZoneList<CharacterRange>* ranges, bool is_one_byte,
+                          Zone* zone);
+  static void Split(ZoneList<CharacterRange>* base,
+                    Vector<const int> overlay,
+                    ZoneList<CharacterRange>** included,
+                    ZoneList<CharacterRange>** excluded,
+                    Zone* zone);
+  // Whether a range list is in canonical form: Ranges ordered by from value,
+  // and ranges non-overlapping and non-adjacent.
+  static bool IsCanonical(ZoneList<CharacterRange>* ranges);
+  // Convert range list to canonical form. The characters covered by the ranges
+  // will still be the same, but no character is in more than one range, and
+  // adjacent ranges are merged. The resulting list may be shorter than the
+  // original, but cannot be longer.
+  static void Canonicalize(ZoneList<CharacterRange>* ranges);
+  // Negate the contents of a character range in canonical form.
+  static void Negate(ZoneList<CharacterRange>* src,
+                     ZoneList<CharacterRange>* dst,
+                     Zone* zone);
+  static const int kStartMarker = (1 << 24);
+  static const int kPayloadMask = (1 << 24) - 1;
+
+ private:
+  uc16 from_;
+  uc16 to_;
+};
+
+
+// A set of unsigned integers that behaves especially well on small
+// integers (< 32).  May do zone-allocation.
+class OutSet: public ZoneObject {
+ public:
+  OutSet() : first_(0), remaining_(NULL), successors_(NULL) { }
+  OutSet* Extend(unsigned value, Zone* zone);
+  bool Get(unsigned value) const;
+  static const unsigned kFirstLimit = 32;
+
+ private:
+  // Destructively set a value in this set.  In most cases you want
+  // to use Extend instead to ensure that only one instance exists
+  // that contains the same values.
+  void Set(unsigned value, Zone* zone);
+
+  // The successors are a list of sets that contain the same values
+  // as this set and the one more value that is not present in this
+  // set.
+  ZoneList<OutSet*>* successors(Zone* zone) { return successors_; }
+
+  OutSet(uint32_t first, ZoneList<unsigned>* remaining)
+      : first_(first), remaining_(remaining), successors_(NULL) { }
+  uint32_t first_;
+  ZoneList<unsigned>* remaining_;
+  ZoneList<OutSet*>* successors_;
+  friend class Trace;
+};
+
+
+// A mapping from integers, specified as ranges, to a set of integers.
+// Used for mapping character ranges to choices.
+class DispatchTable : public ZoneObject {
+ public:
+  explicit DispatchTable(Zone* zone) : tree_(zone) { }
+
+  class Entry {
+   public:
+    Entry() : from_(0), to_(0), out_set_(NULL) { }
+    Entry(uc16 from, uc16 to, OutSet* out_set)
+        : from_(from), to_(to), out_set_(out_set) { }
+    uc16 from() { return from_; }
+    uc16 to() { return to_; }
+    void set_to(uc16 value) { to_ = value; }
+    void AddValue(int value, Zone* zone) {
+      out_set_ = out_set_->Extend(value, zone);
+    }
+    OutSet* out_set() { return out_set_; }
+   private:
+    uc16 from_;
+    uc16 to_;
+    OutSet* out_set_;
+  };
+
+  class Config {
+   public:
+    typedef uc16 Key;
+    typedef Entry Value;
+    static const uc16 kNoKey;
+    static const Entry NoValue() { return Value(); }
+    static inline int Compare(uc16 a, uc16 b) {
+      if (a == b)
+        return 0;
+      else if (a < b)
+        return -1;
+      else
+        return 1;
+    }
+  };
+
+  void AddRange(CharacterRange range, int value, Zone* zone);
+  OutSet* Get(uc16 value);
+  void Dump();
+
+  template <typename Callback>
+  void ForEach(Callback* callback) {
+    return tree()->ForEach(callback);
+  }
+
+ private:
+  // There can't be a static empty set since it allocates its
+  // successors in a zone and caches them.
+  OutSet* empty() { return &empty_; }
+  OutSet empty_;
+  ZoneSplayTree<Config>* tree() { return &tree_; }
+  ZoneSplayTree<Config> tree_;
+};
+
+
+#define FOR_EACH_NODE_TYPE(VISIT)                                    \
+  VISIT(End)                                                         \
+  VISIT(Action)                                                      \
+  VISIT(Choice)                                                      \
+  VISIT(BackReference)                                               \
+  VISIT(Assertion)                                                   \
+  VISIT(Text)
+
+
+#define FOR_EACH_REG_EXP_TREE_TYPE(VISIT)                            \
+  VISIT(Disjunction)                                                 \
+  VISIT(Alternative)                                                 \
+  VISIT(Assertion)                                                   \
+  VISIT(CharacterClass)                                              \
+  VISIT(Atom)                                                        \
+  VISIT(Quantifier)                                                  \
+  VISIT(Capture)                                                     \
+  VISIT(Lookahead)                                                   \
+  VISIT(BackReference)                                               \
+  VISIT(Empty)                                                       \
+  VISIT(Text)
+
+
+#define FORWARD_DECLARE(Name) class RegExp##Name;
+FOR_EACH_REG_EXP_TREE_TYPE(FORWARD_DECLARE)
+#undef FORWARD_DECLARE
+
+
+class TextElement FINAL BASE_EMBEDDED {
+ public:
+  enum TextType {
+    ATOM,
+    CHAR_CLASS
+  };
+
+  static TextElement Atom(RegExpAtom* atom);
+  static TextElement CharClass(RegExpCharacterClass* char_class);
+
+  int cp_offset() const { return cp_offset_; }
+  void set_cp_offset(int cp_offset) { cp_offset_ = cp_offset; }
+  int length() const;
+
+  TextType text_type() const { return text_type_; }
+
+  RegExpTree* tree() const { return tree_; }
+
+  RegExpAtom* atom() const {
+    DCHECK(text_type() == ATOM);
+    return reinterpret_cast<RegExpAtom*>(tree());
+  }
+
+  RegExpCharacterClass* char_class() const {
+    DCHECK(text_type() == CHAR_CLASS);
+    return reinterpret_cast<RegExpCharacterClass*>(tree());
+  }
+
+ private:
+  TextElement(TextType text_type, RegExpTree* tree)
+      : cp_offset_(-1), text_type_(text_type), tree_(tree) {}
+
+  int cp_offset_;
+  TextType text_type_;
+  RegExpTree* tree_;
+};
+
+
+class Trace;
+struct PreloadState;
+class GreedyLoopState;
+class AlternativeGenerationList;
+
+struct NodeInfo {
+  NodeInfo()
+      : being_analyzed(false),
+        been_analyzed(false),
+        follows_word_interest(false),
+        follows_newline_interest(false),
+        follows_start_interest(false),
+        at_end(false),
+        visited(false),
+        replacement_calculated(false) { }
+
+  // Returns true if the interests and assumptions of this node
+  // matches the given one.
+  bool Matches(NodeInfo* that) {
+    return (at_end == that->at_end) &&
+           (follows_word_interest == that->follows_word_interest) &&
+           (follows_newline_interest == that->follows_newline_interest) &&
+           (follows_start_interest == that->follows_start_interest);
+  }
+
+  // Updates the interests of this node given the interests of the
+  // node preceding it.
+  void AddFromPreceding(NodeInfo* that) {
+    at_end |= that->at_end;
+    follows_word_interest |= that->follows_word_interest;
+    follows_newline_interest |= that->follows_newline_interest;
+    follows_start_interest |= that->follows_start_interest;
+  }
+
+  bool HasLookbehind() {
+    return follows_word_interest ||
+           follows_newline_interest ||
+           follows_start_interest;
+  }
+
+  // Sets the interests of this node to include the interests of the
+  // following node.
+  void AddFromFollowing(NodeInfo* that) {
+    follows_word_interest |= that->follows_word_interest;
+    follows_newline_interest |= that->follows_newline_interest;
+    follows_start_interest |= that->follows_start_interest;
+  }
+
+  void ResetCompilationState() {
+    being_analyzed = false;
+    been_analyzed = false;
+  }
+
+  bool being_analyzed: 1;
+  bool been_analyzed: 1;
+
+  // These bits are set of this node has to know what the preceding
+  // character was.
+  bool follows_word_interest: 1;
+  bool follows_newline_interest: 1;
+  bool follows_start_interest: 1;
+
+  bool at_end: 1;
+  bool visited: 1;
+  bool replacement_calculated: 1;
+};
+
+
+// Details of a quick mask-compare check that can look ahead in the
+// input stream.
+class QuickCheckDetails {
+ public:
+  QuickCheckDetails()
+      : characters_(0),
+        mask_(0),
+        value_(0),
+        cannot_match_(false) { }
+  explicit QuickCheckDetails(int characters)
+      : characters_(characters),
+        mask_(0),
+        value_(0),
+        cannot_match_(false) { }
+  bool Rationalize(bool one_byte);
+  // Merge in the information from another branch of an alternation.
+  void Merge(QuickCheckDetails* other, int from_index);
+  // Advance the current position by some amount.
+  void Advance(int by, bool one_byte);
+  void Clear();
+  bool cannot_match() { return cannot_match_; }
+  void set_cannot_match() { cannot_match_ = true; }
+  struct Position {
+    Position() : mask(0), value(0), determines_perfectly(false) { }
+    uc16 mask;
+    uc16 value;
+    bool determines_perfectly;
+  };
+  int characters() { return characters_; }
+  void set_characters(int characters) { characters_ = characters; }
+  Position* positions(int index) {
+    DCHECK(index >= 0);
+    DCHECK(index < characters_);
+    return positions_ + index;
+  }
+  uint32_t mask() { return mask_; }
+  uint32_t value() { return value_; }
+
+ private:
+  // How many characters do we have quick check information from.  This is
+  // the same for all branches of a choice node.
+  int characters_;
+  Position positions_[4];
+  // These values are the condensate of the above array after Rationalize().
+  uint32_t mask_;
+  uint32_t value_;
+  // If set to true, there is no way this quick check can match at all.
+  // E.g., if it requires to be at the start of the input, and isn't.
+  bool cannot_match_;
+};
+
+
+extern int kUninitializedRegExpNodePlaceHolder;
+
+
+class RegExpNode: public ZoneObject {
+ public:
+  explicit RegExpNode(Zone* zone)
+  : replacement_(NULL), trace_count_(0), zone_(zone) {
+    bm_info_[0] = bm_info_[1] = NULL;
+  }
+  virtual ~RegExpNode();
+  virtual void Accept(NodeVisitor* visitor) = 0;
+  // Generates a goto to this node or actually generates the code at this point.
+  virtual void Emit(RegExpCompiler* compiler, Trace* trace) = 0;
+  // How many characters must this node consume at a minimum in order to
+  // succeed.  If we have found at least 'still_to_find' characters that
+  // must be consumed there is no need to ask any following nodes whether
+  // they are sure to eat any more characters.  The not_at_start argument is
+  // used to indicate that we know we are not at the start of the input.  In
+  // this case anchored branches will always fail and can be ignored when
+  // determining how many characters are consumed on success.
+  virtual int EatsAtLeast(int still_to_find, int budget, bool not_at_start) = 0;
+  // Emits some quick code that checks whether the preloaded characters match.
+  // Falls through on certain failure, jumps to the label on possible success.
+  // If the node cannot make a quick check it does nothing and returns false.
+  bool EmitQuickCheck(RegExpCompiler* compiler,
+                      Trace* bounds_check_trace,
+                      Trace* trace,
+                      bool preload_has_checked_bounds,
+                      Label* on_possible_success,
+                      QuickCheckDetails* details_return,
+                      bool fall_through_on_failure);
+  // For a given number of characters this returns a mask and a value.  The
+  // next n characters are anded with the mask and compared with the value.
+  // A comparison failure indicates the node cannot match the next n characters.
+  // A comparison success indicates the node may match.
+  virtual void GetQuickCheckDetails(QuickCheckDetails* details,
+                                    RegExpCompiler* compiler,
+                                    int characters_filled_in,
+                                    bool not_at_start) = 0;
+  static const int kNodeIsTooComplexForGreedyLoops = -1;
+  virtual int GreedyLoopTextLength() { return kNodeIsTooComplexForGreedyLoops; }
+  // Only returns the successor for a text node of length 1 that matches any
+  // character and that has no guards on it.
+  virtual RegExpNode* GetSuccessorOfOmnivorousTextNode(
+      RegExpCompiler* compiler) {
+    return NULL;
+  }
+
+  // Collects information on the possible code units (mod 128) that can match if
+  // we look forward.  This is used for a Boyer-Moore-like string searching
+  // implementation.  TODO(erikcorry):  This should share more code with
+  // EatsAtLeast, GetQuickCheckDetails.  The budget argument is used to limit
+  // the number of nodes we are willing to look at in order to create this data.
+  static const int kRecursionBudget = 200;
+  virtual void FillInBMInfo(int offset,
+                            int budget,
+                            BoyerMooreLookahead* bm,
+                            bool not_at_start) {
+    UNREACHABLE();
+  }
+
+  // If we know that the input is one-byte then there are some nodes that can
+  // never match.  This method returns a node that can be substituted for
+  // itself, or NULL if the node can never match.
+  virtual RegExpNode* FilterOneByte(int depth, bool ignore_case) {
+    return this;
+  }
+  // Helper for FilterOneByte.
+  RegExpNode* replacement() {
+    DCHECK(info()->replacement_calculated);
+    return replacement_;
+  }
+  RegExpNode* set_replacement(RegExpNode* replacement) {
+    info()->replacement_calculated = true;
+    replacement_ =  replacement;
+    return replacement;  // For convenience.
+  }
+
+  // We want to avoid recalculating the lookahead info, so we store it on the
+  // node.  Only info that is for this node is stored.  We can tell that the
+  // info is for this node when offset == 0, so the information is calculated
+  // relative to this node.
+  void SaveBMInfo(BoyerMooreLookahead* bm, bool not_at_start, int offset) {
+    if (offset == 0) set_bm_info(not_at_start, bm);
+  }
+
+  Label* label() { return &label_; }
+  // If non-generic code is generated for a node (i.e. the node is not at the
+  // start of the trace) then it cannot be reused.  This variable sets a limit
+  // on how often we allow that to happen before we insist on starting a new
+  // trace and generating generic code for a node that can be reused by flushing
+  // the deferred actions in the current trace and generating a goto.
+  static const int kMaxCopiesCodeGenerated = 10;
+
+  NodeInfo* info() { return &info_; }
+
+  BoyerMooreLookahead* bm_info(bool not_at_start) {
+    return bm_info_[not_at_start ? 1 : 0];
+  }
+
+  Zone* zone() const { return zone_; }
+
+ protected:
+  enum LimitResult { DONE, CONTINUE };
+  RegExpNode* replacement_;
+
+  LimitResult LimitVersions(RegExpCompiler* compiler, Trace* trace);
+
+  void set_bm_info(bool not_at_start, BoyerMooreLookahead* bm) {
+    bm_info_[not_at_start ? 1 : 0] = bm;
+  }
+
+ private:
+  static const int kFirstCharBudget = 10;
+  Label label_;
+  NodeInfo info_;
+  // This variable keeps track of how many times code has been generated for
+  // this node (in different traces).  We don't keep track of where the
+  // generated code is located unless the code is generated at the start of
+  // a trace, in which case it is generic and can be reused by flushing the
+  // deferred operations in the current trace and generating a goto.
+  int trace_count_;
+  BoyerMooreLookahead* bm_info_[2];
+
+  Zone* zone_;
+};
+
+
+// A simple closed interval.
+class Interval {
+ public:
+  Interval() : from_(kNone), to_(kNone) { }
+  Interval(int from, int to) : from_(from), to_(to) { }
+  Interval Union(Interval that) {
+    if (that.from_ == kNone)
+      return *this;
+    else if (from_ == kNone)
+      return that;
+    else
+      return Interval(Min(from_, that.from_), Max(to_, that.to_));
+  }
+  bool Contains(int value) {
+    return (from_ <= value) && (value <= to_);
+  }
+  bool is_empty() { return from_ == kNone; }
+  int from() const { return from_; }
+  int to() const { return to_; }
+  static Interval Empty() { return Interval(); }
+  static const int kNone = -1;
+ private:
+  int from_;
+  int to_;
+};
+
+
+class SeqRegExpNode: public RegExpNode {
+ public:
+  explicit SeqRegExpNode(RegExpNode* on_success)
+      : RegExpNode(on_success->zone()), on_success_(on_success) { }
+  RegExpNode* on_success() { return on_success_; }
+  void set_on_success(RegExpNode* node) { on_success_ = node; }
+  virtual RegExpNode* FilterOneByte(int depth, bool ignore_case);
+  virtual void FillInBMInfo(int offset,
+                            int budget,
+                            BoyerMooreLookahead* bm,
+                            bool not_at_start) {
+    on_success_->FillInBMInfo(offset, budget - 1, bm, not_at_start);
+    if (offset == 0) set_bm_info(not_at_start, bm);
+  }
+
+ protected:
+  RegExpNode* FilterSuccessor(int depth, bool ignore_case);
+
+ private:
+  RegExpNode* on_success_;
+};
+
+
+class ActionNode: public SeqRegExpNode {
+ public:
+  enum ActionType {
+    SET_REGISTER,
+    INCREMENT_REGISTER,
+    STORE_POSITION,
+    BEGIN_SUBMATCH,
+    POSITIVE_SUBMATCH_SUCCESS,
+    EMPTY_MATCH_CHECK,
+    CLEAR_CAPTURES
+  };
+  static ActionNode* SetRegister(int reg, int val, RegExpNode* on_success);
+  static ActionNode* IncrementRegister(int reg, RegExpNode* on_success);
+  static ActionNode* StorePosition(int reg,
+                                   bool is_capture,
+                                   RegExpNode* on_success);
+  static ActionNode* ClearCaptures(Interval range, RegExpNode* on_success);
+  static ActionNode* BeginSubmatch(int stack_pointer_reg,
+                                   int position_reg,
+                                   RegExpNode* on_success);
+  static ActionNode* PositiveSubmatchSuccess(int stack_pointer_reg,
+                                             int restore_reg,
+                                             int clear_capture_count,
+                                             int clear_capture_from,
+                                             RegExpNode* on_success);
+  static ActionNode* EmptyMatchCheck(int start_register,
+                                     int repetition_register,
+                                     int repetition_limit,
+                                     RegExpNode* on_success);
+  virtual void Accept(NodeVisitor* visitor);
+  virtual void Emit(RegExpCompiler* compiler, Trace* trace);
+  virtual int EatsAtLeast(int still_to_find, int budget, bool not_at_start);
+  virtual void GetQuickCheckDetails(QuickCheckDetails* details,
+                                    RegExpCompiler* compiler,
+                                    int filled_in,
+                                    bool not_at_start) {
+    return on_success()->GetQuickCheckDetails(
+        details, compiler, filled_in, not_at_start);
+  }
+  virtual void FillInBMInfo(int offset,
+                            int budget,
+                            BoyerMooreLookahead* bm,
+                            bool not_at_start);
+  ActionType action_type() { return action_type_; }
+  // TODO(erikcorry): We should allow some action nodes in greedy loops.
+  virtual int GreedyLoopTextLength() { return kNodeIsTooComplexForGreedyLoops; }
+
+ private:
+  union {
+    struct {
+      int reg;
+      int value;
+    } u_store_register;
+    struct {
+      int reg;
+    } u_increment_register;
+    struct {
+      int reg;
+      bool is_capture;
+    } u_position_register;
+    struct {
+      int stack_pointer_register;
+      int current_position_register;
+      int clear_register_count;
+      int clear_register_from;
+    } u_submatch;
+    struct {
+      int start_register;
+      int repetition_register;
+      int repetition_limit;
+    } u_empty_match_check;
+    struct {
+      int range_from;
+      int range_to;
+    } u_clear_captures;
+  } data_;
+  ActionNode(ActionType action_type, RegExpNode* on_success)
+      : SeqRegExpNode(on_success),
+        action_type_(action_type) { }
+  ActionType action_type_;
+  friend class DotPrinter;
+};
+
+
+class TextNode: public SeqRegExpNode {
+ public:
+  TextNode(ZoneList<TextElement>* elms,
+           RegExpNode* on_success)
+      : SeqRegExpNode(on_success),
+        elms_(elms) { }
+  TextNode(RegExpCharacterClass* that,
+           RegExpNode* on_success)
+      : SeqRegExpNode(on_success),
+        elms_(new(zone()) ZoneList<TextElement>(1, zone())) {
+    elms_->Add(TextElement::CharClass(that), zone());
+  }
+  virtual void Accept(NodeVisitor* visitor);
+  virtual void Emit(RegExpCompiler* compiler, Trace* trace);
+  virtual int EatsAtLeast(int still_to_find, int budget, bool not_at_start);
+  virtual void GetQuickCheckDetails(QuickCheckDetails* details,
+                                    RegExpCompiler* compiler,
+                                    int characters_filled_in,
+                                    bool not_at_start);
+  ZoneList<TextElement>* elements() { return elms_; }
+  void MakeCaseIndependent(bool is_one_byte);
+  virtual int GreedyLoopTextLength();
+  virtual RegExpNode* GetSuccessorOfOmnivorousTextNode(
+      RegExpCompiler* compiler);
+  virtual void FillInBMInfo(int offset,
+                            int budget,
+                            BoyerMooreLookahead* bm,
+                            bool not_at_start);
+  void CalculateOffsets();
+  virtual RegExpNode* FilterOneByte(int depth, bool ignore_case);
+
+ private:
+  enum TextEmitPassType {
+    NON_LATIN1_MATCH,            // Check for characters that can't match.
+    SIMPLE_CHARACTER_MATCH,      // Case-dependent single character check.
+    NON_LETTER_CHARACTER_MATCH,  // Check characters that have no case equivs.
+    CASE_CHARACTER_MATCH,        // Case-independent single character check.
+    CHARACTER_CLASS_MATCH        // Character class.
+  };
+  static bool SkipPass(int pass, bool ignore_case);
+  static const int kFirstRealPass = SIMPLE_CHARACTER_MATCH;
+  static const int kLastPass = CHARACTER_CLASS_MATCH;
+  void TextEmitPass(RegExpCompiler* compiler,
+                    TextEmitPassType pass,
+                    bool preloaded,
+                    Trace* trace,
+                    bool first_element_checked,
+                    int* checked_up_to);
+  int Length();
+  ZoneList<TextElement>* elms_;
+};
+
+
+class AssertionNode: public SeqRegExpNode {
+ public:
+  enum AssertionType {
+    AT_END,
+    AT_START,
+    AT_BOUNDARY,
+    AT_NON_BOUNDARY,
+    AFTER_NEWLINE
+  };
+  static AssertionNode* AtEnd(RegExpNode* on_success) {
+    return new(on_success->zone()) AssertionNode(AT_END, on_success);
+  }
+  static AssertionNode* AtStart(RegExpNode* on_success) {
+    return new(on_success->zone()) AssertionNode(AT_START, on_success);
+  }
+  static AssertionNode* AtBoundary(RegExpNode* on_success) {
+    return new(on_success->zone()) AssertionNode(AT_BOUNDARY, on_success);
+  }
+  static AssertionNode* AtNonBoundary(RegExpNode* on_success) {
+    return new(on_success->zone()) AssertionNode(AT_NON_BOUNDARY, on_success);
+  }
+  static AssertionNode* AfterNewline(RegExpNode* on_success) {
+    return new(on_success->zone()) AssertionNode(AFTER_NEWLINE, on_success);
+  }
+  virtual void Accept(NodeVisitor* visitor);
+  virtual void Emit(RegExpCompiler* compiler, Trace* trace);
+  virtual int EatsAtLeast(int still_to_find, int budget, bool not_at_start);
+  virtual void GetQuickCheckDetails(QuickCheckDetails* details,
+                                    RegExpCompiler* compiler,
+                                    int filled_in,
+                                    bool not_at_start);
+  virtual void FillInBMInfo(int offset,
+                            int budget,
+                            BoyerMooreLookahead* bm,
+                            bool not_at_start);
+  AssertionType assertion_type() { return assertion_type_; }
+
+ private:
+  void EmitBoundaryCheck(RegExpCompiler* compiler, Trace* trace);
+  enum IfPrevious { kIsNonWord, kIsWord };
+  void BacktrackIfPrevious(RegExpCompiler* compiler,
+                           Trace* trace,
+                           IfPrevious backtrack_if_previous);
+  AssertionNode(AssertionType t, RegExpNode* on_success)
+      : SeqRegExpNode(on_success), assertion_type_(t) { }
+  AssertionType assertion_type_;
+};
+
+
+class BackReferenceNode: public SeqRegExpNode {
+ public:
+  BackReferenceNode(int start_reg,
+                    int end_reg,
+                    RegExpNode* on_success)
+      : SeqRegExpNode(on_success),
+        start_reg_(start_reg),
+        end_reg_(end_reg) { }
+  virtual void Accept(NodeVisitor* visitor);
+  int start_register() { return start_reg_; }
+  int end_register() { return end_reg_; }
+  virtual void Emit(RegExpCompiler* compiler, Trace* trace);
+  virtual int EatsAtLeast(int still_to_find,
+                          int recursion_depth,
+                          bool not_at_start);
+  virtual void GetQuickCheckDetails(QuickCheckDetails* details,
+                                    RegExpCompiler* compiler,
+                                    int characters_filled_in,
+                                    bool not_at_start) {
+    return;
+  }
+  virtual void FillInBMInfo(int offset,
+                            int budget,
+                            BoyerMooreLookahead* bm,
+                            bool not_at_start);
+
+ private:
+  int start_reg_;
+  int end_reg_;
+};
+
+
+class EndNode: public RegExpNode {
+ public:
+  enum Action { ACCEPT, BACKTRACK, NEGATIVE_SUBMATCH_SUCCESS };
+  explicit EndNode(Action action, Zone* zone)
+      : RegExpNode(zone), action_(action) { }
+  virtual void Accept(NodeVisitor* visitor);
+  virtual void Emit(RegExpCompiler* compiler, Trace* trace);
+  virtual int EatsAtLeast(int still_to_find,
+                          int recursion_depth,
+                          bool not_at_start) { return 0; }
+  virtual void GetQuickCheckDetails(QuickCheckDetails* details,
+                                    RegExpCompiler* compiler,
+                                    int characters_filled_in,
+                                    bool not_at_start) {
+    // Returning 0 from EatsAtLeast should ensure we never get here.
+    UNREACHABLE();
+  }
+  virtual void FillInBMInfo(int offset,
+                            int budget,
+                            BoyerMooreLookahead* bm,
+                            bool not_at_start) {
+    // Returning 0 from EatsAtLeast should ensure we never get here.
+    UNREACHABLE();
+  }
+
+ private:
+  Action action_;
+};
+
+
+class NegativeSubmatchSuccess: public EndNode {
+ public:
+  NegativeSubmatchSuccess(int stack_pointer_reg,
+                          int position_reg,
+                          int clear_capture_count,
+                          int clear_capture_start,
+                          Zone* zone)
+      : EndNode(NEGATIVE_SUBMATCH_SUCCESS, zone),
+        stack_pointer_register_(stack_pointer_reg),
+        current_position_register_(position_reg),
+        clear_capture_count_(clear_capture_count),
+        clear_capture_start_(clear_capture_start) { }
+  virtual void Emit(RegExpCompiler* compiler, Trace* trace);
+
+ private:
+  int stack_pointer_register_;
+  int current_position_register_;
+  int clear_capture_count_;
+  int clear_capture_start_;
+};
+
+
+class Guard: public ZoneObject {
+ public:
+  enum Relation { LT, GEQ };
+  Guard(int reg, Relation op, int value)
+      : reg_(reg),
+        op_(op),
+        value_(value) { }
+  int reg() { return reg_; }
+  Relation op() { return op_; }
+  int value() { return value_; }
+
+ private:
+  int reg_;
+  Relation op_;
+  int value_;
+};
+
+
+class GuardedAlternative {
+ public:
+  explicit GuardedAlternative(RegExpNode* node) : node_(node), guards_(NULL) { }
+  void AddGuard(Guard* guard, Zone* zone);
+  RegExpNode* node() { return node_; }
+  void set_node(RegExpNode* node) { node_ = node; }
+  ZoneList<Guard*>* guards() { return guards_; }
+
+ private:
+  RegExpNode* node_;
+  ZoneList<Guard*>* guards_;
+};
+
+
+class AlternativeGeneration;
+
+
+class ChoiceNode: public RegExpNode {
+ public:
+  explicit ChoiceNode(int expected_size, Zone* zone)
+      : RegExpNode(zone),
+        alternatives_(new(zone)
+                      ZoneList<GuardedAlternative>(expected_size, zone)),
+        table_(NULL),
+        not_at_start_(false),
+        being_calculated_(false) { }
+  virtual void Accept(NodeVisitor* visitor);
+  void AddAlternative(GuardedAlternative node) {
+    alternatives()->Add(node, zone());
+  }
+  ZoneList<GuardedAlternative>* alternatives() { return alternatives_; }
+  DispatchTable* GetTable(bool ignore_case);
+  virtual void Emit(RegExpCompiler* compiler, Trace* trace);
+  virtual int EatsAtLeast(int still_to_find, int budget, bool not_at_start);
+  int EatsAtLeastHelper(int still_to_find,
+                        int budget,
+                        RegExpNode* ignore_this_node,
+                        bool not_at_start);
+  virtual void GetQuickCheckDetails(QuickCheckDetails* details,
+                                    RegExpCompiler* compiler,
+                                    int characters_filled_in,
+                                    bool not_at_start);
+  virtual void FillInBMInfo(int offset,
+                            int budget,
+                            BoyerMooreLookahead* bm,
+                            bool not_at_start);
+
+  bool being_calculated() { return being_calculated_; }
+  bool not_at_start() { return not_at_start_; }
+  void set_not_at_start() { not_at_start_ = true; }
+  void set_being_calculated(bool b) { being_calculated_ = b; }
+  virtual bool try_to_emit_quick_check_for_alternative(bool is_first) {
+    return true;
+  }
+  virtual RegExpNode* FilterOneByte(int depth, bool ignore_case);
+
+ protected:
+  int GreedyLoopTextLengthForAlternative(GuardedAlternative* alternative);
+  ZoneList<GuardedAlternative>* alternatives_;
+
+ private:
+  friend class DispatchTableConstructor;
+  friend class Analysis;
+  void GenerateGuard(RegExpMacroAssembler* macro_assembler,
+                     Guard* guard,
+                     Trace* trace);
+  int CalculatePreloadCharacters(RegExpCompiler* compiler, int eats_at_least);
+  void EmitOutOfLineContinuation(RegExpCompiler* compiler,
+                                 Trace* trace,
+                                 GuardedAlternative alternative,
+                                 AlternativeGeneration* alt_gen,
+                                 int preload_characters,
+                                 bool next_expects_preload);
+  void SetUpPreLoad(RegExpCompiler* compiler,
+                    Trace* current_trace,
+                    PreloadState* preloads);
+  void AssertGuardsMentionRegisters(Trace* trace);
+  int EmitOptimizedUnanchoredSearch(RegExpCompiler* compiler, Trace* trace);
+  Trace* EmitGreedyLoop(RegExpCompiler* compiler,
+                        Trace* trace,
+                        AlternativeGenerationList* alt_gens,
+                        PreloadState* preloads,
+                        GreedyLoopState* greedy_loop_state,
+                        int text_length);
+  void EmitChoices(RegExpCompiler* compiler,
+                   AlternativeGenerationList* alt_gens,
+                   int first_choice,
+                   Trace* trace,
+                   PreloadState* preloads);
+  DispatchTable* table_;
+  // If true, this node is never checked at the start of the input.
+  // Allows a new trace to start with at_start() set to false.
+  bool not_at_start_;
+  bool being_calculated_;
+};
+
+
+class NegativeLookaheadChoiceNode: public ChoiceNode {
+ public:
+  explicit NegativeLookaheadChoiceNode(GuardedAlternative this_must_fail,
+                                       GuardedAlternative then_do_this,
+                                       Zone* zone)
+      : ChoiceNode(2, zone) {
+    AddAlternative(this_must_fail);
+    AddAlternative(then_do_this);
+  }
+  virtual int EatsAtLeast(int still_to_find, int budget, bool not_at_start);
+  virtual void GetQuickCheckDetails(QuickCheckDetails* details,
+                                    RegExpCompiler* compiler,
+                                    int characters_filled_in,
+                                    bool not_at_start);
+  virtual void FillInBMInfo(int offset,
+                            int budget,
+                            BoyerMooreLookahead* bm,
+                            bool not_at_start) {
+    alternatives_->at(1).node()->FillInBMInfo(
+        offset, budget - 1, bm, not_at_start);
+    if (offset == 0) set_bm_info(not_at_start, bm);
+  }
+  // For a negative lookahead we don't emit the quick check for the
+  // alternative that is expected to fail.  This is because quick check code
+  // starts by loading enough characters for the alternative that takes fewest
+  // characters, but on a negative lookahead the negative branch did not take
+  // part in that calculation (EatsAtLeast) so the assumptions don't hold.
+  virtual bool try_to_emit_quick_check_for_alternative(bool is_first) {
+    return !is_first;
+  }
+  virtual RegExpNode* FilterOneByte(int depth, bool ignore_case);
+};
+
+
+class LoopChoiceNode: public ChoiceNode {
+ public:
+  explicit LoopChoiceNode(bool body_can_be_zero_length, Zone* zone)
+      : ChoiceNode(2, zone),
+        loop_node_(NULL),
+        continue_node_(NULL),
+        body_can_be_zero_length_(body_can_be_zero_length)
+        { }
+  void AddLoopAlternative(GuardedAlternative alt);
+  void AddContinueAlternative(GuardedAlternative alt);
+  virtual void Emit(RegExpCompiler* compiler, Trace* trace);
+  virtual int EatsAtLeast(int still_to_find,  int budget, bool not_at_start);
+  virtual void GetQuickCheckDetails(QuickCheckDetails* details,
+                                    RegExpCompiler* compiler,
+                                    int characters_filled_in,
+                                    bool not_at_start);
+  virtual void FillInBMInfo(int offset,
+                            int budget,
+                            BoyerMooreLookahead* bm,
+                            bool not_at_start);
+  RegExpNode* loop_node() { return loop_node_; }
+  RegExpNode* continue_node() { return continue_node_; }
+  bool body_can_be_zero_length() { return body_can_be_zero_length_; }
+  virtual void Accept(NodeVisitor* visitor);
+  virtual RegExpNode* FilterOneByte(int depth, bool ignore_case);
+
+ private:
+  // AddAlternative is made private for loop nodes because alternatives
+  // should not be added freely, we need to keep track of which node
+  // goes back to the node itself.
+  void AddAlternative(GuardedAlternative node) {
+    ChoiceNode::AddAlternative(node);
+  }
+
+  RegExpNode* loop_node_;
+  RegExpNode* continue_node_;
+  bool body_can_be_zero_length_;
+};
+
+
+// Improve the speed that we scan for an initial point where a non-anchored
+// regexp can match by using a Boyer-Moore-like table. This is done by
+// identifying non-greedy non-capturing loops in the nodes that eat any
+// character one at a time.  For example in the middle of the regexp
+// /foo[\s\S]*?bar/ we find such a loop.  There is also such a loop implicitly
+// inserted at the start of any non-anchored regexp.
+//
+// When we have found such a loop we look ahead in the nodes to find the set of
+// characters that can come at given distances. For example for the regexp
+// /.?foo/ we know that there are at least 3 characters ahead of us, and the
+// sets of characters that can occur are [any, [f, o], [o]]. We find a range in
+// the lookahead info where the set of characters is reasonably constrained. In
+// our example this is from index 1 to 2 (0 is not constrained). We can now
+// look 3 characters ahead and if we don't find one of [f, o] (the union of
+// [f, o] and [o]) then we can skip forwards by the range size (in this case 2).
+//
+// For Unicode input strings we do the same, but modulo 128.
+//
+// We also look at the first string fed to the regexp and use that to get a hint
+// of the character frequencies in the inputs. This affects the assessment of
+// whether the set of characters is 'reasonably constrained'.
+//
+// We also have another lookahead mechanism (called quick check in the code),
+// which uses a wide load of multiple characters followed by a mask and compare
+// to determine whether a match is possible at this point.
+enum ContainedInLattice {
+  kNotYet = 0,
+  kLatticeIn = 1,
+  kLatticeOut = 2,
+  kLatticeUnknown = 3  // Can also mean both in and out.
+};
+
+
+inline ContainedInLattice Combine(ContainedInLattice a, ContainedInLattice b) {
+  return static_cast<ContainedInLattice>(a | b);
+}
+
+
+ContainedInLattice AddRange(ContainedInLattice a,
+                            const int* ranges,
+                            int ranges_size,
+                            Interval new_range);
+
+
+class BoyerMoorePositionInfo : public ZoneObject {
+ public:
+  explicit BoyerMoorePositionInfo(Zone* zone)
+      : map_(new(zone) ZoneList<bool>(kMapSize, zone)),
+        map_count_(0),
+        w_(kNotYet),
+        s_(kNotYet),
+        d_(kNotYet),
+        surrogate_(kNotYet) {
+     for (int i = 0; i < kMapSize; i++) {
+       map_->Add(false, zone);
+     }
+  }
+
+  bool& at(int i) { return map_->at(i); }
+
+  static const int kMapSize = 128;
+  static const int kMask = kMapSize - 1;
+
+  int map_count() const { return map_count_; }
+
+  void Set(int character);
+  void SetInterval(const Interval& interval);
+  void SetAll();
+  bool is_non_word() { return w_ == kLatticeOut; }
+  bool is_word() { return w_ == kLatticeIn; }
+
+ private:
+  ZoneList<bool>* map_;
+  int map_count_;  // Number of set bits in the map.
+  ContainedInLattice w_;  // The \w character class.
+  ContainedInLattice s_;  // The \s character class.
+  ContainedInLattice d_;  // The \d character class.
+  ContainedInLattice surrogate_;  // Surrogate UTF-16 code units.
+};
+
+
+class BoyerMooreLookahead : public ZoneObject {
+ public:
+  BoyerMooreLookahead(int length, RegExpCompiler* compiler, Zone* zone);
+
+  int length() { return length_; }
+  int max_char() { return max_char_; }
+  RegExpCompiler* compiler() { return compiler_; }
+
+  int Count(int map_number) {
+    return bitmaps_->at(map_number)->map_count();
+  }
+
+  BoyerMoorePositionInfo* at(int i) { return bitmaps_->at(i); }
+
+  void Set(int map_number, int character) {
+    if (character > max_char_) return;
+    BoyerMoorePositionInfo* info = bitmaps_->at(map_number);
+    info->Set(character);
+  }
+
+  void SetInterval(int map_number, const Interval& interval) {
+    if (interval.from() > max_char_) return;
+    BoyerMoorePositionInfo* info = bitmaps_->at(map_number);
+    if (interval.to() > max_char_) {
+      info->SetInterval(Interval(interval.from(), max_char_));
+    } else {
+      info->SetInterval(interval);
+    }
+  }
+
+  void SetAll(int map_number) {
+    bitmaps_->at(map_number)->SetAll();
+  }
+
+  void SetRest(int from_map) {
+    for (int i = from_map; i < length_; i++) SetAll(i);
+  }
+  void EmitSkipInstructions(RegExpMacroAssembler* masm);
+
+ private:
+  // This is the value obtained by EatsAtLeast.  If we do not have at least this
+  // many characters left in the sample string then the match is bound to fail.
+  // Therefore it is OK to read a character this far ahead of the current match
+  // point.
+  int length_;
+  RegExpCompiler* compiler_;
+  // 0xff for Latin1, 0xffff for UTF-16.
+  int max_char_;
+  ZoneList<BoyerMoorePositionInfo*>* bitmaps_;
+
+  int GetSkipTable(int min_lookahead,
+                   int max_lookahead,
+                   Handle<ByteArray> boolean_skip_table);
+  bool FindWorthwhileInterval(int* from, int* to);
+  int FindBestInterval(
+    int max_number_of_chars, int old_biggest_points, int* from, int* to);
+};
+
+
+// There are many ways to generate code for a node.  This class encapsulates
+// the current way we should be generating.  In other words it encapsulates
+// the current state of the code generator.  The effect of this is that we
+// generate code for paths that the matcher can take through the regular
+// expression.  A given node in the regexp can be code-generated several times
+// as it can be part of several traces.  For example for the regexp:
+// /foo(bar|ip)baz/ the code to match baz will be generated twice, once as part
+// of the foo-bar-baz trace and once as part of the foo-ip-baz trace.  The code
+// to match foo is generated only once (the traces have a common prefix).  The
+// code to store the capture is deferred and generated (twice) after the places
+// where baz has been matched.
+class Trace {
+ public:
+  // A value for a property that is either known to be true, know to be false,
+  // or not known.
+  enum TriBool {
+    UNKNOWN = -1, FALSE_VALUE = 0, TRUE_VALUE = 1
+  };
+
+  class DeferredAction {
+   public:
+    DeferredAction(ActionNode::ActionType action_type, int reg)
+        : action_type_(action_type), reg_(reg), next_(NULL) { }
+    DeferredAction* next() { return next_; }
+    bool Mentions(int reg);
+    int reg() { return reg_; }
+    ActionNode::ActionType action_type() { return action_type_; }
+   private:
+    ActionNode::ActionType action_type_;
+    int reg_;
+    DeferredAction* next_;
+    friend class Trace;
+  };
+
+  class DeferredCapture : public DeferredAction {
+   public:
+    DeferredCapture(int reg, bool is_capture, Trace* trace)
+        : DeferredAction(ActionNode::STORE_POSITION, reg),
+          cp_offset_(trace->cp_offset()),
+          is_capture_(is_capture) { }
+    int cp_offset() { return cp_offset_; }
+    bool is_capture() { return is_capture_; }
+   private:
+    int cp_offset_;
+    bool is_capture_;
+    void set_cp_offset(int cp_offset) { cp_offset_ = cp_offset; }
+  };
+
+  class DeferredSetRegister : public DeferredAction {
+   public:
+    DeferredSetRegister(int reg, int value)
+        : DeferredAction(ActionNode::SET_REGISTER, reg),
+          value_(value) { }
+    int value() { return value_; }
+   private:
+    int value_;
+  };
+
+  class DeferredClearCaptures : public DeferredAction {
+   public:
+    explicit DeferredClearCaptures(Interval range)
+        : DeferredAction(ActionNode::CLEAR_CAPTURES, -1),
+          range_(range) { }
+    Interval range() { return range_; }
+   private:
+    Interval range_;
+  };
+
+  class DeferredIncrementRegister : public DeferredAction {
+   public:
+    explicit DeferredIncrementRegister(int reg)
+        : DeferredAction(ActionNode::INCREMENT_REGISTER, reg) { }
+  };
+
+  Trace()
+      : cp_offset_(0),
+        actions_(NULL),
+        backtrack_(NULL),
+        stop_node_(NULL),
+        loop_label_(NULL),
+        characters_preloaded_(0),
+        bound_checked_up_to_(0),
+        flush_budget_(100),
+        at_start_(UNKNOWN) { }
+
+  // End the trace.  This involves flushing the deferred actions in the trace
+  // and pushing a backtrack location onto the backtrack stack.  Once this is
+  // done we can start a new trace or go to one that has already been
+  // generated.
+  void Flush(RegExpCompiler* compiler, RegExpNode* successor);
+  int cp_offset() { return cp_offset_; }
+  DeferredAction* actions() { return actions_; }
+  // A trivial trace is one that has no deferred actions or other state that
+  // affects the assumptions used when generating code.  There is no recorded
+  // backtrack location in a trivial trace, so with a trivial trace we will
+  // generate code that, on a failure to match, gets the backtrack location
+  // from the backtrack stack rather than using a direct jump instruction.  We
+  // always start code generation with a trivial trace and non-trivial traces
+  // are created as we emit code for nodes or add to the list of deferred
+  // actions in the trace.  The location of the code generated for a node using
+  // a trivial trace is recorded in a label in the node so that gotos can be
+  // generated to that code.
+  bool is_trivial() {
+    return backtrack_ == NULL &&
+           actions_ == NULL &&
+           cp_offset_ == 0 &&
+           characters_preloaded_ == 0 &&
+           bound_checked_up_to_ == 0 &&
+           quick_check_performed_.characters() == 0 &&
+           at_start_ == UNKNOWN;
+  }
+  TriBool at_start() { return at_start_; }
+  void set_at_start(bool at_start) {
+    at_start_ = at_start ? TRUE_VALUE : FALSE_VALUE;
+  }
+  Label* backtrack() { return backtrack_; }
+  Label* loop_label() { return loop_label_; }
+  RegExpNode* stop_node() { return stop_node_; }
+  int characters_preloaded() { return characters_preloaded_; }
+  int bound_checked_up_to() { return bound_checked_up_to_; }
+  int flush_budget() { return flush_budget_; }
+  QuickCheckDetails* quick_check_performed() { return &quick_check_performed_; }
+  bool mentions_reg(int reg);
+  // Returns true if a deferred position store exists to the specified
+  // register and stores the offset in the out-parameter.  Otherwise
+  // returns false.
+  bool GetStoredPosition(int reg, int* cp_offset);
+  // These set methods and AdvanceCurrentPositionInTrace should be used only on
+  // new traces - the intention is that traces are immutable after creation.
+  void add_action(DeferredAction* new_action) {
+    DCHECK(new_action->next_ == NULL);
+    new_action->next_ = actions_;
+    actions_ = new_action;
+  }
+  void set_backtrack(Label* backtrack) { backtrack_ = backtrack; }
+  void set_stop_node(RegExpNode* node) { stop_node_ = node; }
+  void set_loop_label(Label* label) { loop_label_ = label; }
+  void set_characters_preloaded(int count) { characters_preloaded_ = count; }
+  void set_bound_checked_up_to(int to) { bound_checked_up_to_ = to; }
+  void set_flush_budget(int to) { flush_budget_ = to; }
+  void set_quick_check_performed(QuickCheckDetails* d) {
+    quick_check_performed_ = *d;
+  }
+  void InvalidateCurrentCharacter();
+  void AdvanceCurrentPositionInTrace(int by, RegExpCompiler* compiler);
+
+ private:
+  int FindAffectedRegisters(OutSet* affected_registers, Zone* zone);
+  void PerformDeferredActions(RegExpMacroAssembler* macro,
+                              int max_register,
+                              const OutSet& affected_registers,
+                              OutSet* registers_to_pop,
+                              OutSet* registers_to_clear,
+                              Zone* zone);
+  void RestoreAffectedRegisters(RegExpMacroAssembler* macro,
+                                int max_register,
+                                const OutSet& registers_to_pop,
+                                const OutSet& registers_to_clear);
+  int cp_offset_;
+  DeferredAction* actions_;
+  Label* backtrack_;
+  RegExpNode* stop_node_;
+  Label* loop_label_;
+  int characters_preloaded_;
+  int bound_checked_up_to_;
+  QuickCheckDetails quick_check_performed_;
+  int flush_budget_;
+  TriBool at_start_;
+};
+
+
+class GreedyLoopState {
+ public:
+  explicit GreedyLoopState(bool not_at_start);
+
+  Label* label() { return &label_; }
+  Trace* counter_backtrack_trace() { return &counter_backtrack_trace_; }
+
+ private:
+  Label label_;
+  Trace counter_backtrack_trace_;
+};
+
+
+struct PreloadState {
+  static const int kEatsAtLeastNotYetInitialized = -1;
+  bool preload_is_current_;
+  bool preload_has_checked_bounds_;
+  int preload_characters_;
+  int eats_at_least_;
+  void init() {
+    eats_at_least_ = kEatsAtLeastNotYetInitialized;
+  }
+};
+
+
+class NodeVisitor {
+ public:
+  virtual ~NodeVisitor() { }
+#define DECLARE_VISIT(Type)                                          \
+  virtual void Visit##Type(Type##Node* that) = 0;
+FOR_EACH_NODE_TYPE(DECLARE_VISIT)
+#undef DECLARE_VISIT
+  virtual void VisitLoopChoice(LoopChoiceNode* that) { VisitChoice(that); }
+};
+
+
+// Node visitor used to add the start set of the alternatives to the
+// dispatch table of a choice node.
+class DispatchTableConstructor: public NodeVisitor {
+ public:
+  DispatchTableConstructor(DispatchTable* table, bool ignore_case,
+                           Zone* zone)
+      : table_(table),
+        choice_index_(-1),
+        ignore_case_(ignore_case),
+        zone_(zone) { }
+
+  void BuildTable(ChoiceNode* node);
+
+  void AddRange(CharacterRange range) {
+    table()->AddRange(range, choice_index_, zone_);
+  }
+
+  void AddInverse(ZoneList<CharacterRange>* ranges);
+
+#define DECLARE_VISIT(Type)                                          \
+  virtual void Visit##Type(Type##Node* that);
+FOR_EACH_NODE_TYPE(DECLARE_VISIT)
+#undef DECLARE_VISIT
+
+  DispatchTable* table() { return table_; }
+  void set_choice_index(int value) { choice_index_ = value; }
+
+ protected:
+  DispatchTable* table_;
+  int choice_index_;
+  bool ignore_case_;
+  Zone* zone_;
+};
+
+
+// Assertion propagation moves information about assertions such as
+// \b to the affected nodes.  For instance, in /.\b./ information must
+// be propagated to the first '.' that whatever follows needs to know
+// if it matched a word or a non-word, and to the second '.' that it
+// has to check if it succeeds a word or non-word.  In this case the
+// result will be something like:
+//
+//   +-------+        +------------+
+//   |   .   |        |      .     |
+//   +-------+  --->  +------------+
+//   | word? |        | check word |
+//   +-------+        +------------+
+class Analysis: public NodeVisitor {
+ public:
+  Analysis(bool ignore_case, bool is_one_byte)
+      : ignore_case_(ignore_case),
+        is_one_byte_(is_one_byte),
+        error_message_(NULL) {}
+  void EnsureAnalyzed(RegExpNode* node);
+
+#define DECLARE_VISIT(Type)                                          \
+  virtual void Visit##Type(Type##Node* that);
+FOR_EACH_NODE_TYPE(DECLARE_VISIT)
+#undef DECLARE_VISIT
+  virtual void VisitLoopChoice(LoopChoiceNode* that);
+
+  bool has_failed() { return error_message_ != NULL; }
+  const char* error_message() {
+    DCHECK(error_message_ != NULL);
+    return error_message_;
+  }
+  void fail(const char* error_message) {
+    error_message_ = error_message;
+  }
+
+ private:
+  bool ignore_case_;
+  bool is_one_byte_;
+  const char* error_message_;
+
+  DISALLOW_IMPLICIT_CONSTRUCTORS(Analysis);
+};
+
+
+struct RegExpCompileData {
+  RegExpCompileData()
+    : tree(NULL),
+      node(NULL),
+      simple(true),
+      contains_anchor(false),
+      capture_count(0) { }
+  RegExpTree* tree;
+  RegExpNode* node;
+  bool simple;
+  bool contains_anchor;
+  Handle<String> error;
+  int capture_count;
+};
+
+
+class RegExpEngine: public AllStatic {
+ public:
+  struct CompilationResult {
+    CompilationResult(Isolate* isolate, const char* error_message)
+        : error_message(error_message),
+          code(isolate->heap()->the_hole_value()),
+          num_registers(0) {}
+    CompilationResult(Object* code, int registers)
+      : error_message(NULL),
+        code(code),
+        num_registers(registers) {}
+    const char* error_message;
+    Object* code;
+    int num_registers;
+  };
+
+  static CompilationResult Compile(RegExpCompileData* input, bool ignore_case,
+                                   bool global, bool multiline, bool sticky,
+                                   Handle<String> pattern,
+                                   Handle<String> sample_subject,
+                                   bool is_one_byte, Zone* zone);
+
+  static void DotPrint(const char* label, RegExpNode* node, bool ignore_case);
+};
+
+}  // namespace dart
+
+#endif  // VM_REGEXP_H_
diff --git a/runtime/vm/regexp_assembler.cc b/runtime/vm/regexp_assembler.cc
new file mode 100644
index 0000000..8936d9d
--- /dev/null
+++ b/runtime/vm/regexp_assembler.cc
@@ -0,0 +1,23 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for 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/regexp_assembler.h"
+
+// SNIP
+
+namespace dart {
+
+RegExpMacroAssembler::RegExpMacroAssembler(Zone* zone)
+  : slow_safe_compiler_(false),
+    global_mode_(NOT_GLOBAL),
+    zone_(zone) {
+}
+
+
+RegExpMacroAssembler::~RegExpMacroAssembler() {
+}
+
+// SNIP
+
+}  // namespace dart
diff --git a/runtime/vm/regexp_assembler.h b/runtime/vm/regexp_assembler.h
new file mode 100644
index 0000000..ace607b
--- /dev/null
+++ b/runtime/vm/regexp_assembler.h
@@ -0,0 +1,167 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+#ifndef VM_REGEXP_ASSEMBLER_H_
+#define VM_REGEXP_ASSEMBLER_H_
+
+// SNIP
+
+namespace dart {
+
+// SNIP
+
+class RegExpMacroAssembler {
+ public:
+  // The implementation must be able to handle at least:
+  static const int kMaxRegister = (1 << 16) - 1;
+  static const int kMaxCPOffset = (1 << 15) - 1;
+  static const int kMinCPOffset = -(1 << 15);
+
+  static const int kTableSizeBits = 7;
+  static const int kTableSize = 1 << kTableSizeBits;
+  static const int kTableMask = kTableSize - 1;
+
+  enum IrregexpImplementation {
+    kIA32Implementation,
+    kARMImplementation,
+    kARM64Implementation,
+    kMIPSImplementation,
+    kX64Implementation,
+    kX87Implementation,
+    kBytecodeImplementation
+  };
+
+  enum StackCheckFlag {
+    kNoStackLimitCheck = false,
+    kCheckStackLimit = true
+  };
+
+  explicit RegExpMacroAssembler(Zone* zone);
+  virtual ~RegExpMacroAssembler();
+  // The maximal number of pushes between stack checks. Users must supply
+  // kCheckStackLimit flag to push operations (instead of kNoStackLimitCheck)
+  // at least once for every stack_limit() pushes that are executed.
+  virtual int stack_limit_slack() = 0;
+  virtual bool CanReadUnaligned() = 0;
+  virtual void AdvanceCurrentPosition(int by) = 0;  // Signed cp change.
+  virtual void AdvanceRegister(int reg, int by) = 0;  // r[reg] += by.
+  // Continues execution from the position pushed on the top of the backtrack
+  // stack by an earlier PushBacktrack(Label*).
+  virtual void Backtrack() = 0;
+  virtual void Bind(Label* label) = 0;
+  virtual void CheckAtStart(Label* on_at_start) = 0;
+  // Dispatch after looking the current character up in a 2-bits-per-entry
+  // map.  The destinations vector has up to 4 labels.
+  virtual void CheckCharacter(unsigned c, Label* on_equal) = 0;
+  // Bitwise and the current character with the given constant and then
+  // check for a match with c.
+  virtual void CheckCharacterAfterAnd(unsigned c,
+                                      unsigned and_with,
+                                      Label* on_equal) = 0;
+  virtual void CheckCharacterGT(uc16 limit, Label* on_greater) = 0;
+  virtual void CheckCharacterLT(uc16 limit, Label* on_less) = 0;
+  virtual void CheckGreedyLoop(Label* on_tos_equals_current_position) = 0;
+  virtual void CheckNotAtStart(Label* on_not_at_start) = 0;
+  virtual void CheckNotBackReference(int start_reg, Label* on_no_match) = 0;
+  virtual void CheckNotBackReferenceIgnoreCase(int start_reg,
+                                               Label* on_no_match) = 0;
+  // Check the current character for a match with a literal character.  If we
+  // fail to match then goto the on_failure label.  End of input always
+  // matches.  If the label is NULL then we should pop a backtrack address off
+  // the stack and go to that.
+  virtual void CheckNotCharacter(unsigned c, Label* on_not_equal) = 0;
+  virtual void CheckNotCharacterAfterAnd(unsigned c,
+                                         unsigned and_with,
+                                         Label* on_not_equal) = 0;
+  // Subtract a constant from the current character, then and with the given
+  // constant and then check for a match with c.
+  virtual void CheckNotCharacterAfterMinusAnd(uc16 c,
+                                              uc16 minus,
+                                              uc16 and_with,
+                                              Label* on_not_equal) = 0;
+  virtual void CheckCharacterInRange(uc16 from,
+                                     uc16 to,  // Both inclusive.
+                                     Label* on_in_range) = 0;
+  virtual void CheckCharacterNotInRange(uc16 from,
+                                        uc16 to,  // Both inclusive.
+                                        Label* on_not_in_range) = 0;
+
+  // The current character (modulus the kTableSize) is looked up in the byte
+  // array, and if the found byte is non-zero, we jump to the on_bit_set label.
+  virtual void CheckBitInTable(Handle<ByteArray> table, Label* on_bit_set) = 0;
+
+  // Checks whether the given offset from the current position is before
+  // the end of the string.  May overwrite the current character.
+  virtual void CheckPosition(int cp_offset, Label* on_outside_input) {
+    LoadCurrentCharacter(cp_offset, on_outside_input, true);
+  }
+  // Check whether a standard/default character class matches the current
+  // character. Returns false if the type of special character class does
+  // not have custom support.
+  // May clobber the current loaded character.
+  virtual bool CheckSpecialCharacterClass(uc16 type,
+                                          Label* on_no_match) {
+    return false;
+  }
+  virtual void Fail() = 0;
+  virtual Handle<HeapObject> GetCode(Handle<String> source) = 0;
+  virtual void GoTo(Label* label) = 0;
+  // Check whether a register is >= a given constant and go to a label if it
+  // is.  Backtracks instead if the label is NULL.
+  virtual void IfRegisterGE(int reg, int comparand, Label* if_ge) = 0;
+  // Check whether a register is < a given constant and go to a label if it is.
+  // Backtracks instead if the label is NULL.
+  virtual void IfRegisterLT(int reg, int comparand, Label* if_lt) = 0;
+  // Check whether a register is == to the current position and go to a
+  // label if it is.
+  virtual void IfRegisterEqPos(int reg, Label* if_eq) = 0;
+  virtual IrregexpImplementation Implementation() = 0;
+  virtual void LoadCurrentCharacter(int cp_offset,
+                                    Label* on_end_of_input,
+                                    bool check_bounds = true,
+                                    int characters = 1) = 0;
+  virtual void PopCurrentPosition() = 0;
+  virtual void PopRegister(int register_index) = 0;
+  // Pushes the label on the backtrack stack, so that a following Backtrack
+  // will go to this label. Always checks the backtrack stack limit.
+  virtual void PushBacktrack(Label* label) = 0;
+  virtual void PushCurrentPosition() = 0;
+  virtual void PushRegister(int register_index,
+                            StackCheckFlag check_stack_limit) = 0;
+  virtual void ReadCurrentPositionFromRegister(int reg) = 0;
+  virtual void ReadStackPointerFromRegister(int reg) = 0;
+  virtual void SetCurrentPositionFromEnd(int by) = 0;
+  virtual void SetRegister(int register_index, int to) = 0;
+  // Return whether the matching (with a global regexp) will be restarted.
+  virtual bool Succeed() = 0;
+  virtual void WriteCurrentPositionToRegister(int reg, int cp_offset) = 0;
+  virtual void ClearRegisters(int reg_from, int reg_to) = 0;
+  virtual void WriteStackPointerToRegister(int reg) = 0;
+
+  // Controls the generation of large inlined constants in the code.
+  void set_slow_safe(bool ssc) { slow_safe_compiler_ = ssc; }
+  bool slow_safe() { return slow_safe_compiler_; }
+
+  enum GlobalMode { NOT_GLOBAL, GLOBAL, GLOBAL_NO_ZERO_LENGTH_CHECK };
+  // Set whether the regular expression has the global flag.  Exiting due to
+  // a failure in a global regexp may still mean success overall.
+  inline void set_global_mode(GlobalMode mode) { global_mode_ = mode; }
+  inline bool global() { return global_mode_ != NOT_GLOBAL; }
+  inline bool global_with_zero_length_check() {
+    return global_mode_ == GLOBAL;
+  }
+
+  Zone* zone() const { return zone_; }
+
+ private:
+  bool slow_safe_compiler_;
+  bool global_mode_;
+  Zone* zone_;
+};
+
+// SNIP
+
+}  // namespace dart
+
+#endif  // VM_REGEXP_ASSEMBLER_H_
diff --git a/runtime/vm/regexp_ast.cc b/runtime/vm/regexp_ast.cc
new file mode 100644
index 0000000..c36b890
--- /dev/null
+++ b/runtime/vm/regexp_ast.cc
@@ -0,0 +1,336 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for 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/regexp_ast.h"
+
+// SNIP
+
+namespace dart {
+
+#define MAKE_ACCEPT(Name)                                            \
+  void* RegExp##Name::Accept(RegExpVisitor* visitor, void* data) {   \
+    return visitor->Visit##Name(this, data);                         \
+  }
+FOR_EACH_REG_EXP_TREE_TYPE(MAKE_ACCEPT)
+#undef MAKE_ACCEPT
+
+#define MAKE_TYPE_CASE(Name)                                         \
+  RegExp##Name* RegExpTree::As##Name() {                             \
+    return NULL;                                                     \
+  }                                                                  \
+  bool RegExpTree::Is##Name() { return false; }
+FOR_EACH_REG_EXP_TREE_TYPE(MAKE_TYPE_CASE)
+#undef MAKE_TYPE_CASE
+
+#define MAKE_TYPE_CASE(Name)                                        \
+  RegExp##Name* RegExp##Name::As##Name() {                          \
+    return this;                                                    \
+  }                                                                 \
+  bool RegExp##Name::Is##Name() { return true; }
+FOR_EACH_REG_EXP_TREE_TYPE(MAKE_TYPE_CASE)
+#undef MAKE_TYPE_CASE
+
+
+static Interval ListCaptureRegisters(ZoneList<RegExpTree*>* children) {
+  Interval result = Interval::Empty();
+  for (int i = 0; i < children->length(); i++)
+    result = result.Union(children->at(i)->CaptureRegisters());
+  return result;
+}
+
+
+Interval RegExpAlternative::CaptureRegisters() {
+  return ListCaptureRegisters(nodes());
+}
+
+
+Interval RegExpDisjunction::CaptureRegisters() {
+  return ListCaptureRegisters(alternatives());
+}
+
+
+Interval RegExpLookahead::CaptureRegisters() {
+  return body()->CaptureRegisters();
+}
+
+
+Interval RegExpCapture::CaptureRegisters() {
+  Interval self(StartRegister(index()), EndRegister(index()));
+  return self.Union(body()->CaptureRegisters());
+}
+
+
+Interval RegExpQuantifier::CaptureRegisters() {
+  return body()->CaptureRegisters();
+}
+
+
+bool RegExpAssertion::IsAnchoredAtStart() {
+  return assertion_type() == RegExpAssertion::START_OF_INPUT;
+}
+
+
+bool RegExpAssertion::IsAnchoredAtEnd() {
+  return assertion_type() == RegExpAssertion::END_OF_INPUT;
+}
+
+
+bool RegExpAlternative::IsAnchoredAtStart() {
+  ZoneList<RegExpTree*>* nodes = this->nodes();
+  for (int i = 0; i < nodes->length(); i++) {
+    RegExpTree* node = nodes->at(i);
+    if (node->IsAnchoredAtStart()) { return true; }
+    if (node->max_match() > 0) { return false; }
+  }
+  return false;
+}
+
+
+bool RegExpAlternative::IsAnchoredAtEnd() {
+  ZoneList<RegExpTree*>* nodes = this->nodes();
+  for (int i = nodes->length() - 1; i >= 0; i--) {
+    RegExpTree* node = nodes->at(i);
+    if (node->IsAnchoredAtEnd()) { return true; }
+    if (node->max_match() > 0) { return false; }
+  }
+  return false;
+}
+
+
+bool RegExpDisjunction::IsAnchoredAtStart() {
+  ZoneList<RegExpTree*>* alternatives = this->alternatives();
+  for (int i = 0; i < alternatives->length(); i++) {
+    if (!alternatives->at(i)->IsAnchoredAtStart())
+      return false;
+  }
+  return true;
+}
+
+
+bool RegExpDisjunction::IsAnchoredAtEnd() {
+  ZoneList<RegExpTree*>* alternatives = this->alternatives();
+  for (int i = 0; i < alternatives->length(); i++) {
+    if (!alternatives->at(i)->IsAnchoredAtEnd())
+      return false;
+  }
+  return true;
+}
+
+
+bool RegExpLookahead::IsAnchoredAtStart() {
+  return is_positive() && body()->IsAnchoredAtStart();
+}
+
+
+bool RegExpCapture::IsAnchoredAtStart() {
+  return body()->IsAnchoredAtStart();
+}
+
+
+bool RegExpCapture::IsAnchoredAtEnd() {
+  return body()->IsAnchoredAtEnd();
+}
+
+
+// Convert regular expression trees to a simple sexp representation.
+// This representation should be different from the input grammar
+// in as many cases as possible, to make it more difficult for incorrect
+// parses to look as correct ones which is likely if the input and
+// output formats are alike.
+class RegExpUnparser FINAL : public RegExpVisitor {
+ public:
+  RegExpUnparser(OStream& os, Zone* zone) : os_(os), zone_(zone) {}
+  void VisitCharacterRange(CharacterRange that);
+#define MAKE_CASE(Name) virtual void* Visit##Name(RegExp##Name*,          \
+                                                  void* data) OVERRIDE;
+  FOR_EACH_REG_EXP_TREE_TYPE(MAKE_CASE)
+#undef MAKE_CASE
+ private:
+  OStream& os_;
+  Zone* zone_;
+};
+
+
+void* RegExpUnparser::VisitDisjunction(RegExpDisjunction* that, void* data) {
+  os_ << "(|";
+  for (int i = 0; i <  that->alternatives()->length(); i++) {
+    os_ << " ";
+    that->alternatives()->at(i)->Accept(this, data);
+  }
+  os_ << ")";
+  return NULL;
+}
+
+
+void* RegExpUnparser::VisitAlternative(RegExpAlternative* that, void* data) {
+  os_ << "(:";
+  for (int i = 0; i <  that->nodes()->length(); i++) {
+    os_ << " ";
+    that->nodes()->at(i)->Accept(this, data);
+  }
+  os_ << ")";
+  return NULL;
+}
+
+
+void RegExpUnparser::VisitCharacterRange(CharacterRange that) {
+  os_ << AsUC16(that.from());
+  if (!that.IsSingleton()) {
+    os_ << "-" << AsUC16(that.to());
+  }
+}
+
+
+
+void* RegExpUnparser::VisitCharacterClass(RegExpCharacterClass* that,
+                                          void* data) {
+  if (that->is_negated()) os_ << "^";
+  os_ << "[";
+  for (int i = 0; i < that->ranges(zone_)->length(); i++) {
+    if (i > 0) os_ << " ";
+    VisitCharacterRange(that->ranges(zone_)->at(i));
+  }
+  os_ << "]";
+  return NULL;
+}
+
+
+void* RegExpUnparser::VisitAssertion(RegExpAssertion* that, void* data) {
+  switch (that->assertion_type()) {
+    case RegExpAssertion::START_OF_INPUT:
+      os_ << "@^i";
+      break;
+    case RegExpAssertion::END_OF_INPUT:
+      os_ << "@$i";
+      break;
+    case RegExpAssertion::START_OF_LINE:
+      os_ << "@^l";
+      break;
+    case RegExpAssertion::END_OF_LINE:
+      os_ << "@$l";
+       break;
+    case RegExpAssertion::BOUNDARY:
+      os_ << "@b";
+      break;
+    case RegExpAssertion::NON_BOUNDARY:
+      os_ << "@B";
+      break;
+  }
+  return NULL;
+}
+
+
+void* RegExpUnparser::VisitAtom(RegExpAtom* that, void* data) {
+  os_ << "'";
+  Vector<const uc16> chardata = that->data();
+  for (int i = 0; i < chardata.length(); i++) {
+    os_ << AsUC16(chardata[i]);
+  }
+  os_ << "'";
+  return NULL;
+}
+
+
+void* RegExpUnparser::VisitText(RegExpText* that, void* data) {
+  if (that->elements()->length() == 1) {
+    that->elements()->at(0).tree()->Accept(this, data);
+  } else {
+    os_ << "(!";
+    for (int i = 0; i < that->elements()->length(); i++) {
+      os_ << " ";
+      that->elements()->at(i).tree()->Accept(this, data);
+    }
+    os_ << ")";
+  }
+  return NULL;
+}
+
+
+void* RegExpUnparser::VisitQuantifier(RegExpQuantifier* that, void* data) {
+  os_ << "(# " << that->min() << " ";
+  if (that->max() == RegExpTree::kInfinity) {
+    os_ << "- ";
+  } else {
+    os_ << that->max() << " ";
+  }
+  os_ << (that->is_greedy() ? "g " : that->is_possessive() ? "p " : "n ");
+  that->body()->Accept(this, data);
+  os_ << ")";
+  return NULL;
+}
+
+
+void* RegExpUnparser::VisitCapture(RegExpCapture* that, void* data) {
+  os_ << "(^ ";
+  that->body()->Accept(this, data);
+  os_ << ")";
+  return NULL;
+}
+
+
+void* RegExpUnparser::VisitLookahead(RegExpLookahead* that, void* data) {
+  os_ << "(-> " << (that->is_positive() ? "+ " : "- ");
+  that->body()->Accept(this, data);
+  os_ << ")";
+  return NULL;
+}
+
+
+void* RegExpUnparser::VisitBackReference(RegExpBackReference* that,
+                                         void* data) {
+  os_ << "(<- " << that->index() << ")";
+  return NULL;
+}
+
+
+void* RegExpUnparser::VisitEmpty(RegExpEmpty* that, void* data) {
+  os_ << '%';
+  return NULL;
+}
+
+
+OStream& RegExpTree::Print(OStream& os, Zone* zone) {  // NOLINT
+  RegExpUnparser unparser(os, zone);
+  Accept(&unparser, NULL);
+  return os;
+}
+
+
+RegExpDisjunction::RegExpDisjunction(ZoneList<RegExpTree*>* alternatives)
+    : alternatives_(alternatives) {
+  DCHECK(alternatives->length() > 1);
+  RegExpTree* first_alternative = alternatives->at(0);
+  min_match_ = first_alternative->min_match();
+  max_match_ = first_alternative->max_match();
+  for (int i = 1; i < alternatives->length(); i++) {
+    RegExpTree* alternative = alternatives->at(i);
+    min_match_ = Min(min_match_, alternative->min_match());
+    max_match_ = Max(max_match_, alternative->max_match());
+  }
+}
+
+
+static int IncreaseBy(int previous, int increase) {
+  if (RegExpTree::kInfinity - previous < increase) {
+    return RegExpTree::kInfinity;
+  } else {
+    return previous + increase;
+  }
+}
+
+RegExpAlternative::RegExpAlternative(ZoneList<RegExpTree*>* nodes)
+    : nodes_(nodes) {
+  DCHECK(nodes->length() > 1);
+  min_match_ = 0;
+  max_match_ = 0;
+  for (int i = 0; i < nodes->length(); i++) {
+    RegExpTree* node = nodes->at(i);
+    int node_min_match = node->min_match();
+    min_match_ = IncreaseBy(min_match_, node_min_match);
+    int node_max_match = node->max_match();
+    max_match_ = IncreaseBy(max_match_, node_max_match);
+  }
+}
+
+}  // namespace dart
diff --git a/runtime/vm/regexp_ast.h b/runtime/vm/regexp_ast.h
new file mode 100644
index 0000000..e0d68c9
--- /dev/null
+++ b/runtime/vm/regexp_ast.h
@@ -0,0 +1,386 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+#ifndef VM_REGEXP_AST_H_
+#define VM_REGEXP_AST_H_
+
+// SNIP
+
+namespace dart {
+
+// SNIP
+
+class RegExpAlternative;
+class RegExpAssertion;
+class RegExpAtom;
+class RegExpBackReference;
+class RegExpCapture;
+class RegExpCharacterClass;
+class RegExpCompiler;
+class RegExpDisjunction;
+class RegExpEmpty;
+class RegExpLookahead;
+class RegExpQuantifier;
+class RegExpText;
+
+// SNIP
+
+class RegExpVisitor BASE_EMBEDDED {
+ public:
+  virtual ~RegExpVisitor() { }
+#define MAKE_CASE(Name)                                              \
+  virtual void* Visit##Name(RegExp##Name*, void* data) = 0;
+  FOR_EACH_REG_EXP_TREE_TYPE(MAKE_CASE)
+#undef MAKE_CASE
+};
+
+
+class RegExpTree : public ZoneObject {
+ public:
+  static const int kInfinity = kMaxInt;
+  virtual ~RegExpTree() {}
+  virtual void* Accept(RegExpVisitor* visitor, void* data) = 0;
+  virtual RegExpNode* ToNode(RegExpCompiler* compiler,
+                             RegExpNode* on_success) = 0;
+  virtual bool IsTextElement() { return false; }
+  virtual bool IsAnchoredAtStart() { return false; }
+  virtual bool IsAnchoredAtEnd() { return false; }
+  virtual int min_match() = 0;
+  virtual int max_match() = 0;
+  // Returns the interval of registers used for captures within this
+  // expression.
+  virtual Interval CaptureRegisters() { return Interval::Empty(); }
+  virtual void AppendToText(RegExpText* text, Zone* zone);
+  OStream& Print(OStream& os, Zone* zone);  // NOLINT
+#define MAKE_ASTYPE(Name)                                                  \
+  virtual RegExp##Name* As##Name();                                        \
+  virtual bool Is##Name();
+  FOR_EACH_REG_EXP_TREE_TYPE(MAKE_ASTYPE)
+#undef MAKE_ASTYPE
+};
+
+
+class RegExpDisjunction FINAL : public RegExpTree {
+ public:
+  explicit RegExpDisjunction(ZoneList<RegExpTree*>* alternatives);
+  virtual void* Accept(RegExpVisitor* visitor, void* data) OVERRIDE;
+  virtual RegExpNode* ToNode(RegExpCompiler* compiler,
+                             RegExpNode* on_success) OVERRIDE;
+  virtual RegExpDisjunction* AsDisjunction() OVERRIDE;
+  virtual Interval CaptureRegisters() OVERRIDE;
+  virtual bool IsDisjunction() OVERRIDE;
+  virtual bool IsAnchoredAtStart() OVERRIDE;
+  virtual bool IsAnchoredAtEnd() OVERRIDE;
+  virtual int min_match() OVERRIDE { return min_match_; }
+  virtual int max_match() OVERRIDE { return max_match_; }
+  ZoneList<RegExpTree*>* alternatives() { return alternatives_; }
+ private:
+  ZoneList<RegExpTree*>* alternatives_;
+  int min_match_;
+  int max_match_;
+};
+
+
+class RegExpAlternative FINAL : public RegExpTree {
+ public:
+  explicit RegExpAlternative(ZoneList<RegExpTree*>* nodes);
+  virtual void* Accept(RegExpVisitor* visitor, void* data) OVERRIDE;
+  virtual RegExpNode* ToNode(RegExpCompiler* compiler,
+                             RegExpNode* on_success) OVERRIDE;
+  virtual RegExpAlternative* AsAlternative() OVERRIDE;
+  virtual Interval CaptureRegisters() OVERRIDE;
+  virtual bool IsAlternative() OVERRIDE;
+  virtual bool IsAnchoredAtStart() OVERRIDE;
+  virtual bool IsAnchoredAtEnd() OVERRIDE;
+  virtual int min_match() OVERRIDE { return min_match_; }
+  virtual int max_match() OVERRIDE { return max_match_; }
+  ZoneList<RegExpTree*>* nodes() { return nodes_; }
+ private:
+  ZoneList<RegExpTree*>* nodes_;
+  int min_match_;
+  int max_match_;
+};
+
+
+class RegExpAssertion FINAL : public RegExpTree {
+ public:
+  enum AssertionType {
+    START_OF_LINE,
+    START_OF_INPUT,
+    END_OF_LINE,
+    END_OF_INPUT,
+    BOUNDARY,
+    NON_BOUNDARY
+  };
+  explicit RegExpAssertion(AssertionType type) : assertion_type_(type) { }
+  virtual void* Accept(RegExpVisitor* visitor, void* data) OVERRIDE;
+  virtual RegExpNode* ToNode(RegExpCompiler* compiler,
+                             RegExpNode* on_success) OVERRIDE;
+  virtual RegExpAssertion* AsAssertion() OVERRIDE;
+  virtual bool IsAssertion() OVERRIDE;
+  virtual bool IsAnchoredAtStart() OVERRIDE;
+  virtual bool IsAnchoredAtEnd() OVERRIDE;
+  virtual int min_match() OVERRIDE { return 0; }
+  virtual int max_match() OVERRIDE { return 0; }
+  AssertionType assertion_type() { return assertion_type_; }
+ private:
+  AssertionType assertion_type_;
+};
+
+
+class CharacterSet FINAL BASE_EMBEDDED {
+ public:
+  explicit CharacterSet(uc16 standard_set_type)
+      : ranges_(NULL),
+        standard_set_type_(standard_set_type) {}
+  explicit CharacterSet(ZoneList<CharacterRange>* ranges)
+      : ranges_(ranges),
+        standard_set_type_(0) {}
+  ZoneList<CharacterRange>* ranges(Zone* zone);
+  uc16 standard_set_type() { return standard_set_type_; }
+  void set_standard_set_type(uc16 special_set_type) {
+    standard_set_type_ = special_set_type;
+  }
+  bool is_standard() { return standard_set_type_ != 0; }
+  void Canonicalize();
+ private:
+  ZoneList<CharacterRange>* ranges_;
+  // If non-zero, the value represents a standard set (e.g., all whitespace
+  // characters) without having to expand the ranges.
+  uc16 standard_set_type_;
+};
+
+
+class RegExpCharacterClass FINAL : public RegExpTree {
+ public:
+  RegExpCharacterClass(ZoneList<CharacterRange>* ranges, bool is_negated)
+      : set_(ranges),
+        is_negated_(is_negated) { }
+  explicit RegExpCharacterClass(uc16 type)
+      : set_(type),
+        is_negated_(false) { }
+  virtual void* Accept(RegExpVisitor* visitor, void* data) OVERRIDE;
+  virtual RegExpNode* ToNode(RegExpCompiler* compiler,
+                             RegExpNode* on_success) OVERRIDE;
+  virtual RegExpCharacterClass* AsCharacterClass() OVERRIDE;
+  virtual bool IsCharacterClass() OVERRIDE;
+  virtual bool IsTextElement() OVERRIDE { return true; }
+  virtual int min_match() OVERRIDE { return 1; }
+  virtual int max_match() OVERRIDE { return 1; }
+  virtual void AppendToText(RegExpText* text, Zone* zone) OVERRIDE;
+  CharacterSet character_set() { return set_; }
+  // TODO(lrn): Remove need for complex version if is_standard that
+  // recognizes a mangled standard set and just do { return set_.is_special(); }
+  bool is_standard(Zone* zone);
+  // Returns a value representing the standard character set if is_standard()
+  // returns true.
+  // Currently used values are:
+  // s : unicode whitespace
+  // S : unicode non-whitespace
+  // w : ASCII word character (digit, letter, underscore)
+  // W : non-ASCII word character
+  // d : ASCII digit
+  // D : non-ASCII digit
+  // . : non-unicode non-newline
+  // * : All characters
+  uc16 standard_type() { return set_.standard_set_type(); }
+  ZoneList<CharacterRange>* ranges(Zone* zone) { return set_.ranges(zone); }
+  bool is_negated() { return is_negated_; }
+
+ private:
+  CharacterSet set_;
+  bool is_negated_;
+};
+
+
+class RegExpAtom FINAL : public RegExpTree {
+ public:
+  explicit RegExpAtom(Vector<const uc16> data) : data_(data) { }
+  virtual void* Accept(RegExpVisitor* visitor, void* data) OVERRIDE;
+  virtual RegExpNode* ToNode(RegExpCompiler* compiler,
+                             RegExpNode* on_success) OVERRIDE;
+  virtual RegExpAtom* AsAtom() OVERRIDE;
+  virtual bool IsAtom() OVERRIDE;
+  virtual bool IsTextElement() OVERRIDE { return true; }
+  virtual int min_match() OVERRIDE { return data_.length(); }
+  virtual int max_match() OVERRIDE { return data_.length(); }
+  virtual void AppendToText(RegExpText* text, Zone* zone) OVERRIDE;
+  Vector<const uc16> data() { return data_; }
+  int length() { return data_.length(); }
+ private:
+  Vector<const uc16> data_;
+};
+
+
+class RegExpText FINAL : public RegExpTree {
+ public:
+  explicit RegExpText(Zone* zone) : elements_(2, zone), length_(0) {}
+  virtual void* Accept(RegExpVisitor* visitor, void* data) OVERRIDE;
+  virtual RegExpNode* ToNode(RegExpCompiler* compiler,
+                             RegExpNode* on_success) OVERRIDE;
+  virtual RegExpText* AsText() OVERRIDE;
+  virtual bool IsText() OVERRIDE;
+  virtual bool IsTextElement() OVERRIDE { return true; }
+  virtual int min_match() OVERRIDE { return length_; }
+  virtual int max_match() OVERRIDE { return length_; }
+  virtual void AppendToText(RegExpText* text, Zone* zone) OVERRIDE;
+  void AddElement(TextElement elm, Zone* zone)  {
+    elements_.Add(elm, zone);
+    length_ += elm.length();
+  }
+  ZoneList<TextElement>* elements() { return &elements_; }
+ private:
+  ZoneList<TextElement> elements_;
+  int length_;
+};
+
+
+class RegExpQuantifier FINAL : public RegExpTree {
+ public:
+  enum QuantifierType { GREEDY, NON_GREEDY, POSSESSIVE };
+  RegExpQuantifier(int min, int max, QuantifierType type, RegExpTree* body)
+      : body_(body),
+        min_(min),
+        max_(max),
+        min_match_(min * body->min_match()),
+        quantifier_type_(type) {
+    if (max > 0 && body->max_match() > kInfinity / max) {
+      max_match_ = kInfinity;
+    } else {
+      max_match_ = max * body->max_match();
+    }
+  }
+  virtual void* Accept(RegExpVisitor* visitor, void* data) OVERRIDE;
+  virtual RegExpNode* ToNode(RegExpCompiler* compiler,
+                             RegExpNode* on_success) OVERRIDE;
+  static RegExpNode* ToNode(int min,
+                            int max,
+                            bool is_greedy,
+                            RegExpTree* body,
+                            RegExpCompiler* compiler,
+                            RegExpNode* on_success,
+                            bool not_at_start = false);
+  virtual RegExpQuantifier* AsQuantifier() OVERRIDE;
+  virtual Interval CaptureRegisters() OVERRIDE;
+  virtual bool IsQuantifier() OVERRIDE;
+  virtual int min_match() OVERRIDE { return min_match_; }
+  virtual int max_match() OVERRIDE { return max_match_; }
+  int min() { return min_; }
+  int max() { return max_; }
+  bool is_possessive() { return quantifier_type_ == POSSESSIVE; }
+  bool is_non_greedy() { return quantifier_type_ == NON_GREEDY; }
+  bool is_greedy() { return quantifier_type_ == GREEDY; }
+  RegExpTree* body() { return body_; }
+
+ private:
+  RegExpTree* body_;
+  int min_;
+  int max_;
+  int min_match_;
+  int max_match_;
+  QuantifierType quantifier_type_;
+};
+
+
+class RegExpCapture FINAL : public RegExpTree {
+ public:
+  explicit RegExpCapture(RegExpTree* body, int index)
+      : body_(body), index_(index) { }
+  virtual void* Accept(RegExpVisitor* visitor, void* data) OVERRIDE;
+  virtual RegExpNode* ToNode(RegExpCompiler* compiler,
+                             RegExpNode* on_success) OVERRIDE;
+  static RegExpNode* ToNode(RegExpTree* body,
+                            int index,
+                            RegExpCompiler* compiler,
+                            RegExpNode* on_success);
+  virtual RegExpCapture* AsCapture() OVERRIDE;
+  virtual bool IsAnchoredAtStart() OVERRIDE;
+  virtual bool IsAnchoredAtEnd() OVERRIDE;
+  virtual Interval CaptureRegisters() OVERRIDE;
+  virtual bool IsCapture() OVERRIDE;
+  virtual int min_match() OVERRIDE { return body_->min_match(); }
+  virtual int max_match() OVERRIDE { return body_->max_match(); }
+  RegExpTree* body() { return body_; }
+  int index() { return index_; }
+  static int StartRegister(int index) { return index * 2; }
+  static int EndRegister(int index) { return index * 2 + 1; }
+
+ private:
+  RegExpTree* body_;
+  int index_;
+};
+
+
+class RegExpLookahead FINAL : public RegExpTree {
+ public:
+  RegExpLookahead(RegExpTree* body,
+                  bool is_positive,
+                  int capture_count,
+                  int capture_from)
+      : body_(body),
+        is_positive_(is_positive),
+        capture_count_(capture_count),
+        capture_from_(capture_from) { }
+
+  virtual void* Accept(RegExpVisitor* visitor, void* data) OVERRIDE;
+  virtual RegExpNode* ToNode(RegExpCompiler* compiler,
+                             RegExpNode* on_success) OVERRIDE;
+  virtual RegExpLookahead* AsLookahead() OVERRIDE;
+  virtual Interval CaptureRegisters() OVERRIDE;
+  virtual bool IsLookahead() OVERRIDE;
+  virtual bool IsAnchoredAtStart() OVERRIDE;
+  virtual int min_match() OVERRIDE { return 0; }
+  virtual int max_match() OVERRIDE { return 0; }
+  RegExpTree* body() { return body_; }
+  bool is_positive() { return is_positive_; }
+  int capture_count() { return capture_count_; }
+  int capture_from() { return capture_from_; }
+
+ private:
+  RegExpTree* body_;
+  bool is_positive_;
+  int capture_count_;
+  int capture_from_;
+};
+
+
+class RegExpBackReference FINAL : public RegExpTree {
+ public:
+  explicit RegExpBackReference(RegExpCapture* capture)
+      : capture_(capture) { }
+  virtual void* Accept(RegExpVisitor* visitor, void* data) OVERRIDE;
+  virtual RegExpNode* ToNode(RegExpCompiler* compiler,
+                             RegExpNode* on_success) OVERRIDE;
+  virtual RegExpBackReference* AsBackReference() OVERRIDE;
+  virtual bool IsBackReference() OVERRIDE;
+  virtual int min_match() OVERRIDE { return 0; }
+  virtual int max_match() OVERRIDE { return capture_->max_match(); }
+  int index() { return capture_->index(); }
+  RegExpCapture* capture() { return capture_; }
+ private:
+  RegExpCapture* capture_;
+};
+
+
+class RegExpEmpty FINAL : public RegExpTree {
+ public:
+  RegExpEmpty() { }
+  virtual void* Accept(RegExpVisitor* visitor, void* data) OVERRIDE;
+  virtual RegExpNode* ToNode(RegExpCompiler* compiler,
+                             RegExpNode* on_success) OVERRIDE;
+  virtual RegExpEmpty* AsEmpty() OVERRIDE;
+  virtual bool IsEmpty() OVERRIDE;
+  virtual int min_match() OVERRIDE { return 0; }
+  virtual int max_match() OVERRIDE { return 0; }
+  static RegExpEmpty* GetInstance() {
+    static RegExpEmpty* instance = ::new RegExpEmpty();
+    return instance;
+  }
+};
+
+// SNIP
+
+}  // namespace dart
+
+#endif  // VM_REGEXP_AST_H_
diff --git a/runtime/vm/regexp_parser.cc b/runtime/vm/regexp_parser.cc
new file mode 100644
index 0000000..72e8d7f
--- /dev/null
+++ b/runtime/vm/regexp_parser.cc
@@ -0,0 +1,1003 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for 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/regexp_parser.h"
+
+// SNIP
+
+namespace dart {
+
+RegExpBuilder::RegExpBuilder(Zone* zone)
+    : zone_(zone),
+      pending_empty_(false),
+      characters_(NULL),
+      terms_(),
+      alternatives_()
+#ifdef DEBUG
+    , last_added_(ADD_NONE)
+#endif
+  {}
+
+
+void RegExpBuilder::FlushCharacters() {
+  pending_empty_ = false;
+  if (characters_ != NULL) {
+    RegExpTree* atom = new(zone()) RegExpAtom(characters_->ToConstVector());
+    characters_ = NULL;
+    text_.Add(atom, zone());
+    LAST(ADD_ATOM);
+  }
+}
+
+
+void RegExpBuilder::FlushText() {
+  FlushCharacters();
+  int num_text = text_.length();
+  if (num_text == 0) {
+    return;
+  } else if (num_text == 1) {
+    terms_.Add(text_.last(), zone());
+  } else {
+    RegExpText* text = new(zone()) RegExpText(zone());
+    for (int i = 0; i < num_text; i++)
+      text_.Get(i)->AppendToText(text, zone());
+    terms_.Add(text, zone());
+  }
+  text_.Clear();
+}
+
+
+void RegExpBuilder::AddCharacter(uc16 c) {
+  pending_empty_ = false;
+  if (characters_ == NULL) {
+    characters_ = new(zone()) ZoneList<uc16>(4, zone());
+  }
+  characters_->Add(c, zone());
+  LAST(ADD_CHAR);
+}
+
+
+void RegExpBuilder::AddEmpty() {
+  pending_empty_ = true;
+}
+
+
+void RegExpBuilder::AddAtom(RegExpTree* term) {
+  if (term->IsEmpty()) {
+    AddEmpty();
+    return;
+  }
+  if (term->IsTextElement()) {
+    FlushCharacters();
+    text_.Add(term, zone());
+  } else {
+    FlushText();
+    terms_.Add(term, zone());
+  }
+  LAST(ADD_ATOM);
+}
+
+
+void RegExpBuilder::AddAssertion(RegExpTree* assert) {
+  FlushText();
+  terms_.Add(assert, zone());
+  LAST(ADD_ASSERT);
+}
+
+
+void RegExpBuilder::NewAlternative() {
+  FlushTerms();
+}
+
+
+void RegExpBuilder::FlushTerms() {
+  FlushText();
+  int num_terms = terms_.length();
+  RegExpTree* alternative;
+  if (num_terms == 0) {
+    alternative = RegExpEmpty::GetInstance();
+  } else if (num_terms == 1) {
+    alternative = terms_.last();
+  } else {
+    alternative = new(zone()) RegExpAlternative(terms_.GetList(zone()));
+  }
+  alternatives_.Add(alternative, zone());
+  terms_.Clear();
+  LAST(ADD_NONE);
+}
+
+
+RegExpTree* RegExpBuilder::ToRegExp() {
+  FlushTerms();
+  int num_alternatives = alternatives_.length();
+  if (num_alternatives == 0) {
+    return RegExpEmpty::GetInstance();
+  }
+  if (num_alternatives == 1) {
+    return alternatives_.last();
+  }
+  return new(zone()) RegExpDisjunction(alternatives_.GetList(zone()));
+}
+
+
+void RegExpBuilder::AddQuantifierToAtom(
+    int min, int max, RegExpQuantifier::QuantifierType quantifier_type) {
+  if (pending_empty_) {
+    pending_empty_ = false;
+    return;
+  }
+  RegExpTree* atom;
+  if (characters_ != NULL) {
+    DCHECK(last_added_ == ADD_CHAR);
+    // Last atom was character.
+    Vector<const uc16> char_vector = characters_->ToConstVector();
+    int num_chars = char_vector.length();
+    if (num_chars > 1) {
+      Vector<const uc16> prefix = char_vector.SubVector(0, num_chars - 1);
+      text_.Add(new(zone()) RegExpAtom(prefix), zone());
+      char_vector = char_vector.SubVector(num_chars - 1, num_chars);
+    }
+    characters_ = NULL;
+    atom = new(zone()) RegExpAtom(char_vector);
+    FlushText();
+  } else if (text_.length() > 0) {
+    DCHECK(last_added_ == ADD_ATOM);
+    atom = text_.RemoveLast();
+    FlushText();
+  } else if (terms_.length() > 0) {
+    DCHECK(last_added_ == ADD_ATOM);
+    atom = terms_.RemoveLast();
+    if (atom->max_match() == 0) {
+      // Guaranteed to only match an empty string.
+      LAST(ADD_TERM);
+      if (min == 0) {
+        return;
+      }
+      terms_.Add(atom, zone());
+      return;
+    }
+  } else {
+    // Only call immediately after adding an atom or character!
+    UNREACHABLE();
+    return;
+  }
+  terms_.Add(
+      new(zone()) RegExpQuantifier(min, max, quantifier_type, atom), zone());
+  LAST(ADD_TERM);
+}
+
+// SNIP
+
+// ----------------------------------------------------------------------------
+// Regular expressions
+
+RegExpParser::RegExpParser(FlatStringReader* in,
+                           Handle<String>* error,
+                           bool multiline,
+                           Zone* zone)
+    : isolate_(zone->isolate()),
+      zone_(zone),
+      error_(error),
+      captures_(NULL),
+      in_(in),
+      current_(kEndMarker),
+      next_pos_(0),
+      capture_count_(0),
+      has_more_(true),
+      multiline_(multiline),
+      simple_(false),
+      contains_anchor_(false),
+      is_scanned_for_captures_(false),
+      failed_(false) {
+  Advance();
+}
+
+
+uc32 RegExpParser::Next() {
+  if (has_next()) {
+    return in()->Get(next_pos_);
+  } else {
+    return kEndMarker;
+  }
+}
+
+
+void RegExpParser::Advance() {
+  if (next_pos_ < in()->length()) {
+    StackLimitCheck check(isolate());
+    if (check.HasOverflowed()) {
+      ReportError(CStrVector(Isolate::kStackOverflowMessage));
+    } else if (zone()->excess_allocation()) {
+      ReportError(CStrVector("Regular expression too large"));
+    } else {
+      current_ = in()->Get(next_pos_);
+      next_pos_++;
+    }
+  } else {
+    current_ = kEndMarker;
+    has_more_ = false;
+  }
+}
+
+
+void RegExpParser::Reset(int pos) {
+  next_pos_ = pos;
+  has_more_ = (pos < in()->length());
+  Advance();
+}
+
+
+void RegExpParser::Advance(int dist) {
+  next_pos_ += dist - 1;
+  Advance();
+}
+
+
+bool RegExpParser::simple() {
+  return simple_;
+}
+
+
+RegExpTree* RegExpParser::ReportError(Vector<const char> message) {
+  failed_ = true;
+  *error_ = isolate()->factory()->NewStringFromAscii(message).ToHandleChecked();
+  // Zip to the end to make sure the no more input is read.
+  current_ = kEndMarker;
+  next_pos_ = in()->length();
+  return NULL;
+}
+
+
+// Pattern ::
+//   Disjunction
+RegExpTree* RegExpParser::ParsePattern() {
+  RegExpTree* result = ParseDisjunction(CHECK_FAILED);
+  DCHECK(!has_more());
+  // If the result of parsing is a literal string atom, and it has the
+  // same length as the input, then the atom is identical to the input.
+  if (result->IsAtom() && result->AsAtom()->length() == in()->length()) {
+    simple_ = true;
+  }
+  return result;
+}
+
+
+// Disjunction ::
+//   Alternative
+//   Alternative | Disjunction
+// Alternative ::
+//   [empty]
+//   Term Alternative
+// Term ::
+//   Assertion
+//   Atom
+//   Atom Quantifier
+RegExpTree* RegExpParser::ParseDisjunction() {
+  // Used to store current state while parsing subexpressions.
+  RegExpParserState initial_state(NULL, INITIAL, 0, zone());
+  RegExpParserState* stored_state = &initial_state;
+  // Cache the builder in a local variable for quick access.
+  RegExpBuilder* builder = initial_state.builder();
+  while (true) {
+    switch (current()) {
+    case kEndMarker:
+      if (stored_state->IsSubexpression()) {
+        // Inside a parenthesized group when hitting end of input.
+        ReportError(CStrVector("Unterminated group") CHECK_FAILED);
+      }
+      DCHECK_EQ(INITIAL, stored_state->group_type());
+      // Parsing completed successfully.
+      return builder->ToRegExp();
+    case ')': {
+      if (!stored_state->IsSubexpression()) {
+        ReportError(CStrVector("Unmatched ')'") CHECK_FAILED);
+      }
+      DCHECK_NE(INITIAL, stored_state->group_type());
+
+      Advance();
+      // End disjunction parsing and convert builder content to new single
+      // regexp atom.
+      RegExpTree* body = builder->ToRegExp();
+
+      int end_capture_index = captures_started();
+
+      int capture_index = stored_state->capture_index();
+      SubexpressionType group_type = stored_state->group_type();
+
+      // Restore previous state.
+      stored_state = stored_state->previous_state();
+      builder = stored_state->builder();
+
+      // Build result of subexpression.
+      if (group_type == CAPTURE) {
+        RegExpCapture* capture = new(zone()) RegExpCapture(body, capture_index);
+        captures_->at(capture_index - 1) = capture;
+        body = capture;
+      } else if (group_type != GROUPING) {
+        DCHECK(group_type == POSITIVE_LOOKAHEAD ||
+               group_type == NEGATIVE_LOOKAHEAD);
+        bool is_positive = (group_type == POSITIVE_LOOKAHEAD);
+        body = new(zone()) RegExpLookahead(body,
+                                   is_positive,
+                                   end_capture_index - capture_index,
+                                   capture_index);
+      }
+      builder->AddAtom(body);
+      // For compatability with JSC and ES3, we allow quantifiers after
+      // lookaheads, and break in all cases.
+      break;
+    }
+    case '|': {
+      Advance();
+      builder->NewAlternative();
+      continue;
+    }
+    case '*':
+    case '+':
+    case '?':
+      return ReportError(CStrVector("Nothing to repeat"));
+    case '^': {
+      Advance();
+      if (multiline_) {
+        builder->AddAssertion(
+            new(zone()) RegExpAssertion(RegExpAssertion::START_OF_LINE));
+      } else {
+        builder->AddAssertion(
+            new(zone()) RegExpAssertion(RegExpAssertion::START_OF_INPUT));
+        set_contains_anchor();
+      }
+      continue;
+    }
+    case '$': {
+      Advance();
+      RegExpAssertion::AssertionType assertion_type =
+          multiline_ ? RegExpAssertion::END_OF_LINE :
+                       RegExpAssertion::END_OF_INPUT;
+      builder->AddAssertion(new(zone()) RegExpAssertion(assertion_type));
+      continue;
+    }
+    case '.': {
+      Advance();
+      // everything except \x0a, \x0d, \u2028 and \u2029
+      ZoneList<CharacterRange>* ranges =
+          new(zone()) ZoneList<CharacterRange>(2, zone());
+      CharacterRange::AddClassEscape('.', ranges, zone());
+      RegExpTree* atom = new(zone()) RegExpCharacterClass(ranges, false);
+      builder->AddAtom(atom);
+      break;
+    }
+    case '(': {
+      SubexpressionType subexpr_type = CAPTURE;
+      Advance();
+      if (current() == '?') {
+        switch (Next()) {
+          case ':':
+            subexpr_type = GROUPING;
+            break;
+          case '=':
+            subexpr_type = POSITIVE_LOOKAHEAD;
+            break;
+          case '!':
+            subexpr_type = NEGATIVE_LOOKAHEAD;
+            break;
+          default:
+            ReportError(CStrVector("Invalid group") CHECK_FAILED);
+            break;
+        }
+        Advance(2);
+      } else {
+        if (captures_ == NULL) {
+          captures_ = new(zone()) ZoneList<RegExpCapture*>(2, zone());
+        }
+        if (captures_started() >= kMaxCaptures) {
+          ReportError(CStrVector("Too many captures") CHECK_FAILED);
+        }
+        captures_->Add(NULL, zone());
+      }
+      // Store current state and begin new disjunction parsing.
+      stored_state = new(zone()) RegExpParserState(stored_state, subexpr_type,
+                                                   captures_started(), zone());
+      builder = stored_state->builder();
+      continue;
+    }
+    case '[': {
+      RegExpTree* atom = ParseCharacterClass(CHECK_FAILED);
+      builder->AddAtom(atom);
+      break;
+    }
+    // Atom ::
+    //   \ AtomEscape
+    case '\\':
+      switch (Next()) {
+      case kEndMarker:
+        return ReportError(CStrVector("\\ at end of pattern"));
+      case 'b':
+        Advance(2);
+        builder->AddAssertion(
+            new(zone()) RegExpAssertion(RegExpAssertion::BOUNDARY));
+        continue;
+      case 'B':
+        Advance(2);
+        builder->AddAssertion(
+            new(zone()) RegExpAssertion(RegExpAssertion::NON_BOUNDARY));
+        continue;
+      // AtomEscape ::
+      //   CharacterClassEscape
+      //
+      // CharacterClassEscape :: one of
+      //   d D s S w W
+      case 'd': case 'D': case 's': case 'S': case 'w': case 'W': {
+        uc32 c = Next();
+        Advance(2);
+        ZoneList<CharacterRange>* ranges =
+            new(zone()) ZoneList<CharacterRange>(2, zone());
+        CharacterRange::AddClassEscape(c, ranges, zone());
+        RegExpTree* atom = new(zone()) RegExpCharacterClass(ranges, false);
+        builder->AddAtom(atom);
+        break;
+      }
+      case '1': case '2': case '3': case '4': case '5': case '6':
+      case '7': case '8': case '9': {
+        int index = 0;
+        if (ParseBackReferenceIndex(&index)) {
+          RegExpCapture* capture = NULL;
+          if (captures_ != NULL && index <= captures_->length()) {
+            capture = captures_->at(index - 1);
+          }
+          if (capture == NULL) {
+            builder->AddEmpty();
+            break;
+          }
+          RegExpTree* atom = new(zone()) RegExpBackReference(capture);
+          builder->AddAtom(atom);
+          break;
+        }
+        uc32 first_digit = Next();
+        if (first_digit == '8' || first_digit == '9') {
+          // Treat as identity escape
+          builder->AddCharacter(first_digit);
+          Advance(2);
+          break;
+        }
+      }
+      // FALLTHROUGH
+      case '0': {
+        Advance();
+        uc32 octal = ParseOctalLiteral();
+        builder->AddCharacter(octal);
+        break;
+      }
+      // ControlEscape :: one of
+      //   f n r t v
+      case 'f':
+        Advance(2);
+        builder->AddCharacter('\f');
+        break;
+      case 'n':
+        Advance(2);
+        builder->AddCharacter('\n');
+        break;
+      case 'r':
+        Advance(2);
+        builder->AddCharacter('\r');
+        break;
+      case 't':
+        Advance(2);
+        builder->AddCharacter('\t');
+        break;
+      case 'v':
+        Advance(2);
+        builder->AddCharacter('\v');
+        break;
+      case 'c': {
+        Advance();
+        uc32 controlLetter = Next();
+        // Special case if it is an ASCII letter.
+        // Convert lower case letters to uppercase.
+        uc32 letter = controlLetter & ~('a' ^ 'A');
+        if (letter < 'A' || 'Z' < letter) {
+          // controlLetter is not in range 'A'-'Z' or 'a'-'z'.
+          // This is outside the specification. We match JSC in
+          // reading the backslash as a literal character instead
+          // of as starting an escape.
+          builder->AddCharacter('\\');
+        } else {
+          Advance(2);
+          builder->AddCharacter(controlLetter & 0x1f);
+        }
+        break;
+      }
+      case 'x': {
+        Advance(2);
+        uc32 value;
+        if (ParseHexEscape(2, &value)) {
+          builder->AddCharacter(value);
+        } else {
+          builder->AddCharacter('x');
+        }
+        break;
+      }
+      case 'u': {
+        Advance(2);
+        uc32 value;
+        if (ParseHexEscape(4, &value)) {
+          builder->AddCharacter(value);
+        } else {
+          builder->AddCharacter('u');
+        }
+        break;
+      }
+      default:
+        // Identity escape.
+        builder->AddCharacter(Next());
+        Advance(2);
+        break;
+      }
+      break;
+    case '{': {
+      int dummy;
+      if (ParseIntervalQuantifier(&dummy, &dummy)) {
+        ReportError(CStrVector("Nothing to repeat") CHECK_FAILED);
+      }
+      // fallthrough
+    }
+    default:
+      builder->AddCharacter(current());
+      Advance();
+      break;
+    }  // end switch(current())
+
+    int min;
+    int max;
+    switch (current()) {
+    // QuantifierPrefix ::
+    //   *
+    //   +
+    //   ?
+    //   {
+    case '*':
+      min = 0;
+      max = RegExpTree::kInfinity;
+      Advance();
+      break;
+    case '+':
+      min = 1;
+      max = RegExpTree::kInfinity;
+      Advance();
+      break;
+    case '?':
+      min = 0;
+      max = 1;
+      Advance();
+      break;
+    case '{':
+      if (ParseIntervalQuantifier(&min, &max)) {
+        if (max < min) {
+          ReportError(CStrVector("numbers out of order in {} quantifier.")
+                      CHECK_FAILED);
+        }
+        break;
+      } else {
+        continue;
+      }
+    default:
+      continue;
+    }
+    RegExpQuantifier::QuantifierType quantifier_type = RegExpQuantifier::GREEDY;
+    if (current() == '?') {
+      quantifier_type = RegExpQuantifier::NON_GREEDY;
+      Advance();
+    } else if (FLAG_regexp_possessive_quantifier && current() == '+') {
+      // FLAG_regexp_possessive_quantifier is a debug-only flag.
+      quantifier_type = RegExpQuantifier::POSSESSIVE;
+      Advance();
+    }
+    builder->AddQuantifierToAtom(min, max, quantifier_type);
+  }
+}
+
+
+#ifdef DEBUG
+// Currently only used in an DCHECK.
+static bool IsSpecialClassEscape(uc32 c) {
+  switch (c) {
+    case 'd': case 'D':
+    case 's': case 'S':
+    case 'w': case 'W':
+      return true;
+    default:
+      return false;
+  }
+}
+#endif
+
+
+// In order to know whether an escape is a backreference or not we have to scan
+// the entire regexp and find the number of capturing parentheses.  However we
+// don't want to scan the regexp twice unless it is necessary.  This mini-parser
+// is called when needed.  It can see the difference between capturing and
+// noncapturing parentheses and can skip character classes and backslash-escaped
+// characters.
+void RegExpParser::ScanForCaptures() {
+  // Start with captures started previous to current position
+  int capture_count = captures_started();
+  // Add count of captures after this position.
+  int n;
+  while ((n = current()) != kEndMarker) {
+    Advance();
+    switch (n) {
+      case '\\':
+        Advance();
+        break;
+      case '[': {
+        int c;
+        while ((c = current()) != kEndMarker) {
+          Advance();
+          if (c == '\\') {
+            Advance();
+          } else {
+            if (c == ']') break;
+          }
+        }
+        break;
+      }
+      case '(':
+        if (current() != '?') capture_count++;
+        break;
+    }
+  }
+  capture_count_ = capture_count;
+  is_scanned_for_captures_ = true;
+}
+
+
+bool RegExpParser::ParseBackReferenceIndex(int* index_out) {
+  DCHECK_EQ('\\', current());
+  DCHECK('1' <= Next() && Next() <= '9');
+  // Try to parse a decimal literal that is no greater than the total number
+  // of left capturing parentheses in the input.
+  int start = position();
+  int value = Next() - '0';
+  Advance(2);
+  while (true) {
+    uc32 c = current();
+    if (IsDecimalDigit(c)) {
+      value = 10 * value + (c - '0');
+      if (value > kMaxCaptures) {
+        Reset(start);
+        return false;
+      }
+      Advance();
+    } else {
+      break;
+    }
+  }
+  if (value > captures_started()) {
+    if (!is_scanned_for_captures_) {
+      int saved_position = position();
+      ScanForCaptures();
+      Reset(saved_position);
+    }
+    if (value > capture_count_) {
+      Reset(start);
+      return false;
+    }
+  }
+  *index_out = value;
+  return true;
+}
+
+
+// QuantifierPrefix ::
+//   { DecimalDigits }
+//   { DecimalDigits , }
+//   { DecimalDigits , DecimalDigits }
+//
+// Returns true if parsing succeeds, and set the min_out and max_out
+// values. Values are truncated to RegExpTree::kInfinity if they overflow.
+bool RegExpParser::ParseIntervalQuantifier(int* min_out, int* max_out) {
+  DCHECK_EQ(current(), '{');
+  int start = position();
+  Advance();
+  int min = 0;
+  if (!IsDecimalDigit(current())) {
+    Reset(start);
+    return false;
+  }
+  while (IsDecimalDigit(current())) {
+    int next = current() - '0';
+    if (min > (RegExpTree::kInfinity - next) / 10) {
+      // Overflow. Skip past remaining decimal digits and return -1.
+      do {
+        Advance();
+      } while (IsDecimalDigit(current()));
+      min = RegExpTree::kInfinity;
+      break;
+    }
+    min = 10 * min + next;
+    Advance();
+  }
+  int max = 0;
+  if (current() == '}') {
+    max = min;
+    Advance();
+  } else if (current() == ',') {
+    Advance();
+    if (current() == '}') {
+      max = RegExpTree::kInfinity;
+      Advance();
+    } else {
+      while (IsDecimalDigit(current())) {
+        int next = current() - '0';
+        if (max > (RegExpTree::kInfinity - next) / 10) {
+          do {
+            Advance();
+          } while (IsDecimalDigit(current()));
+          max = RegExpTree::kInfinity;
+          break;
+        }
+        max = 10 * max + next;
+        Advance();
+      }
+      if (current() != '}') {
+        Reset(start);
+        return false;
+      }
+      Advance();
+    }
+  } else {
+    Reset(start);
+    return false;
+  }
+  *min_out = min;
+  *max_out = max;
+  return true;
+}
+
+
+uc32 RegExpParser::ParseOctalLiteral() {
+  DCHECK(('0' <= current() && current() <= '7') || current() == kEndMarker);
+  // For compatibility with some other browsers (not all), we parse
+  // up to three octal digits with a value below 256.
+  uc32 value = current() - '0';
+  Advance();
+  if ('0' <= current() && current() <= '7') {
+    value = value * 8 + current() - '0';
+    Advance();
+    if (value < 32 && '0' <= current() && current() <= '7') {
+      value = value * 8 + current() - '0';
+      Advance();
+    }
+  }
+  return value;
+}
+
+
+bool RegExpParser::ParseHexEscape(int length, uc32 *value) {
+  int start = position();
+  uc32 val = 0;
+  bool done = false;
+  for (int i = 0; !done; i++) {
+    uc32 c = current();
+    int d = HexValue(c);
+    if (d < 0) {
+      Reset(start);
+      return false;
+    }
+    val = val * 16 + d;
+    Advance();
+    if (i == length - 1) {
+      done = true;
+    }
+  }
+  *value = val;
+  return true;
+}
+
+
+uc32 RegExpParser::ParseClassCharacterEscape() {
+  DCHECK(current() == '\\');
+  DCHECK(has_next() && !IsSpecialClassEscape(Next()));
+  Advance();
+  switch (current()) {
+    case 'b':
+      Advance();
+      return '\b';
+    // ControlEscape :: one of
+    //   f n r t v
+    case 'f':
+      Advance();
+      return '\f';
+    case 'n':
+      Advance();
+      return '\n';
+    case 'r':
+      Advance();
+      return '\r';
+    case 't':
+      Advance();
+      return '\t';
+    case 'v':
+      Advance();
+      return '\v';
+    case 'c': {
+      uc32 controlLetter = Next();
+      uc32 letter = controlLetter & ~('A' ^ 'a');
+      // For compatibility with JSC, inside a character class
+      // we also accept digits and underscore as control characters.
+      if ((controlLetter >= '0' && controlLetter <= '9') ||
+          controlLetter == '_' ||
+          (letter >= 'A' && letter <= 'Z')) {
+        Advance(2);
+        // Control letters mapped to ASCII control characters in the range
+        // 0x00-0x1f.
+        return controlLetter & 0x1f;
+      }
+      // We match JSC in reading the backslash as a literal
+      // character instead of as starting an escape.
+      return '\\';
+    }
+    case '0': case '1': case '2': case '3': case '4': case '5':
+    case '6': case '7':
+      // For compatibility, we interpret a decimal escape that isn't
+      // a back reference (and therefore either \0 or not valid according
+      // to the specification) as a 1..3 digit octal character code.
+      return ParseOctalLiteral();
+    case 'x': {
+      Advance();
+      uc32 value;
+      if (ParseHexEscape(2, &value)) {
+        return value;
+      }
+      // If \x is not followed by a two-digit hexadecimal, treat it
+      // as an identity escape.
+      return 'x';
+    }
+    case 'u': {
+      Advance();
+      uc32 value;
+      if (ParseHexEscape(4, &value)) {
+        return value;
+      }
+      // If \u is not followed by a four-digit hexadecimal, treat it
+      // as an identity escape.
+      return 'u';
+    }
+    default: {
+      // Extended identity escape. We accept any character that hasn't
+      // been matched by a more specific case, not just the subset required
+      // by the ECMAScript specification.
+      uc32 result = current();
+      Advance();
+      return result;
+    }
+  }
+  return 0;
+}
+
+
+CharacterRange RegExpParser::ParseClassAtom(uc16* char_class) {
+  DCHECK_EQ(0, *char_class);
+  uc32 first = current();
+  if (first == '\\') {
+    switch (Next()) {
+      case 'w': case 'W': case 'd': case 'D': case 's': case 'S': {
+        *char_class = Next();
+        Advance(2);
+        return CharacterRange::Singleton(0);  // Return dummy value.
+      }
+      case kEndMarker:
+        return ReportError(CStrVector("\\ at end of pattern"));
+      default:
+        uc32 c = ParseClassCharacterEscape(CHECK_FAILED);
+        return CharacterRange::Singleton(c);
+    }
+  } else {
+    Advance();
+    return CharacterRange::Singleton(first);
+  }
+}
+
+
+static const uc16 kNoCharClass = 0;
+
+// Adds range or pre-defined character class to character ranges.
+// If char_class is not kInvalidClass, it's interpreted as a class
+// escape (i.e., 's' means whitespace, from '\s').
+static inline void AddRangeOrEscape(ZoneList<CharacterRange>* ranges,
+                                    uc16 char_class,
+                                    CharacterRange range,
+                                    Zone* zone) {
+  if (char_class != kNoCharClass) {
+    CharacterRange::AddClassEscape(char_class, ranges, zone);
+  } else {
+    ranges->Add(range, zone);
+  }
+}
+
+
+RegExpTree* RegExpParser::ParseCharacterClass() {
+  static const char* kUnterminated = "Unterminated character class";
+  static const char* kRangeOutOfOrder = "Range out of order in character class";
+
+  DCHECK_EQ(current(), '[');
+  Advance();
+  bool is_negated = false;
+  if (current() == '^') {
+    is_negated = true;
+    Advance();
+  }
+  ZoneList<CharacterRange>* ranges =
+      new(zone()) ZoneList<CharacterRange>(2, zone());
+  while (has_more() && current() != ']') {
+    uc16 char_class = kNoCharClass;
+    CharacterRange first = ParseClassAtom(&char_class CHECK_FAILED);
+    if (current() == '-') {
+      Advance();
+      if (current() == kEndMarker) {
+        // If we reach the end we break out of the loop and let the
+        // following code report an error.
+        break;
+      } else if (current() == ']') {
+        AddRangeOrEscape(ranges, char_class, first, zone());
+        ranges->Add(CharacterRange::Singleton('-'), zone());
+        break;
+      }
+      uc16 char_class_2 = kNoCharClass;
+      CharacterRange next = ParseClassAtom(&char_class_2 CHECK_FAILED);
+      if (char_class != kNoCharClass || char_class_2 != kNoCharClass) {
+        // Either end is an escaped character class. Treat the '-' verbatim.
+        AddRangeOrEscape(ranges, char_class, first, zone());
+        ranges->Add(CharacterRange::Singleton('-'), zone());
+        AddRangeOrEscape(ranges, char_class_2, next, zone());
+        continue;
+      }
+      if (first.from() > next.to()) {
+        return ReportError(CStrVector(kRangeOutOfOrder) CHECK_FAILED);
+      }
+      ranges->Add(CharacterRange::Range(first.from(), next.to()), zone());
+    } else {
+      AddRangeOrEscape(ranges, char_class, first, zone());
+    }
+  }
+  if (!has_more()) {
+    return ReportError(CStrVector(kUnterminated) CHECK_FAILED);
+  }
+  Advance();
+  if (ranges->length() == 0) {
+    ranges->Add(CharacterRange::Everything(), zone());
+    is_negated = !is_negated;
+  }
+  return new(zone()) RegExpCharacterClass(ranges, is_negated);
+}
+
+
+// ----------------------------------------------------------------------------
+// The Parser interface.
+
+bool RegExpParser::ParseRegExp(FlatStringReader* input,
+                               bool multiline,
+                               RegExpCompileData* result,
+                               Zone* zone) {
+  DCHECK(result != NULL);
+  RegExpParser parser(input, &result->error, multiline, zone);
+  RegExpTree* tree = parser.ParsePattern();
+  if (parser.failed()) {
+    DCHECK(tree == NULL);
+    DCHECK(!result->error.is_null());
+  } else {
+    DCHECK(tree != NULL);
+    DCHECK(result->error.is_null());
+    result->tree = tree;
+    int capture_count = parser.captures_started();
+    result->simple = tree->IsAtom() && parser.simple() && capture_count == 0;
+    result->contains_anchor = parser.contains_anchor();
+    result->capture_count = capture_count;
+  }
+  return !parser.failed();
+}
+
+// SNIP
+
+}  // namespace dart
diff --git a/runtime/vm/regexp_parser.h b/runtime/vm/regexp_parser.h
new file mode 100644
index 0000000..42cedd4
--- /dev/null
+++ b/runtime/vm/regexp_parser.h
@@ -0,0 +1,178 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+#ifndef VM_REGEXP_PARSER_H_
+#define VM_REGEXP_PARSER_H_
+
+// SNIP
+
+namespace dart {
+
+// SNIP
+
+// Accumulates RegExp atoms and assertions into lists of terms and alternatives.
+class RegExpBuilder: public ZoneObject {
+ public:
+  explicit RegExpBuilder(Zone* zone);
+  void AddCharacter(uc16 character);
+  // "Adds" an empty expression. Does nothing except consume a
+  // following quantifier
+  void AddEmpty();
+  void AddAtom(RegExpTree* tree);
+  void AddAssertion(RegExpTree* tree);
+  void NewAlternative();  // '|'
+  void AddQuantifierToAtom(
+      int min, int max, RegExpQuantifier::QuantifierType type);
+  RegExpTree* ToRegExp();
+
+ private:
+  void FlushCharacters();
+  void FlushText();
+  void FlushTerms();
+  Zone* zone() const { return zone_; }
+
+  Zone* zone_;
+  bool pending_empty_;
+  ZoneList<uc16>* characters_;
+  BufferedZoneList<RegExpTree, 2> terms_;
+  BufferedZoneList<RegExpTree, 2> text_;
+  BufferedZoneList<RegExpTree, 2> alternatives_;
+#ifdef DEBUG
+  enum {ADD_NONE, ADD_CHAR, ADD_TERM, ADD_ASSERT, ADD_ATOM} last_added_;
+#define LAST(x) last_added_ = x;
+#else
+#define LAST(x)
+#endif
+};
+
+
+class RegExpParser BASE_EMBEDDED {
+ public:
+  RegExpParser(FlatStringReader* in,
+               Handle<String>* error,
+               bool multiline_mode,
+               Zone* zone);
+
+  static bool ParseRegExp(FlatStringReader* input,
+                          bool multiline,
+                          RegExpCompileData* result,
+                          Zone* zone);
+
+  RegExpTree* ParsePattern();
+  RegExpTree* ParseDisjunction();
+  RegExpTree* ParseGroup();
+  RegExpTree* ParseCharacterClass();
+
+  // Parses a {...,...} quantifier and stores the range in the given
+  // out parameters.
+  bool ParseIntervalQuantifier(int* min_out, int* max_out);
+
+  // Parses and returns a single escaped character.  The character
+  // must not be 'b' or 'B' since they are usually handle specially.
+  uc32 ParseClassCharacterEscape();
+
+  // Checks whether the following is a length-digit hexadecimal number,
+  // and sets the value if it is.
+  bool ParseHexEscape(int length, uc32* value);
+
+  uc32 ParseOctalLiteral();
+
+  // Tries to parse the input as a back reference.  If successful it
+  // stores the result in the output parameter and returns true.  If
+  // it fails it will push back the characters read so the same characters
+  // can be reparsed.
+  bool ParseBackReferenceIndex(int* index_out);
+
+  CharacterRange ParseClassAtom(uc16* char_class);
+  RegExpTree* ReportError(Vector<const char> message);
+  void Advance();
+  void Advance(int dist);
+  void Reset(int pos);
+
+  // Reports whether the pattern might be used as a literal search string.
+  // Only use if the result of the parse is a single atom node.
+  bool simple();
+  bool contains_anchor() { return contains_anchor_; }
+  void set_contains_anchor() { contains_anchor_ = true; }
+  int captures_started() { return captures_ == NULL ? 0 : captures_->length(); }
+  int position() { return next_pos_ - 1; }
+  bool failed() { return failed_; }
+
+  static const int kMaxCaptures = 1 << 16;
+  static const uc32 kEndMarker = (1 << 21);
+
+ private:
+  enum SubexpressionType {
+    INITIAL,
+    CAPTURE,  // All positive values represent captures.
+    POSITIVE_LOOKAHEAD,
+    NEGATIVE_LOOKAHEAD,
+    GROUPING
+  };
+
+  class RegExpParserState : public ZoneObject {
+   public:
+    RegExpParserState(RegExpParserState* previous_state,
+                      SubexpressionType group_type,
+                      int disjunction_capture_index,
+                      Zone* zone)
+        : previous_state_(previous_state),
+          builder_(new(zone) RegExpBuilder(zone)),
+          group_type_(group_type),
+          disjunction_capture_index_(disjunction_capture_index) {}
+    // Parser state of containing expression, if any.
+    RegExpParserState* previous_state() { return previous_state_; }
+    bool IsSubexpression() { return previous_state_ != NULL; }
+    // RegExpBuilder building this regexp's AST.
+    RegExpBuilder* builder() { return builder_; }
+    // Type of regexp being parsed (parenthesized group or entire regexp).
+    SubexpressionType group_type() { return group_type_; }
+    // Index in captures array of first capture in this sub-expression, if any.
+    // Also the capture index of this sub-expression itself, if group_type
+    // is CAPTURE.
+    int capture_index() { return disjunction_capture_index_; }
+
+   private:
+    // Linked list implementation of stack of states.
+    RegExpParserState* previous_state_;
+    // Builder for the stored disjunction.
+    RegExpBuilder* builder_;
+    // Stored disjunction type (capture, look-ahead or grouping), if any.
+    SubexpressionType group_type_;
+    // Stored disjunction's capture index (if any).
+    int disjunction_capture_index_;
+  };
+
+  Isolate* isolate() { return isolate_; }
+  Zone* zone() const { return zone_; }
+
+  uc32 current() { return current_; }
+  bool has_more() { return has_more_; }
+  bool has_next() { return next_pos_ < in()->length(); }
+  uc32 Next();
+  FlatStringReader* in() { return in_; }
+  void ScanForCaptures();
+
+  Isolate* isolate_;
+  Zone* zone_;
+  Handle<String>* error_;
+  ZoneList<RegExpCapture*>* captures_;
+  FlatStringReader* in_;
+  uc32 current_;
+  int next_pos_;
+  // The capture count is only valid after we have scanned for captures.
+  int capture_count_;
+  bool has_more_;
+  bool multiline_;
+  bool simple_;
+  bool contains_anchor_;
+  bool is_scanned_for_captures_;
+  bool failed_;
+};
+
+// SNIP
+
+}  // namespace dart
+
+#endif  // VM_REGEXP_PARSER_H_
diff --git a/runtime/vm/scopes.cc b/runtime/vm/scopes.cc
index dd3f1bd..b92feae 100644
--- a/runtime/vm/scopes.cc
+++ b/runtime/vm/scopes.cc
@@ -325,18 +325,7 @@
         desc.info.end_pos = var->owner()->end_token_pos();
         desc.info.set_index(var->index());
         vars->Add(desc);
-      } else if (var->name().raw() == Symbols::SavedEntryContextVar().raw()) {
-        // This is the local variable in which the function saves the
-        // caller's chain of closure contexts (caller's CTX register).
-        VarDesc desc;
-        desc.name = &var->name();
-        desc.info.set_kind(RawLocalVarDescriptors::kSavedEntryContext);
-        desc.info.scope_id = 0;
-        desc.info.begin_pos = 0;
-        desc.info.end_pos = 0;
-        desc.info.set_index(var->index());
-        vars->Add(desc);
-      } else if (var->name().raw() == Symbols::SavedCurrentContextVar().raw()) {
+      } else if (var->name().raw() == Symbols::CurrentContextVar().raw()) {
         // This is the local variable in which the function saves its
         // own context before calling a closure function.
         VarDesc desc;
diff --git a/runtime/vm/stack_frame.cc b/runtime/vm/stack_frame.cc
index 950f02e..e37bf11 100644
--- a/runtime/vm/stack_frame.cc
+++ b/runtime/vm/stack_frame.cc
@@ -60,12 +60,6 @@
 }
 
 
-RawContext* EntryFrame::SavedContext() const {
-  return *(reinterpret_cast<RawContext**>(
-      fp() + (kSavedContextSlotFromEntryFp * kWordSize)));
-}
-
-
 void EntryFrame::VisitObjectPointers(ObjectPointerVisitor* visitor) {
   ASSERT(isolate() == Isolate::Current());
   // Visit objects between SP and (FP - callee_save_area).
diff --git a/runtime/vm/stack_frame.h b/runtime/vm/stack_frame.h
index d80eca7..2195d81 100644
--- a/runtime/vm/stack_frame.h
+++ b/runtime/vm/stack_frame.h
@@ -150,8 +150,6 @@
   bool IsStubFrame() const { return false; }
   bool IsEntryFrame() const { return true; }
 
-  RawContext* SavedContext() const;
-
   // Visit objects in the frame.
   virtual void VisitObjectPointers(ObjectPointerVisitor* visitor);
 
diff --git a/runtime/vm/stack_frame_arm.h b/runtime/vm/stack_frame_arm.h
index ef2bd1e..b23b719 100644
--- a/runtime/vm/stack_frame_arm.h
+++ b/runtime/vm/stack_frame_arm.h
@@ -43,9 +43,7 @@
 static const int kCallerSpSlotFromFp = 3;
 
 // Entry and exit frame layout.
-static const int kSavedContextSlotFromEntryFp = -27;
-static const int kExitLinkSlotFromEntryFp = -26;
-static const int kSavedVMTagSlotFromEntryFp = -25;
+static const int kExitLinkSlotFromEntryFp = -25;
 
 }  // namespace dart
 
diff --git a/runtime/vm/stack_frame_arm64.h b/runtime/vm/stack_frame_arm64.h
index 491b8f2..d8a848f 100644
--- a/runtime/vm/stack_frame_arm64.h
+++ b/runtime/vm/stack_frame_arm64.h
@@ -44,9 +44,7 @@
 static const int kSavedAboveReturnAddress = 3;  // Saved above return address.
 
 // Entry and exit frame layout.
-static const int kSavedContextSlotFromEntryFp = -22;
-static const int kExitLinkSlotFromEntryFp = -21;
-static const int kSavedVMTagSlotFromEntryFp = -20;
+static const int kExitLinkSlotFromEntryFp = -20;
 
 }  // namespace dart
 
diff --git a/runtime/vm/stack_frame_ia32.h b/runtime/vm/stack_frame_ia32.h
index b7d5997..7b5032f 100644
--- a/runtime/vm/stack_frame_ia32.h
+++ b/runtime/vm/stack_frame_ia32.h
@@ -42,9 +42,7 @@
 static const int kSavedCallerPpSlotFromFp = kSavedCallerFpSlotFromFp;
 
 // Entry and exit frame layout.
-static const int kSavedContextSlotFromEntryFp = -6;
 static const int kExitLinkSlotFromEntryFp = -5;
-static const int kSavedVMTagSlotFromEntryFp = -4;
 
 }  // namespace dart
 
diff --git a/runtime/vm/stack_frame_mips.h b/runtime/vm/stack_frame_mips.h
index 94c8c25..891fa2e 100644
--- a/runtime/vm/stack_frame_mips.h
+++ b/runtime/vm/stack_frame_mips.h
@@ -41,9 +41,7 @@
 static const int kCallerSpSlotFromFp = 3;
 
 // Entry and exit frame layout.
-static const int kSavedContextSlotFromEntryFp = -24;
-static const int kExitLinkSlotFromEntryFp = -23;
-static const int kSavedVMTagSlotFromEntryFp = -22;
+static const int kExitLinkSlotFromEntryFp = -22;
 
 }  // namespace dart
 
diff --git a/runtime/vm/stack_frame_x64.h b/runtime/vm/stack_frame_x64.h
index 125735d..a80a291 100644
--- a/runtime/vm/stack_frame_x64.h
+++ b/runtime/vm/stack_frame_x64.h
@@ -46,13 +46,9 @@
 
 // Entry and exit frame layout.
 #if defined(_WIN64)
-static const int kSavedContextSlotFromEntryFp = -32;
-static const int kExitLinkSlotFromEntryFp = -31;
-static const int kSavedVMTagSlotFromEntryFp = -30;
+static const int kExitLinkSlotFromEntryFp = -30;
 #else
-static const int kSavedContextSlotFromEntryFp = -10;
-static const int kExitLinkSlotFromEntryFp = -9;
-static const int kSavedVMTagSlotFromEntryFp = -8;
+static const int kExitLinkSlotFromEntryFp = -8;
 #endif  // defined(_WIN64)
 
 }  // namespace dart
diff --git a/runtime/vm/stub_code_arm.cc b/runtime/vm/stub_code_arm.cc
index 77f9f74..7e836b3 100644
--- a/runtime/vm/stub_code_arm.cc
+++ b/runtime/vm/stub_code_arm.cc
@@ -45,22 +45,17 @@
   __ Push(IP);  // Push 0 for the PC marker.
   __ EnterFrame((1 << FP) | (1 << LR), 0);
 
-  __ LoadIsolate(R0);
+  COMPILE_ASSERT((kAbiPreservedCpuRegs & (1 << R9)) != 0);
+  __ LoadIsolate(R9);
 
   // Save exit frame information to enable stack walking as we are about
   // to transition to Dart VM C++ code.
-  __ StoreToOffset(kWord, SP, R0, Isolate::top_exit_frame_info_offset());
-
-  // Save current Context pointer into Isolate structure.
-  __ StoreToOffset(kWord, CTX, R0, Isolate::top_context_offset());
-
-  // Cache Isolate pointer into CTX while executing runtime code.
-  __ mov(CTX, Operand(R0));
+  __ StoreToOffset(kWord, SP, R9, Isolate::top_exit_frame_info_offset());
 
 #if defined(DEBUG)
   { Label ok;
     // Check that we are always entering from Dart code.
-    __ LoadFromOffset(kWord, R6, CTX, Isolate::vm_tag_offset());
+    __ LoadFromOffset(kWord, R6, R9, Isolate::vm_tag_offset());
     __ CompareImmediate(R6, VMTag::kDartTagId);
     __ b(&ok, EQ);
     __ Stop("Not coming from Dart code.");
@@ -69,7 +64,7 @@
 #endif
 
   // Mark that the isolate is executing VM code.
-  __ StoreToOffset(kWord, R5, CTX, Isolate::vm_tag_offset());
+  __ StoreToOffset(kWord, R5, R9, Isolate::vm_tag_offset());
 
   // Reserve space for arguments and align frame before entering C++ world.
   // NativeArguments are passed in registers.
@@ -80,7 +75,8 @@
   // Registers R0, R1, R2, and R3 are used.
 
   ASSERT(isolate_offset == 0 * kWordSize);
-  // Set isolate in NativeArgs: R0 already contains CTX.
+  // Set isolate in NativeArgs.
+  __ mov(R0, Operand(R9));
 
   // There are no runtime calls to closures, so we do not need to set the tag
   // bits kClosureFunctionBit and kInstanceFunctionBit in argc_tag_.
@@ -100,21 +96,11 @@
 
   // Mark that the isolate is executing Dart code.
   __ LoadImmediate(R2, VMTag::kDartTagId);
-  __ StoreToOffset(kWord, R2, CTX, Isolate::vm_tag_offset());
+  __ StoreToOffset(kWord, R2, R9, Isolate::vm_tag_offset());
 
   // Reset exit frame information in Isolate structure.
   __ LoadImmediate(R2, 0);
-  __ StoreToOffset(kWord, R2, CTX, Isolate::top_exit_frame_info_offset());
-
-  // Load Context pointer from Isolate structure into R2.
-  __ LoadFromOffset(kWord, R2, CTX, Isolate::top_context_offset());
-
-  // Reset Context pointer in Isolate structure.
-  __ LoadImmediate(R3, reinterpret_cast<intptr_t>(Object::null()));
-  __ StoreToOffset(kWord, R3, CTX, Isolate::top_context_offset());
-
-  // Cache Context pointer into CTX while executing Dart code.
-  __ mov(CTX, Operand(R2));
+  __ StoreToOffset(kWord, R2, R9, Isolate::top_exit_frame_info_offset());
 
   __ LeaveFrame((1 << FP) | (1 << LR));
   // Adjust SP for the empty PC marker.
@@ -158,22 +144,17 @@
   __ Push(IP);  // Push 0 for the PC marker.
   __ EnterFrame((1 << FP) | (1 << LR), 0);
 
-  __ LoadIsolate(R0);
+  COMPILE_ASSERT((kAbiPreservedCpuRegs & (1 << R9)) != 0);
+  __ LoadIsolate(R9);
 
   // Save exit frame information to enable stack walking as we are about
   // to transition to native code.
-  __ StoreToOffset(kWord, SP, R0, Isolate::top_exit_frame_info_offset());
-
-  // Save current Context pointer into Isolate structure.
-  __ StoreToOffset(kWord, CTX, R0, Isolate::top_context_offset());
-
-  // Cache Isolate pointer into CTX while executing native code.
-  __ mov(CTX, Operand(R0));
+  __ StoreToOffset(kWord, SP, R9, Isolate::top_exit_frame_info_offset());
 
 #if defined(DEBUG)
   { Label ok;
     // Check that we are always entering from Dart code.
-    __ LoadFromOffset(kWord, R6, CTX, Isolate::vm_tag_offset());
+    __ LoadFromOffset(kWord, R6, R9, Isolate::vm_tag_offset());
     __ CompareImmediate(R6, VMTag::kDartTagId);
     __ b(&ok, EQ);
     __ Stop("Not coming from Dart code.");
@@ -182,7 +163,7 @@
 #endif
 
   // Mark that the isolate is executing Native code.
-  __ StoreToOffset(kWord, R5, CTX, Isolate::vm_tag_offset());
+  __ StoreToOffset(kWord, R5, R9, Isolate::vm_tag_offset());
 
   // Reserve space for the native arguments structure passed on the stack (the
   // outgoing pointer parameter to the native arguments structure is passed in
@@ -193,7 +174,8 @@
   // Registers R0, R1, R2, and R3 are used.
 
   ASSERT(isolate_offset == 0 * kWordSize);
-  // Set isolate in NativeArgs: R0 already contains CTX.
+  // Set isolate in NativeArgs.
+  __ mov(R0, Operand(R9));
 
   // There are no native calls to closures, so we do not need to set the tag
   // bits kClosureFunctionBit and kInstanceFunctionBit in argc_tag_.
@@ -226,21 +208,11 @@
 
   // Mark that the isolate is executing Dart code.
   __ LoadImmediate(R2, VMTag::kDartTagId);
-  __ StoreToOffset(kWord, R2, CTX, Isolate::vm_tag_offset());
+  __ StoreToOffset(kWord, R2, R9, Isolate::vm_tag_offset());
 
   // Reset exit frame information in Isolate structure.
   __ LoadImmediate(R2, 0);
-  __ StoreToOffset(kWord, R2, CTX, Isolate::top_exit_frame_info_offset());
-
-  // Load Context pointer from Isolate structure into R2.
-  __ LoadFromOffset(kWord, R2, CTX, Isolate::top_context_offset());
-
-  // Reset Context pointer in Isolate structure.
-  __ LoadImmediate(R3, reinterpret_cast<intptr_t>(Object::null()));
-  __ StoreToOffset(kWord, R3, CTX, Isolate::top_context_offset());
-
-  // Cache Context pointer into CTX while executing Dart code.
-  __ mov(CTX, Operand(R2));
+  __ StoreToOffset(kWord, R2, R9, Isolate::top_exit_frame_info_offset());
 
   __ LeaveFrame((1 << FP) | (1 << LR));
   // Adjust SP for the empty PC marker.
@@ -265,22 +237,17 @@
   __ Push(IP);  // Push 0 for the PC marker.
   __ EnterFrame((1 << FP) | (1 << LR), 0);
 
-  __ LoadIsolate(R0);
+  COMPILE_ASSERT((kAbiPreservedCpuRegs & (1 << R9)) != 0);
+  __ LoadIsolate(R9);
 
   // Save exit frame information to enable stack walking as we are about
   // to transition to native code.
-  __ StoreToOffset(kWord, SP, R0, Isolate::top_exit_frame_info_offset());
-
-  // Save current Context pointer into Isolate structure.
-  __ StoreToOffset(kWord, CTX, R0, Isolate::top_context_offset());
-
-  // Cache Isolate pointer into CTX while executing native code.
-  __ mov(CTX, Operand(R0));
+  __ StoreToOffset(kWord, SP, R9, Isolate::top_exit_frame_info_offset());
 
 #if defined(DEBUG)
   { Label ok;
     // Check that we are always entering from Dart code.
-    __ LoadFromOffset(kWord, R6, CTX, Isolate::vm_tag_offset());
+    __ LoadFromOffset(kWord, R6, R9, Isolate::vm_tag_offset());
     __ CompareImmediate(R6, VMTag::kDartTagId);
     __ b(&ok, EQ);
     __ Stop("Not coming from Dart code.");
@@ -289,7 +256,7 @@
 #endif
 
   // Mark that the isolate is executing Native code.
-  __ StoreToOffset(kWord, R5, CTX, Isolate::vm_tag_offset());
+  __ StoreToOffset(kWord, R5, R9, Isolate::vm_tag_offset());
 
   // Reserve space for the native arguments structure passed on the stack (the
   // outgoing pointer parameter to the native arguments structure is passed in
@@ -300,7 +267,8 @@
   // Registers R0, R1, R2, and R3 are used.
 
   ASSERT(isolate_offset == 0 * kWordSize);
-  // Set isolate in NativeArgs: R0 already contains CTX.
+  // Set isolate in NativeArgs.
+  __ mov(R0, Operand(R9));
 
   // There are no native calls to closures, so we do not need to set the tag
   // bits kClosureFunctionBit and kInstanceFunctionBit in argc_tag_.
@@ -324,21 +292,11 @@
 
   // Mark that the isolate is executing Dart code.
   __ LoadImmediate(R2, VMTag::kDartTagId);
-  __ StoreToOffset(kWord, R2, CTX, Isolate::vm_tag_offset());
+  __ StoreToOffset(kWord, R2, R9, Isolate::vm_tag_offset());
 
   // Reset exit frame information in Isolate structure.
   __ LoadImmediate(R2, 0);
-  __ StoreToOffset(kWord, R2, CTX, Isolate::top_exit_frame_info_offset());
-
-  // Load Context pointer from Isolate structure into R2.
-  __ LoadFromOffset(kWord, R2, CTX, Isolate::top_context_offset());
-
-  // Reset Context pointer in Isolate structure.
-  __ LoadImmediate(R3, reinterpret_cast<intptr_t>(Object::null()));
-  __ StoreToOffset(kWord, R3, CTX, Isolate::top_context_offset());
-
-  // Cache Context pointer into CTX while executing Dart code.
-  __ mov(CTX, Operand(R2));
+  __ StoreToOffset(kWord, R2, R9, Isolate::top_exit_frame_info_offset());
 
   __ LeaveFrame((1 << FP) | (1 << LR));
   // Adjust SP for the empty PC marker.
@@ -785,7 +743,7 @@
   __ EnterFrame((1 << FP) | (1 << LR), 0);
 
   // Save new context and C++ ABI callee-saved registers.
-  __ PushList((1 << R3) | kAbiPreservedCpuRegs);
+  __ PushList(kAbiPreservedCpuRegs);
 
   const DRegister firstd = EvenDRegisterOf(kAbiFirstPreservedFpuReg);
   if (TargetCPUFeatures::vfp_supported()) {
@@ -801,19 +759,9 @@
   // set up.
   __ LoadPoolPointer();
 
-  // The new Context structure contains a pointer to the current Isolate
-  // structure. Cache the Context pointer in the CTX register so that it is
-  // available in generated code and calls to Isolate::Current() need not be
-  // done. The assumption is that this register will never be clobbered by
-  // compiled or runtime stub code.
-
-  // Cache the new Context pointer into CTX while executing Dart code.
-  __ ldr(CTX, Address(R3, VMHandles::kOffsetOfRawPtrInHandle));
-
   __ LoadIsolate(R8);
 
   // Save the current VMTag on the stack.
-  ASSERT(kSavedVMTagSlotFromEntryFp == -25);
   __ LoadFromOffset(kWord, R5, R8, Isolate::vm_tag_offset());
   __ Push(R5);
 
@@ -827,18 +775,9 @@
   __ LoadImmediate(R6, 0);
   __ StoreToOffset(kWord, R6, R8, Isolate::top_exit_frame_info_offset());
 
-  // Save the old Context pointer. Use R4 as a temporary register.
-  // Note that VisitObjectPointers will find this saved Context pointer during
-  // GC marking, since it traverses any information between SP and
-  // FP - kExitLinkSlotFromEntryFp.
-  // EntryFrame::SavedContext reads the context saved in this frame.
-  __ LoadFromOffset(kWord, R4, R8, Isolate::top_context_offset());
-
-  // The constants kSavedContextSlotFromEntryFp and
   // kExitLinkSlotFromEntryFp must be kept in sync with the code below.
-  ASSERT(kExitLinkSlotFromEntryFp == -26);
-  ASSERT(kSavedContextSlotFromEntryFp == -27);
-  __ PushList((1 << R4) | (1 << R5));
+  ASSERT(kExitLinkSlotFromEntryFp == -25);
+  __ Push(R5);
 
   // Load arguments descriptor array into R4, which is passed to Dart code.
   __ ldr(R4, Address(R1, VMHandles::kOffsetOfRawPtrInHandle));
@@ -870,22 +809,18 @@
   __ blx(R0);  // R4 is the arguments descriptor array.
 
   // Get rid of arguments pushed on the stack.
-  __ AddImmediate(SP, FP, kSavedContextSlotFromEntryFp * kWordSize);
+  __ AddImmediate(SP, FP, kExitLinkSlotFromEntryFp * kWordSize);
 
-  // Load Isolate pointer into CTX.
-  __ LoadIsolate(CTX);
+  __ LoadIsolate(R8);
 
-  // Restore the saved Context pointer into the Isolate structure.
-  // Uses R4 as a temporary register for this.
   // Restore the saved top exit frame info back into the Isolate structure.
   // Uses R5 as a temporary register for this.
-  __ PopList((1 << R4) | (1 << R5));
-  __ StoreToOffset(kWord, R4, CTX, Isolate::top_context_offset());
-  __ StoreToOffset(kWord, R5, CTX, Isolate::top_exit_frame_info_offset());
+  __ Pop(R5);
+  __ StoreToOffset(kWord, R5, R8, Isolate::top_exit_frame_info_offset());
 
   // Restore the current VMTag from the stack.
   __ Pop(R4);
-  __ StoreToOffset(kWord, R4, CTX, Isolate::vm_tag_offset());
+  __ StoreToOffset(kWord, R4, R8, Isolate::vm_tag_offset());
 
   // Restore C++ ABI callee-saved registers.
   if (TargetCPUFeatures::vfp_supported()) {
@@ -895,7 +830,7 @@
     __ AddImmediate(SP, kAbiPreservedFpuRegCount * kFpuRegisterSize);
   }
   // Restore CPU registers.
-  __ PopList((1 << R3) | kAbiPreservedCpuRegs);  // Ignore restored R3.
+  __ PopList(kAbiPreservedCpuRegs);
 
   // Restore the frame pointer and return.
   __ LeaveFrame((1 << FP) | (1 << LR));
diff --git a/runtime/vm/stub_code_arm64.cc b/runtime/vm/stub_code_arm64.cc
index 6fb4a0d..4228a7f 100644
--- a/runtime/vm/stub_code_arm64.cc
+++ b/runtime/vm/stub_code_arm64.cc
@@ -44,22 +44,17 @@
   __ Comment("CallToRuntimeStub");
   __ EnterFrame(0);
 
-  __ LoadIsolate(R0, kNoPP);
+  COMPILE_ASSERT((kAbiPreservedCpuRegs & (1 << R28)) != 0);
+  __ LoadIsolate(R28, kNoPP);
 
   // Save exit frame information to enable stack walking as we are about
   // to transition to Dart VM C++ code.
-  __ StoreToOffset(SP, R0, Isolate::top_exit_frame_info_offset(), kNoPP);
-
-  // Save current Context pointer into Isolate structure.
-  __ StoreToOffset(CTX, R0, Isolate::top_context_offset(), kNoPP);
-
-  // Cache Isolate pointer into CTX while executing runtime code.
-  __ mov(CTX, R0);
+  __ StoreToOffset(SP, R28, Isolate::top_exit_frame_info_offset(), kNoPP);
 
 #if defined(DEBUG)
   { Label ok;
     // Check that we are always entering from Dart code.
-    __ LoadFromOffset(R8, R0, Isolate::vm_tag_offset(), kNoPP);
+    __ LoadFromOffset(R8, R28, Isolate::vm_tag_offset(), kNoPP);
     __ CompareImmediate(R8, VMTag::kDartTagId, kNoPP);
     __ b(&ok, EQ);
     __ Stop("Not coming from Dart code.");
@@ -68,7 +63,7 @@
 #endif
 
   // Mark that the isolate is executing VM code.
-  __ StoreToOffset(R5, R0, Isolate::vm_tag_offset(), kNoPP);
+  __ StoreToOffset(R5, R28, Isolate::vm_tag_offset(), kNoPP);
 
   // Reserve space for arguments and align frame before entering C++ world.
   // NativeArguments are passed in registers.
@@ -81,7 +76,8 @@
   // Registers R0, R1, R2, and R3 are used.
 
   ASSERT(isolate_offset == 0 * kWordSize);
-  // Set isolate in NativeArgs: R0 already contains CTX.
+  // Set isolate in NativeArgs.
+  __ mov(R0, R28);
 
   // There are no runtime calls to closures, so we do not need to set the tag
   // bits kClosureFunctionBit and kInstanceFunctionBit in argc_tag_.
@@ -119,22 +115,10 @@
   // Retval is next to 1st argument.
   // Mark that the isolate is executing Dart code.
   __ LoadImmediate(R2, VMTag::kDartTagId, kNoPP);
-  __ StoreToOffset(R2, CTX, Isolate::vm_tag_offset(), kNoPP);
+  __ StoreToOffset(R2, R28, Isolate::vm_tag_offset(), kNoPP);
 
   // Reset exit frame information in Isolate structure.
-  __ StoreToOffset(ZR, CTX, Isolate::top_exit_frame_info_offset(), kNoPP);
-
-  // Load Context pointer from Isolate structure into A2.
-  __ LoadFromOffset(R2, CTX, Isolate::top_context_offset(), kNoPP);
-
-  // Load null.
-  __ LoadObject(TMP, Object::null_object(), PP);
-
-  // Reset Context pointer in Isolate structure.
-  __ StoreToOffset(TMP, CTX, Isolate::top_context_offset(), kNoPP);
-
-  // Cache Context pointer into CTX while executing Dart code.
-  __ mov(CTX, R2);
+  __ StoreToOffset(ZR, R28, Isolate::top_exit_frame_info_offset(), kNoPP);
 
   __ LeaveFrame();
   __ ret();
@@ -160,22 +144,17 @@
 
   __ EnterFrame(0);
 
-  __ LoadIsolate(R0, kNoPP);
+  COMPILE_ASSERT((kAbiPreservedCpuRegs & (1 << R28)) != 0);
+  __ LoadIsolate(R28, kNoPP);
 
   // Save exit frame information to enable stack walking as we are about
   // to transition to native code.
-  __ StoreToOffset(SP, R0, Isolate::top_exit_frame_info_offset(), kNoPP);
-
-  // Save current Context pointer into Isolate structure.
-  __ StoreToOffset(CTX, R0, Isolate::top_context_offset(), kNoPP);
-
-  // Cache Isolate pointer into CTX while executing native code.
-  __ mov(CTX, R0);
+  __ StoreToOffset(SP, R28, Isolate::top_exit_frame_info_offset(), kNoPP);
 
 #if defined(DEBUG)
   { Label ok;
     // Check that we are always entering from Dart code.
-    __ LoadFromOffset(R6, CTX, Isolate::vm_tag_offset(), kNoPP);
+    __ LoadFromOffset(R6, R28, Isolate::vm_tag_offset(), kNoPP);
     __ CompareImmediate(R6, VMTag::kDartTagId, kNoPP);
     __ b(&ok, EQ);
     __ Stop("Not coming from Dart code.");
@@ -184,7 +163,7 @@
 #endif
 
   // Mark that the isolate is executing Native code.
-  __ StoreToOffset(R5, CTX, Isolate::vm_tag_offset(), kNoPP);
+  __ StoreToOffset(R5, R28, Isolate::vm_tag_offset(), kNoPP);
 
   // Reserve space for the native arguments structure passed on the stack (the
   // outgoing pointer parameter to the native arguments structure is passed in
@@ -195,7 +174,8 @@
   // Registers R0, R1, R2, and R3 are used.
 
   ASSERT(isolate_offset == 0 * kWordSize);
-  // Set isolate in NativeArgs: R0 already contains CTX.
+  // Set isolate in NativeArgs.
+  __ mov(R0, R28);
 
   // There are no native calls to closures, so we do not need to set the tag
   // bits kClosureFunctionBit and kInstanceFunctionBit in argc_tag_.
@@ -242,20 +222,10 @@
 
   // Mark that the isolate is executing Dart code.
   __ LoadImmediate(R2, VMTag::kDartTagId, kNoPP);
-  __ StoreToOffset(R2, CTX, Isolate::vm_tag_offset(), kNoPP);
+  __ StoreToOffset(R2, R28, Isolate::vm_tag_offset(), kNoPP);
 
   // Reset exit frame information in Isolate structure.
-  __ StoreToOffset(ZR, CTX, Isolate::top_exit_frame_info_offset(), kNoPP);
-
-  // Load Context pointer from Isolate structure into R2.
-  __ LoadFromOffset(R2, CTX, Isolate::top_context_offset(), kNoPP);
-
-  // Reset Context pointer in Isolate structure.
-  __ LoadObject(R3, Object::null_object(), PP);
-  __ StoreToOffset(R3, CTX, Isolate::top_context_offset(), kNoPP);
-
-  // Cache Context pointer into CTX while executing Dart code.
-  __ mov(CTX, R2);
+  __ StoreToOffset(ZR, R28, Isolate::top_exit_frame_info_offset(), kNoPP);
 
   __ LeaveFrame();
   __ ret();
@@ -276,22 +246,17 @@
 
   __ EnterFrame(0);
 
-  __ LoadIsolate(R0, kNoPP);
+  COMPILE_ASSERT((kAbiPreservedCpuRegs & (1 << R28)) != 0);
+  __ LoadIsolate(R28, kNoPP);
 
   // Save exit frame information to enable stack walking as we are about
   // to transition to native code.
-  __ StoreToOffset(SP, R0, Isolate::top_exit_frame_info_offset(), kNoPP);
-
-  // Save current Context pointer into Isolate structure.
-  __ StoreToOffset(CTX, R0, Isolate::top_context_offset(), kNoPP);
-
-  // Cache Isolate pointer into CTX while executing native code.
-  __ mov(CTX, R0);
+  __ StoreToOffset(SP, R28, Isolate::top_exit_frame_info_offset(), kNoPP);
 
 #if defined(DEBUG)
   { Label ok;
     // Check that we are always entering from Dart code.
-    __ LoadFromOffset(R6, CTX, Isolate::vm_tag_offset(), kNoPP);
+    __ LoadFromOffset(R6, R28, Isolate::vm_tag_offset(), kNoPP);
     __ CompareImmediate(R6, VMTag::kDartTagId, kNoPP);
     __ b(&ok, EQ);
     __ Stop("Not coming from Dart code.");
@@ -300,7 +265,7 @@
 #endif
 
   // Mark that the isolate is executing Native code.
-  __ StoreToOffset(R5, CTX, Isolate::vm_tag_offset(), kNoPP);
+  __ StoreToOffset(R5, R28, Isolate::vm_tag_offset(), kNoPP);
 
   // Reserve space for the native arguments structure passed on the stack (the
   // outgoing pointer parameter to the native arguments structure is passed in
@@ -311,7 +276,8 @@
   // Registers R0, R1, R2, and R3 are used.
 
   ASSERT(isolate_offset == 0 * kWordSize);
-  // Set isolate in NativeArgs: R0 already contains CTX.
+  // Set isolate in NativeArgs.
+  __ mov(R0, R28);
 
   // There are no native calls to closures, so we do not need to set the tag
   // bits kClosureFunctionBit and kInstanceFunctionBit in argc_tag_.
@@ -349,20 +315,10 @@
 
   // Mark that the isolate is executing Dart code.
   __ LoadImmediate(R2, VMTag::kDartTagId, kNoPP);
-  __ StoreToOffset(R2, CTX, Isolate::vm_tag_offset(), kNoPP);
+  __ StoreToOffset(R2, R28, Isolate::vm_tag_offset(), kNoPP);
 
   // Reset exit frame information in Isolate structure.
-  __ StoreToOffset(ZR, CTX, Isolate::top_exit_frame_info_offset(), kNoPP);
-
-  // Load Context pointer from Isolate structure into R2.
-  __ LoadFromOffset(R2, CTX, Isolate::top_context_offset(), kNoPP);
-
-  // Reset Context pointer in Isolate structure.
-  __ LoadObject(R3, Object::null_object(), PP);
-  __ StoreToOffset(R3, CTX, Isolate::top_context_offset(), kNoPP);
-
-  // Cache Context pointer into CTX while executing Dart code.
-  __ mov(CTX, R2);
+  __ StoreToOffset(ZR, R28, Isolate::top_exit_frame_info_offset(), kNoPP);
 
   __ LeaveFrame();
   __ ret();
@@ -833,41 +789,15 @@
     __ PushDouble(r);
   }
 
-  // Push new context.
-  __ Push(R3);
-#if defined(DEBUG)
-  {
-    Label ok;
-    // The new context, saved vm tag, the top exit frame, and the old context.
-    const intptr_t kNewContextOffsetFromFp =
-        -(1 + kAbiPreservedCpuRegCount + kAbiPreservedFpuRegCount) * kWordSize;
-    __ AddImmediate(R4, FP, kNewContextOffsetFromFp, kNoPP);
-    __ CompareRegisters(R4, SP);
-    __ b(&ok, EQ);
-    __ Stop("kNewContextOffsetFromFp mismatch");
-    __ Bind(&ok);
-  }
-#endif
-
   // We now load the pool pointer(PP) as we are about to invoke dart code and we
   // could potentially invoke some intrinsic functions which need the PP to be
   // set up.
   __ LoadPoolPointer(PP);
 
-  // The new Context structure contains a pointer to the current Isolate
-  // structure. Cache the Context pointer in the CTX register so that it is
-  // available in generated code and calls to Isolate::Current() need not be
-  // done. The assumption is that this register will never be clobbered by
-  // compiled or runtime stub code.
-
-  // Cache the new Context pointer into CTX while executing Dart code.
-  __ LoadFromOffset(CTX, R3, VMHandles::kOffsetOfRawPtrInHandle, PP);
-
   // Load Isolate pointer into temporary register R5.
   __ LoadIsolate(R5, PP);
 
   // Save the current VMTag on the stack.
-  ASSERT(kSavedVMTagSlotFromEntryFp == -20);
   __ LoadFromOffset(R4, R5, Isolate::vm_tag_offset(), PP);
   __ Push(R4);
 
@@ -880,19 +810,9 @@
   __ LoadFromOffset(R6, R5, Isolate::top_exit_frame_info_offset(), PP);
   __ StoreToOffset(ZR, R5, Isolate::top_exit_frame_info_offset(), PP);
 
-  // Save the old Context pointer. Use R4 as a temporary register.
-  // Note that VisitObjectPointers will find this saved Context pointer during
-  // GC marking, since it traverses any information between SP and
-  // FP - kExitLinkSlotFromEntryFp.
-  // EntryFrame::SavedContext reads the context saved in this frame.
-  __ LoadFromOffset(R4, R5, Isolate::top_context_offset(), PP);
-
-  // The constants kSavedContextSlotFromEntryFp and
   // kExitLinkSlotFromEntryFp must be kept in sync with the code below.
-  ASSERT(kExitLinkSlotFromEntryFp == -21);
-  ASSERT(kSavedContextSlotFromEntryFp == -22);
+  ASSERT(kExitLinkSlotFromEntryFp == -20);
   __ Push(R6);
-  __ Push(R4);
 
   // Load arguments descriptor array into R4, which is passed to Dart code.
   __ LoadFromOffset(R4, R1, VMHandles::kOffsetOfRawPtrInHandle, PP);
@@ -928,26 +848,18 @@
   __ LoadPoolPointer(PP);
 
   // Get rid of arguments pushed on the stack.
-  __ AddImmediate(SP, FP, kSavedContextSlotFromEntryFp * kWordSize, PP);
+  __ AddImmediate(SP, FP, kExitLinkSlotFromEntryFp * kWordSize, PP);
 
-  // Load Isolate pointer into CTX.
-  __ LoadIsolate(CTX, PP);
+  __ LoadIsolate(R28, PP);
 
-  // Restore the current VMTag from the stack.
-  __ ldr(R4, Address(SP, 2 * kWordSize));
-  __ StoreToOffset(R4, CTX, Isolate::vm_tag_offset(), PP);
-
-  // Restore the saved Context pointer into the Isolate structure.
-  // Uses R4 as a temporary register for this.
   // Restore the saved top exit frame info back into the Isolate structure.
   // Uses R6 as a temporary register for this.
-  __ Pop(R4);
   __ Pop(R6);
-  __ StoreToOffset(R4, CTX, Isolate::top_context_offset(), PP);
-  __ StoreToOffset(R6, CTX, Isolate::top_exit_frame_info_offset(), PP);
+  __ StoreToOffset(R6, R28, Isolate::top_exit_frame_info_offset(), PP);
 
-  __ Pop(R3);
+  // Restore the current VMTag from the stack.
   __ Pop(R4);
+  __ StoreToOffset(R4, R28, Isolate::vm_tag_offset(), PP);
 
   // Restore the bottom 64-bits of callee-saved V registers.
   for (int i = kAbiLastPreservedFpuReg; i >= kAbiFirstPreservedFpuReg; i--) {
diff --git a/runtime/vm/stub_code_arm64_test.cc b/runtime/vm/stub_code_arm64_test.cc
index 94da954..94e40ab 100644
--- a/runtime/vm/stub_code_arm64_test.cc
+++ b/runtime/vm/stub_code_arm64_test.cc
@@ -44,9 +44,7 @@
   const int argc = 2;
   const Smi& smi1 = Smi::ZoneHandle(Smi::New(value1));
   const Smi& smi2 = Smi::ZoneHandle(Smi::New(value2));
-  const Context& context = Context::ZoneHandle(Context::New(0, Heap::kOld));
   __ EnterDartFrame(0);
-  __ LoadObject(CTX, context, PP);
   __ PushObject(Object::null_object(), PP);  // Push Null obj for return value.
   __ PushObject(smi1, PP);  // Push argument 1 smi1.
   __ PushObject(smi2, PP);  // Push argument 2 smi2.
diff --git a/runtime/vm/stub_code_arm_test.cc b/runtime/vm/stub_code_arm_test.cc
index 9cd96ab..986007f 100644
--- a/runtime/vm/stub_code_arm_test.cc
+++ b/runtime/vm/stub_code_arm_test.cc
@@ -44,9 +44,7 @@
   const int argc = 2;
   const Smi& smi1 = Smi::ZoneHandle(Smi::New(value1));
   const Smi& smi2 = Smi::ZoneHandle(Smi::New(value2));
-  const Context& context = Context::ZoneHandle(Context::New(0, Heap::kOld));
   __ EnterDartFrame(0);
-  __ LoadObject(CTX, context);
   __ PushObject(Object::null_object());  // Push Null object for return value.
   __ PushObject(smi1);  // Push argument 1 smi1.
   __ PushObject(smi2);  // Push argument 2 smi2.
diff --git a/runtime/vm/stub_code_ia32.cc b/runtime/vm/stub_code_ia32.cc
index 5b336a4..763d2e5 100644
--- a/runtime/vm/stub_code_ia32.cc
+++ b/runtime/vm/stub_code_ia32.cc
@@ -47,36 +47,17 @@
 
   __ EnterFrame(0);
 
-  __ LoadIsolate(EAX);
+  __ LoadIsolate(ESI);
 
   // Save exit frame information to enable stack walking as we are about
   // to transition to Dart VM C++ code.
-  __ movl(Address(EAX, Isolate::top_exit_frame_info_offset()), ESP);
-
-#if defined(DEBUG)
-  if (FLAG_verify_incoming_contexts) {
-    Label ok;
-    // Check that the isolate's saved ctx is null.
-    const Immediate& raw_null =
-        Immediate(reinterpret_cast<intptr_t>(Object::null()));
-    __ cmpl(Address(EAX, Isolate::top_context_offset()), raw_null);
-    __ j(EQUAL, &ok, Assembler::kNearJump);
-    __ Stop("Found non-null incoming top context: call to runtime stub");
-    __ Bind(&ok);
-  }
-#endif
-
-  // Save current Context pointer into Isolate structure.
-  __ movl(Address(EAX, Isolate::top_context_offset()), CTX);
-
-  // Cache Isolate pointer into CTX while executing runtime code.
-  __ movl(CTX, EAX);
+  __ movl(Address(ESI, Isolate::top_exit_frame_info_offset()), ESP);
 
 #if defined(DEBUG)
   { Label ok;
     // Check that we are always entering from Dart code.
-    __ movl(EAX, Address(CTX, Isolate::vm_tag_offset()));
-    __ cmpl(EAX, Immediate(VMTag::kDartTagId));
+    __ cmpl(Address(ESI, Isolate::vm_tag_offset()),
+            Immediate(VMTag::kDartTagId));
     __ j(EQUAL, &ok, Assembler::kNearJump);
     __ Stop("Not coming from Dart code.");
     __ Bind(&ok);
@@ -84,7 +65,7 @@
 #endif
 
   // Mark that the isolate is executing VM code.
-  __ movl(Address(CTX, Isolate::vm_tag_offset()), ECX);
+  __ movl(Address(ESI, Isolate::vm_tag_offset()), ECX);
 
   // Reserve space for arguments and align frame before entering C++ world.
   __ AddImmediate(ESP, Immediate(-INT32_SIZEOF(NativeArguments)));
@@ -93,7 +74,7 @@
   }
 
   // Pass NativeArguments structure by value and call runtime.
-  __ movl(Address(ESP, isolate_offset), CTX);  // Set isolate in NativeArgs.
+  __ movl(Address(ESP, isolate_offset), ESI);  // Set isolate in NativeArgs.
   // There are no runtime calls to closures, so we do not need to set the tag
   // bits kClosureFunctionBit and kInstanceFunctionBit in argc_tag_.
   __ movl(Address(ESP, argc_tag_offset), EDX);  // Set argc in NativeArguments.
@@ -103,23 +84,12 @@
   __ movl(Address(ESP, retval_offset), EAX);  // Set retval in NativeArguments.
   __ call(ECX);
 
-  // Mark that the isolate is executing Dart code.
-  __ movl(Address(CTX, Isolate::vm_tag_offset()),
+  // Mark that the isolate is executing Dart code. ESI is callee saved.
+  __ movl(Address(ESI, Isolate::vm_tag_offset()),
           Immediate(VMTag::kDartTagId));
 
   // Reset exit frame information in Isolate structure.
-  __ movl(Address(CTX, Isolate::top_exit_frame_info_offset()), Immediate(0));
-
-  // Load Context pointer from Isolate structure into ECX.
-  __ movl(ECX, Address(CTX, Isolate::top_context_offset()));
-
-  // Reset Context pointer in Isolate structure.
-  const Immediate& raw_null =
-      Immediate(reinterpret_cast<intptr_t>(Object::null()));
-  __ movl(Address(CTX, Isolate::top_context_offset()), raw_null);
-
-  // Cache Context pointer into CTX while executing Dart code.
-  __ movl(CTX, ECX);
+  __ movl(Address(ESI, Isolate::top_exit_frame_info_offset()), Immediate(0));
 
   __ LeaveFrame();
   __ ret();
@@ -167,37 +137,17 @@
 
   __ EnterFrame(0);
 
-  __ LoadIsolate(EDI);
+  __ LoadIsolate(ESI);
 
   // Save exit frame information to enable stack walking as we are about
   // to transition to dart VM code.
-  __ movl(Address(EDI, Isolate::top_exit_frame_info_offset()), ESP);
-
-#if defined(DEBUG)
-  if (FLAG_verify_incoming_contexts) {
-    Label ok;
-    // Check that the isolate's saved ctx is null.
-    const Immediate& raw_null =
-        Immediate(reinterpret_cast<intptr_t>(Object::null()));
-    __ cmpl(Address(EDI, Isolate::top_context_offset()), raw_null);
-    __ j(EQUAL, &ok, Assembler::kNearJump);
-    __ Stop("Found non-null incoming top context: "
-            "call to native c function stub");
-    __ Bind(&ok);
-  }
-#endif
-
-  // Save current Context pointer into Isolate structure.
-  __ movl(Address(EDI, Isolate::top_context_offset()), CTX);
-
-  // Cache Isolate pointer into CTX while executing native code.
-  __ movl(CTX, EDI);
+  __ movl(Address(ESI, Isolate::top_exit_frame_info_offset()), ESP);
 
 #if defined(DEBUG)
   { Label ok;
     // Check that we are always entering from Dart code.
-    __ movl(EDI, Address(CTX, Isolate::vm_tag_offset()));
-    __ cmpl(EDI, Immediate(VMTag::kDartTagId));
+    __ cmpl(Address(ESI, Isolate::vm_tag_offset()),
+            Immediate(VMTag::kDartTagId));
     __ j(EQUAL, &ok, Assembler::kNearJump);
     __ Stop("Not coming from Dart code.");
     __ Bind(&ok);
@@ -205,7 +155,7 @@
 #endif
 
   // Mark that the isolate is executing Native code.
-  __ movl(Address(CTX, Isolate::vm_tag_offset()), ECX);
+  __ movl(Address(ESI, Isolate::vm_tag_offset()), ECX);
 
   // Reserve space for the native arguments structure, the outgoing parameters
   // (pointer to the native arguments structure, the C function entry point)
@@ -217,7 +167,7 @@
   }
 
   // Pass NativeArguments structure by value and call native function.
-  __ movl(Address(ESP, isolate_offset), CTX);  // Set isolate in NativeArgs.
+  __ movl(Address(ESP, isolate_offset), ESI);  // Set isolate in NativeArgs.
   __ movl(Address(ESP, argc_tag_offset), EDX);  // Set argc in NativeArguments.
   __ movl(Address(ESP, argv_offset), EAX);  // Set argv in NativeArguments.
   __ leal(EAX, Address(EBP, 2 * kWordSize));  // Compute return value addr.
@@ -228,23 +178,12 @@
   __ movl(Address(ESP, kWordSize), ECX);  // Function to call.
   __ call(&NativeEntry::NativeCallWrapperLabel());
 
-  // Mark that the isolate is executing Dart code.
-  __ movl(Address(CTX, Isolate::vm_tag_offset()),
+  // Mark that the isolate is executing Dart code. ESI is callee saved.
+  __ movl(Address(ESI, Isolate::vm_tag_offset()),
           Immediate(VMTag::kDartTagId));
 
   // Reset exit frame information in Isolate structure.
-  __ movl(Address(CTX, Isolate::top_exit_frame_info_offset()), Immediate(0));
-
-  // Load Context pointer from Isolate structure into EDI.
-  __ movl(EDI, Address(CTX, Isolate::top_context_offset()));
-
-  // Reset Context pointer in Isolate structure.
-  const Immediate& raw_null =
-      Immediate(reinterpret_cast<intptr_t>(Object::null()));
-  __ movl(Address(CTX, Isolate::top_context_offset()), raw_null);
-
-  // Cache Context pointer into CTX while executing Dart code.
-  __ movl(CTX, EDI);
+  __ movl(Address(ESI, Isolate::top_exit_frame_info_offset()), Immediate(0));
 
   __ LeaveFrame();
   __ ret();
@@ -271,37 +210,17 @@
 
   __ EnterFrame(0);
 
-  __ LoadIsolate(EDI);
+  __ LoadIsolate(ESI);
 
   // Save exit frame information to enable stack walking as we are about
   // to transition to dart VM code.
-  __ movl(Address(EDI, Isolate::top_exit_frame_info_offset()), ESP);
-
-#if defined(DEBUG)
-  if (FLAG_verify_incoming_contexts) {
-    Label ok;
-    // Check that the isolate's saved ctx is null.
-    const Immediate& raw_null =
-        Immediate(reinterpret_cast<intptr_t>(Object::null()));
-    __ cmpl(Address(EDI, Isolate::top_context_offset()), raw_null);
-    __ j(EQUAL, &ok, Assembler::kNearJump);
-    __ Stop("Found non-null incoming top context: "
-            "call to bootstrap c function stub");
-    __ Bind(&ok);
-  }
-#endif
-
-  // Save current Context pointer into Isolate structure.
-  __ movl(Address(EDI, Isolate::top_context_offset()), CTX);
-
-  // Cache Isolate pointer into CTX while executing native code.
-  __ movl(CTX, EDI);
+  __ movl(Address(ESI, Isolate::top_exit_frame_info_offset()), ESP);
 
 #if defined(DEBUG)
   { Label ok;
     // Check that we are always entering from Dart code.
-    __ movl(EDI, Address(CTX, Isolate::vm_tag_offset()));
-    __ cmpl(EDI, Immediate(VMTag::kDartTagId));
+    __ cmpl(Address(ESI, Isolate::vm_tag_offset()),
+            Immediate(VMTag::kDartTagId));
     __ j(EQUAL, &ok, Assembler::kNearJump);
     __ Stop("Not coming from Dart code.");
     __ Bind(&ok);
@@ -309,7 +228,7 @@
 #endif
 
   // Mark that the isolate is executing Native code.
-  __ movl(Address(CTX, Isolate::vm_tag_offset()), ECX);
+  __ movl(Address(ESI, Isolate::vm_tag_offset()), ECX);
 
   // Reserve space for the native arguments structure, the outgoing parameter
   // (pointer to the native arguments structure) and align frame before
@@ -320,7 +239,7 @@
   }
 
   // Pass NativeArguments structure by value and call native function.
-  __ movl(Address(ESP, isolate_offset), CTX);  // Set isolate in NativeArgs.
+  __ movl(Address(ESP, isolate_offset), ESI);  // Set isolate in NativeArgs.
   __ movl(Address(ESP, argc_tag_offset), EDX);  // Set argc in NativeArguments.
   __ movl(Address(ESP, argv_offset), EAX);  // Set argv in NativeArguments.
   __ leal(EAX, Address(EBP, 2 * kWordSize));  // Compute return value addr.
@@ -329,23 +248,12 @@
   __ movl(Address(ESP, 0), EAX);  // Pass the pointer to the NativeArguments.
   __ call(ECX);
 
-  // Mark that the isolate is executing Dart code.
-  __ movl(Address(CTX, Isolate::vm_tag_offset()),
+  // Mark that the isolate is executing Dart code. ESI is callee saved.
+  __ movl(Address(ESI, Isolate::vm_tag_offset()),
           Immediate(VMTag::kDartTagId));
 
   // Reset exit frame information in Isolate structure.
-  __ movl(Address(CTX, Isolate::top_exit_frame_info_offset()), Immediate(0));
-
-  // Load Context pointer from Isolate structure into EDI.
-  __ movl(EDI, Address(CTX, Isolate::top_context_offset()));
-
-  // Reset Context pointer in Isolate structure.
-  const Immediate& raw_null =
-      Immediate(reinterpret_cast<intptr_t>(Object::null()));
-  __ movl(Address(CTX, Isolate::top_context_offset()), raw_null);
-
-  // Cache Context pointer into CTX while executing Dart code.
-  __ movl(CTX, EDI);
+  __ movl(Address(ESI, Isolate::top_exit_frame_info_offset()), Immediate(0));
 
   __ LeaveFrame();
   __ ret();
@@ -779,13 +687,11 @@
 //   ESP + 4 : entrypoint of the dart function to call.
 //   ESP + 8 : arguments descriptor array.
 //   ESP + 12 : arguments array.
-//   ESP + 16 : new context containing the current isolate pointer.
 // Uses EAX, EDX, ECX, EDI as temporary registers.
 void StubCode::GenerateInvokeDartCodeStub(Assembler* assembler) {
   const intptr_t kEntryPointOffset = 2 * kWordSize;
   const intptr_t kArgumentsDescOffset = 3 * kWordSize;
   const intptr_t kArgumentsOffset = 4 * kWordSize;
-  const intptr_t kNewContextOffset = 5 * kWordSize;
 
   // Save frame pointer coming in.
   __ EnterFrame(0);
@@ -795,25 +701,14 @@
   __ pushl(ESI);
   __ pushl(EDI);
 
-  // The new Context structure contains a pointer to the current Isolate
-  // structure. Cache the Context pointer in the CTX register so that it is
-  // available in generated code and calls to Isolate::Current() need not be
-  // done. The assumption is that this register will never be clobbered by
-  // compiled or runtime stub code.
-
-  // Cache the new Context pointer into CTX while executing dart code.
-  __ movl(CTX, Address(EBP, kNewContextOffset));
-  __ movl(CTX, Address(CTX, VMHandles::kOffsetOfRawPtrInHandle));
-
-  __ LoadIsolate(EDI);
+  __ LoadIsolate(ESI);
 
   // Save the current VMTag on the stack.
-  ASSERT(kSavedVMTagSlotFromEntryFp == -4);
-  __ movl(ECX, Address(EDI, Isolate::vm_tag_offset()));
+  __ movl(ECX, Address(ESI, Isolate::vm_tag_offset()));
   __ pushl(ECX);
 
   // Mark that the isolate is executing Dart code.
-  __ movl(Address(EDI, Isolate::vm_tag_offset()),
+  __ movl(Address(ESI, Isolate::vm_tag_offset()),
           Immediate(VMTag::kDartTagId));
 
   // Save the top exit frame info. Use EDX as a temporary register.
@@ -821,32 +716,9 @@
   // The constant kExitLinkSlotFromEntryFp must be kept in sync with the
   // code below.
   ASSERT(kExitLinkSlotFromEntryFp == -5);
-  __ movl(EDX, Address(EDI, Isolate::top_exit_frame_info_offset()));
+  __ movl(EDX, Address(ESI, Isolate::top_exit_frame_info_offset()));
   __ pushl(EDX);
-  __ movl(Address(EDI, Isolate::top_exit_frame_info_offset()), Immediate(0));
-
-  // Save the old Context pointer. Use ECX as a temporary register.
-  // Note that VisitObjectPointers will find this saved Context pointer during
-  // GC marking, since it traverses any information between SP and
-  // FP - kExitLinkSlotFromEntryFp.
-  // EntryFrame::SavedContext reads the context saved in this frame.
-  // The constant kSavedContextSlotFromEntryFp must be kept in sync with
-  // the code below.
-  ASSERT(kSavedContextSlotFromEntryFp == -6);
-  __ movl(ECX, Address(EDI, Isolate::top_context_offset()));
-  __ pushl(ECX);
-
-  // TODO(turnidge): This code should probably be emitted all the time
-  // on all architectures but I am leaving it under DEBUG/flag for
-  // now.
-#if defined(DEBUG)
-  if (FLAG_verify_incoming_contexts) {
-    // Clear Context pointer in Isolate structure.
-    const Immediate& raw_null =
-        Immediate(reinterpret_cast<intptr_t>(Object::null()));
-    __ movl(Address(EDI, Isolate::top_context_offset()), raw_null);
-  }
-#endif
+  __ movl(Address(ESI, Isolate::top_exit_frame_info_offset()), Immediate(0));
 
   // Load arguments descriptor array into EDX.
   __ movl(EDX, Address(EBP, kArgumentsDescOffset));
@@ -887,17 +759,12 @@
   // Get rid of arguments pushed on the stack.
   __ leal(ESP, Address(ESP, EDX, TIMES_2, 0));  // EDX is a Smi.
 
-  // Load Isolate pointer into CTX.
-  __ LoadIsolate(CTX);
-
-  // Restore the saved Context pointer into the Isolate structure.
-  __ popl(Address(CTX, Isolate::top_context_offset()));
-
   // Restore the saved top exit frame info back into the Isolate structure.
-  __ popl(Address(CTX, Isolate::top_exit_frame_info_offset()));
+  __ LoadIsolate(ESI);
+  __ popl(Address(ESI, Isolate::top_exit_frame_info_offset()));
 
   // Restore the current VMTag from the stack.
-  __ popl(Address(CTX, Isolate::vm_tag_offset()));
+  __ popl(Address(ESI, Isolate::vm_tag_offset()));
 
   // Restore C++ ABI callee-saved registers.
   __ popl(EDI);
diff --git a/runtime/vm/stub_code_ia32_test.cc b/runtime/vm/stub_code_ia32_test.cc
index 468a607..ce07b83 100644
--- a/runtime/vm/stub_code_ia32_test.cc
+++ b/runtime/vm/stub_code_ia32_test.cc
@@ -44,9 +44,7 @@
   const int argc = 2;
   const Smi& smi1 = Smi::ZoneHandle(Smi::New(value1));
   const Smi& smi2 = Smi::ZoneHandle(Smi::New(value2));
-  const Context& context = Context::ZoneHandle(Context::New(0, Heap::kOld));
   __ enter(Immediate(0));
-  __ LoadObject(CTX, context);
   __ PushObject(Object::null_object());  // Push Null object for return value.
   __ PushObject(smi1);  // Push argument 1 smi1.
   __ PushObject(smi2);  // Push argument 2 smi2.
diff --git a/runtime/vm/stub_code_mips.cc b/runtime/vm/stub_code_mips.cc
index 9cfd32f..55f533f 100644
--- a/runtime/vm/stub_code_mips.cc
+++ b/runtime/vm/stub_code_mips.cc
@@ -48,22 +48,17 @@
   __ sw(FP, Address(SP, 0 * kWordSize));
   __ mov(FP, SP);
 
-  __ LoadIsolate(A0);
+  COMPILE_ASSERT((kAbiPreservedCpuRegs & (1 << S6)) != 0);
+  __ LoadIsolate(S6);
 
   // Save exit frame information to enable stack walking as we are about
   // to transition to Dart VM C++ code.
-  __ sw(SP, Address(A0, Isolate::top_exit_frame_info_offset()));
-
-  // Save current Context pointer into Isolate structure.
-  __ sw(CTX, Address(A0, Isolate::top_context_offset()));
-
-  // Cache Isolate pointer into CTX while executing runtime code.
-  __ mov(CTX, A0);
+  __ sw(SP, Address(S6, Isolate::top_exit_frame_info_offset()));
 
 #if defined(DEBUG)
   { Label ok;
     // Check that we are always entering from Dart code.
-    __ lw(T0, Address(A0, Isolate::vm_tag_offset()));
+    __ lw(T0, Address(S6, Isolate::vm_tag_offset()));
     __ BranchEqual(T0, Immediate(VMTag::kDartTagId), &ok);
     __ Stop("Not coming from Dart code.");
     __ Bind(&ok);
@@ -71,7 +66,7 @@
 #endif
 
   // Mark that the isolate is executing VM code.
-  __ sw(S5, Address(A0, Isolate::vm_tag_offset()));
+  __ sw(S5, Address(S6, Isolate::vm_tag_offset()));
 
   // Reserve space for arguments and align frame before entering C++ world.
   // NativeArguments are passed in registers.
@@ -82,7 +77,8 @@
   // Registers A0, A1, A2, and A3 are used.
 
   ASSERT(isolate_offset == 0 * kWordSize);
-  // Set isolate in NativeArgs: A0 already contains CTX.
+  // Set isolate in NativeArgs.
+  __ mov(A0, S6);
 
   // There are no runtime calls to closures, so we do not need to set the tag
   // bits kClosureFunctionBit and kInstanceFunctionBit in argc_tag_.
@@ -109,22 +105,10 @@
 
   // Mark that the isolate is executing Dart code.
   __ LoadImmediate(A2, VMTag::kDartTagId);
-  __ sw(A2, Address(CTX, Isolate::vm_tag_offset()));
+  __ sw(A2, Address(S6, Isolate::vm_tag_offset()));
 
   // Reset exit frame information in Isolate structure.
-  __ sw(ZR, Address(CTX, Isolate::top_exit_frame_info_offset()));
-
-  // Load Context pointer from Isolate structure into A2.
-  __ lw(A2, Address(CTX, Isolate::top_context_offset()));
-
-  // Load null.
-  __ LoadImmediate(TMP, reinterpret_cast<intptr_t>(Object::null()));
-
-  // Reset Context pointer in Isolate structure.
-  __ sw(TMP, Address(CTX, Isolate::top_context_offset()));
-
-  // Cache Context pointer into CTX while executing Dart code.
-  __ mov(CTX, A2);
+  __ sw(ZR, Address(S6, Isolate::top_exit_frame_info_offset()));
 
   __ mov(SP, FP);
   __ lw(RA, Address(SP, 1 * kWordSize));
@@ -173,22 +157,17 @@
   __ sw(FP, Address(SP, 0 * kWordSize));
   __ mov(FP, SP);
 
-  __ LoadIsolate(A0);
+  COMPILE_ASSERT((kAbiPreservedCpuRegs & (1 << S6)) != 0);
+  __ LoadIsolate(S6);
 
   // Save exit frame information to enable stack walking as we are about
   // to transition to native code.
-  __ sw(SP, Address(A0, Isolate::top_exit_frame_info_offset()));
-
-  // Save current Context pointer into Isolate structure.
-  __ sw(CTX, Address(A0, Isolate::top_context_offset()));
-
-  // Cache Isolate pointer into CTX while executing native code.
-  __ mov(CTX, A0);
+  __ sw(SP, Address(S6, Isolate::top_exit_frame_info_offset()));
 
 #if defined(DEBUG)
   { Label ok;
     // Check that we are always entering from Dart code.
-    __ lw(T0, Address(A0, Isolate::vm_tag_offset()));
+    __ lw(T0, Address(S6, Isolate::vm_tag_offset()));
     __ BranchEqual(T0, Immediate(VMTag::kDartTagId), &ok);
     __ Stop("Not coming from Dart code.");
     __ Bind(&ok);
@@ -196,13 +175,14 @@
 #endif
 
   // Mark that the isolate is executing Native code.
-  __ sw(T5, Address(A0, Isolate::vm_tag_offset()));
+  __ sw(T5, Address(S6, Isolate::vm_tag_offset()));
 
   // Initialize NativeArguments structure and call native function.
   // Registers A0, A1, A2, and A3 are used.
 
   ASSERT(isolate_offset == 0 * kWordSize);
-  // Set isolate in NativeArgs: A0 already contains CTX.
+  // Set isolate in NativeArgs.
+  __ mov(A0, S6);
 
   // There are no native calls to closures, so we do not need to set the tag
   // bits kClosureFunctionBit and kInstanceFunctionBit in argc_tag_.
@@ -242,22 +222,10 @@
 
   // Mark that the isolate is executing Dart code.
   __ LoadImmediate(A2, VMTag::kDartTagId);
-  __ sw(A2, Address(CTX, Isolate::vm_tag_offset()));
+  __ sw(A2, Address(S6, Isolate::vm_tag_offset()));
 
   // Reset exit frame information in Isolate structure.
-  __ sw(ZR, Address(CTX, Isolate::top_exit_frame_info_offset()));
-
-  // Load Context pointer from Isolate structure into A2.
-  __ lw(A2, Address(CTX, Isolate::top_context_offset()));
-
-  // Load null.
-  __ LoadImmediate(TMP, reinterpret_cast<intptr_t>(Object::null()));
-
-  // Reset Context pointer in Isolate structure.
-  __ sw(TMP, Address(CTX, Isolate::top_context_offset()));
-
-  // Cache Context pointer into CTX while executing Dart code.
-  __ mov(CTX, A2);
+  __ sw(ZR, Address(S6, Isolate::top_exit_frame_info_offset()));
 
   __ mov(SP, FP);
   __ lw(RA, Address(SP, 1 * kWordSize));
@@ -287,22 +255,17 @@
   __ sw(FP, Address(SP, 0 * kWordSize));
   __ mov(FP, SP);
 
-  __ LoadIsolate(A0);
+  COMPILE_ASSERT((kAbiPreservedCpuRegs & (1 << S6)) != 0);
+  __ LoadIsolate(S6);
 
   // Save exit frame information to enable stack walking as we are about
   // to transition to native code.
-  __ sw(SP, Address(A0, Isolate::top_exit_frame_info_offset()));
-
-  // Save current Context pointer into Isolate structure.
-  __ sw(CTX, Address(A0, Isolate::top_context_offset()));
-
-  // Cache Isolate pointer into CTX while executing native code.
-  __ mov(CTX, A0);
+  __ sw(SP, Address(S6, Isolate::top_exit_frame_info_offset()));
 
 #if defined(DEBUG)
   { Label ok;
     // Check that we are always entering from Dart code.
-    __ lw(T0, Address(A0, Isolate::vm_tag_offset()));
+    __ lw(T0, Address(S6, Isolate::vm_tag_offset()));
     __ BranchEqual(T0, Immediate(VMTag::kDartTagId), &ok);
     __ Stop("Not coming from Dart code.");
     __ Bind(&ok);
@@ -310,13 +273,14 @@
 #endif
 
   // Mark that the isolate is executing Native code.
-  __ sw(T5, Address(A0, Isolate::vm_tag_offset()));
+  __ sw(T5, Address(S6, Isolate::vm_tag_offset()));
 
   // Initialize NativeArguments structure and call native function.
   // Registers A0, A1, A2, and A3 are used.
 
   ASSERT(isolate_offset == 0 * kWordSize);
-  // Set isolate in NativeArgs: A0 already contains CTX.
+  // Set isolate in NativeArgs.
+  __ mov(A0, S6);
 
   // There are no native calls to closures, so we do not need to set the tag
   // bits kClosureFunctionBit and kInstanceFunctionBit in argc_tag_.
@@ -351,22 +315,10 @@
 
   // Mark that the isolate is executing Dart code.
   __ LoadImmediate(A2, VMTag::kDartTagId);
-  __ sw(A2, Address(CTX, Isolate::vm_tag_offset()));
+  __ sw(A2, Address(S6, Isolate::vm_tag_offset()));
 
   // Reset exit frame information in Isolate structure.
-  __ sw(ZR, Address(CTX, Isolate::top_exit_frame_info_offset()));
-
-  // Load Context pointer from Isolate structure into A2.
-  __ lw(A2, Address(CTX, Isolate::top_context_offset()));
-
-  // Load null.
-  __ LoadImmediate(TMP, reinterpret_cast<intptr_t>(Object::null()));
-
-  // Reset Context pointer in Isolate structure.
-  __ sw(TMP, Address(CTX, Isolate::top_context_offset()));
-
-  // Cache Context pointer into CTX while executing Dart code.
-  __ mov(CTX, A2);
+  __ sw(ZR, Address(S6, Isolate::top_exit_frame_info_offset()));
 
   __ mov(SP, FP);
   __ lw(RA, Address(SP, 1 * kWordSize));
@@ -860,7 +812,6 @@
 //   A0 : entrypoint of the Dart function to call.
 //   A1 : arguments descriptor array.
 //   A2 : arguments array.
-//   A3 : new context containing the current isolate pointer.
 void StubCode::GenerateInvokeDartCodeStub(Assembler* assembler) {
   // Save frame pointer coming in.
   __ TraceSimMsg("InvokeDartCodeStub");
@@ -868,16 +819,16 @@
 
   // Save new context and C++ ABI callee-saved registers.
 
-  // The new context, saved vm tag, the top exit frame, and the old context.
-  const intptr_t kPreservedContextSlots = 4;
+  // The saved vm tag and the top exit frame.
+  const intptr_t kPreservedSlots = 2;
   const intptr_t kPreservedRegSpace =
       kWordSize * (kAbiPreservedCpuRegCount + kAbiPreservedFpuRegCount +
-                   kPreservedContextSlots);
+                   kPreservedSlots);
 
   __ addiu(SP, SP, Immediate(-kPreservedRegSpace));
   for (int i = S0; i <= S7; i++) {
     Register r = static_cast<Register>(i);
-    const intptr_t slot = i - S0 + kPreservedContextSlots;
+    const intptr_t slot = i - S0 + kPreservedSlots;
     __ sw(r, Address(SP, slot * kWordSize));
   }
 
@@ -885,33 +836,21 @@
        i <= kAbiLastPreservedFpuReg; i++) {
     FRegister r = static_cast<FRegister>(i);
     const intptr_t slot =
-        kAbiPreservedCpuRegCount + kPreservedContextSlots + i -
+        kAbiPreservedCpuRegCount + kPreservedSlots + i -
         kAbiFirstPreservedFpuReg;
     __ swc1(r, Address(SP, slot * kWordSize));
   }
 
-  __ sw(A3, Address(SP, 3 * kWordSize));
-
   // We now load the pool pointer(PP) as we are about to invoke dart code and we
   // could potentially invoke some intrinsic functions which need the PP to be
   // set up.
   __ LoadPoolPointer();
 
-  // The new Context structure contains a pointer to the current Isolate
-  // structure. Cache the Context pointer in the CTX register so that it is
-  // available in generated code and calls to Isolate::Current() need not be
-  // done. The assumption is that this register will never be clobbered by
-  // compiled or runtime stub code.
-
-  // Cache the new Context pointer into CTX while executing Dart code.
-  __ lw(CTX, Address(A3, VMHandles::kOffsetOfRawPtrInHandle));
-
   __ LoadIsolate(T2);
 
   // Save the current VMTag on the stack.
-  ASSERT(kSavedVMTagSlotFromEntryFp == -22);
   __ lw(T1, Address(T2, Isolate::vm_tag_offset()));
-  __ sw(T1, Address(SP, 2 * kWordSize));
+  __ sw(T1, Address(SP, 1 * kWordSize));
 
   // Mark that the isolate is executing Dart code.
   __ LoadImmediate(T0, VMTag::kDartTagId);
@@ -922,22 +861,12 @@
   __ lw(T0, Address(T2, Isolate::top_exit_frame_info_offset()));
   __ sw(ZR, Address(T2, Isolate::top_exit_frame_info_offset()));
 
-  // Save the old Context pointer. Use T1 as a temporary register.
-  // Note that VisitObjectPointers will find this saved Context pointer during
-  // GC marking, since it traverses any information between SP and
-  // FP - kExitLinkSlotFromEntryFp.
-  // EntryFrame::SavedContext reads the context saved in this frame.
-  __ lw(T1, Address(T2, Isolate::top_context_offset()));
-
-  // The constants kSavedContextSlotFromEntryFp and
   // kExitLinkSlotFromEntryFp must be kept in sync with the code below.
-  ASSERT(kExitLinkSlotFromEntryFp == -23);
-  ASSERT(kSavedContextSlotFromEntryFp == -24);
-  __ sw(T0, Address(SP, 1 * kWordSize));
-  __ sw(T1, Address(SP, 0 * kWordSize));
+  ASSERT(kExitLinkSlotFromEntryFp == -22);
+  __ sw(T0, Address(SP, 0 * kWordSize));
 
   // After the call, The stack pointer is restored to this location.
-  // Pushed A3, S0-7, F20-31, T0, T1 = 23.
+  // Pushed S0-7, F20-31, T0, T1 = 22.
 
   // Load arguments descriptor array into S4, which is passed to Dart code.
   __ lw(S4, Address(A1, VMHandles::kOffsetOfRawPtrInHandle));
@@ -972,28 +901,23 @@
   __ TraceSimMsg("InvokeDartCodeStub return");
 
   // Get rid of arguments pushed on the stack.
-  __ AddImmediate(SP, FP, kSavedContextSlotFromEntryFp * kWordSize);
+  __ AddImmediate(SP, FP, kExitLinkSlotFromEntryFp * kWordSize);
 
-  // Load Isolate pointer into CTX.
-  __ LoadIsolate(CTX);
+  __ LoadIsolate(S6);
 
   // Restore the current VMTag from the stack.
-  __ lw(T1, Address(SP, 2 * kWordSize));
-  __ sw(T1, Address(CTX, Isolate::vm_tag_offset()));
+  __ lw(T1, Address(SP, 1 * kWordSize));
+  __ sw(T1, Address(S6, Isolate::vm_tag_offset()));
 
-  // Restore the saved Context pointer into the Isolate structure.
-  // Uses T1 as a temporary register for this.
   // Restore the saved top exit frame info back into the Isolate structure.
   // Uses T0 as a temporary register for this.
-  __ lw(T1, Address(SP, 0 * kWordSize));
-  __ lw(T0, Address(SP, 1 * kWordSize));
-  __ sw(T1, Address(CTX, Isolate::top_context_offset()));
-  __ sw(T0, Address(CTX, Isolate::top_exit_frame_info_offset()));
+  __ lw(T0, Address(SP, 0 * kWordSize));
+  __ sw(T0, Address(S6, Isolate::top_exit_frame_info_offset()));
 
   // Restore C++ ABI callee-saved registers.
   for (int i = S0; i <= S7; i++) {
     Register r = static_cast<Register>(i);
-    const intptr_t slot = i - S0 + kPreservedContextSlots;
+    const intptr_t slot = i - S0 + kPreservedSlots;
     __ lw(r, Address(SP, slot * kWordSize));
   }
 
@@ -1001,12 +925,11 @@
        i <= kAbiLastPreservedFpuReg; i++) {
     FRegister r = static_cast<FRegister>(i);
     const intptr_t slot =
-        kAbiPreservedCpuRegCount + kPreservedContextSlots + i -
+        kAbiPreservedCpuRegCount + kPreservedSlots + i -
         kAbiFirstPreservedFpuReg;
     __ lwc1(r, Address(SP, slot * kWordSize));
   }
 
-  __ lw(A3, Address(SP, 3 * kWordSize));
   __ addiu(SP, SP, Immediate(kPreservedRegSpace));
 
   // Restore the frame pointer and return.
diff --git a/runtime/vm/stub_code_mips_test.cc b/runtime/vm/stub_code_mips_test.cc
index 5582ec5..7a87baf 100644
--- a/runtime/vm/stub_code_mips_test.cc
+++ b/runtime/vm/stub_code_mips_test.cc
@@ -44,9 +44,7 @@
   const int argc = 2;
   const Smi& smi1 = Smi::ZoneHandle(Smi::New(value1));
   const Smi& smi2 = Smi::ZoneHandle(Smi::New(value2));
-  const Context& context = Context::ZoneHandle(Context::New(0, Heap::kOld));
   __ EnterDartFrame(0);
-  __ LoadObject(CTX, context);
   __ PushObject(Object::null_object());  // Push Null object for return value.
   __ PushObject(smi1);  // Push argument 1 smi1.
   __ PushObject(smi2);  // Push argument 2 smi2.
diff --git a/runtime/vm/stub_code_x64.cc b/runtime/vm/stub_code_x64.cc
index 7be3f88..c2f69e0 100644
--- a/runtime/vm/stub_code_x64.cc
+++ b/runtime/vm/stub_code_x64.cc
@@ -36,7 +36,6 @@
 //   R10 : number of arguments to the call.
 // Must preserve callee saved registers R12 and R13.
 void StubCode::GenerateCallToRuntimeStub(Assembler* assembler) {
-  ASSERT((R12 != CTX) && (R13 != CTX));
   const intptr_t isolate_offset = NativeArguments::isolate_offset();
   const intptr_t argc_tag_offset = NativeArguments::argc_tag_offset();
   const intptr_t argv_offset = NativeArguments::argv_offset();
@@ -44,23 +43,19 @@
 
   __ EnterFrame(0);
 
-  __ LoadIsolate(RAX);
+  COMPILE_ASSERT(
+      (CallingConventions::kCalleeSaveCpuRegisters & (1 << R12)) != 0);
+  __ LoadIsolate(R12);
 
   // Save exit frame information to enable stack walking as we are about
   // to transition to Dart VM C++ code.
-  __ movq(Address(RAX, Isolate::top_exit_frame_info_offset()), RSP);
-
-  // Save current Context pointer into Isolate structure.
-  __ movq(Address(RAX, Isolate::top_context_offset()), CTX);
-
-  // Cache Isolate pointer into CTX while executing runtime code.
-  __ movq(CTX, RAX);
+  __ movq(Address(R12, Isolate::top_exit_frame_info_offset()), RSP);
 
 #if defined(DEBUG)
   { Label ok;
     // Check that we are always entering from Dart code.
     __ movq(RAX, Immediate(VMTag::kDartTagId));
-    __ cmpq(RAX, Address(CTX, Isolate::vm_tag_offset()));
+    __ cmpq(RAX, Address(R12, Isolate::vm_tag_offset()));
     __ j(EQUAL, &ok, Assembler::kNearJump);
     __ Stop("Not coming from Dart code.");
     __ Bind(&ok);
@@ -68,7 +63,7 @@
 #endif
 
   // Mark that the isolate is executing VM code.
-  __ movq(Address(CTX, Isolate::vm_tag_offset()), RBX);
+  __ movq(Address(R12, Isolate::vm_tag_offset()), RBX);
 
   // Reserve space for arguments and align frame before entering C++ world.
   __ subq(RSP, Immediate(sizeof(NativeArguments)));
@@ -77,7 +72,7 @@
   }
 
   // Pass NativeArguments structure by value and call runtime.
-  __ movq(Address(RSP, isolate_offset), CTX);  // Set isolate in NativeArgs.
+  __ movq(Address(RSP, isolate_offset), R12);  // Set isolate in NativeArgs.
   // There are no runtime calls to closures, so we do not need to set the tag
   // bits kClosureFunctionBit and kInstanceFunctionBit in argc_tag_.
   __ movq(Address(RSP, argc_tag_offset), R10);  // Set argc in NativeArguments.
@@ -92,21 +87,11 @@
   __ CallCFunction(RBX);
 
   // Mark that the isolate is executing Dart code.
-  __ movq(Address(CTX, Isolate::vm_tag_offset()),
+  __ movq(Address(R12, Isolate::vm_tag_offset()),
           Immediate(VMTag::kDartTagId));
 
   // Reset exit frame information in Isolate structure.
-  __ movq(Address(CTX, Isolate::top_exit_frame_info_offset()), Immediate(0));
-
-  // Load Context pointer from Isolate structure into RBX.
-  __ movq(RBX, Address(CTX, Isolate::top_context_offset()));
-
-  // Reset Context pointer in Isolate structure.
-  __ LoadObject(R12, Object::null_object(), PP);
-  __ movq(Address(CTX, Isolate::top_context_offset()), R12);
-
-  // Cache Context pointer into CTX while executing Dart code.
-  __ movq(CTX, RBX);
+  __ movq(Address(R12, Isolate::top_exit_frame_info_offset()), Immediate(0));
 
   __ LeaveFrame();
   __ ret();
@@ -155,23 +140,19 @@
 
   __ EnterFrame(0);
 
-  __ LoadIsolate(R8);
+  COMPILE_ASSERT(
+      (CallingConventions::kCalleeSaveCpuRegisters & (1 << R12)) != 0);
+  __ LoadIsolate(R12);
 
   // Save exit frame information to enable stack walking as we are about
   // to transition to native code.
-  __ movq(Address(R8, Isolate::top_exit_frame_info_offset()), RSP);
-
-// Save current Context pointer into Isolate structure.
-  __ movq(Address(R8, Isolate::top_context_offset()), CTX);
-
-  // Cache Isolate pointer into CTX while executing native code.
-  __ movq(CTX, R8);
+  __ movq(Address(R12, Isolate::top_exit_frame_info_offset()), RSP);
 
 #if defined(DEBUG)
   { Label ok;
     // Check that we are always entering from Dart code.
     __ movq(R8, Immediate(VMTag::kDartTagId));
-    __ cmpq(R8, Address(CTX, Isolate::vm_tag_offset()));
+    __ cmpq(R8, Address(R12, Isolate::vm_tag_offset()));
     __ j(EQUAL, &ok, Assembler::kNearJump);
     __ Stop("Not coming from Dart code.");
     __ Bind(&ok);
@@ -179,7 +160,7 @@
 #endif
 
   // Mark that the isolate is executing Native code.
-  __ movq(Address(CTX, Isolate::vm_tag_offset()), RBX);
+  __ movq(Address(R12, Isolate::vm_tag_offset()), RBX);
 
   // Reserve space for the native arguments structure passed on the stack (the
   // outgoing pointer parameter to the native arguments structure is passed in
@@ -190,7 +171,7 @@
   }
 
   // Pass NativeArguments structure by value and call native function.
-  __ movq(Address(RSP, isolate_offset), CTX);  // Set isolate in NativeArgs.
+  __ movq(Address(RSP, isolate_offset), R12);  // Set isolate in NativeArgs.
   __ movq(Address(RSP, argc_tag_offset), R10);  // Set argc in NativeArguments.
   __ movq(Address(RSP, argv_offset), RAX);  // Set argv in NativeArguments.
   __ leaq(RAX, Address(RBP, 2 * kWordSize));  // Compute return value addr.
@@ -203,21 +184,11 @@
   __ CallCFunction(&NativeEntry::NativeCallWrapperLabel());
 
   // Mark that the isolate is executing Dart code.
-  __ movq(Address(CTX, Isolate::vm_tag_offset()),
+  __ movq(Address(R12, Isolate::vm_tag_offset()),
           Immediate(VMTag::kDartTagId));
 
   // Reset exit frame information in Isolate structure.
-  __ movq(Address(CTX, Isolate::top_exit_frame_info_offset()), Immediate(0));
-
-  // Load Context pointer from Isolate structure into R8.
-  __ movq(R8, Address(CTX, Isolate::top_context_offset()));
-
-  // Reset Context pointer in Isolate structure.
-  __ LoadObject(R12, Object::null_object(), PP);
-  __ movq(Address(CTX, Isolate::top_context_offset()), R12);
-
-  // Cache Context pointer into CTX while executing Dart code.
-  __ movq(CTX, R8);
+  __ movq(Address(R12, Isolate::top_exit_frame_info_offset()), Immediate(0));
 
   __ LeaveFrame();
   __ ret();
@@ -243,23 +214,19 @@
 
   __ EnterFrame(0);
 
-  __ LoadIsolate(R8);
+  COMPILE_ASSERT(
+      (CallingConventions::kCalleeSaveCpuRegisters & (1 << R12)) != 0);
+  __ LoadIsolate(R12);
 
   // Save exit frame information to enable stack walking as we are about
   // to transition to native code.
-  __ movq(Address(R8, Isolate::top_exit_frame_info_offset()), RSP);
-
-  // Save current Context pointer into Isolate structure.
-  __ movq(Address(R8, Isolate::top_context_offset()), CTX);
-
-  // Cache Isolate pointer into CTX while executing native code.
-  __ movq(CTX, R8);
+  __ movq(Address(R12, Isolate::top_exit_frame_info_offset()), RSP);
 
 #if defined(DEBUG)
   { Label ok;
     // Check that we are always entering from Dart code.
     __ movq(R8, Immediate(VMTag::kDartTagId));
-    __ cmpq(R8, Address(CTX, Isolate::vm_tag_offset()));
+    __ cmpq(R8, Address(R12, Isolate::vm_tag_offset()));
     __ j(EQUAL, &ok, Assembler::kNearJump);
     __ Stop("Not coming from Dart code.");
     __ Bind(&ok);
@@ -267,7 +234,7 @@
 #endif
 
   // Mark that the isolate is executing Native code.
-  __ movq(Address(CTX, Isolate::vm_tag_offset()), RBX);
+  __ movq(Address(R12, Isolate::vm_tag_offset()), RBX);
 
   // Reserve space for the native arguments structure passed on the stack (the
   // outgoing pointer parameter to the native arguments structure is passed in
@@ -278,7 +245,7 @@
   }
 
   // Pass NativeArguments structure by value and call native function.
-  __ movq(Address(RSP, isolate_offset), CTX);  // Set isolate in NativeArgs.
+  __ movq(Address(RSP, isolate_offset), R12);  // Set isolate in NativeArgs.
   __ movq(Address(RSP, argc_tag_offset), R10);  // Set argc in NativeArguments.
   __ movq(Address(RSP, argv_offset), RAX);  // Set argv in NativeArguments.
   __ leaq(RAX, Address(RBP, 2 * kWordSize));  // Compute return value addr.
@@ -289,21 +256,11 @@
   __ CallCFunction(RBX);
 
   // Mark that the isolate is executing Dart code.
-  __ movq(Address(CTX, Isolate::vm_tag_offset()),
+  __ movq(Address(R12, Isolate::vm_tag_offset()),
           Immediate(VMTag::kDartTagId));
 
   // Reset exit frame information in Isolate structure.
-  __ movq(Address(CTX, Isolate::top_exit_frame_info_offset()), Immediate(0));
-
-  // Load Context pointer from Isolate structure into R8.
-  __ movq(R8, Address(CTX, Isolate::top_context_offset()));
-
-  // Reset Context pointer in Isolate structure.
-  __ LoadObject(R12, Object::null_object(), PP);
-  __ movq(Address(CTX, Isolate::top_context_offset()), R12);
-
-  // Cache Context pointer into CTX while executing Dart code.
-  __ movq(CTX, R8);
+  __ movq(Address(R12, Isolate::top_exit_frame_info_offset()), Immediate(0));
 
   __ LeaveFrame();
   __ ret();
@@ -737,17 +694,15 @@
   const Register kEntryPointReg = CallingConventions::kArg1Reg;
   const Register kArgDescReg    = CallingConventions::kArg2Reg;
   const Register kArgsReg       = CallingConventions::kArg3Reg;
-  const Register kNewContextReg = CallingConventions::kArg4Reg;
 
   // At this point, the stack looks like:
   // | saved RBP                                      | <-- RBP
   // | saved PC (return to DartEntry::InvokeFunction) |
 
   const intptr_t kInitialOffset = 1;
-  // Save arguments descriptor array and new context.
+  // Save arguments descriptor array.
   const intptr_t kArgumentsDescOffset = -(kInitialOffset) * kWordSize;
   __ pushq(kArgDescReg);
-  __ pushq(kNewContextReg);
 
   // Save C++ ABI callee-saved registers.
   __ PushRegisters(CallingConventions::kCalleeSaveCpuRegisters,
@@ -759,36 +714,15 @@
   __ LoadPoolPointer(PP);
 
   // If any additional (or fewer) values are pushed, the offsets in
-  // kExitLinkSlotFromEntryFp and kSavedContextSlotFromEntryFp will need to be
-  // changed.
-
-  // The new Context structure contains a pointer to the current Isolate
-  // structure. Cache the Context pointer in the CTX register so that it is
-  // available in generated code and calls to Isolate::Current() need not be
-  // done. The assumption is that this register will never be clobbered by
-  // compiled or runtime stub code.
-
-  // Cache the new Context pointer into CTX while executing Dart code.
-  __ movq(CTX, Address(kNewContextReg, VMHandles::kOffsetOfRawPtrInHandle));
-
-  const Register kIsolateReg = RBX;
+  // kExitLinkSlotFromEntryFp will need to be changed.
 
   // Load Isolate pointer into kIsolateReg.
+  const Register kIsolateReg = RBX;
   __ LoadIsolate(kIsolateReg);
 
   // Save the current VMTag on the stack.
   __ movq(RAX, Address(kIsolateReg, Isolate::vm_tag_offset()));
   __ pushq(RAX);
-#if defined(DEBUG)
-  {
-    Label ok;
-    __ leaq(RAX, Address(RBP, kSavedVMTagSlotFromEntryFp * kWordSize));
-    __ cmpq(RAX, RSP);
-    __ j(EQUAL, &ok);
-    __ Stop("kSavedVMTagSlotFromEntryFp mismatch");
-    __ Bind(&ok);
-  }
-#endif
 
   // Mark that the isolate is executing Dart code.
   __ movq(Address(kIsolateReg, Isolate::vm_tag_offset()),
@@ -814,26 +748,6 @@
   __ movq(Address(kIsolateReg, Isolate::top_exit_frame_info_offset()),
           Immediate(0));
 
-  // Save the old Context pointer. Use RAX as a temporary register.
-  // Note that VisitObjectPointers will find this saved Context pointer during
-  // GC marking, since it traverses any information between SP and
-  // FP - kExitLinkSlotFromEntryFp * kWordSize.
-  // EntryFrame::SavedContext reads the context saved in this frame.
-  // The constant kSavedContextSlotFromEntryFp must be kept in sync with
-  // the code below.
-  __ movq(RAX, Address(kIsolateReg, Isolate::top_context_offset()));
-  __ pushq(RAX);
-#if defined(DEBUG)
-  {
-    Label ok;
-    __ leaq(RAX, Address(RBP, kSavedContextSlotFromEntryFp * kWordSize));
-    __ cmpq(RAX, RSP);
-    __ j(EQUAL, &ok);
-    __ Stop("kSavedContextSlotFromEntryFp mismatch");
-    __ Bind(&ok);
-  }
-#endif
-
   // Load arguments descriptor array into R10, which is passed to Dart code.
   __ movq(R10, Address(kArgDescReg, VMHandles::kOffsetOfRawPtrInHandle));
 
@@ -872,11 +786,8 @@
   // Get rid of arguments pushed on the stack.
   __ leaq(RSP, Address(RSP, RDX, TIMES_4, 0));  // RDX is a Smi.
 
-  __ LoadIsolate(kIsolateReg);
-  // Restore the saved Context pointer into the Isolate structure.
-  __ popq(Address(kIsolateReg, Isolate::top_context_offset()));
-
   // Restore the saved top exit frame info back into the Isolate structure.
+  __ LoadIsolate(kIsolateReg);
   __ popq(Address(kIsolateReg, Isolate::top_exit_frame_info_offset()));
 
   // Restore the current VMTag from the stack.
diff --git a/runtime/vm/stub_code_x64_test.cc b/runtime/vm/stub_code_x64_test.cc
index bff9297..348d493 100644
--- a/runtime/vm/stub_code_x64_test.cc
+++ b/runtime/vm/stub_code_x64_test.cc
@@ -44,9 +44,7 @@
   const int argc = 2;
   const Smi& smi1 = Smi::ZoneHandle(Smi::New(value1));
   const Smi& smi2 = Smi::ZoneHandle(Smi::New(value2));
-  const Context& context = Context::ZoneHandle(Context::New(0, Heap::kOld));
   __ EnterStubFrame(true);
-  __ LoadObject(CTX, context, PP);
   __ PushObject(Object::null_object(), PP);  // Push Null obj for return value.
   __ PushObject(smi1, PP);  // Push argument 1 smi1.
   __ PushObject(smi2, PP);  // Push argument 2 smi2.
diff --git a/runtime/vm/symbols.h b/runtime/vm/symbols.h
index 2a013e9..4abe031 100644
--- a/runtime/vm/symbols.h
+++ b/runtime/vm/symbols.h
@@ -58,8 +58,7 @@
   V(InterpolateSingle, "_interpolateSingle")                                   \
   V(GetIterator, "iterator")                                                   \
   V(NoSuchMethod, "noSuchMethod")                                              \
-  V(SavedCurrentContextVar, ":saved_current_context_var")                      \
-  V(SavedEntryContextVar, ":saved_entry_context_var")                          \
+  V(CurrentContextVar, ":current_context_var")                                 \
   V(SavedTryContextVar, ":saved_try_context_var")                              \
   V(ExceptionParameter, ":exception")                                          \
   V(StackTraceParameter, ":stack_trace")                                       \
diff --git a/runtime/vm/unibrow-inl.h b/runtime/vm/unibrow-inl.h
new file mode 100644
index 0000000..a7e3b22
--- /dev/null
+++ b/runtime/vm/unibrow-inl.h
@@ -0,0 +1,52 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+#ifndef VM_UNIBROW_INL_H_
+#define VM_UNIBROW_INL_H_
+
+#include "vm/unibrow.h"
+
+// SNIP
+
+namespace unibrow {
+
+// SNIP
+
+template <class T, int s> int Mapping<T, s>::get(uchar c, uchar n,
+    uchar* result) {
+  CacheEntry entry = entries_[c & kMask];
+  if (entry.code_point_ == c) {
+    if (entry.offset_ == 0) {
+      return 0;
+    } else {
+      result[0] = c + entry.offset_;
+      return 1;
+    }
+  } else {
+    return CalculateValue(c, n, result);
+  }
+}
+
+template <class T, int s> int Mapping<T, s>::CalculateValue(uchar c, uchar n,
+    uchar* result) {
+  bool allow_caching = true;
+  int length = T::Convert(c, n, result, &allow_caching);
+  if (allow_caching) {
+    if (length == 1) {
+      entries_[c & kMask] = CacheEntry(c, result[0] - c);
+      return 1;
+    } else {
+      entries_[c & kMask] = CacheEntry(c, 0);
+      return 0;
+    }
+  } else {
+    return length;
+  }
+}
+
+// SNIP
+
+}  // namespace unibrow
+
+#endif  // VM_UNIBROW_INL_H_
diff --git a/runtime/vm/unibrow.cc b/runtime/vm/unibrow.cc
new file mode 100644
index 0000000..7b4246b
--- /dev/null
+++ b/runtime/vm/unibrow.cc
@@ -0,0 +1,3393 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for 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 was generated at 2014-10-08 15:25:47.940335 (in v8, copied to dart)
+
+#include "vm/unicode-inl.h"
+#include <stdio.h>
+#include <stdlib.h>
+
+namespace unibrow {
+
+static const int kStartBit = (1 << 30);
+static const int kChunkBits = (1 << 13);
+static const uchar kSentinel = static_cast<uchar>(-1);
+
+/**
+ * \file
+ * Implementations of functions for working with unicode.
+ */
+
+// SNIP
+
+// All access to the character table should go through this function.
+template <int D>
+static inline uchar TableGet(const int32_t* table, int index) {
+  return table[D * index];
+}
+
+
+static inline uchar GetEntry(int32_t entry) {
+  return entry & (kStartBit - 1);
+}
+
+
+static inline bool IsStart(int32_t entry) {
+  return (entry & kStartBit) != 0;
+}
+
+
+/**
+ * Look up a character in the unicode table using a mix of binary and
+ * interpolation search.  For a uniformly distributed array
+ * interpolation search beats binary search by a wide margin.  However,
+ * in this case interpolation search degenerates because of some very
+ * high values in the lower end of the table so this function uses a
+ * combination.  The average number of steps to look up the information
+ * about a character is around 10, slightly higher if there is no
+ * information available about the character.
+ */
+static bool LookupPredicate(const int32_t* table, uint16_t size, uchar chr) {
+  static const int kEntryDist = 1;
+  uint16_t value = chr & (kChunkBits - 1);
+  unsigned int low = 0;
+  unsigned int high = size - 1;
+  while (high != low) {
+    unsigned int mid = low + ((high - low) >> 1);
+    uchar current_value = GetEntry(TableGet<kEntryDist>(table, mid));
+    // If we've found an entry less than or equal to this one, and the
+    // next one is not also less than this one, we've arrived.
+    if ((current_value <= value) &&
+        (mid + 1 == size ||
+         GetEntry(TableGet<kEntryDist>(table, mid + 1)) > value)) {
+      low = mid;
+      break;
+    } else if (current_value < value) {
+      low = mid + 1;
+    } else if (current_value > value) {
+      // If we've just checked the bottom-most value and it's not
+      // the one we're looking for, we're done.
+      if (mid == 0) break;
+      high = mid - 1;
+    }
+  }
+  int32_t field = TableGet<kEntryDist>(table, low);
+  uchar entry = GetEntry(field);
+  bool is_start = IsStart(field);
+  return (entry == value) || (entry < value && is_start);
+}
+
+template <int kW>
+struct MultiCharacterSpecialCase {
+  static const uchar kEndOfEncoding = kSentinel;
+  uchar chars[kW];
+};
+
+
+// Look up the mapping for the given character in the specified table,
+// which is of the specified length and uses the specified special case
+// mapping for multi-char mappings.  The next parameter is the character
+// following the one to map.  The result will be written in to the result
+// buffer and the number of characters written will be returned.  Finally,
+// if the allow_caching_ptr is non-null then false will be stored in
+// it if the result contains multiple characters or depends on the
+// context.
+// If ranges are linear, a match between a start and end point is
+// offset by the distance between the match and the start. Otherwise
+// the result is the same as for the start point on the entire range.
+template <bool ranges_are_linear, int kW>
+static int LookupMapping(const int32_t* table,
+                         uint16_t size,
+                         const MultiCharacterSpecialCase<kW>* multi_chars,
+                         uchar chr,
+                         uchar next,
+                         uchar* result,
+                         bool* allow_caching_ptr) {
+  static const int kEntryDist = 2;
+  uint16_t key = chr & (kChunkBits - 1);
+  uint16_t chunk_start = chr - key;
+  unsigned int low = 0;
+  unsigned int high = size - 1;
+  while (high != low) {
+    unsigned int mid = low + ((high - low) >> 1);
+    uchar current_value = GetEntry(TableGet<kEntryDist>(table, mid));
+    // If we've found an entry less than or equal to this one, and the next one
+    // is not also less than this one, we've arrived.
+    if ((current_value <= key) &&
+        (mid + 1 == size ||
+         GetEntry(TableGet<kEntryDist>(table, mid + 1)) > key)) {
+      low = mid;
+      break;
+    } else if (current_value < key) {
+      low = mid + 1;
+    } else if (current_value > key) {
+      // If we've just checked the bottom-most value and it's not
+      // the one we're looking for, we're done.
+      if (mid == 0) break;
+      high = mid - 1;
+    }
+  }
+  int32_t field = TableGet<kEntryDist>(table, low);
+  uchar entry = GetEntry(field);
+  bool is_start = IsStart(field);
+  bool found = (entry == key) || (entry < key && is_start);
+  if (found) {
+    int32_t value = table[2 * low + 1];
+    if (value == 0) {
+      // 0 means not present
+      return 0;
+    } else if ((value & 3) == 0) {
+      // Low bits 0 means a constant offset from the given character.
+      if (ranges_are_linear) {
+        result[0] = chr + (value >> 2);
+      } else {
+        result[0] = entry + chunk_start + (value >> 2);
+      }
+      return 1;
+    } else if ((value & 3) == 1) {
+      // Low bits 1 means a special case mapping
+      if (allow_caching_ptr) *allow_caching_ptr = false;
+      const MultiCharacterSpecialCase<kW>& mapping = multi_chars[value >> 2];
+      int length = 0;
+      for (length = 0; length < kW; length++) {
+        uchar mapped = mapping.chars[length];
+        if (mapped == MultiCharacterSpecialCase<kW>::kEndOfEncoding) break;
+        if (ranges_are_linear) {
+          result[length] = mapped + (key - entry);
+        } else {
+          result[length] = mapped;
+        }
+      }
+      return length;
+    } else {
+      // Low bits 2 means a really really special case
+      if (allow_caching_ptr) *allow_caching_ptr = false;
+      // The cases of this switch are defined in unicode.py in the
+      // really_special_cases mapping.
+      switch (value >> 2) {
+        case 1:
+          // Really special case 1: upper case sigma.  This letter
+          // converts to two different lower case sigmas depending on
+          // whether or not it occurs at the end of a word.
+          if (next != 0 && Letter::Is(next)) {
+            result[0] = 0x03C3;
+          } else {
+            result[0] = 0x03C2;
+          }
+          return 1;
+        default:
+          return 0;
+      }
+      return -1;
+    }
+  } else {
+    return 0;
+  }
+}
+
+
+uchar Utf8::CalculateValue(const byte* str,
+                           unsigned length,
+                           unsigned* cursor) {
+  // We only get called for non-ASCII characters.
+  if (length == 1) {
+    *cursor += 1;
+    return kBadChar;
+  }
+  byte first = str[0];
+  byte second = str[1] ^ 0x80;
+  if (second & 0xC0) {
+    *cursor += 1;
+    return kBadChar;
+  }
+  if (first < 0xE0) {
+    if (first < 0xC0) {
+      *cursor += 1;
+      return kBadChar;
+    }
+    uchar code_point = ((first << 6) | second) & kMaxTwoByteChar;
+    if (code_point <= kMaxOneByteChar) {
+      *cursor += 1;
+      return kBadChar;
+    }
+    *cursor += 2;
+    return code_point;
+  }
+  if (length == 2) {
+    *cursor += 1;
+    return kBadChar;
+  }
+  byte third = str[2] ^ 0x80;
+  if (third & 0xC0) {
+    *cursor += 1;
+    return kBadChar;
+  }
+  if (first < 0xF0) {
+    uchar code_point = ((((first << 6) | second) << 6) | third)
+        & kMaxThreeByteChar;
+    if (code_point <= kMaxTwoByteChar) {
+      *cursor += 1;
+      return kBadChar;
+    }
+    *cursor += 3;
+    return code_point;
+  }
+  if (length == 3) {
+    *cursor += 1;
+    return kBadChar;
+  }
+  byte fourth = str[3] ^ 0x80;
+  if (fourth & 0xC0) {
+    *cursor += 1;
+    return kBadChar;
+  }
+  if (first < 0xF8) {
+    uchar code_point = (((((first << 6 | second) << 6) | third) << 6) | fourth)
+        & kMaxFourByteChar;
+    if (code_point <= kMaxThreeByteChar) {
+      *cursor += 1;
+      return kBadChar;
+    }
+    *cursor += 4;
+    return code_point;
+  }
+  *cursor += 1;
+  return kBadChar;
+}
+
+
+// Uppercase:            point.category == 'Lu'
+
+static const uint16_t kUppercaseTable0Size = 455;
+static const int32_t kUppercaseTable0[455] = {
+    1073741889, 90,         1073742016, 214,
+    1073742040, 222,        256,        258,  // NOLINT
+    260,        262,        264,        266,
+    268,        270,        272,        274,  // NOLINT
+    276,        278,        280,        282,
+    284,        286,        288,        290,  // NOLINT
+    292,        294,        296,        298,
+    300,        302,        304,        306,  // NOLINT
+    308,        310,        313,        315,
+    317,        319,        321,        323,  // NOLINT
+    325,        327,        330,        332,
+    334,        336,        338,        340,  // NOLINT
+    342,        344,        346,        348,
+    350,        352,        354,        356,  // NOLINT
+    358,        360,        362,        364,
+    366,        368,        370,        372,  // NOLINT
+    374,        1073742200, 377,        379,
+    381,        1073742209, 386,        388,  // NOLINT
+    1073742214, 391,        1073742217, 395,
+    1073742222, 401,        1073742227, 404,  // NOLINT
+    1073742230, 408,        1073742236, 413,
+    1073742239, 416,        418,        420,  // NOLINT
+    1073742246, 423,        425,        428,
+    1073742254, 431,        1073742257, 435,  // NOLINT
+    437,        1073742263, 440,        444,
+    452,        455,        458,        461,  // NOLINT
+    463,        465,        467,        469,
+    471,        473,        475,        478,  // NOLINT
+    480,        482,        484,        486,
+    488,        490,        492,        494,  // NOLINT
+    497,        500,        1073742326, 504,
+    506,        508,        510,        512,  // NOLINT
+    514,        516,        518,        520,
+    522,        524,        526,        528,  // NOLINT
+    530,        532,        534,        536,
+    538,        540,        542,        544,  // NOLINT
+    546,        548,        550,        552,
+    554,        556,        558,        560,  // NOLINT
+    562,        1073742394, 571,        1073742397,
+    574,        577,        1073742403, 582,  // NOLINT
+    584,        586,        588,        590,
+    880,        882,        886,        895,  // NOLINT
+    902,        1073742728, 906,        908,
+    1073742734, 911,        1073742737, 929,  // NOLINT
+    1073742755, 939,        975,        1073742802,
+    980,        984,        986,        988,  // NOLINT
+    990,        992,        994,        996,
+    998,        1000,       1002,       1004,  // NOLINT
+    1006,       1012,       1015,       1073742841,
+    1018,       1073742845, 1071,       1120,  // NOLINT
+    1122,       1124,       1126,       1128,
+    1130,       1132,       1134,       1136,  // NOLINT
+    1138,       1140,       1142,       1144,
+    1146,       1148,       1150,       1152,  // NOLINT
+    1162,       1164,       1166,       1168,
+    1170,       1172,       1174,       1176,  // NOLINT
+    1178,       1180,       1182,       1184,
+    1186,       1188,       1190,       1192,  // NOLINT
+    1194,       1196,       1198,       1200,
+    1202,       1204,       1206,       1208,  // NOLINT
+    1210,       1212,       1214,       1073743040,
+    1217,       1219,       1221,       1223,  // NOLINT
+    1225,       1227,       1229,       1232,
+    1234,       1236,       1238,       1240,  // NOLINT
+    1242,       1244,       1246,       1248,
+    1250,       1252,       1254,       1256,  // NOLINT
+    1258,       1260,       1262,       1264,
+    1266,       1268,       1270,       1272,  // NOLINT
+    1274,       1276,       1278,       1280,
+    1282,       1284,       1286,       1288,  // NOLINT
+    1290,       1292,       1294,       1296,
+    1298,       1300,       1302,       1304,  // NOLINT
+    1306,       1308,       1310,       1312,
+    1314,       1316,       1318,       1320,  // NOLINT
+    1322,       1324,       1326,       1073743153,
+    1366,       1073746080, 4293,       4295,  // NOLINT
+    4301,       7680,       7682,       7684,
+    7686,       7688,       7690,       7692,  // NOLINT
+    7694,       7696,       7698,       7700,
+    7702,       7704,       7706,       7708,  // NOLINT
+    7710,       7712,       7714,       7716,
+    7718,       7720,       7722,       7724,  // NOLINT
+    7726,       7728,       7730,       7732,
+    7734,       7736,       7738,       7740,  // NOLINT
+    7742,       7744,       7746,       7748,
+    7750,       7752,       7754,       7756,  // NOLINT
+    7758,       7760,       7762,       7764,
+    7766,       7768,       7770,       7772,  // NOLINT
+    7774,       7776,       7778,       7780,
+    7782,       7784,       7786,       7788,  // NOLINT
+    7790,       7792,       7794,       7796,
+    7798,       7800,       7802,       7804,  // NOLINT
+    7806,       7808,       7810,       7812,
+    7814,       7816,       7818,       7820,  // NOLINT
+    7822,       7824,       7826,       7828,
+    7838,       7840,       7842,       7844,  // NOLINT
+    7846,       7848,       7850,       7852,
+    7854,       7856,       7858,       7860,  // NOLINT
+    7862,       7864,       7866,       7868,
+    7870,       7872,       7874,       7876,  // NOLINT
+    7878,       7880,       7882,       7884,
+    7886,       7888,       7890,       7892,  // NOLINT
+    7894,       7896,       7898,       7900,
+    7902,       7904,       7906,       7908,  // NOLINT
+    7910,       7912,       7914,       7916,
+    7918,       7920,       7922,       7924,  // NOLINT
+    7926,       7928,       7930,       7932,
+    7934,       1073749768, 7951,       1073749784,  // NOLINT
+    7965,       1073749800, 7983,       1073749816,
+    7999,       1073749832, 8013,       8025,  // NOLINT
+    8027,       8029,       8031,       1073749864,
+    8047,       1073749944, 8123,       1073749960,  // NOLINT
+    8139,       1073749976, 8155,       1073749992,
+    8172,       1073750008, 8187};  // NOLINT
+static const uint16_t kUppercaseTable1Size = 86;
+static const int32_t kUppercaseTable1[86] = {
+  258, 263, 1073742091, 269, 1073742096, 274, 277, 1073742105,  // NOLINT
+  285, 292, 294, 296, 1073742122, 301, 1073742128, 307,  // NOLINT
+  1073742142, 319, 325, 387, 1073744896, 3118, 3168, 1073744994,  // NOLINT
+  3172, 3175, 3177, 3179, 1073745005, 3184, 3186, 3189,  // NOLINT
+  1073745022, 3200, 3202, 3204, 3206, 3208, 3210, 3212,  // NOLINT
+  3214, 3216, 3218, 3220, 3222, 3224, 3226, 3228,  // NOLINT
+  3230, 3232, 3234, 3236, 3238, 3240, 3242, 3244,  // NOLINT
+  3246, 3248, 3250, 3252, 3254, 3256, 3258, 3260,  // NOLINT
+  3262, 3264, 3266, 3268, 3270, 3272, 3274, 3276,  // NOLINT
+  3278, 3280, 3282, 3284, 3286, 3288, 3290, 3292,  // NOLINT
+  3294, 3296, 3298, 3307, 3309, 3314 };  // NOLINT
+static const uint16_t kUppercaseTable5Size = 101;
+static const int32_t kUppercaseTable5[101] = {
+    1600, 1602,       1604, 1606,       1608, 1610,       1612, 1614,  // NOLINT
+    1616, 1618,       1620, 1622,       1624, 1626,       1628, 1630,  // NOLINT
+    1632, 1634,       1636, 1638,       1640, 1642,       1644, 1664,  // NOLINT
+    1666, 1668,       1670, 1672,       1674, 1676,       1678, 1680,  // NOLINT
+    1682, 1684,       1686, 1688,       1690, 1826,       1828, 1830,  // NOLINT
+    1832, 1834,       1836, 1838,       1842, 1844,       1846, 1848,  // NOLINT
+    1850, 1852,       1854, 1856,       1858, 1860,       1862, 1864,  // NOLINT
+    1866, 1868,       1870, 1872,       1874, 1876,       1878, 1880,  // NOLINT
+    1882, 1884,       1886, 1888,       1890, 1892,       1894, 1896,  // NOLINT
+    1898, 1900,       1902, 1913,       1915, 1073743741, 1918, 1920,  // NOLINT
+    1922, 1924,       1926, 1931,       1933, 1936,       1938, 1942,  // NOLINT
+    1944, 1946,       1948, 1950,       1952, 1954,       1956, 1958,  // NOLINT
+    1960, 1073743786, 1965, 1073743792, 1969};                         // NOLINT
+static const uint16_t kUppercaseTable7Size = 2;
+static const int32_t kUppercaseTable7[2] = {
+  1073749793, 7994 };  // NOLINT
+bool Uppercase::Is(uchar c) {
+  int chunk_index = c >> 13;
+  switch (chunk_index) {
+    case 0: return LookupPredicate(kUppercaseTable0,
+                                       kUppercaseTable0Size,
+                                       c);
+    case 1: return LookupPredicate(kUppercaseTable1,
+                                       kUppercaseTable1Size,
+                                       c);
+    case 5: return LookupPredicate(kUppercaseTable5,
+                                       kUppercaseTable5Size,
+                                       c);
+    case 7: return LookupPredicate(kUppercaseTable7,
+                                       kUppercaseTable7Size,
+                                       c);
+    default: return false;
+  }
+}
+
+
+// Lowercase:            point.category == 'Ll'
+
+static const uint16_t kLowercaseTable0Size = 467;
+static const int32_t kLowercaseTable0[467] = {
+    1073741921, 122,        181,        1073742047,
+    246,        1073742072, 255,        257,  // NOLINT
+    259,        261,        263,        265,
+    267,        269,        271,        273,  // NOLINT
+    275,        277,        279,        281,
+    283,        285,        287,        289,  // NOLINT
+    291,        293,        295,        297,
+    299,        301,        303,        305,  // NOLINT
+    307,        309,        1073742135, 312,
+    314,        316,        318,        320,  // NOLINT
+    322,        324,        326,        1073742152,
+    329,        331,        333,        335,  // NOLINT
+    337,        339,        341,        343,
+    345,        347,        349,        351,  // NOLINT
+    353,        355,        357,        359,
+    361,        363,        365,        367,  // NOLINT
+    369,        371,        373,        375,
+    378,        380,        1073742206, 384,  // NOLINT
+    387,        389,        392,        1073742220,
+    397,        402,        405,        1073742233,  // NOLINT
+    411,        414,        417,        419,
+    421,        424,        1073742250, 427,  // NOLINT
+    429,        432,        436,        438,
+    1073742265, 442,        1073742269, 447,  // NOLINT
+    454,        457,        460,        462,
+    464,        466,        468,        470,  // NOLINT
+    472,        474,        1073742300, 477,
+    479,        481,        483,        485,  // NOLINT
+    487,        489,        491,        493,
+    1073742319, 496,        499,        501,  // NOLINT
+    505,        507,        509,        511,
+    513,        515,        517,        519,  // NOLINT
+    521,        523,        525,        527,
+    529,        531,        533,        535,  // NOLINT
+    537,        539,        541,        543,
+    545,        547,        549,        551,  // NOLINT
+    553,        555,        557,        559,
+    561,        1073742387, 569,        572,  // NOLINT
+    1073742399, 576,        578,        583,
+    585,        587,        589,        1073742415,  // NOLINT
+    659,        1073742485, 687,        881,
+    883,        887,        1073742715, 893,  // NOLINT
+    912,        1073742764, 974,        1073742800,
+    977,        1073742805, 983,        985,  // NOLINT
+    987,        989,        991,        993,
+    995,        997,        999,        1001,  // NOLINT
+    1003,       1005,       1073742831, 1011,
+    1013,       1016,       1073742843, 1020,  // NOLINT
+    1073742896, 1119,       1121,       1123,
+    1125,       1127,       1129,       1131,  // NOLINT
+    1133,       1135,       1137,       1139,
+    1141,       1143,       1145,       1147,  // NOLINT
+    1149,       1151,       1153,       1163,
+    1165,       1167,       1169,       1171,  // NOLINT
+    1173,       1175,       1177,       1179,
+    1181,       1183,       1185,       1187,  // NOLINT
+    1189,       1191,       1193,       1195,
+    1197,       1199,       1201,       1203,  // NOLINT
+    1205,       1207,       1209,       1211,
+    1213,       1215,       1218,       1220,  // NOLINT
+    1222,       1224,       1226,       1228,
+    1073743054, 1231,       1233,       1235,  // NOLINT
+    1237,       1239,       1241,       1243,
+    1245,       1247,       1249,       1251,  // NOLINT
+    1253,       1255,       1257,       1259,
+    1261,       1263,       1265,       1267,  // NOLINT
+    1269,       1271,       1273,       1275,
+    1277,       1279,       1281,       1283,  // NOLINT
+    1285,       1287,       1289,       1291,
+    1293,       1295,       1297,       1299,  // NOLINT
+    1301,       1303,       1305,       1307,
+    1309,       1311,       1313,       1315,  // NOLINT
+    1317,       1319,       1321,       1323,
+    1325,       1327,       1073743201, 1415,  // NOLINT
+    1073749248, 7467,       1073749355, 7543,
+    1073749369, 7578,       7681,       7683,  // NOLINT
+    7685,       7687,       7689,       7691,
+    7693,       7695,       7697,       7699,  // NOLINT
+    7701,       7703,       7705,       7707,
+    7709,       7711,       7713,       7715,  // NOLINT
+    7717,       7719,       7721,       7723,
+    7725,       7727,       7729,       7731,  // NOLINT
+    7733,       7735,       7737,       7739,
+    7741,       7743,       7745,       7747,  // NOLINT
+    7749,       7751,       7753,       7755,
+    7757,       7759,       7761,       7763,  // NOLINT
+    7765,       7767,       7769,       7771,
+    7773,       7775,       7777,       7779,  // NOLINT
+    7781,       7783,       7785,       7787,
+    7789,       7791,       7793,       7795,  // NOLINT
+    7797,       7799,       7801,       7803,
+    7805,       7807,       7809,       7811,  // NOLINT
+    7813,       7815,       7817,       7819,
+    7821,       7823,       7825,       7827,  // NOLINT
+    1073749653, 7837,       7839,       7841,
+    7843,       7845,       7847,       7849,  // NOLINT
+    7851,       7853,       7855,       7857,
+    7859,       7861,       7863,       7865,  // NOLINT
+    7867,       7869,       7871,       7873,
+    7875,       7877,       7879,       7881,  // NOLINT
+    7883,       7885,       7887,       7889,
+    7891,       7893,       7895,       7897,  // NOLINT
+    7899,       7901,       7903,       7905,
+    7907,       7909,       7911,       7913,  // NOLINT
+    7915,       7917,       7919,       7921,
+    7923,       7925,       7927,       7929,  // NOLINT
+    7931,       7933,       1073749759, 7943,
+    1073749776, 7957,       1073749792, 7975,  // NOLINT
+    1073749808, 7991,       1073749824, 8005,
+    1073749840, 8023,       1073749856, 8039,  // NOLINT
+    1073749872, 8061,       1073749888, 8071,
+    1073749904, 8087,       1073749920, 8103,  // NOLINT
+    1073749936, 8116,       1073749942, 8119,
+    8126,       1073749954, 8132,       1073749958,  // NOLINT
+    8135,       1073749968, 8147,       1073749974,
+    8151,       1073749984, 8167,       1073750002,  // NOLINT
+    8180,       1073750006, 8183};                   // NOLINT
+static const uint16_t kLowercaseTable1Size = 84;
+static const int32_t kLowercaseTable1[84] = {
+  266, 1073742094, 271, 275, 303, 308, 313, 1073742140,  // NOLINT
+  317, 1073742150, 329, 334, 388, 1073744944, 3166, 3169,  // NOLINT
+  1073744997, 3174, 3176, 3178, 3180, 3185, 1073745011, 3188,  // NOLINT
+  1073745014, 3195, 3201, 3203, 3205, 3207, 3209, 3211,  // NOLINT
+  3213, 3215, 3217, 3219, 3221, 3223, 3225, 3227,  // NOLINT
+  3229, 3231, 3233, 3235, 3237, 3239, 3241, 3243,  // NOLINT
+  3245, 3247, 3249, 3251, 3253, 3255, 3257, 3259,  // NOLINT
+  3261, 3263, 3265, 3267, 3269, 3271, 3273, 3275,  // NOLINT
+  3277, 3279, 3281, 3283, 3285, 3287, 3289, 3291,  // NOLINT
+  3293, 3295, 3297, 1073745123, 3300, 3308, 3310, 3315,  // NOLINT
+  1073745152, 3365, 3367, 3373 };  // NOLINT
+static const uint16_t kLowercaseTable5Size = 105;
+static const int32_t kLowercaseTable5[105] = {
+    1601,       1603,       1605, 1607,
+    1609,       1611,       1613, 1615,  // NOLINT
+    1617,       1619,       1621, 1623,
+    1625,       1627,       1629, 1631,  // NOLINT
+    1633,       1635,       1637, 1639,
+    1641,       1643,       1645, 1665,  // NOLINT
+    1667,       1669,       1671, 1673,
+    1675,       1677,       1679, 1681,  // NOLINT
+    1683,       1685,       1687, 1689,
+    1691,       1827,       1829, 1831,  // NOLINT
+    1833,       1835,       1837, 1073743663,
+    1841,       1843,       1845, 1847,  // NOLINT
+    1849,       1851,       1853, 1855,
+    1857,       1859,       1861, 1863,  // NOLINT
+    1865,       1867,       1869, 1871,
+    1873,       1875,       1877, 1879,  // NOLINT
+    1881,       1883,       1885, 1887,
+    1889,       1891,       1893, 1895,  // NOLINT
+    1897,       1899,       1901, 1903,
+    1073743729, 1912,       1914, 1916,  // NOLINT
+    1919,       1921,       1923, 1925,
+    1927,       1932,       1934, 1937,  // NOLINT
+    1073743763, 1941,       1943, 1945,
+    1947,       1949,       1951, 1953,  // NOLINT
+    1955,       1957,       1959, 1961,
+    2042,       1073744688, 2906, 1073744740,  // NOLINT
+    2917};                                     // NOLINT
+static const uint16_t kLowercaseTable7Size = 6;
+static const int32_t kLowercaseTable7[6] = {
+  1073748736, 6918, 1073748755, 6935, 1073749825, 8026 };  // NOLINT
+bool Lowercase::Is(uchar c) {
+  int chunk_index = c >> 13;
+  switch (chunk_index) {
+    case 0: return LookupPredicate(kLowercaseTable0,
+                                       kLowercaseTable0Size,
+                                       c);
+    case 1: return LookupPredicate(kLowercaseTable1,
+                                       kLowercaseTable1Size,
+                                       c);
+    case 5: return LookupPredicate(kLowercaseTable5,
+                                       kLowercaseTable5Size,
+                                       c);
+    case 7: return LookupPredicate(kLowercaseTable7,
+                                       kLowercaseTable7Size,
+                                       c);
+    default: return false;
+  }
+}
+
+
+// Letter:               point.category in ['Lu', 'Ll', 'Lt', 'Lm', 'Lo', 'Nl']
+
+static const uint16_t kLetterTable0Size = 431;
+static const int32_t kLetterTable0[431] = {
+    1073741889, 90,         1073741921, 122,
+    170,        181,        186,        1073742016,  // NOLINT
+    214,        1073742040, 246,        1073742072,
+    705,        1073742534, 721,        1073742560,  // NOLINT
+    740,        748,        750,        1073742704,
+    884,        1073742710, 887,        1073742714,  // NOLINT
+    893,        895,        902,        1073742728,
+    906,        908,        1073742734, 929,  // NOLINT
+    1073742755, 1013,       1073742839, 1153,
+    1073742986, 1327,       1073743153, 1366,  // NOLINT
+    1369,       1073743201, 1415,       1073743312,
+    1514,       1073743344, 1522,       1073743392,  // NOLINT
+    1610,       1073743470, 1647,       1073743473,
+    1747,       1749,       1073743589, 1766,  // NOLINT
+    1073743598, 1775,       1073743610, 1788,
+    1791,       1808,       1073743634, 1839,  // NOLINT
+    1073743693, 1957,       1969,       1073743818,
+    2026,       1073743860, 2037,       2042,  // NOLINT
+    1073743872, 2069,       2074,       2084,
+    2088,       1073743936, 2136,       1073744032,  // NOLINT
+    2226,       1073744132, 2361,       2365,
+    2384,       1073744216, 2401,       1073744241,  // NOLINT
+    2432,       1073744261, 2444,       1073744271,
+    2448,       1073744275, 2472,       1073744298,  // NOLINT
+    2480,       2482,       1073744310, 2489,
+    2493,       2510,       1073744348, 2525,  // NOLINT
+    1073744351, 2529,       1073744368, 2545,
+    1073744389, 2570,       1073744399, 2576,  // NOLINT
+    1073744403, 2600,       1073744426, 2608,
+    1073744434, 2611,       1073744437, 2614,  // NOLINT
+    1073744440, 2617,       1073744473, 2652,
+    2654,       1073744498, 2676,       1073744517,  // NOLINT
+    2701,       1073744527, 2705,       1073744531,
+    2728,       1073744554, 2736,       1073744562,  // NOLINT
+    2739,       1073744565, 2745,       2749,
+    2768,       1073744608, 2785,       1073744645,  // NOLINT
+    2828,       1073744655, 2832,       1073744659,
+    2856,       1073744682, 2864,       1073744690,  // NOLINT
+    2867,       1073744693, 2873,       2877,
+    1073744732, 2909,       1073744735, 2913,  // NOLINT
+    2929,       2947,       1073744773, 2954,
+    1073744782, 2960,       1073744786, 2965,  // NOLINT
+    1073744793, 2970,       2972,       1073744798,
+    2975,       1073744803, 2980,       1073744808,  // NOLINT
+    2986,       1073744814, 3001,       3024,
+    1073744901, 3084,       1073744910, 3088,  // NOLINT
+    1073744914, 3112,       1073744938, 3129,
+    3133,       1073744984, 3161,       1073744992,  // NOLINT
+    3169,       1073745029, 3212,       1073745038,
+    3216,       1073745042, 3240,       1073745066,  // NOLINT
+    3251,       1073745077, 3257,       3261,
+    3294,       1073745120, 3297,       1073745137,  // NOLINT
+    3314,       1073745157, 3340,       1073745166,
+    3344,       1073745170, 3386,       3389,  // NOLINT
+    3406,       1073745248, 3425,       1073745274,
+    3455,       1073745285, 3478,       1073745306,  // NOLINT
+    3505,       1073745331, 3515,       3517,
+    1073745344, 3526,       1073745409, 3632,  // NOLINT
+    1073745458, 3635,       1073745472, 3654,
+    1073745537, 3714,       3716,       1073745543,  // NOLINT
+    3720,       3722,       3725,       1073745556,
+    3735,       1073745561, 3743,       1073745569,  // NOLINT
+    3747,       3749,       3751,       1073745578,
+    3755,       1073745581, 3760,       1073745586,  // NOLINT
+    3763,       3773,       1073745600, 3780,
+    3782,       1073745628, 3807,       3840,  // NOLINT
+    1073745728, 3911,       1073745737, 3948,
+    1073745800, 3980,       1073745920, 4138,  // NOLINT
+    4159,       1073746000, 4181,       1073746010,
+    4189,       4193,       1073746021, 4198,  // NOLINT
+    1073746030, 4208,       1073746037, 4225,
+    4238,       1073746080, 4293,       4295,  // NOLINT
+    4301,       1073746128, 4346,       1073746172,
+    4680,       1073746506, 4685,       1073746512,  // NOLINT
+    4694,       4696,       1073746522, 4701,
+    1073746528, 4744,       1073746570, 4749,  // NOLINT
+    1073746576, 4784,       1073746610, 4789,
+    1073746616, 4798,       4800,       1073746626,  // NOLINT
+    4805,       1073746632, 4822,       1073746648,
+    4880,       1073746706, 4885,       1073746712,  // NOLINT
+    4954,       1073746816, 5007,       1073746848,
+    5108,       1073746945, 5740,       1073747567,  // NOLINT
+    5759,       1073747585, 5786,       1073747616,
+    5866,       1073747694, 5880,       1073747712,  // NOLINT
+    5900,       1073747726, 5905,       1073747744,
+    5937,       1073747776, 5969,       1073747808,  // NOLINT
+    5996,       1073747822, 6000,       1073747840,
+    6067,       6103,       6108,       1073748000,  // NOLINT
+    6263,       1073748096, 6312,       6314,
+    1073748144, 6389,       1073748224, 6430,  // NOLINT
+    1073748304, 6509,       1073748336, 6516,
+    1073748352, 6571,       1073748417, 6599,  // NOLINT
+    1073748480, 6678,       1073748512, 6740,
+    6823,       1073748741, 6963,       1073748805,  // NOLINT
+    6987,       1073748867, 7072,       1073748910,
+    7087,       1073748922, 7141,       1073748992,  // NOLINT
+    7203,       1073749069, 7247,       1073749082,
+    7293,       1073749225, 7404,       1073749230,  // NOLINT
+    7409,       1073749237, 7414,       1073749248,
+    7615,       1073749504, 7957,       1073749784,  // NOLINT
+    7965,       1073749792, 8005,       1073749832,
+    8013,       1073749840, 8023,       8025,  // NOLINT
+    8027,       8029,       1073749855, 8061,
+    1073749888, 8116,       1073749942, 8124,  // NOLINT
+    8126,       1073749954, 8132,       1073749958,
+    8140,       1073749968, 8147,       1073749974,  // NOLINT
+    8155,       1073749984, 8172,       1073750002,
+    8180,       1073750006, 8188};  // NOLINT
+static const uint16_t kLetterTable1Size = 87;
+static const int32_t kLetterTable1[87] = {
+  113, 127, 1073741968, 156, 258, 263, 1073742090, 275,  // NOLINT
+  277, 1073742105, 285, 292, 294, 296, 1073742122, 301,  // NOLINT
+  1073742127, 313, 1073742140, 319, 1073742149, 329, 334, 1073742176,  // NOLINT
+  392, 1073744896, 3118, 1073744944, 3166, 1073744992, 3300, 1073745131,  // NOLINT
+  3310, 1073745138, 3315, 1073745152, 3365, 3367, 3373, 1073745200,  // NOLINT
+  3431, 3439, 1073745280, 3478, 1073745312, 3494, 1073745320, 3502,  // NOLINT
+  1073745328, 3510, 1073745336, 3518, 1073745344, 3526, 1073745352, 3534,  // NOLINT
+  1073745360, 3542, 1073745368, 3550, 3631, 1073745925, 4103, 1073745953,  // NOLINT
+  4137, 1073745969, 4149, 1073745976, 4156, 1073745985, 4246, 1073746077,  // NOLINT
+  4255, 1073746081, 4346, 1073746172, 4351, 1073746181, 4397, 1073746225,  // NOLINT
+  4494, 1073746336, 4538, 1073746416, 4607, 1073746944, 8191 };  // NOLINT
+static const uint16_t kLetterTable2Size = 4;
+static const int32_t kLetterTable2[4] = {
+  1073741824, 3509, 1073745408, 8191 };  // NOLINT
+static const uint16_t kLetterTable3Size = 2;
+static const int32_t kLetterTable3[2] = {
+  1073741824, 8191 };  // NOLINT
+static const uint16_t kLetterTable4Size = 2;
+static const int32_t kLetterTable4[2] = {
+  1073741824, 8140 };  // NOLINT
+static const uint16_t kLetterTable5Size = 100;
+static const int32_t kLetterTable5[100] = {
+    1073741824, 1164,       1073743056, 1277,
+    1073743104, 1548,       1073743376, 1567,  // NOLINT
+    1073743402, 1579,       1073743424, 1646,
+    1073743487, 1693,       1073743520, 1775,  // NOLINT
+    1073743639, 1823,       1073743650, 1928,
+    1073743755, 1934,       1073743760, 1965,  // NOLINT
+    1073743792, 1969,       1073743863, 2049,
+    1073743875, 2053,       1073743879, 2058,  // NOLINT
+    1073743884, 2082,       1073743936, 2163,
+    1073744002, 2227,       1073744114, 2295,  // NOLINT
+    2299,       1073744138, 2341,       1073744176,
+    2374,       1073744224, 2428,       1073744260,  // NOLINT
+    2482,       2511,       1073744352, 2532,
+    1073744358, 2543,       1073744378, 2558,  // NOLINT
+    1073744384, 2600,       1073744448, 2626,
+    1073744452, 2635,       1073744480, 2678,  // NOLINT
+    2682,       1073744510, 2735,       2737,
+    1073744565, 2742,       1073744569, 2749,  // NOLINT
+    2752,       2754,       1073744603, 2781,
+    1073744608, 2794,       1073744626, 2804,  // NOLINT
+    1073744641, 2822,       1073744649, 2830,
+    1073744657, 2838,       1073744672, 2854,  // NOLINT
+    1073744680, 2862,       1073744688, 2906,
+    1073744732, 2911,       1073744740, 2917,   // NOLINT
+    1073744832, 3042,       1073744896, 8191};  // NOLINT
+static const uint16_t kLetterTable6Size = 6;
+static const int32_t kLetterTable6[6] = {
+  1073741824, 6051, 1073747888, 6086, 1073747915, 6139 };  // NOLINT
+static const uint16_t kLetterTable7Size = 48;
+static const int32_t kLetterTable7[48] = {
+  1073748224, 6765, 1073748592, 6873, 1073748736, 6918, 1073748755, 6935,  // NOLINT
+  6941, 1073748767, 6952, 1073748778, 6966, 1073748792, 6972, 6974,  // NOLINT
+  1073748800, 6977, 1073748803, 6980, 1073748806, 7089, 1073748947, 7485,  // NOLINT
+  1073749328, 7567, 1073749394, 7623, 1073749488, 7675, 1073749616, 7796,  // NOLINT
+  1073749622, 7932, 1073749793, 7994, 1073749825, 8026, 1073749862, 8126,  // NOLINT
+  1073749954, 8135, 1073749962, 8143, 1073749970, 8151, 1073749978, 8156 };  // NOLINT
+bool Letter::Is(uchar c) {
+  int chunk_index = c >> 13;
+  switch (chunk_index) {
+    case 0: return LookupPredicate(kLetterTable0,
+                                       kLetterTable0Size,
+                                       c);
+    case 1: return LookupPredicate(kLetterTable1,
+                                       kLetterTable1Size,
+                                       c);
+    case 2: return LookupPredicate(kLetterTable2,
+                                       kLetterTable2Size,
+                                       c);
+    case 3: return LookupPredicate(kLetterTable3,
+                                       kLetterTable3Size,
+                                       c);
+    case 4: return LookupPredicate(kLetterTable4,
+                                       kLetterTable4Size,
+                                       c);
+    case 5: return LookupPredicate(kLetterTable5,
+                                       kLetterTable5Size,
+                                       c);
+    case 6: return LookupPredicate(kLetterTable6,
+                                       kLetterTable6Size,
+                                       c);
+    case 7: return LookupPredicate(kLetterTable7,
+                                       kLetterTable7Size,
+                                       c);
+    default: return false;
+  }
+}
+
+
+// ID_Start:             ((point.category in ['Lu', 'Ll', 'Lt', 'Lm', 'Lo',
+// 'Nl'] or 'Other_ID_Start' in point.properties) and ('Pattern_Syntax' not in
+// point.properties) and ('Pattern_White_Space' not in point.properties)) or
+// ('JS_ID_Start' in point.properties)
+
+static const uint16_t kID_StartTable0Size = 434;
+static const int32_t kID_StartTable0[434] = {
+    36,         1073741889, 90,         92,
+    95,         1073741921, 122,        170,  // NOLINT
+    181,        186,        1073742016, 214,
+    1073742040, 246,        1073742072, 705,  // NOLINT
+    1073742534, 721,        1073742560, 740,
+    748,        750,        1073742704, 884,  // NOLINT
+    1073742710, 887,        1073742714, 893,
+    895,        902,        1073742728, 906,  // NOLINT
+    908,        1073742734, 929,        1073742755,
+    1013,       1073742839, 1153,       1073742986,  // NOLINT
+    1327,       1073743153, 1366,       1369,
+    1073743201, 1415,       1073743312, 1514,  // NOLINT
+    1073743344, 1522,       1073743392, 1610,
+    1073743470, 1647,       1073743473, 1747,  // NOLINT
+    1749,       1073743589, 1766,       1073743598,
+    1775,       1073743610, 1788,       1791,  // NOLINT
+    1808,       1073743634, 1839,       1073743693,
+    1957,       1969,       1073743818, 2026,  // NOLINT
+    1073743860, 2037,       2042,       1073743872,
+    2069,       2074,       2084,       2088,  // NOLINT
+    1073743936, 2136,       1073744032, 2226,
+    1073744132, 2361,       2365,       2384,  // NOLINT
+    1073744216, 2401,       1073744241, 2432,
+    1073744261, 2444,       1073744271, 2448,  // NOLINT
+    1073744275, 2472,       1073744298, 2480,
+    2482,       1073744310, 2489,       2493,  // NOLINT
+    2510,       1073744348, 2525,       1073744351,
+    2529,       1073744368, 2545,       1073744389,  // NOLINT
+    2570,       1073744399, 2576,       1073744403,
+    2600,       1073744426, 2608,       1073744434,  // NOLINT
+    2611,       1073744437, 2614,       1073744440,
+    2617,       1073744473, 2652,       2654,  // NOLINT
+    1073744498, 2676,       1073744517, 2701,
+    1073744527, 2705,       1073744531, 2728,  // NOLINT
+    1073744554, 2736,       1073744562, 2739,
+    1073744565, 2745,       2749,       2768,  // NOLINT
+    1073744608, 2785,       1073744645, 2828,
+    1073744655, 2832,       1073744659, 2856,  // NOLINT
+    1073744682, 2864,       1073744690, 2867,
+    1073744693, 2873,       2877,       1073744732,  // NOLINT
+    2909,       1073744735, 2913,       2929,
+    2947,       1073744773, 2954,       1073744782,  // NOLINT
+    2960,       1073744786, 2965,       1073744793,
+    2970,       2972,       1073744798, 2975,  // NOLINT
+    1073744803, 2980,       1073744808, 2986,
+    1073744814, 3001,       3024,       1073744901,  // NOLINT
+    3084,       1073744910, 3088,       1073744914,
+    3112,       1073744938, 3129,       3133,  // NOLINT
+    1073744984, 3161,       1073744992, 3169,
+    1073745029, 3212,       1073745038, 3216,  // NOLINT
+    1073745042, 3240,       1073745066, 3251,
+    1073745077, 3257,       3261,       3294,  // NOLINT
+    1073745120, 3297,       1073745137, 3314,
+    1073745157, 3340,       1073745166, 3344,  // NOLINT
+    1073745170, 3386,       3389,       3406,
+    1073745248, 3425,       1073745274, 3455,  // NOLINT
+    1073745285, 3478,       1073745306, 3505,
+    1073745331, 3515,       3517,       1073745344,  // NOLINT
+    3526,       1073745409, 3632,       1073745458,
+    3635,       1073745472, 3654,       1073745537,  // NOLINT
+    3714,       3716,       1073745543, 3720,
+    3722,       3725,       1073745556, 3735,  // NOLINT
+    1073745561, 3743,       1073745569, 3747,
+    3749,       3751,       1073745578, 3755,  // NOLINT
+    1073745581, 3760,       1073745586, 3763,
+    3773,       1073745600, 3780,       3782,  // NOLINT
+    1073745628, 3807,       3840,       1073745728,
+    3911,       1073745737, 3948,       1073745800,  // NOLINT
+    3980,       1073745920, 4138,       4159,
+    1073746000, 4181,       1073746010, 4189,  // NOLINT
+    4193,       1073746021, 4198,       1073746030,
+    4208,       1073746037, 4225,       4238,  // NOLINT
+    1073746080, 4293,       4295,       4301,
+    1073746128, 4346,       1073746172, 4680,  // NOLINT
+    1073746506, 4685,       1073746512, 4694,
+    4696,       1073746522, 4701,       1073746528,  // NOLINT
+    4744,       1073746570, 4749,       1073746576,
+    4784,       1073746610, 4789,       1073746616,  // NOLINT
+    4798,       4800,       1073746626, 4805,
+    1073746632, 4822,       1073746648, 4880,  // NOLINT
+    1073746706, 4885,       1073746712, 4954,
+    1073746816, 5007,       1073746848, 5108,  // NOLINT
+    1073746945, 5740,       1073747567, 5759,
+    1073747585, 5786,       1073747616, 5866,  // NOLINT
+    1073747694, 5880,       1073747712, 5900,
+    1073747726, 5905,       1073747744, 5937,  // NOLINT
+    1073747776, 5969,       1073747808, 5996,
+    1073747822, 6000,       1073747840, 6067,  // NOLINT
+    6103,       6108,       1073748000, 6263,
+    1073748096, 6312,       6314,       1073748144,  // NOLINT
+    6389,       1073748224, 6430,       1073748304,
+    6509,       1073748336, 6516,       1073748352,  // NOLINT
+    6571,       1073748417, 6599,       1073748480,
+    6678,       1073748512, 6740,       6823,  // NOLINT
+    1073748741, 6963,       1073748805, 6987,
+    1073748867, 7072,       1073748910, 7087,  // NOLINT
+    1073748922, 7141,       1073748992, 7203,
+    1073749069, 7247,       1073749082, 7293,  // NOLINT
+    1073749225, 7404,       1073749230, 7409,
+    1073749237, 7414,       1073749248, 7615,  // NOLINT
+    1073749504, 7957,       1073749784, 7965,
+    1073749792, 8005,       1073749832, 8013,  // NOLINT
+    1073749840, 8023,       8025,       8027,
+    8029,       1073749855, 8061,       1073749888,  // NOLINT
+    8116,       1073749942, 8124,       8126,
+    1073749954, 8132,       1073749958, 8140,  // NOLINT
+    1073749968, 8147,       1073749974, 8155,
+    1073749984, 8172,       1073750002, 8180,  // NOLINT
+    1073750006, 8188};                         // NOLINT
+static const uint16_t kID_StartTable1Size = 84;
+static const int32_t kID_StartTable1[84] = {
+    113,        127,        1073741968, 156,
+    258,        263,        1073742090, 275,  // NOLINT
+    277,        1073742104, 285,        292,
+    294,        296,        1073742122, 313,  // NOLINT
+    1073742140, 319,        1073742149, 329,
+    334,        1073742176, 392,        1073744896,  // NOLINT
+    3118,       1073744944, 3166,       1073744992,
+    3300,       1073745131, 3310,       1073745138,  // NOLINT
+    3315,       1073745152, 3365,       3367,
+    3373,       1073745200, 3431,       3439,  // NOLINT
+    1073745280, 3478,       1073745312, 3494,
+    1073745320, 3502,       1073745328, 3510,  // NOLINT
+    1073745336, 3518,       1073745344, 3526,
+    1073745352, 3534,       1073745360, 3542,  // NOLINT
+    1073745368, 3550,       1073745925, 4103,
+    1073745953, 4137,       1073745969, 4149,  // NOLINT
+    1073745976, 4156,       1073745985, 4246,
+    1073746075, 4255,       1073746081, 4346,  // NOLINT
+    1073746172, 4351,       1073746181, 4397,
+    1073746225, 4494,       1073746336, 4538,   // NOLINT
+    1073746416, 4607,       1073746944, 8191};  // NOLINT
+static const uint16_t kID_StartTable2Size = 4;
+static const int32_t kID_StartTable2[4] = {1073741824, 3509, 1073745408,
+                                           8191};  // NOLINT
+static const uint16_t kID_StartTable3Size = 2;
+static const int32_t kID_StartTable3[2] = {1073741824, 8191};  // NOLINT
+static const uint16_t kID_StartTable4Size = 2;
+static const int32_t kID_StartTable4[2] = {1073741824, 8140};  // NOLINT
+static const uint16_t kID_StartTable5Size = 100;
+static const int32_t kID_StartTable5[100] = {
+    1073741824, 1164,       1073743056, 1277,
+    1073743104, 1548,       1073743376, 1567,  // NOLINT
+    1073743402, 1579,       1073743424, 1646,
+    1073743487, 1693,       1073743520, 1775,  // NOLINT
+    1073743639, 1823,       1073743650, 1928,
+    1073743755, 1934,       1073743760, 1965,  // NOLINT
+    1073743792, 1969,       1073743863, 2049,
+    1073743875, 2053,       1073743879, 2058,  // NOLINT
+    1073743884, 2082,       1073743936, 2163,
+    1073744002, 2227,       1073744114, 2295,  // NOLINT
+    2299,       1073744138, 2341,       1073744176,
+    2374,       1073744224, 2428,       1073744260,  // NOLINT
+    2482,       2511,       1073744352, 2532,
+    1073744358, 2543,       1073744378, 2558,  // NOLINT
+    1073744384, 2600,       1073744448, 2626,
+    1073744452, 2635,       1073744480, 2678,  // NOLINT
+    2682,       1073744510, 2735,       2737,
+    1073744565, 2742,       1073744569, 2749,  // NOLINT
+    2752,       2754,       1073744603, 2781,
+    1073744608, 2794,       1073744626, 2804,  // NOLINT
+    1073744641, 2822,       1073744649, 2830,
+    1073744657, 2838,       1073744672, 2854,  // NOLINT
+    1073744680, 2862,       1073744688, 2906,
+    1073744732, 2911,       1073744740, 2917,   // NOLINT
+    1073744832, 3042,       1073744896, 8191};  // NOLINT
+static const uint16_t kID_StartTable6Size = 6;
+static const int32_t kID_StartTable6[6] = {1073741824, 6051, 1073747888, 6086,
+                                           1073747915, 6139};  // NOLINT
+static const uint16_t kID_StartTable7Size = 48;
+static const int32_t kID_StartTable7[48] = {
+    1073748224, 6765,       1073748592, 6873,
+    1073748736, 6918,       1073748755, 6935,  // NOLINT
+    6941,       1073748767, 6952,       1073748778,
+    6966,       1073748792, 6972,       6974,  // NOLINT
+    1073748800, 6977,       1073748803, 6980,
+    1073748806, 7089,       1073748947, 7485,  // NOLINT
+    1073749328, 7567,       1073749394, 7623,
+    1073749488, 7675,       1073749616, 7796,  // NOLINT
+    1073749622, 7932,       1073749793, 7994,
+    1073749825, 8026,       1073749862, 8126,  // NOLINT
+    1073749954, 8135,       1073749962, 8143,
+    1073749970, 8151,       1073749978, 8156};  // NOLINT
+bool ID_Start::Is(uchar c) {
+  int chunk_index = c >> 13;
+  switch (chunk_index) {
+    case 0:
+      return LookupPredicate(kID_StartTable0, kID_StartTable0Size, c);
+    case 1:
+      return LookupPredicate(kID_StartTable1, kID_StartTable1Size, c);
+    case 2:
+      return LookupPredicate(kID_StartTable2, kID_StartTable2Size, c);
+    case 3:
+      return LookupPredicate(kID_StartTable3, kID_StartTable3Size, c);
+    case 4:
+      return LookupPredicate(kID_StartTable4, kID_StartTable4Size, c);
+    case 5:
+      return LookupPredicate(kID_StartTable5, kID_StartTable5Size, c);
+    case 6:
+      return LookupPredicate(kID_StartTable6, kID_StartTable6Size, c);
+    case 7:
+      return LookupPredicate(kID_StartTable7, kID_StartTable7Size, c);
+    default:
+      return false;
+  }
+}
+
+
+// ID_Continue:          point.category in ['Nd', 'Mn', 'Mc', 'Pc'] or
+// 'Other_ID_Continue' in point.properties or 'JS_ID_Continue' in
+// point.properties
+
+static const uint16_t kID_ContinueTable0Size = 315;
+static const int32_t kID_ContinueTable0[315] = {
+    1073741872, 57,         95,         183,
+    1073742592, 879,        903,        1073742979,  // NOLINT
+    1159,       1073743249, 1469,       1471,
+    1073743297, 1474,       1073743300, 1477,  // NOLINT
+    1479,       1073743376, 1562,       1073743435,
+    1641,       1648,       1073743574, 1756,  // NOLINT
+    1073743583, 1764,       1073743591, 1768,
+    1073743594, 1773,       1073743600, 1785,  // NOLINT
+    1809,       1073743664, 1866,       1073743782,
+    1968,       1073743808, 1993,       1073743851,  // NOLINT
+    2035,       1073743894, 2073,       1073743899,
+    2083,       1073743909, 2087,       1073743913,  // NOLINT
+    2093,       1073743961, 2139,       1073744100,
+    2307,       1073744186, 2364,       1073744190,  // NOLINT
+    2383,       1073744209, 2391,       1073744226,
+    2403,       1073744230, 2415,       1073744257,  // NOLINT
+    2435,       2492,       1073744318, 2500,
+    1073744327, 2504,       1073744331, 2509,  // NOLINT
+    2519,       1073744354, 2531,       1073744358,
+    2543,       1073744385, 2563,       2620,  // NOLINT
+    1073744446, 2626,       1073744455, 2632,
+    1073744459, 2637,       2641,       1073744486,  // NOLINT
+    2673,       2677,       1073744513, 2691,
+    2748,       1073744574, 2757,       1073744583,  // NOLINT
+    2761,       1073744587, 2765,       1073744610,
+    2787,       1073744614, 2799,       1073744641,  // NOLINT
+    2819,       2876,       1073744702, 2884,
+    1073744711, 2888,       1073744715, 2893,  // NOLINT
+    1073744726, 2903,       1073744738, 2915,
+    1073744742, 2927,       2946,       1073744830,  // NOLINT
+    3010,       1073744838, 3016,       1073744842,
+    3021,       3031,       1073744870, 3055,  // NOLINT
+    1073744896, 3075,       1073744958, 3140,
+    1073744966, 3144,       1073744970, 3149,  // NOLINT
+    1073744981, 3158,       1073744994, 3171,
+    1073744998, 3183,       1073745025, 3203,  // NOLINT
+    3260,       1073745086, 3268,       1073745094,
+    3272,       1073745098, 3277,       1073745109,  // NOLINT
+    3286,       1073745122, 3299,       1073745126,
+    3311,       1073745153, 3331,       1073745214,  // NOLINT
+    3396,       1073745222, 3400,       1073745226,
+    3405,       3415,       1073745250, 3427,  // NOLINT
+    1073745254, 3439,       1073745282, 3459,
+    3530,       1073745359, 3540,       3542,  // NOLINT
+    1073745368, 3551,       1073745382, 3567,
+    1073745394, 3571,       3633,       1073745460,  // NOLINT
+    3642,       1073745479, 3662,       1073745488,
+    3673,       3761,       1073745588, 3769,  // NOLINT
+    1073745595, 3772,       1073745608, 3789,
+    1073745616, 3801,       1073745688, 3865,  // NOLINT
+    1073745696, 3881,       3893,       3895,
+    3897,       1073745726, 3903,       1073745777,  // NOLINT
+    3972,       1073745798, 3975,       1073745805,
+    3991,       1073745817, 4028,       4038,  // NOLINT
+    1073745963, 4158,       1073745984, 4169,
+    1073746006, 4185,       1073746014, 4192,  // NOLINT
+    1073746018, 4196,       1073746023, 4205,
+    1073746033, 4212,       1073746050, 4237,  // NOLINT
+    1073746063, 4253,       1073746781, 4959,
+    1073746793, 4977,       1073747730, 5908,  // NOLINT
+    1073747762, 5940,       1073747794, 5971,
+    1073747826, 6003,       1073747892, 6099,  // NOLINT
+    6109,       1073747936, 6121,       1073747979,
+    6157,       1073747984, 6169,       6313,  // NOLINT
+    1073748256, 6443,       1073748272, 6459,
+    1073748294, 6479,       1073748400, 6592,  // NOLINT
+    1073748424, 6601,       1073748432, 6618,
+    1073748503, 6683,       1073748565, 6750,  // NOLINT
+    1073748576, 6780,       1073748607, 6793,
+    1073748624, 6809,       1073748656, 6845,  // NOLINT
+    1073748736, 6916,       1073748788, 6980,
+    1073748816, 7001,       1073748843, 7027,  // NOLINT
+    1073748864, 7042,       1073748897, 7085,
+    1073748912, 7097,       1073748966, 7155,  // NOLINT
+    1073749028, 7223,       1073749056, 7241,
+    1073749072, 7257,       1073749200, 7378,  // NOLINT
+    1073749204, 7400,       7405,       1073749234,
+    7412,       1073749240, 7417,       1073749440,  // NOLINT
+    7669,       1073749500, 7679};                   // NOLINT
+static const uint16_t kID_ContinueTable1Size = 19;
+static const int32_t kID_ContinueTable1[19] = {
+    1073741836, 13,         1073741887, 64,
+    84,         1073742032, 220,        225,  // NOLINT
+    1073742053, 240,        1073745135, 3313,
+    3455,       1073745376, 3583,       1073745962,  // NOLINT
+    4143,       1073746073, 4250};                   // NOLINT
+static const uint16_t kID_ContinueTable5Size = 63;
+static const int32_t kID_ContinueTable5[63] = {
+    1073743392, 1577,       1647,       1073743476,
+    1661,       1695,       1073743600, 1777,  // NOLINT
+    2050,       2054,       2059,       1073743907,
+    2087,       1073744000, 2177,       1073744052,  // NOLINT
+    2244,       1073744080, 2265,       1073744096,
+    2289,       1073744128, 2313,       1073744166,  // NOLINT
+    2349,       1073744199, 2387,       1073744256,
+    2435,       1073744307, 2496,       1073744336,  // NOLINT
+    2521,       2533,       1073744368, 2553,
+    1073744425, 2614,       2627,       1073744460,  // NOLINT
+    2637,       1073744464, 2649,       1073744507,
+    2685,       2736,       1073744562, 2740,  // NOLINT
+    1073744567, 2744,       1073744574, 2751,
+    2753,       1073744619, 2799,       1073744629,  // NOLINT
+    2806,       1073744867, 3050,       1073744876,
+    3053,       1073744880, 3065};  // NOLINT
+static const uint16_t kID_ContinueTable7Size = 12;
+static const int32_t kID_ContinueTable7[12] = {
+    6942, 1073749504, 7695, 1073749536,
+    7725, 1073749555, 7732, 1073749581,  // NOLINT
+    7759, 1073749776, 7961, 7999};       // NOLINT
+bool ID_Continue::Is(uchar c) {
+  int chunk_index = c >> 13;
+  switch (chunk_index) {
+    case 0:
+      return LookupPredicate(kID_ContinueTable0, kID_ContinueTable0Size, c);
+    case 1:
+      return LookupPredicate(kID_ContinueTable1, kID_ContinueTable1Size, c);
+    case 5:
+      return LookupPredicate(kID_ContinueTable5, kID_ContinueTable5Size, c);
+    case 7:
+      return LookupPredicate(kID_ContinueTable7, kID_ContinueTable7Size, c);
+    default: return false;
+  }
+}
+
+
+// WhiteSpace:           (point.category == 'Zs') or ('JS_White_Space' in
+// point.properties)
+
+static const uint16_t kWhiteSpaceTable0Size = 7;
+static const int32_t kWhiteSpaceTable0[7] = {9,   1073741835, 12,  32,
+                                             160, 5760,       6158};  // NOLINT
+static const uint16_t kWhiteSpaceTable1Size = 5;
+static const int32_t kWhiteSpaceTable1[5] = {
+  1073741824, 10, 47, 95, 4096 };  // NOLINT
+static const uint16_t kWhiteSpaceTable7Size = 1;
+static const int32_t kWhiteSpaceTable7[1] = {7935};  // NOLINT
+bool WhiteSpace::Is(uchar c) {
+  int chunk_index = c >> 13;
+  switch (chunk_index) {
+    case 0: return LookupPredicate(kWhiteSpaceTable0,
+                                       kWhiteSpaceTable0Size,
+                                       c);
+    case 1: return LookupPredicate(kWhiteSpaceTable1,
+                                       kWhiteSpaceTable1Size,
+                                       c);
+    case 7:
+      return LookupPredicate(kWhiteSpaceTable7, kWhiteSpaceTable7Size, c);
+    default: return false;
+  }
+}
+
+
+// LineTerminator:       'JS_Line_Terminator' in point.properties
+
+static const uint16_t kLineTerminatorTable0Size = 2;
+static const int32_t kLineTerminatorTable0[2] = {
+  10, 13 };  // NOLINT
+static const uint16_t kLineTerminatorTable1Size = 2;
+static const int32_t kLineTerminatorTable1[2] = {
+  1073741864, 41 };  // NOLINT
+bool LineTerminator::Is(uchar c) {
+  int chunk_index = c >> 13;
+  switch (chunk_index) {
+    case 0: return LookupPredicate(kLineTerminatorTable0,
+                                       kLineTerminatorTable0Size,
+                                       c);
+    case 1: return LookupPredicate(kLineTerminatorTable1,
+                                       kLineTerminatorTable1Size,
+                                       c);
+    default: return false;
+  }
+}
+
+static const MultiCharacterSpecialCase<2> kToLowercaseMultiStrings0[2] = {  // NOLINT
+  {{105, 775}}, {{kSentinel}} }; // NOLINT
+static const uint16_t kToLowercaseTable0Size = 488;  // NOLINT
+static const int32_t kToLowercaseTable0[976] = {
+    1073741889, 128,    90,         128,   1073742016, 128,
+    214,        128,    1073742040, 128,   222,        128,
+    256,        4,      258,        4,  // NOLINT
+    260,        4,      262,        4,     264,        4,
+    266,        4,      268,        4,     270,        4,
+    272,        4,      274,        4,  // NOLINT
+    276,        4,      278,        4,     280,        4,
+    282,        4,      284,        4,     286,        4,
+    288,        4,      290,        4,  // NOLINT
+    292,        4,      294,        4,     296,        4,
+    298,        4,      300,        4,     302,        4,
+    304,        1,      306,        4,  // NOLINT
+    308,        4,      310,        4,     313,        4,
+    315,        4,      317,        4,     319,        4,
+    321,        4,      323,        4,  // NOLINT
+    325,        4,      327,        4,     330,        4,
+    332,        4,      334,        4,     336,        4,
+    338,        4,      340,        4,  // NOLINT
+    342,        4,      344,        4,     346,        4,
+    348,        4,      350,        4,     352,        4,
+    354,        4,      356,        4,  // NOLINT
+    358,        4,      360,        4,     362,        4,
+    364,        4,      366,        4,     368,        4,
+    370,        4,      372,        4,  // NOLINT
+    374,        4,      376,        -484,  377,        4,
+    379,        4,      381,        4,     385,        840,
+    386,        4,      388,        4,  // NOLINT
+    390,        824,    391,        4,     1073742217, 820,
+    394,        820,    395,        4,     398,        316,
+    399,        808,    400,        812,  // NOLINT
+    401,        4,      403,        820,   404,        828,
+    406,        844,    407,        836,   408,        4,
+    412,        844,    413,        852,  // NOLINT
+    415,        856,    416,        4,     418,        4,
+    420,        4,      422,        872,   423,        4,
+    425,        872,    428,        4,  // NOLINT
+    430,        872,    431,        4,     1073742257, 868,
+    434,        868,    435,        4,     437,        4,
+    439,        876,    440,        4,  // NOLINT
+    444,        4,      452,        8,     453,        4,
+    455,        8,      456,        4,     458,        8,
+    459,        4,      461,        4,  // NOLINT
+    463,        4,      465,        4,     467,        4,
+    469,        4,      471,        4,     473,        4,
+    475,        4,      478,        4,  // NOLINT
+    480,        4,      482,        4,     484,        4,
+    486,        4,      488,        4,     490,        4,
+    492,        4,      494,        4,  // NOLINT
+    497,        8,      498,        4,     500,        4,
+    502,        -388,   503,        -224,  504,        4,
+    506,        4,      508,        4,  // NOLINT
+    510,        4,      512,        4,     514,        4,
+    516,        4,      518,        4,     520,        4,
+    522,        4,      524,        4,  // NOLINT
+    526,        4,      528,        4,     530,        4,
+    532,        4,      534,        4,     536,        4,
+    538,        4,      540,        4,  // NOLINT
+    542,        4,      544,        -520,  546,        4,
+    548,        4,      550,        4,     552,        4,
+    554,        4,      556,        4,  // NOLINT
+    558,        4,      560,        4,     562,        4,
+    570,        43180,  571,        4,     573,        -652,
+    574,        43168,  577,        4,  // NOLINT
+    579,        -780,   580,        276,   581,        284,
+    582,        4,      584,        4,     586,        4,
+    588,        4,      590,        4,  // NOLINT
+    880,        4,      882,        4,     886,        4,
+    895,        464,    902,        152,   1073742728, 148,
+    906,        148,    908,        256,  // NOLINT
+    1073742734, 252,    911,        252,   1073742737, 128,
+    929,        128,    931,        6,     1073742756, 128,
+    939,        128,    975,        32,  // NOLINT
+    984,        4,      986,        4,     988,        4,
+    990,        4,      992,        4,     994,        4,
+    996,        4,      998,        4,  // NOLINT
+    1000,       4,      1002,       4,     1004,       4,
+    1006,       4,      1012,       -240,  1015,       4,
+    1017,       -28,    1018,       4,  // NOLINT
+    1073742845, -520,   1023,       -520,  1073742848, 320,
+    1039,       320,    1073742864, 128,   1071,       128,
+    1120,       4,      1122,       4,  // NOLINT
+    1124,       4,      1126,       4,     1128,       4,
+    1130,       4,      1132,       4,     1134,       4,
+    1136,       4,      1138,       4,  // NOLINT
+    1140,       4,      1142,       4,     1144,       4,
+    1146,       4,      1148,       4,     1150,       4,
+    1152,       4,      1162,       4,  // NOLINT
+    1164,       4,      1166,       4,     1168,       4,
+    1170,       4,      1172,       4,     1174,       4,
+    1176,       4,      1178,       4,  // NOLINT
+    1180,       4,      1182,       4,     1184,       4,
+    1186,       4,      1188,       4,     1190,       4,
+    1192,       4,      1194,       4,  // NOLINT
+    1196,       4,      1198,       4,     1200,       4,
+    1202,       4,      1204,       4,     1206,       4,
+    1208,       4,      1210,       4,  // NOLINT
+    1212,       4,      1214,       4,     1216,       60,
+    1217,       4,      1219,       4,     1221,       4,
+    1223,       4,      1225,       4,  // NOLINT
+    1227,       4,      1229,       4,     1232,       4,
+    1234,       4,      1236,       4,     1238,       4,
+    1240,       4,      1242,       4,  // NOLINT
+    1244,       4,      1246,       4,     1248,       4,
+    1250,       4,      1252,       4,     1254,       4,
+    1256,       4,      1258,       4,  // NOLINT
+    1260,       4,      1262,       4,     1264,       4,
+    1266,       4,      1268,       4,     1270,       4,
+    1272,       4,      1274,       4,  // NOLINT
+    1276,       4,      1278,       4,     1280,       4,
+    1282,       4,      1284,       4,     1286,       4,
+    1288,       4,      1290,       4,  // NOLINT
+    1292,       4,      1294,       4,     1296,       4,
+    1298,       4,      1300,       4,     1302,       4,
+    1304,       4,      1306,       4,  // NOLINT
+    1308,       4,      1310,       4,     1312,       4,
+    1314,       4,      1316,       4,     1318,       4,
+    1320,       4,      1322,       4,  // NOLINT
+    1324,       4,      1326,       4,     1073743153, 192,
+    1366,       192,    1073746080, 29056, 4293,       29056,
+    4295,       29056,  4301,       29056,  // NOLINT
+    7680,       4,      7682,       4,     7684,       4,
+    7686,       4,      7688,       4,     7690,       4,
+    7692,       4,      7694,       4,  // NOLINT
+    7696,       4,      7698,       4,     7700,       4,
+    7702,       4,      7704,       4,     7706,       4,
+    7708,       4,      7710,       4,  // NOLINT
+    7712,       4,      7714,       4,     7716,       4,
+    7718,       4,      7720,       4,     7722,       4,
+    7724,       4,      7726,       4,  // NOLINT
+    7728,       4,      7730,       4,     7732,       4,
+    7734,       4,      7736,       4,     7738,       4,
+    7740,       4,      7742,       4,  // NOLINT
+    7744,       4,      7746,       4,     7748,       4,
+    7750,       4,      7752,       4,     7754,       4,
+    7756,       4,      7758,       4,  // NOLINT
+    7760,       4,      7762,       4,     7764,       4,
+    7766,       4,      7768,       4,     7770,       4,
+    7772,       4,      7774,       4,  // NOLINT
+    7776,       4,      7778,       4,     7780,       4,
+    7782,       4,      7784,       4,     7786,       4,
+    7788,       4,      7790,       4,  // NOLINT
+    7792,       4,      7794,       4,     7796,       4,
+    7798,       4,      7800,       4,     7802,       4,
+    7804,       4,      7806,       4,  // NOLINT
+    7808,       4,      7810,       4,     7812,       4,
+    7814,       4,      7816,       4,     7818,       4,
+    7820,       4,      7822,       4,  // NOLINT
+    7824,       4,      7826,       4,     7828,       4,
+    7838,       -30460, 7840,       4,     7842,       4,
+    7844,       4,      7846,       4,  // NOLINT
+    7848,       4,      7850,       4,     7852,       4,
+    7854,       4,      7856,       4,     7858,       4,
+    7860,       4,      7862,       4,  // NOLINT
+    7864,       4,      7866,       4,     7868,       4,
+    7870,       4,      7872,       4,     7874,       4,
+    7876,       4,      7878,       4,  // NOLINT
+    7880,       4,      7882,       4,     7884,       4,
+    7886,       4,      7888,       4,     7890,       4,
+    7892,       4,      7894,       4,  // NOLINT
+    7896,       4,      7898,       4,     7900,       4,
+    7902,       4,      7904,       4,     7906,       4,
+    7908,       4,      7910,       4,  // NOLINT
+    7912,       4,      7914,       4,     7916,       4,
+    7918,       4,      7920,       4,     7922,       4,
+    7924,       4,      7926,       4,  // NOLINT
+    7928,       4,      7930,       4,     7932,       4,
+    7934,       4,      1073749768, -32,   7951,       -32,
+    1073749784, -32,    7965,       -32,  // NOLINT
+    1073749800, -32,    7983,       -32,   1073749816, -32,
+    7999,       -32,    1073749832, -32,   8013,       -32,
+    8025,       -32,    8027,       -32,  // NOLINT
+    8029,       -32,    8031,       -32,   1073749864, -32,
+    8047,       -32,    1073749896, -32,   8079,       -32,
+    1073749912, -32,    8095,       -32,  // NOLINT
+    1073749928, -32,    8111,       -32,   1073749944, -32,
+    8121,       -32,    1073749946, -296,  8123,       -296,
+    8124,       -36,    1073749960, -344,  // NOLINT
+    8139,       -344,   8140,       -36,   1073749976, -32,
+    8153,       -32,    1073749978, -400,  8155,       -400,
+    1073749992, -32,    8169,       -32,  // NOLINT
+    1073749994, -448,   8171,       -448,  8172,       -28,
+    1073750008, -512,   8185,       -512,  1073750010, -504,
+    8187,       -504,   8188,       -36};                 // NOLINT
+static const uint16_t kToLowercaseMultiStrings0Size = 2;  // NOLINT
+static const MultiCharacterSpecialCase<1> kToLowercaseMultiStrings1[1] = {  // NOLINT
+  {{kSentinel}} }; // NOLINT
+static const uint16_t kToLowercaseTable1Size = 79;  // NOLINT
+static const int32_t kToLowercaseTable1[158] = {
+  294, -30068, 298, -33532, 299, -33048, 306, 112, 1073742176, 64, 367, 64, 387, 4, 1073743030, 104,  // NOLINT
+  1231, 104, 1073744896, 192, 3118, 192, 3168, 4, 3170, -42972, 3171, -15256, 3172, -42908, 3175, 4,  // NOLINT
+  3177, 4, 3179, 4, 3181, -43120, 3182, -42996, 3183, -43132, 3184, -43128, 3186, 4, 3189, 4,  // NOLINT
+  1073745022, -43260, 3199, -43260, 3200, 4, 3202, 4, 3204, 4, 3206, 4, 3208, 4, 3210, 4,  // NOLINT
+  3212, 4, 3214, 4, 3216, 4, 3218, 4, 3220, 4, 3222, 4, 3224, 4, 3226, 4,  // NOLINT
+  3228, 4, 3230, 4, 3232, 4, 3234, 4, 3236, 4, 3238, 4, 3240, 4, 3242, 4,  // NOLINT
+  3244, 4, 3246, 4, 3248, 4, 3250, 4, 3252, 4, 3254, 4, 3256, 4, 3258, 4,  // NOLINT
+  3260, 4, 3262, 4, 3264, 4, 3266, 4, 3268, 4, 3270, 4, 3272, 4, 3274, 4,  // NOLINT
+  3276, 4, 3278, 4, 3280, 4, 3282, 4, 3284, 4, 3286, 4, 3288, 4, 3290, 4,  // NOLINT
+  3292, 4, 3294, 4, 3296, 4, 3298, 4, 3307, 4, 3309, 4, 3314, 4 };  // NOLINT
+static const uint16_t kToLowercaseMultiStrings1Size = 1;  // NOLINT
+static const MultiCharacterSpecialCase<1> kToLowercaseMultiStrings5[1] = {  // NOLINT
+  {{kSentinel}} }; // NOLINT
+static const uint16_t kToLowercaseTable5Size = 103;  // NOLINT
+static const int32_t kToLowercaseTable5[206] = {
+    1600, 4,       1602, 4,       1604, 4,       1606, 4,
+    1608, 4,       1610, 4,       1612, 4,       1614, 4,  // NOLINT
+    1616, 4,       1618, 4,       1620, 4,       1622, 4,
+    1624, 4,       1626, 4,       1628, 4,       1630, 4,  // NOLINT
+    1632, 4,       1634, 4,       1636, 4,       1638, 4,
+    1640, 4,       1642, 4,       1644, 4,       1664, 4,  // NOLINT
+    1666, 4,       1668, 4,       1670, 4,       1672, 4,
+    1674, 4,       1676, 4,       1678, 4,       1680, 4,  // NOLINT
+    1682, 4,       1684, 4,       1686, 4,       1688, 4,
+    1690, 4,       1826, 4,       1828, 4,       1830, 4,  // NOLINT
+    1832, 4,       1834, 4,       1836, 4,       1838, 4,
+    1842, 4,       1844, 4,       1846, 4,       1848, 4,  // NOLINT
+    1850, 4,       1852, 4,       1854, 4,       1856, 4,
+    1858, 4,       1860, 4,       1862, 4,       1864, 4,  // NOLINT
+    1866, 4,       1868, 4,       1870, 4,       1872, 4,
+    1874, 4,       1876, 4,       1878, 4,       1880, 4,  // NOLINT
+    1882, 4,       1884, 4,       1886, 4,       1888, 4,
+    1890, 4,       1892, 4,       1894, 4,       1896, 4,  // NOLINT
+    1898, 4,       1900, 4,       1902, 4,       1913, 4,
+    1915, 4,       1917, -141328, 1918, 4,       1920, 4,  // NOLINT
+    1922, 4,       1924, 4,       1926, 4,       1931, 4,
+    1933, -169120, 1936, 4,       1938, 4,       1942, 4,  // NOLINT
+    1944, 4,       1946, 4,       1948, 4,       1950, 4,
+    1952, 4,       1954, 4,       1956, 4,       1958, 4,  // NOLINT
+    1960, 4,       1962, -169232, 1963, -169276, 1964, -169260,
+    1965, -169220, 1968, -169032, 1969, -169128};         // NOLINT
+static const uint16_t kToLowercaseMultiStrings5Size = 1;  // NOLINT
+static const MultiCharacterSpecialCase<1> kToLowercaseMultiStrings7[1] = {  // NOLINT
+  {{kSentinel}} }; // NOLINT
+static const uint16_t kToLowercaseTable7Size = 2;  // NOLINT
+static const int32_t kToLowercaseTable7[4] = {
+  1073749793, 128, 7994, 128 };  // NOLINT
+static const uint16_t kToLowercaseMultiStrings7Size = 1;  // NOLINT
+int ToLowercase::Convert(uchar c,
+                      uchar n,
+                      uchar* result,
+                      bool* allow_caching_ptr) {
+  int chunk_index = c >> 13;
+  switch (chunk_index) {
+    case 0: return LookupMapping<true>(kToLowercaseTable0,
+                                           kToLowercaseTable0Size,
+                                           kToLowercaseMultiStrings0,
+                                           c,
+                                           n,
+                                           result,
+                                           allow_caching_ptr);
+    case 1: return LookupMapping<true>(kToLowercaseTable1,
+                                           kToLowercaseTable1Size,
+                                           kToLowercaseMultiStrings1,
+                                           c,
+                                           n,
+                                           result,
+                                           allow_caching_ptr);
+    case 5: return LookupMapping<true>(kToLowercaseTable5,
+                                           kToLowercaseTable5Size,
+                                           kToLowercaseMultiStrings5,
+                                           c,
+                                           n,
+                                           result,
+                                           allow_caching_ptr);
+    case 7: return LookupMapping<true>(kToLowercaseTable7,
+                                           kToLowercaseTable7Size,
+                                           kToLowercaseMultiStrings7,
+                                           c,
+                                           n,
+                                           result,
+                                           allow_caching_ptr);
+    default: return 0;
+  }
+}
+
+static const MultiCharacterSpecialCase<3> kToUppercaseMultiStrings0[62] = {  // NOLINT
+  {{83, 83, kSentinel}}, {{700, 78, kSentinel}}, {{74, 780, kSentinel}}, {{921, 776, 769}},  // NOLINT
+  {{933, 776, 769}}, {{1333, 1362, kSentinel}}, {{72, 817, kSentinel}}, {{84, 776, kSentinel}},  // NOLINT
+  {{87, 778, kSentinel}}, {{89, 778, kSentinel}}, {{65, 702, kSentinel}}, {{933, 787, kSentinel}},  // NOLINT
+  {{933, 787, 768}}, {{933, 787, 769}}, {{933, 787, 834}}, {{7944, 921, kSentinel}},  // NOLINT
+  {{7945, 921, kSentinel}}, {{7946, 921, kSentinel}}, {{7947, 921, kSentinel}}, {{7948, 921, kSentinel}},  // NOLINT
+  {{7949, 921, kSentinel}}, {{7950, 921, kSentinel}}, {{7951, 921, kSentinel}}, {{7976, 921, kSentinel}},  // NOLINT
+  {{7977, 921, kSentinel}}, {{7978, 921, kSentinel}}, {{7979, 921, kSentinel}}, {{7980, 921, kSentinel}},  // NOLINT
+  {{7981, 921, kSentinel}}, {{7982, 921, kSentinel}}, {{7983, 921, kSentinel}}, {{8040, 921, kSentinel}},  // NOLINT
+  {{8041, 921, kSentinel}}, {{8042, 921, kSentinel}}, {{8043, 921, kSentinel}}, {{8044, 921, kSentinel}},  // NOLINT
+  {{8045, 921, kSentinel}}, {{8046, 921, kSentinel}}, {{8047, 921, kSentinel}}, {{8122, 921, kSentinel}},  // NOLINT
+  {{913, 921, kSentinel}}, {{902, 921, kSentinel}}, {{913, 834, kSentinel}}, {{913, 834, 921}},  // NOLINT
+  {{8138, 921, kSentinel}}, {{919, 921, kSentinel}}, {{905, 921, kSentinel}}, {{919, 834, kSentinel}},  // NOLINT
+  {{919, 834, 921}}, {{921, 776, 768}}, {{921, 834, kSentinel}}, {{921, 776, 834}},  // NOLINT
+  {{933, 776, 768}}, {{929, 787, kSentinel}}, {{933, 834, kSentinel}}, {{933, 776, 834}},  // NOLINT
+  {{8186, 921, kSentinel}}, {{937, 921, kSentinel}}, {{911, 921, kSentinel}}, {{937, 834, kSentinel}},  // NOLINT
+  {{937, 834, 921}}, {{kSentinel}} }; // NOLINT
+static const uint16_t kToUppercaseTable0Size = 590;  // NOLINT
+static const int32_t kToUppercaseTable0[1180] = {
+    1073741921, -128,   122,        -128,   181,        2972,
+    223,        1,      1073742048, -128,   246,        -128,
+    1073742072, -128,   254,        -128,  // NOLINT
+    255,        484,    257,        -4,     259,        -4,
+    261,        -4,     263,        -4,     265,        -4,
+    267,        -4,     269,        -4,  // NOLINT
+    271,        -4,     273,        -4,     275,        -4,
+    277,        -4,     279,        -4,     281,        -4,
+    283,        -4,     285,        -4,  // NOLINT
+    287,        -4,     289,        -4,     291,        -4,
+    293,        -4,     295,        -4,     297,        -4,
+    299,        -4,     301,        -4,  // NOLINT
+    303,        -4,     305,        -928,   307,        -4,
+    309,        -4,     311,        -4,     314,        -4,
+    316,        -4,     318,        -4,  // NOLINT
+    320,        -4,     322,        -4,     324,        -4,
+    326,        -4,     328,        -4,     329,        5,
+    331,        -4,     333,        -4,  // NOLINT
+    335,        -4,     337,        -4,     339,        -4,
+    341,        -4,     343,        -4,     345,        -4,
+    347,        -4,     349,        -4,  // NOLINT
+    351,        -4,     353,        -4,     355,        -4,
+    357,        -4,     359,        -4,     361,        -4,
+    363,        -4,     365,        -4,  // NOLINT
+    367,        -4,     369,        -4,     371,        -4,
+    373,        -4,     375,        -4,     378,        -4,
+    380,        -4,     382,        -4,  // NOLINT
+    383,        -1200,  384,        780,    387,        -4,
+    389,        -4,     392,        -4,     396,        -4,
+    402,        -4,     405,        388,  // NOLINT
+    409,        -4,     410,        652,    414,        520,
+    417,        -4,     419,        -4,     421,        -4,
+    424,        -4,     429,        -4,  // NOLINT
+    432,        -4,     436,        -4,     438,        -4,
+    441,        -4,     445,        -4,     447,        224,
+    453,        -4,     454,        -8,  // NOLINT
+    456,        -4,     457,        -8,     459,        -4,
+    460,        -8,     462,        -4,     464,        -4,
+    466,        -4,     468,        -4,  // NOLINT
+    470,        -4,     472,        -4,     474,        -4,
+    476,        -4,     477,        -316,   479,        -4,
+    481,        -4,     483,        -4,  // NOLINT
+    485,        -4,     487,        -4,     489,        -4,
+    491,        -4,     493,        -4,     495,        -4,
+    496,        9,      498,        -4,  // NOLINT
+    499,        -8,     501,        -4,     505,        -4,
+    507,        -4,     509,        -4,     511,        -4,
+    513,        -4,     515,        -4,  // NOLINT
+    517,        -4,     519,        -4,     521,        -4,
+    523,        -4,     525,        -4,     527,        -4,
+    529,        -4,     531,        -4,  // NOLINT
+    533,        -4,     535,        -4,     537,        -4,
+    539,        -4,     541,        -4,     543,        -4,
+    547,        -4,     549,        -4,  // NOLINT
+    551,        -4,     553,        -4,     555,        -4,
+    557,        -4,     559,        -4,     561,        -4,
+    563,        -4,     572,        -4,  // NOLINT
+    1073742399, 43260,  576,        43260,  578,        -4,
+    583,        -4,     585,        -4,     587,        -4,
+    589,        -4,     591,        -4,  // NOLINT
+    592,        43132,  593,        43120,  594,        43128,
+    595,        -840,   596,        -824,   1073742422, -820,
+    599,        -820,   601,        -808,  // NOLINT
+    603,        -812,   604,        169276, 608,        -820,
+    609,        169260, 611,        -828,   613,        169120,
+    614,        169232, 616,        -836,  // NOLINT
+    617,        -844,   619,        42972,  620,        169220,
+    623,        -844,   625,        42996,  626,        -852,
+    629,        -856,   637,        42908,  // NOLINT
+    640,        -872,   643,        -872,   647,        169128,
+    648,        -872,   649,        -276,   1073742474, -868,
+    651,        -868,   652,        -284,  // NOLINT
+    658,        -876,   670,        169032, 837,        336,
+    881,        -4,     883,        -4,     887,        -4,
+    1073742715, 520,    893,        520,  // NOLINT
+    912,        13,     940,        -152,   1073742765, -148,
+    943,        -148,   944,        17,     1073742769, -128,
+    961,        -128,   962,        -124,  // NOLINT
+    1073742787, -128,   971,        -128,   972,        -256,
+    1073742797, -252,   974,        -252,   976,        -248,
+    977,        -228,   981,        -188,  // NOLINT
+    982,        -216,   983,        -32,    985,        -4,
+    987,        -4,     989,        -4,     991,        -4,
+    993,        -4,     995,        -4,  // NOLINT
+    997,        -4,     999,        -4,     1001,       -4,
+    1003,       -4,     1005,       -4,     1007,       -4,
+    1008,       -344,   1009,       -320,  // NOLINT
+    1010,       28,     1011,       -464,   1013,       -384,
+    1016,       -4,     1019,       -4,     1073742896, -128,
+    1103,       -128,   1073742928, -320,  // NOLINT
+    1119,       -320,   1121,       -4,     1123,       -4,
+    1125,       -4,     1127,       -4,     1129,       -4,
+    1131,       -4,     1133,       -4,  // NOLINT
+    1135,       -4,     1137,       -4,     1139,       -4,
+    1141,       -4,     1143,       -4,     1145,       -4,
+    1147,       -4,     1149,       -4,  // NOLINT
+    1151,       -4,     1153,       -4,     1163,       -4,
+    1165,       -4,     1167,       -4,     1169,       -4,
+    1171,       -4,     1173,       -4,  // NOLINT
+    1175,       -4,     1177,       -4,     1179,       -4,
+    1181,       -4,     1183,       -4,     1185,       -4,
+    1187,       -4,     1189,       -4,  // NOLINT
+    1191,       -4,     1193,       -4,     1195,       -4,
+    1197,       -4,     1199,       -4,     1201,       -4,
+    1203,       -4,     1205,       -4,  // NOLINT
+    1207,       -4,     1209,       -4,     1211,       -4,
+    1213,       -4,     1215,       -4,     1218,       -4,
+    1220,       -4,     1222,       -4,  // NOLINT
+    1224,       -4,     1226,       -4,     1228,       -4,
+    1230,       -4,     1231,       -60,    1233,       -4,
+    1235,       -4,     1237,       -4,  // NOLINT
+    1239,       -4,     1241,       -4,     1243,       -4,
+    1245,       -4,     1247,       -4,     1249,       -4,
+    1251,       -4,     1253,       -4,  // NOLINT
+    1255,       -4,     1257,       -4,     1259,       -4,
+    1261,       -4,     1263,       -4,     1265,       -4,
+    1267,       -4,     1269,       -4,  // NOLINT
+    1271,       -4,     1273,       -4,     1275,       -4,
+    1277,       -4,     1279,       -4,     1281,       -4,
+    1283,       -4,     1285,       -4,  // NOLINT
+    1287,       -4,     1289,       -4,     1291,       -4,
+    1293,       -4,     1295,       -4,     1297,       -4,
+    1299,       -4,     1301,       -4,  // NOLINT
+    1303,       -4,     1305,       -4,     1307,       -4,
+    1309,       -4,     1311,       -4,     1313,       -4,
+    1315,       -4,     1317,       -4,  // NOLINT
+    1319,       -4,     1321,       -4,     1323,       -4,
+    1325,       -4,     1327,       -4,     1073743201, -192,
+    1414,       -192,   1415,       21,  // NOLINT
+    7545,       141328, 7549,       15256,  7681,       -4,
+    7683,       -4,     7685,       -4,     7687,       -4,
+    7689,       -4,     7691,       -4,  // NOLINT
+    7693,       -4,     7695,       -4,     7697,       -4,
+    7699,       -4,     7701,       -4,     7703,       -4,
+    7705,       -4,     7707,       -4,  // NOLINT
+    7709,       -4,     7711,       -4,     7713,       -4,
+    7715,       -4,     7717,       -4,     7719,       -4,
+    7721,       -4,     7723,       -4,  // NOLINT
+    7725,       -4,     7727,       -4,     7729,       -4,
+    7731,       -4,     7733,       -4,     7735,       -4,
+    7737,       -4,     7739,       -4,  // NOLINT
+    7741,       -4,     7743,       -4,     7745,       -4,
+    7747,       -4,     7749,       -4,     7751,       -4,
+    7753,       -4,     7755,       -4,  // NOLINT
+    7757,       -4,     7759,       -4,     7761,       -4,
+    7763,       -4,     7765,       -4,     7767,       -4,
+    7769,       -4,     7771,       -4,  // NOLINT
+    7773,       -4,     7775,       -4,     7777,       -4,
+    7779,       -4,     7781,       -4,     7783,       -4,
+    7785,       -4,     7787,       -4,  // NOLINT
+    7789,       -4,     7791,       -4,     7793,       -4,
+    7795,       -4,     7797,       -4,     7799,       -4,
+    7801,       -4,     7803,       -4,  // NOLINT
+    7805,       -4,     7807,       -4,     7809,       -4,
+    7811,       -4,     7813,       -4,     7815,       -4,
+    7817,       -4,     7819,       -4,  // NOLINT
+    7821,       -4,     7823,       -4,     7825,       -4,
+    7827,       -4,     7829,       -4,     7830,       25,
+    7831,       29,     7832,       33,  // NOLINT
+    7833,       37,     7834,       41,     7835,       -236,
+    7841,       -4,     7843,       -4,     7845,       -4,
+    7847,       -4,     7849,       -4,  // NOLINT
+    7851,       -4,     7853,       -4,     7855,       -4,
+    7857,       -4,     7859,       -4,     7861,       -4,
+    7863,       -4,     7865,       -4,  // NOLINT
+    7867,       -4,     7869,       -4,     7871,       -4,
+    7873,       -4,     7875,       -4,     7877,       -4,
+    7879,       -4,     7881,       -4,  // NOLINT
+    7883,       -4,     7885,       -4,     7887,       -4,
+    7889,       -4,     7891,       -4,     7893,       -4,
+    7895,       -4,     7897,       -4,  // NOLINT
+    7899,       -4,     7901,       -4,     7903,       -4,
+    7905,       -4,     7907,       -4,     7909,       -4,
+    7911,       -4,     7913,       -4,  // NOLINT
+    7915,       -4,     7917,       -4,     7919,       -4,
+    7921,       -4,     7923,       -4,     7925,       -4,
+    7927,       -4,     7929,       -4,  // NOLINT
+    7931,       -4,     7933,       -4,     7935,       -4,
+    1073749760, 32,     7943,       32,     1073749776, 32,
+    7957,       32,     1073749792, 32,  // NOLINT
+    7975,       32,     1073749808, 32,     7991,       32,
+    1073749824, 32,     8005,       32,     8016,       45,
+    8017,       32,     8018,       49,  // NOLINT
+    8019,       32,     8020,       53,     8021,       32,
+    8022,       57,     8023,       32,     1073749856, 32,
+    8039,       32,     1073749872, 296,  // NOLINT
+    8049,       296,    1073749874, 344,    8053,       344,
+    1073749878, 400,    8055,       400,    1073749880, 512,
+    8057,       512,    1073749882, 448,  // NOLINT
+    8059,       448,    1073749884, 504,    8061,       504,
+    8064,       61,     8065,       65,     8066,       69,
+    8067,       73,     8068,       77,  // NOLINT
+    8069,       81,     8070,       85,     8071,       89,
+    8072,       61,     8073,       65,     8074,       69,
+    8075,       73,     8076,       77,  // NOLINT
+    8077,       81,     8078,       85,     8079,       89,
+    8080,       93,     8081,       97,     8082,       101,
+    8083,       105,    8084,       109,  // NOLINT
+    8085,       113,    8086,       117,    8087,       121,
+    8088,       93,     8089,       97,     8090,       101,
+    8091,       105,    8092,       109,  // NOLINT
+    8093,       113,    8094,       117,    8095,       121,
+    8096,       125,    8097,       129,    8098,       133,
+    8099,       137,    8100,       141,  // NOLINT
+    8101,       145,    8102,       149,    8103,       153,
+    8104,       125,    8105,       129,    8106,       133,
+    8107,       137,    8108,       141,  // NOLINT
+    8109,       145,    8110,       149,    8111,       153,
+    1073749936, 32,     8113,       32,     8114,       157,
+    8115,       161,    8116,       165,  // NOLINT
+    8118,       169,    8119,       173,    8124,       161,
+    8126,       -28820, 8130,       177,    8131,       181,
+    8132,       185,    8134,       189,  // NOLINT
+    8135,       193,    8140,       181,    1073749968, 32,
+    8145,       32,     8146,       197,    8147,       13,
+    8150,       201,    8151,       205,  // NOLINT
+    1073749984, 32,     8161,       32,     8162,       209,
+    8163,       17,     8164,       213,    8165,       28,
+    8166,       217,    8167,       221,  // NOLINT
+    8178,       225,    8179,       229,    8180,       233,
+    8182,       237,    8183,       241,    8188,       229};  // NOLINT
+static const uint16_t kToUppercaseMultiStrings0Size = 62;  // NOLINT
+static const MultiCharacterSpecialCase<1> kToUppercaseMultiStrings1[1] = {  // NOLINT
+  {{kSentinel}} }; // NOLINT
+static const uint16_t kToUppercaseTable1Size = 73;  // NOLINT
+static const int32_t kToUppercaseTable1[146] = {
+  334, -112, 1073742192, -64, 383, -64, 388, -4, 1073743056, -104, 1257, -104, 1073744944, -192, 3166, -192,  // NOLINT
+  3169, -4, 3173, -43180, 3174, -43168, 3176, -4, 3178, -4, 3180, -4, 3187, -4, 3190, -4,  // NOLINT
+  3201, -4, 3203, -4, 3205, -4, 3207, -4, 3209, -4, 3211, -4, 3213, -4, 3215, -4,  // NOLINT
+  3217, -4, 3219, -4, 3221, -4, 3223, -4, 3225, -4, 3227, -4, 3229, -4, 3231, -4,  // NOLINT
+  3233, -4, 3235, -4, 3237, -4, 3239, -4, 3241, -4, 3243, -4, 3245, -4, 3247, -4,  // NOLINT
+  3249, -4, 3251, -4, 3253, -4, 3255, -4, 3257, -4, 3259, -4, 3261, -4, 3263, -4,  // NOLINT
+  3265, -4, 3267, -4, 3269, -4, 3271, -4, 3273, -4, 3275, -4, 3277, -4, 3279, -4,  // NOLINT
+  3281, -4, 3283, -4, 3285, -4, 3287, -4, 3289, -4, 3291, -4, 3293, -4, 3295, -4,  // NOLINT
+  3297, -4, 3299, -4, 3308, -4, 3310, -4, 3315, -4, 1073745152, -29056, 3365, -29056, 3367, -29056,  // NOLINT
+  3373, -29056 };  // NOLINT
+static const uint16_t kToUppercaseMultiStrings1Size = 1;  // NOLINT
+static const MultiCharacterSpecialCase<1> kToUppercaseMultiStrings5[1] = {  // NOLINT
+  {{kSentinel}} }; // NOLINT
+static const uint16_t kToUppercaseTable5Size = 95;  // NOLINT
+static const int32_t
+    kToUppercaseTable5[190] = {1601, -4, 1603, -4, 1605, -4, 1607, -4, 1609, -4,
+                               1611, -4, 1613, -4, 1615, -4,  // NOLINT
+                               1617, -4, 1619, -4, 1621, -4, 1623, -4, 1625, -4,
+                               1627, -4, 1629, -4, 1631, -4,  // NOLINT
+                               1633, -4, 1635, -4, 1637, -4, 1639, -4, 1641, -4,
+                               1643, -4, 1645, -4, 1665, -4,  // NOLINT
+                               1667, -4, 1669, -4, 1671, -4, 1673, -4, 1675, -4,
+                               1677, -4, 1679, -4, 1681, -4,  // NOLINT
+                               1683, -4, 1685, -4, 1687, -4, 1689, -4, 1691, -4,
+                               1827, -4, 1829, -4, 1831, -4,  // NOLINT
+                               1833, -4, 1835, -4, 1837, -4, 1839, -4, 1843, -4,
+                               1845, -4, 1847, -4, 1849, -4,  // NOLINT
+                               1851, -4, 1853, -4, 1855, -4, 1857, -4, 1859, -4,
+                               1861, -4, 1863, -4, 1865, -4,  // NOLINT
+                               1867, -4, 1869, -4, 1871, -4, 1873, -4, 1875, -4,
+                               1877, -4, 1879, -4, 1881, -4,  // NOLINT
+                               1883, -4, 1885, -4, 1887, -4, 1889, -4, 1891, -4,
+                               1893, -4, 1895, -4, 1897, -4,  // NOLINT
+                               1899, -4, 1901, -4, 1903, -4, 1914, -4, 1916, -4,
+                               1919, -4, 1921, -4, 1923, -4,  // NOLINT
+                               1925, -4, 1927, -4, 1932, -4, 1937, -4, 1939, -4,
+                               1943, -4, 1945, -4, 1947, -4,  // NOLINT
+                               1949, -4, 1951, -4, 1953, -4, 1955, -4, 1957, -4,
+                               1959, -4, 1961, -4};       // NOLINT
+static const uint16_t kToUppercaseMultiStrings5Size = 1;  // NOLINT
+static const MultiCharacterSpecialCase<3> kToUppercaseMultiStrings7[12] = {  // NOLINT
+  {{70, 70, kSentinel}}, {{70, 73, kSentinel}}, {{70, 76, kSentinel}}, {{70, 70, 73}},  // NOLINT
+  {{70, 70, 76}}, {{83, 84, kSentinel}}, {{1348, 1350, kSentinel}}, {{1348, 1333, kSentinel}},  // NOLINT
+  {{1348, 1339, kSentinel}}, {{1358, 1350, kSentinel}}, {{1348, 1341, kSentinel}}, {{kSentinel}} }; // NOLINT
+static const uint16_t kToUppercaseTable7Size = 14;  // NOLINT
+static const int32_t kToUppercaseTable7[28] = {
+  6912, 1, 6913, 5, 6914, 9, 6915, 13, 6916, 17, 6917, 21, 6918, 21, 6931, 25,  // NOLINT
+  6932, 29, 6933, 33, 6934, 37, 6935, 41, 1073749825, -128, 8026, -128 };  // NOLINT
+static const uint16_t kToUppercaseMultiStrings7Size = 12;  // NOLINT
+int ToUppercase::Convert(uchar c,
+                      uchar n,
+                      uchar* result,
+                      bool* allow_caching_ptr) {
+  int chunk_index = c >> 13;
+  switch (chunk_index) {
+    case 0: return LookupMapping<true>(kToUppercaseTable0,
+                                           kToUppercaseTable0Size,
+                                           kToUppercaseMultiStrings0,
+                                           c,
+                                           n,
+                                           result,
+                                           allow_caching_ptr);
+    case 1: return LookupMapping<true>(kToUppercaseTable1,
+                                           kToUppercaseTable1Size,
+                                           kToUppercaseMultiStrings1,
+                                           c,
+                                           n,
+                                           result,
+                                           allow_caching_ptr);
+    case 5: return LookupMapping<true>(kToUppercaseTable5,
+                                           kToUppercaseTable5Size,
+                                           kToUppercaseMultiStrings5,
+                                           c,
+                                           n,
+                                           result,
+                                           allow_caching_ptr);
+    case 7: return LookupMapping<true>(kToUppercaseTable7,
+                                           kToUppercaseTable7Size,
+                                           kToUppercaseMultiStrings7,
+                                           c,
+                                           n,
+                                           result,
+                                           allow_caching_ptr);
+    default: return 0;
+  }
+}
+
+static const MultiCharacterSpecialCase<1> kEcma262CanonicalizeMultiStrings0[1] = {  // NOLINT
+  {{kSentinel}} }; // NOLINT
+static const uint16_t kEcma262CanonicalizeTable0Size = 498;  // NOLINT
+static const int32_t kEcma262CanonicalizeTable0[996] = {
+    1073741921, -128,   122,        -128,   181,        2972,
+    1073742048, -128,   246,        -128,   1073742072, -128,
+    254,        -128,   255,        484,  // NOLINT
+    257,        -4,     259,        -4,     261,        -4,
+    263,        -4,     265,        -4,     267,        -4,
+    269,        -4,     271,        -4,  // NOLINT
+    273,        -4,     275,        -4,     277,        -4,
+    279,        -4,     281,        -4,     283,        -4,
+    285,        -4,     287,        -4,  // NOLINT
+    289,        -4,     291,        -4,     293,        -4,
+    295,        -4,     297,        -4,     299,        -4,
+    301,        -4,     303,        -4,  // NOLINT
+    307,        -4,     309,        -4,     311,        -4,
+    314,        -4,     316,        -4,     318,        -4,
+    320,        -4,     322,        -4,  // NOLINT
+    324,        -4,     326,        -4,     328,        -4,
+    331,        -4,     333,        -4,     335,        -4,
+    337,        -4,     339,        -4,  // NOLINT
+    341,        -4,     343,        -4,     345,        -4,
+    347,        -4,     349,        -4,     351,        -4,
+    353,        -4,     355,        -4,  // NOLINT
+    357,        -4,     359,        -4,     361,        -4,
+    363,        -4,     365,        -4,     367,        -4,
+    369,        -4,     371,        -4,  // NOLINT
+    373,        -4,     375,        -4,     378,        -4,
+    380,        -4,     382,        -4,     384,        780,
+    387,        -4,     389,        -4,  // NOLINT
+    392,        -4,     396,        -4,     402,        -4,
+    405,        388,    409,        -4,     410,        652,
+    414,        520,    417,        -4,  // NOLINT
+    419,        -4,     421,        -4,     424,        -4,
+    429,        -4,     432,        -4,     436,        -4,
+    438,        -4,     441,        -4,  // NOLINT
+    445,        -4,     447,        224,    453,        -4,
+    454,        -8,     456,        -4,     457,        -8,
+    459,        -4,     460,        -8,  // NOLINT
+    462,        -4,     464,        -4,     466,        -4,
+    468,        -4,     470,        -4,     472,        -4,
+    474,        -4,     476,        -4,  // NOLINT
+    477,        -316,   479,        -4,     481,        -4,
+    483,        -4,     485,        -4,     487,        -4,
+    489,        -4,     491,        -4,  // NOLINT
+    493,        -4,     495,        -4,     498,        -4,
+    499,        -8,     501,        -4,     505,        -4,
+    507,        -4,     509,        -4,  // NOLINT
+    511,        -4,     513,        -4,     515,        -4,
+    517,        -4,     519,        -4,     521,        -4,
+    523,        -4,     525,        -4,  // NOLINT
+    527,        -4,     529,        -4,     531,        -4,
+    533,        -4,     535,        -4,     537,        -4,
+    539,        -4,     541,        -4,  // NOLINT
+    543,        -4,     547,        -4,     549,        -4,
+    551,        -4,     553,        -4,     555,        -4,
+    557,        -4,     559,        -4,  // NOLINT
+    561,        -4,     563,        -4,     572,        -4,
+    1073742399, 43260,  576,        43260,  578,        -4,
+    583,        -4,     585,        -4,  // NOLINT
+    587,        -4,     589,        -4,     591,        -4,
+    592,        43132,  593,        43120,  594,        43128,
+    595,        -840,   596,        -824,  // NOLINT
+    1073742422, -820,   599,        -820,   601,        -808,
+    603,        -812,   604,        169276, 608,        -820,
+    609,        169260, 611,        -828,  // NOLINT
+    613,        169120, 614,        169232, 616,        -836,
+    617,        -844,   619,        42972,  620,        169220,
+    623,        -844,   625,        42996,  // NOLINT
+    626,        -852,   629,        -856,   637,        42908,
+    640,        -872,   643,        -872,   647,        169128,
+    648,        -872,   649,        -276,  // NOLINT
+    1073742474, -868,   651,        -868,   652,        -284,
+    658,        -876,   670,        169032, 837,        336,
+    881,        -4,     883,        -4,  // NOLINT
+    887,        -4,     1073742715, 520,    893,        520,
+    940,        -152,   1073742765, -148,   943,        -148,
+    1073742769, -128,   961,        -128,  // NOLINT
+    962,        -124,   1073742787, -128,   971,        -128,
+    972,        -256,   1073742797, -252,   974,        -252,
+    976,        -248,   977,        -228,  // NOLINT
+    981,        -188,   982,        -216,   983,        -32,
+    985,        -4,     987,        -4,     989,        -4,
+    991,        -4,     993,        -4,  // NOLINT
+    995,        -4,     997,        -4,     999,        -4,
+    1001,       -4,     1003,       -4,     1005,       -4,
+    1007,       -4,     1008,       -344,  // NOLINT
+    1009,       -320,   1010,       28,     1011,       -464,
+    1013,       -384,   1016,       -4,     1019,       -4,
+    1073742896, -128,   1103,       -128,  // NOLINT
+    1073742928, -320,   1119,       -320,   1121,       -4,
+    1123,       -4,     1125,       -4,     1127,       -4,
+    1129,       -4,     1131,       -4,  // NOLINT
+    1133,       -4,     1135,       -4,     1137,       -4,
+    1139,       -4,     1141,       -4,     1143,       -4,
+    1145,       -4,     1147,       -4,  // NOLINT
+    1149,       -4,     1151,       -4,     1153,       -4,
+    1163,       -4,     1165,       -4,     1167,       -4,
+    1169,       -4,     1171,       -4,  // NOLINT
+    1173,       -4,     1175,       -4,     1177,       -4,
+    1179,       -4,     1181,       -4,     1183,       -4,
+    1185,       -4,     1187,       -4,  // NOLINT
+    1189,       -4,     1191,       -4,     1193,       -4,
+    1195,       -4,     1197,       -4,     1199,       -4,
+    1201,       -4,     1203,       -4,  // NOLINT
+    1205,       -4,     1207,       -4,     1209,       -4,
+    1211,       -4,     1213,       -4,     1215,       -4,
+    1218,       -4,     1220,       -4,  // NOLINT
+    1222,       -4,     1224,       -4,     1226,       -4,
+    1228,       -4,     1230,       -4,     1231,       -60,
+    1233,       -4,     1235,       -4,  // NOLINT
+    1237,       -4,     1239,       -4,     1241,       -4,
+    1243,       -4,     1245,       -4,     1247,       -4,
+    1249,       -4,     1251,       -4,  // NOLINT
+    1253,       -4,     1255,       -4,     1257,       -4,
+    1259,       -4,     1261,       -4,     1263,       -4,
+    1265,       -4,     1267,       -4,  // NOLINT
+    1269,       -4,     1271,       -4,     1273,       -4,
+    1275,       -4,     1277,       -4,     1279,       -4,
+    1281,       -4,     1283,       -4,  // NOLINT
+    1285,       -4,     1287,       -4,     1289,       -4,
+    1291,       -4,     1293,       -4,     1295,       -4,
+    1297,       -4,     1299,       -4,  // NOLINT
+    1301,       -4,     1303,       -4,     1305,       -4,
+    1307,       -4,     1309,       -4,     1311,       -4,
+    1313,       -4,     1315,       -4,  // NOLINT
+    1317,       -4,     1319,       -4,     1321,       -4,
+    1323,       -4,     1325,       -4,     1327,       -4,
+    1073743201, -192,   1414,       -192,  // NOLINT
+    7545,       141328, 7549,       15256,  7681,       -4,
+    7683,       -4,     7685,       -4,     7687,       -4,
+    7689,       -4,     7691,       -4,  // NOLINT
+    7693,       -4,     7695,       -4,     7697,       -4,
+    7699,       -4,     7701,       -4,     7703,       -4,
+    7705,       -4,     7707,       -4,  // NOLINT
+    7709,       -4,     7711,       -4,     7713,       -4,
+    7715,       -4,     7717,       -4,     7719,       -4,
+    7721,       -4,     7723,       -4,  // NOLINT
+    7725,       -4,     7727,       -4,     7729,       -4,
+    7731,       -4,     7733,       -4,     7735,       -4,
+    7737,       -4,     7739,       -4,  // NOLINT
+    7741,       -4,     7743,       -4,     7745,       -4,
+    7747,       -4,     7749,       -4,     7751,       -4,
+    7753,       -4,     7755,       -4,  // NOLINT
+    7757,       -4,     7759,       -4,     7761,       -4,
+    7763,       -4,     7765,       -4,     7767,       -4,
+    7769,       -4,     7771,       -4,  // NOLINT
+    7773,       -4,     7775,       -4,     7777,       -4,
+    7779,       -4,     7781,       -4,     7783,       -4,
+    7785,       -4,     7787,       -4,  // NOLINT
+    7789,       -4,     7791,       -4,     7793,       -4,
+    7795,       -4,     7797,       -4,     7799,       -4,
+    7801,       -4,     7803,       -4,  // NOLINT
+    7805,       -4,     7807,       -4,     7809,       -4,
+    7811,       -4,     7813,       -4,     7815,       -4,
+    7817,       -4,     7819,       -4,  // NOLINT
+    7821,       -4,     7823,       -4,     7825,       -4,
+    7827,       -4,     7829,       -4,     7835,       -236,
+    7841,       -4,     7843,       -4,  // NOLINT
+    7845,       -4,     7847,       -4,     7849,       -4,
+    7851,       -4,     7853,       -4,     7855,       -4,
+    7857,       -4,     7859,       -4,  // NOLINT
+    7861,       -4,     7863,       -4,     7865,       -4,
+    7867,       -4,     7869,       -4,     7871,       -4,
+    7873,       -4,     7875,       -4,  // NOLINT
+    7877,       -4,     7879,       -4,     7881,       -4,
+    7883,       -4,     7885,       -4,     7887,       -4,
+    7889,       -4,     7891,       -4,  // NOLINT
+    7893,       -4,     7895,       -4,     7897,       -4,
+    7899,       -4,     7901,       -4,     7903,       -4,
+    7905,       -4,     7907,       -4,  // NOLINT
+    7909,       -4,     7911,       -4,     7913,       -4,
+    7915,       -4,     7917,       -4,     7919,       -4,
+    7921,       -4,     7923,       -4,  // NOLINT
+    7925,       -4,     7927,       -4,     7929,       -4,
+    7931,       -4,     7933,       -4,     7935,       -4,
+    1073749760, 32,     7943,       32,  // NOLINT
+    1073749776, 32,     7957,       32,     1073749792, 32,
+    7975,       32,     1073749808, 32,     7991,       32,
+    1073749824, 32,     8005,       32,  // NOLINT
+    8017,       32,     8019,       32,     8021,       32,
+    8023,       32,     1073749856, 32,     8039,       32,
+    1073749872, 296,    8049,       296,  // NOLINT
+    1073749874, 344,    8053,       344,    1073749878, 400,
+    8055,       400,    1073749880, 512,    8057,       512,
+    1073749882, 448,    8059,       448,  // NOLINT
+    1073749884, 504,    8061,       504,    1073749936, 32,
+    8113,       32,     8126,       -28820, 1073749968, 32,
+    8145,       32,     1073749984, 32,                           // NOLINT
+    8161,       32,     8165,       28};                          // NOLINT
+static const uint16_t kEcma262CanonicalizeMultiStrings0Size = 1;  // NOLINT
+static const MultiCharacterSpecialCase<1> kEcma262CanonicalizeMultiStrings1[1] = {  // NOLINT
+  {{kSentinel}} }; // NOLINT
+static const uint16_t kEcma262CanonicalizeTable1Size = 73;  // NOLINT
+static const int32_t kEcma262CanonicalizeTable1[146] = {
+  334, -112, 1073742192, -64, 383, -64, 388, -4, 1073743056, -104, 1257, -104, 1073744944, -192, 3166, -192,  // NOLINT
+  3169, -4, 3173, -43180, 3174, -43168, 3176, -4, 3178, -4, 3180, -4, 3187, -4, 3190, -4,  // NOLINT
+  3201, -4, 3203, -4, 3205, -4, 3207, -4, 3209, -4, 3211, -4, 3213, -4, 3215, -4,  // NOLINT
+  3217, -4, 3219, -4, 3221, -4, 3223, -4, 3225, -4, 3227, -4, 3229, -4, 3231, -4,  // NOLINT
+  3233, -4, 3235, -4, 3237, -4, 3239, -4, 3241, -4, 3243, -4, 3245, -4, 3247, -4,  // NOLINT
+  3249, -4, 3251, -4, 3253, -4, 3255, -4, 3257, -4, 3259, -4, 3261, -4, 3263, -4,  // NOLINT
+  3265, -4, 3267, -4, 3269, -4, 3271, -4, 3273, -4, 3275, -4, 3277, -4, 3279, -4,  // NOLINT
+  3281, -4, 3283, -4, 3285, -4, 3287, -4, 3289, -4, 3291, -4, 3293, -4, 3295, -4,  // NOLINT
+  3297, -4, 3299, -4, 3308, -4, 3310, -4, 3315, -4, 1073745152, -29056, 3365, -29056, 3367, -29056,  // NOLINT
+  3373, -29056 };  // NOLINT
+static const uint16_t kEcma262CanonicalizeMultiStrings1Size = 1;  // NOLINT
+static const MultiCharacterSpecialCase<1> kEcma262CanonicalizeMultiStrings5[1] = {  // NOLINT
+  {{kSentinel}} }; // NOLINT
+static const uint16_t kEcma262CanonicalizeTable5Size = 95;  // NOLINT
+static const int32_t kEcma262CanonicalizeTable5
+    [190] = {1601, -4, 1603, -4, 1605, -4, 1607, -4,
+             1609, -4, 1611, -4, 1613, -4, 1615, -4,  // NOLINT
+             1617, -4, 1619, -4, 1621, -4, 1623, -4,
+             1625, -4, 1627, -4, 1629, -4, 1631, -4,  // NOLINT
+             1633, -4, 1635, -4, 1637, -4, 1639, -4,
+             1641, -4, 1643, -4, 1645, -4, 1665, -4,  // NOLINT
+             1667, -4, 1669, -4, 1671, -4, 1673, -4,
+             1675, -4, 1677, -4, 1679, -4, 1681, -4,  // NOLINT
+             1683, -4, 1685, -4, 1687, -4, 1689, -4,
+             1691, -4, 1827, -4, 1829, -4, 1831, -4,  // NOLINT
+             1833, -4, 1835, -4, 1837, -4, 1839, -4,
+             1843, -4, 1845, -4, 1847, -4, 1849, -4,  // NOLINT
+             1851, -4, 1853, -4, 1855, -4, 1857, -4,
+             1859, -4, 1861, -4, 1863, -4, 1865, -4,  // NOLINT
+             1867, -4, 1869, -4, 1871, -4, 1873, -4,
+             1875, -4, 1877, -4, 1879, -4, 1881, -4,  // NOLINT
+             1883, -4, 1885, -4, 1887, -4, 1889, -4,
+             1891, -4, 1893, -4, 1895, -4, 1897, -4,  // NOLINT
+             1899, -4, 1901, -4, 1903, -4, 1914, -4,
+             1916, -4, 1919, -4, 1921, -4, 1923, -4,  // NOLINT
+             1925, -4, 1927, -4, 1932, -4, 1937, -4,
+             1939, -4, 1943, -4, 1945, -4, 1947, -4,  // NOLINT
+             1949, -4, 1951, -4, 1953, -4, 1955, -4,
+             1957, -4, 1959, -4, 1961, -4};                       // NOLINT
+static const uint16_t kEcma262CanonicalizeMultiStrings5Size = 1;  // NOLINT
+static const MultiCharacterSpecialCase<1> kEcma262CanonicalizeMultiStrings7[1] = {  // NOLINT
+  {{kSentinel}} }; // NOLINT
+static const uint16_t kEcma262CanonicalizeTable7Size = 2;  // NOLINT
+static const int32_t kEcma262CanonicalizeTable7[4] = {
+  1073749825, -128, 8026, -128 };  // NOLINT
+static const uint16_t kEcma262CanonicalizeMultiStrings7Size = 1;  // NOLINT
+int Ecma262Canonicalize::Convert(uchar c,
+                      uchar n,
+                      uchar* result,
+                      bool* allow_caching_ptr) {
+  int chunk_index = c >> 13;
+  switch (chunk_index) {
+    case 0: return LookupMapping<true>(kEcma262CanonicalizeTable0,
+                                           kEcma262CanonicalizeTable0Size,
+                                           kEcma262CanonicalizeMultiStrings0,
+                                           c,
+                                           n,
+                                           result,
+                                           allow_caching_ptr);
+    case 1: return LookupMapping<true>(kEcma262CanonicalizeTable1,
+                                           kEcma262CanonicalizeTable1Size,
+                                           kEcma262CanonicalizeMultiStrings1,
+                                           c,
+                                           n,
+                                           result,
+                                           allow_caching_ptr);
+    case 5: return LookupMapping<true>(kEcma262CanonicalizeTable5,
+                                           kEcma262CanonicalizeTable5Size,
+                                           kEcma262CanonicalizeMultiStrings5,
+                                           c,
+                                           n,
+                                           result,
+                                           allow_caching_ptr);
+    case 7: return LookupMapping<true>(kEcma262CanonicalizeTable7,
+                                           kEcma262CanonicalizeTable7Size,
+                                           kEcma262CanonicalizeMultiStrings7,
+                                           c,
+                                           n,
+                                           result,
+                                           allow_caching_ptr);
+    default: return 0;
+  }
+}
+
+static const MultiCharacterSpecialCase<4>
+    kEcma262UnCanonicalizeMultiStrings0[507] = {  // NOLINT
+        {{65, 97, kSentinel}},
+        {{90, 122, kSentinel}},
+        {{181, 924, 956, kSentinel}},
+        {{192, 224, kSentinel}},  // NOLINT
+        {{214, 246, kSentinel}},
+        {{216, 248, kSentinel}},
+        {{222, 254, kSentinel}},
+        {{255, 376, kSentinel}},  // NOLINT
+        {{256, 257, kSentinel}},
+        {{258, 259, kSentinel}},
+        {{260, 261, kSentinel}},
+        {{262, 263, kSentinel}},  // NOLINT
+        {{264, 265, kSentinel}},
+        {{266, 267, kSentinel}},
+        {{268, 269, kSentinel}},
+        {{270, 271, kSentinel}},  // NOLINT
+        {{272, 273, kSentinel}},
+        {{274, 275, kSentinel}},
+        {{276, 277, kSentinel}},
+        {{278, 279, kSentinel}},  // NOLINT
+        {{280, 281, kSentinel}},
+        {{282, 283, kSentinel}},
+        {{284, 285, kSentinel}},
+        {{286, 287, kSentinel}},  // NOLINT
+        {{288, 289, kSentinel}},
+        {{290, 291, kSentinel}},
+        {{292, 293, kSentinel}},
+        {{294, 295, kSentinel}},  // NOLINT
+        {{296, 297, kSentinel}},
+        {{298, 299, kSentinel}},
+        {{300, 301, kSentinel}},
+        {{302, 303, kSentinel}},  // NOLINT
+        {{306, 307, kSentinel}},
+        {{308, 309, kSentinel}},
+        {{310, 311, kSentinel}},
+        {{313, 314, kSentinel}},  // NOLINT
+        {{315, 316, kSentinel}},
+        {{317, 318, kSentinel}},
+        {{319, 320, kSentinel}},
+        {{321, 322, kSentinel}},  // NOLINT
+        {{323, 324, kSentinel}},
+        {{325, 326, kSentinel}},
+        {{327, 328, kSentinel}},
+        {{330, 331, kSentinel}},  // NOLINT
+        {{332, 333, kSentinel}},
+        {{334, 335, kSentinel}},
+        {{336, 337, kSentinel}},
+        {{338, 339, kSentinel}},  // NOLINT
+        {{340, 341, kSentinel}},
+        {{342, 343, kSentinel}},
+        {{344, 345, kSentinel}},
+        {{346, 347, kSentinel}},  // NOLINT
+        {{348, 349, kSentinel}},
+        {{350, 351, kSentinel}},
+        {{352, 353, kSentinel}},
+        {{354, 355, kSentinel}},  // NOLINT
+        {{356, 357, kSentinel}},
+        {{358, 359, kSentinel}},
+        {{360, 361, kSentinel}},
+        {{362, 363, kSentinel}},  // NOLINT
+        {{364, 365, kSentinel}},
+        {{366, 367, kSentinel}},
+        {{368, 369, kSentinel}},
+        {{370, 371, kSentinel}},  // NOLINT
+        {{372, 373, kSentinel}},
+        {{374, 375, kSentinel}},
+        {{377, 378, kSentinel}},
+        {{379, 380, kSentinel}},  // NOLINT
+        {{381, 382, kSentinel}},
+        {{384, 579, kSentinel}},
+        {{385, 595, kSentinel}},
+        {{386, 387, kSentinel}},  // NOLINT
+        {{388, 389, kSentinel}},
+        {{390, 596, kSentinel}},
+        {{391, 392, kSentinel}},
+        {{393, 598, kSentinel}},  // NOLINT
+        {{394, 599, kSentinel}},
+        {{395, 396, kSentinel}},
+        {{398, 477, kSentinel}},
+        {{399, 601, kSentinel}},  // NOLINT
+        {{400, 603, kSentinel}},
+        {{401, 402, kSentinel}},
+        {{403, 608, kSentinel}},
+        {{404, 611, kSentinel}},  // NOLINT
+        {{405, 502, kSentinel}},
+        {{406, 617, kSentinel}},
+        {{407, 616, kSentinel}},
+        {{408, 409, kSentinel}},  // NOLINT
+        {{410, 573, kSentinel}},
+        {{412, 623, kSentinel}},
+        {{413, 626, kSentinel}},
+        {{414, 544, kSentinel}},  // NOLINT
+        {{415, 629, kSentinel}},
+        {{416, 417, kSentinel}},
+        {{418, 419, kSentinel}},
+        {{420, 421, kSentinel}},  // NOLINT
+        {{422, 640, kSentinel}},
+        {{423, 424, kSentinel}},
+        {{425, 643, kSentinel}},
+        {{428, 429, kSentinel}},  // NOLINT
+        {{430, 648, kSentinel}},
+        {{431, 432, kSentinel}},
+        {{433, 650, kSentinel}},
+        {{434, 651, kSentinel}},  // NOLINT
+        {{435, 436, kSentinel}},
+        {{437, 438, kSentinel}},
+        {{439, 658, kSentinel}},
+        {{440, 441, kSentinel}},  // NOLINT
+        {{444, 445, kSentinel}},
+        {{447, 503, kSentinel}},
+        {{452, 453, 454, kSentinel}},
+        {{455, 456, 457, kSentinel}},  // NOLINT
+        {{458, 459, 460, kSentinel}},
+        {{461, 462, kSentinel}},
+        {{463, 464, kSentinel}},
+        {{465, 466, kSentinel}},  // NOLINT
+        {{467, 468, kSentinel}},
+        {{469, 470, kSentinel}},
+        {{471, 472, kSentinel}},
+        {{473, 474, kSentinel}},  // NOLINT
+        {{475, 476, kSentinel}},
+        {{478, 479, kSentinel}},
+        {{480, 481, kSentinel}},
+        {{482, 483, kSentinel}},  // NOLINT
+        {{484, 485, kSentinel}},
+        {{486, 487, kSentinel}},
+        {{488, 489, kSentinel}},
+        {{490, 491, kSentinel}},  // NOLINT
+        {{492, 493, kSentinel}},
+        {{494, 495, kSentinel}},
+        {{497, 498, 499, kSentinel}},
+        {{500, 501, kSentinel}},  // NOLINT
+        {{504, 505, kSentinel}},
+        {{506, 507, kSentinel}},
+        {{508, 509, kSentinel}},
+        {{510, 511, kSentinel}},  // NOLINT
+        {{512, 513, kSentinel}},
+        {{514, 515, kSentinel}},
+        {{516, 517, kSentinel}},
+        {{518, 519, kSentinel}},  // NOLINT
+        {{520, 521, kSentinel}},
+        {{522, 523, kSentinel}},
+        {{524, 525, kSentinel}},
+        {{526, 527, kSentinel}},  // NOLINT
+        {{528, 529, kSentinel}},
+        {{530, 531, kSentinel}},
+        {{532, 533, kSentinel}},
+        {{534, 535, kSentinel}},  // NOLINT
+        {{536, 537, kSentinel}},
+        {{538, 539, kSentinel}},
+        {{540, 541, kSentinel}},
+        {{542, 543, kSentinel}},  // NOLINT
+        {{546, 547, kSentinel}},
+        {{548, 549, kSentinel}},
+        {{550, 551, kSentinel}},
+        {{552, 553, kSentinel}},  // NOLINT
+        {{554, 555, kSentinel}},
+        {{556, 557, kSentinel}},
+        {{558, 559, kSentinel}},
+        {{560, 561, kSentinel}},  // NOLINT
+        {{562, 563, kSentinel}},
+        {{570, 11365, kSentinel}},
+        {{571, 572, kSentinel}},
+        {{574, 11366, kSentinel}},  // NOLINT
+        {{575, 11390, kSentinel}},
+        {{576, 11391, kSentinel}},
+        {{577, 578, kSentinel}},
+        {{580, 649, kSentinel}},  // NOLINT
+        {{581, 652, kSentinel}},
+        {{582, 583, kSentinel}},
+        {{584, 585, kSentinel}},
+        {{586, 587, kSentinel}},  // NOLINT
+        {{588, 589, kSentinel}},
+        {{590, 591, kSentinel}},
+        {{592, 11375, kSentinel}},
+        {{593, 11373, kSentinel}},  // NOLINT
+        {{594, 11376, kSentinel}},
+        {{604, 42923, kSentinel}},
+        {{609, 42924, kSentinel}},
+        {{613, 42893, kSentinel}},  // NOLINT
+        {{614, 42922, kSentinel}},
+        {{619, 11362, kSentinel}},
+        {{620, 42925, kSentinel}},
+        {{625, 11374, kSentinel}},  // NOLINT
+        {{637, 11364, kSentinel}},
+        {{647, 42929, kSentinel}},
+        {{670, 42928, kSentinel}},
+        {{837, 921, 953, 8126}},  // NOLINT
+        {{880, 881, kSentinel}},
+        {{882, 883, kSentinel}},
+        {{886, 887, kSentinel}},
+        {{891, 1021, kSentinel}},  // NOLINT
+        {{893, 1023, kSentinel}},
+        {{895, 1011, kSentinel}},
+        {{902, 940, kSentinel}},
+        {{904, 941, kSentinel}},  // NOLINT
+        {{906, 943, kSentinel}},
+        {{908, 972, kSentinel}},
+        {{910, 973, kSentinel}},
+        {{911, 974, kSentinel}},  // NOLINT
+        {{913, 945, kSentinel}},
+        {{914, 946, 976, kSentinel}},
+        {{915, 947, kSentinel}},
+        {{916, 948, kSentinel}},  // NOLINT
+        {{917, 949, 1013, kSentinel}},
+        {{918, 950, kSentinel}},
+        {{919, 951, kSentinel}},
+        {{920, 952, 977, kSentinel}},  // NOLINT
+        {{922, 954, 1008, kSentinel}},
+        {{923, 955, kSentinel}},
+        {{925, 957, kSentinel}},
+        {{927, 959, kSentinel}},  // NOLINT
+        {{928, 960, 982, kSentinel}},
+        {{929, 961, 1009, kSentinel}},
+        {{931, 962, 963, kSentinel}},
+        {{932, 964, kSentinel}},  // NOLINT
+        {{933, 965, kSentinel}},
+        {{934, 966, 981, kSentinel}},
+        {{935, 967, kSentinel}},
+        {{939, 971, kSentinel}},  // NOLINT
+        {{975, 983, kSentinel}},
+        {{984, 985, kSentinel}},
+        {{986, 987, kSentinel}},
+        {{988, 989, kSentinel}},  // NOLINT
+        {{990, 991, kSentinel}},
+        {{992, 993, kSentinel}},
+        {{994, 995, kSentinel}},
+        {{996, 997, kSentinel}},  // NOLINT
+        {{998, 999, kSentinel}},
+        {{1000, 1001, kSentinel}},
+        {{1002, 1003, kSentinel}},
+        {{1004, 1005, kSentinel}},  // NOLINT
+        {{1006, 1007, kSentinel}},
+        {{1010, 1017, kSentinel}},
+        {{1015, 1016, kSentinel}},
+        {{1018, 1019, kSentinel}},  // NOLINT
+        {{1024, 1104, kSentinel}},
+        {{1039, 1119, kSentinel}},
+        {{1040, 1072, kSentinel}},
+        {{1071, 1103, kSentinel}},  // NOLINT
+        {{1120, 1121, kSentinel}},
+        {{1122, 1123, kSentinel}},
+        {{1124, 1125, kSentinel}},
+        {{1126, 1127, kSentinel}},  // NOLINT
+        {{1128, 1129, kSentinel}},
+        {{1130, 1131, kSentinel}},
+        {{1132, 1133, kSentinel}},
+        {{1134, 1135, kSentinel}},  // NOLINT
+        {{1136, 1137, kSentinel}},
+        {{1138, 1139, kSentinel}},
+        {{1140, 1141, kSentinel}},
+        {{1142, 1143, kSentinel}},  // NOLINT
+        {{1144, 1145, kSentinel}},
+        {{1146, 1147, kSentinel}},
+        {{1148, 1149, kSentinel}},
+        {{1150, 1151, kSentinel}},  // NOLINT
+        {{1152, 1153, kSentinel}},
+        {{1162, 1163, kSentinel}},
+        {{1164, 1165, kSentinel}},
+        {{1166, 1167, kSentinel}},  // NOLINT
+        {{1168, 1169, kSentinel}},
+        {{1170, 1171, kSentinel}},
+        {{1172, 1173, kSentinel}},
+        {{1174, 1175, kSentinel}},  // NOLINT
+        {{1176, 1177, kSentinel}},
+        {{1178, 1179, kSentinel}},
+        {{1180, 1181, kSentinel}},
+        {{1182, 1183, kSentinel}},  // NOLINT
+        {{1184, 1185, kSentinel}},
+        {{1186, 1187, kSentinel}},
+        {{1188, 1189, kSentinel}},
+        {{1190, 1191, kSentinel}},  // NOLINT
+        {{1192, 1193, kSentinel}},
+        {{1194, 1195, kSentinel}},
+        {{1196, 1197, kSentinel}},
+        {{1198, 1199, kSentinel}},  // NOLINT
+        {{1200, 1201, kSentinel}},
+        {{1202, 1203, kSentinel}},
+        {{1204, 1205, kSentinel}},
+        {{1206, 1207, kSentinel}},  // NOLINT
+        {{1208, 1209, kSentinel}},
+        {{1210, 1211, kSentinel}},
+        {{1212, 1213, kSentinel}},
+        {{1214, 1215, kSentinel}},  // NOLINT
+        {{1216, 1231, kSentinel}},
+        {{1217, 1218, kSentinel}},
+        {{1219, 1220, kSentinel}},
+        {{1221, 1222, kSentinel}},  // NOLINT
+        {{1223, 1224, kSentinel}},
+        {{1225, 1226, kSentinel}},
+        {{1227, 1228, kSentinel}},
+        {{1229, 1230, kSentinel}},  // NOLINT
+        {{1232, 1233, kSentinel}},
+        {{1234, 1235, kSentinel}},
+        {{1236, 1237, kSentinel}},
+        {{1238, 1239, kSentinel}},  // NOLINT
+        {{1240, 1241, kSentinel}},
+        {{1242, 1243, kSentinel}},
+        {{1244, 1245, kSentinel}},
+        {{1246, 1247, kSentinel}},  // NOLINT
+        {{1248, 1249, kSentinel}},
+        {{1250, 1251, kSentinel}},
+        {{1252, 1253, kSentinel}},
+        {{1254, 1255, kSentinel}},  // NOLINT
+        {{1256, 1257, kSentinel}},
+        {{1258, 1259, kSentinel}},
+        {{1260, 1261, kSentinel}},
+        {{1262, 1263, kSentinel}},  // NOLINT
+        {{1264, 1265, kSentinel}},
+        {{1266, 1267, kSentinel}},
+        {{1268, 1269, kSentinel}},
+        {{1270, 1271, kSentinel}},  // NOLINT
+        {{1272, 1273, kSentinel}},
+        {{1274, 1275, kSentinel}},
+        {{1276, 1277, kSentinel}},
+        {{1278, 1279, kSentinel}},  // NOLINT
+        {{1280, 1281, kSentinel}},
+        {{1282, 1283, kSentinel}},
+        {{1284, 1285, kSentinel}},
+        {{1286, 1287, kSentinel}},  // NOLINT
+        {{1288, 1289, kSentinel}},
+        {{1290, 1291, kSentinel}},
+        {{1292, 1293, kSentinel}},
+        {{1294, 1295, kSentinel}},  // NOLINT
+        {{1296, 1297, kSentinel}},
+        {{1298, 1299, kSentinel}},
+        {{1300, 1301, kSentinel}},
+        {{1302, 1303, kSentinel}},  // NOLINT
+        {{1304, 1305, kSentinel}},
+        {{1306, 1307, kSentinel}},
+        {{1308, 1309, kSentinel}},
+        {{1310, 1311, kSentinel}},  // NOLINT
+        {{1312, 1313, kSentinel}},
+        {{1314, 1315, kSentinel}},
+        {{1316, 1317, kSentinel}},
+        {{1318, 1319, kSentinel}},  // NOLINT
+        {{1320, 1321, kSentinel}},
+        {{1322, 1323, kSentinel}},
+        {{1324, 1325, kSentinel}},
+        {{1326, 1327, kSentinel}},  // NOLINT
+        {{1329, 1377, kSentinel}},
+        {{1366, 1414, kSentinel}},
+        {{4256, 11520, kSentinel}},
+        {{4293, 11557, kSentinel}},  // NOLINT
+        {{4295, 11559, kSentinel}},
+        {{4301, 11565, kSentinel}},
+        {{7545, 42877, kSentinel}},
+        {{7549, 11363, kSentinel}},  // NOLINT
+        {{7680, 7681, kSentinel}},
+        {{7682, 7683, kSentinel}},
+        {{7684, 7685, kSentinel}},
+        {{7686, 7687, kSentinel}},  // NOLINT
+        {{7688, 7689, kSentinel}},
+        {{7690, 7691, kSentinel}},
+        {{7692, 7693, kSentinel}},
+        {{7694, 7695, kSentinel}},  // NOLINT
+        {{7696, 7697, kSentinel}},
+        {{7698, 7699, kSentinel}},
+        {{7700, 7701, kSentinel}},
+        {{7702, 7703, kSentinel}},  // NOLINT
+        {{7704, 7705, kSentinel}},
+        {{7706, 7707, kSentinel}},
+        {{7708, 7709, kSentinel}},
+        {{7710, 7711, kSentinel}},  // NOLINT
+        {{7712, 7713, kSentinel}},
+        {{7714, 7715, kSentinel}},
+        {{7716, 7717, kSentinel}},
+        {{7718, 7719, kSentinel}},  // NOLINT
+        {{7720, 7721, kSentinel}},
+        {{7722, 7723, kSentinel}},
+        {{7724, 7725, kSentinel}},
+        {{7726, 7727, kSentinel}},  // NOLINT
+        {{7728, 7729, kSentinel}},
+        {{7730, 7731, kSentinel}},
+        {{7732, 7733, kSentinel}},
+        {{7734, 7735, kSentinel}},  // NOLINT
+        {{7736, 7737, kSentinel}},
+        {{7738, 7739, kSentinel}},
+        {{7740, 7741, kSentinel}},
+        {{7742, 7743, kSentinel}},  // NOLINT
+        {{7744, 7745, kSentinel}},
+        {{7746, 7747, kSentinel}},
+        {{7748, 7749, kSentinel}},
+        {{7750, 7751, kSentinel}},  // NOLINT
+        {{7752, 7753, kSentinel}},
+        {{7754, 7755, kSentinel}},
+        {{7756, 7757, kSentinel}},
+        {{7758, 7759, kSentinel}},  // NOLINT
+        {{7760, 7761, kSentinel}},
+        {{7762, 7763, kSentinel}},
+        {{7764, 7765, kSentinel}},
+        {{7766, 7767, kSentinel}},  // NOLINT
+        {{7768, 7769, kSentinel}},
+        {{7770, 7771, kSentinel}},
+        {{7772, 7773, kSentinel}},
+        {{7774, 7775, kSentinel}},  // NOLINT
+        {{7776, 7777, 7835, kSentinel}},
+        {{7778, 7779, kSentinel}},
+        {{7780, 7781, kSentinel}},
+        {{7782, 7783, kSentinel}},  // NOLINT
+        {{7784, 7785, kSentinel}},
+        {{7786, 7787, kSentinel}},
+        {{7788, 7789, kSentinel}},
+        {{7790, 7791, kSentinel}},  // NOLINT
+        {{7792, 7793, kSentinel}},
+        {{7794, 7795, kSentinel}},
+        {{7796, 7797, kSentinel}},
+        {{7798, 7799, kSentinel}},  // NOLINT
+        {{7800, 7801, kSentinel}},
+        {{7802, 7803, kSentinel}},
+        {{7804, 7805, kSentinel}},
+        {{7806, 7807, kSentinel}},  // NOLINT
+        {{7808, 7809, kSentinel}},
+        {{7810, 7811, kSentinel}},
+        {{7812, 7813, kSentinel}},
+        {{7814, 7815, kSentinel}},  // NOLINT
+        {{7816, 7817, kSentinel}},
+        {{7818, 7819, kSentinel}},
+        {{7820, 7821, kSentinel}},
+        {{7822, 7823, kSentinel}},  // NOLINT
+        {{7824, 7825, kSentinel}},
+        {{7826, 7827, kSentinel}},
+        {{7828, 7829, kSentinel}},
+        {{7840, 7841, kSentinel}},  // NOLINT
+        {{7842, 7843, kSentinel}},
+        {{7844, 7845, kSentinel}},
+        {{7846, 7847, kSentinel}},
+        {{7848, 7849, kSentinel}},  // NOLINT
+        {{7850, 7851, kSentinel}},
+        {{7852, 7853, kSentinel}},
+        {{7854, 7855, kSentinel}},
+        {{7856, 7857, kSentinel}},  // NOLINT
+        {{7858, 7859, kSentinel}},
+        {{7860, 7861, kSentinel}},
+        {{7862, 7863, kSentinel}},
+        {{7864, 7865, kSentinel}},  // NOLINT
+        {{7866, 7867, kSentinel}},
+        {{7868, 7869, kSentinel}},
+        {{7870, 7871, kSentinel}},
+        {{7872, 7873, kSentinel}},  // NOLINT
+        {{7874, 7875, kSentinel}},
+        {{7876, 7877, kSentinel}},
+        {{7878, 7879, kSentinel}},
+        {{7880, 7881, kSentinel}},  // NOLINT
+        {{7882, 7883, kSentinel}},
+        {{7884, 7885, kSentinel}},
+        {{7886, 7887, kSentinel}},
+        {{7888, 7889, kSentinel}},  // NOLINT
+        {{7890, 7891, kSentinel}},
+        {{7892, 7893, kSentinel}},
+        {{7894, 7895, kSentinel}},
+        {{7896, 7897, kSentinel}},  // NOLINT
+        {{7898, 7899, kSentinel}},
+        {{7900, 7901, kSentinel}},
+        {{7902, 7903, kSentinel}},
+        {{7904, 7905, kSentinel}},  // NOLINT
+        {{7906, 7907, kSentinel}},
+        {{7908, 7909, kSentinel}},
+        {{7910, 7911, kSentinel}},
+        {{7912, 7913, kSentinel}},  // NOLINT
+        {{7914, 7915, kSentinel}},
+        {{7916, 7917, kSentinel}},
+        {{7918, 7919, kSentinel}},
+        {{7920, 7921, kSentinel}},  // NOLINT
+        {{7922, 7923, kSentinel}},
+        {{7924, 7925, kSentinel}},
+        {{7926, 7927, kSentinel}},
+        {{7928, 7929, kSentinel}},  // NOLINT
+        {{7930, 7931, kSentinel}},
+        {{7932, 7933, kSentinel}},
+        {{7934, 7935, kSentinel}},
+        {{7936, 7944, kSentinel}},  // NOLINT
+        {{7943, 7951, kSentinel}},
+        {{7952, 7960, kSentinel}},
+        {{7957, 7965, kSentinel}},
+        {{7968, 7976, kSentinel}},  // NOLINT
+        {{7975, 7983, kSentinel}},
+        {{7984, 7992, kSentinel}},
+        {{7991, 7999, kSentinel}},
+        {{8000, 8008, kSentinel}},  // NOLINT
+        {{8005, 8013, kSentinel}},
+        {{8017, 8025, kSentinel}},
+        {{8019, 8027, kSentinel}},
+        {{8021, 8029, kSentinel}},  // NOLINT
+        {{8023, 8031, kSentinel}},
+        {{8032, 8040, kSentinel}},
+        {{8039, 8047, kSentinel}},
+        {{8048, 8122, kSentinel}},  // NOLINT
+        {{8049, 8123, kSentinel}},
+        {{8050, 8136, kSentinel}},
+        {{8053, 8139, kSentinel}},
+        {{8054, 8154, kSentinel}},  // NOLINT
+        {{8055, 8155, kSentinel}},
+        {{8056, 8184, kSentinel}},
+        {{8057, 8185, kSentinel}},
+        {{8058, 8170, kSentinel}},  // NOLINT
+        {{8059, 8171, kSentinel}},
+        {{8060, 8186, kSentinel}},
+        {{8061, 8187, kSentinel}},
+        {{8112, 8120, kSentinel}},  // NOLINT
+        {{8113, 8121, kSentinel}},
+        {{8144, 8152, kSentinel}},
+        {{8145, 8153, kSentinel}},
+        {{8160, 8168, kSentinel}},  // NOLINT
+        {{8161, 8169, kSentinel}},
+        {{8165, 8172, kSentinel}},
+        {{kSentinel}}};                                         // NOLINT
+static const uint16_t kEcma262UnCanonicalizeTable0Size = 1005;  // NOLINT
+static const int32_t kEcma262UnCanonicalizeTable0[2010] = {
+    1073741889, 1,    90,         5,    1073741921, 1,
+    122,        5,    181,        9,    1073742016, 13,
+    214,        17,   1073742040, 21,  // NOLINT
+    222,        25,   1073742048, 13,   246,        17,
+    1073742072, 21,   254,        25,   255,        29,
+    256,        33,   257,        33,  // NOLINT
+    258,        37,   259,        37,   260,        41,
+    261,        41,   262,        45,   263,        45,
+    264,        49,   265,        49,  // NOLINT
+    266,        53,   267,        53,   268,        57,
+    269,        57,   270,        61,   271,        61,
+    272,        65,   273,        65,  // NOLINT
+    274,        69,   275,        69,   276,        73,
+    277,        73,   278,        77,   279,        77,
+    280,        81,   281,        81,  // NOLINT
+    282,        85,   283,        85,   284,        89,
+    285,        89,   286,        93,   287,        93,
+    288,        97,   289,        97,  // NOLINT
+    290,        101,  291,        101,  292,        105,
+    293,        105,  294,        109,  295,        109,
+    296,        113,  297,        113,  // NOLINT
+    298,        117,  299,        117,  300,        121,
+    301,        121,  302,        125,  303,        125,
+    306,        129,  307,        129,  // NOLINT
+    308,        133,  309,        133,  310,        137,
+    311,        137,  313,        141,  314,        141,
+    315,        145,  316,        145,  // NOLINT
+    317,        149,  318,        149,  319,        153,
+    320,        153,  321,        157,  322,        157,
+    323,        161,  324,        161,  // NOLINT
+    325,        165,  326,        165,  327,        169,
+    328,        169,  330,        173,  331,        173,
+    332,        177,  333,        177,  // NOLINT
+    334,        181,  335,        181,  336,        185,
+    337,        185,  338,        189,  339,        189,
+    340,        193,  341,        193,  // NOLINT
+    342,        197,  343,        197,  344,        201,
+    345,        201,  346,        205,  347,        205,
+    348,        209,  349,        209,  // NOLINT
+    350,        213,  351,        213,  352,        217,
+    353,        217,  354,        221,  355,        221,
+    356,        225,  357,        225,  // NOLINT
+    358,        229,  359,        229,  360,        233,
+    361,        233,  362,        237,  363,        237,
+    364,        241,  365,        241,  // NOLINT
+    366,        245,  367,        245,  368,        249,
+    369,        249,  370,        253,  371,        253,
+    372,        257,  373,        257,  // NOLINT
+    374,        261,  375,        261,  376,        29,
+    377,        265,  378,        265,  379,        269,
+    380,        269,  381,        273,  // NOLINT
+    382,        273,  384,        277,  385,        281,
+    386,        285,  387,        285,  388,        289,
+    389,        289,  390,        293,  // NOLINT
+    391,        297,  392,        297,  1073742217, 301,
+    394,        305,  395,        309,  396,        309,
+    398,        313,  399,        317,  // NOLINT
+    400,        321,  401,        325,  402,        325,
+    403,        329,  404,        333,  405,        337,
+    406,        341,  407,        345,  // NOLINT
+    408,        349,  409,        349,  410,        353,
+    412,        357,  413,        361,  414,        365,
+    415,        369,  416,        373,  // NOLINT
+    417,        373,  418,        377,  419,        377,
+    420,        381,  421,        381,  422,        385,
+    423,        389,  424,        389,  // NOLINT
+    425,        393,  428,        397,  429,        397,
+    430,        401,  431,        405,  432,        405,
+    1073742257, 409,  434,        413,  // NOLINT
+    435,        417,  436,        417,  437,        421,
+    438,        421,  439,        425,  440,        429,
+    441,        429,  444,        433,  // NOLINT
+    445,        433,  447,        437,  452,        441,
+    453,        441,  454,        441,  455,        445,
+    456,        445,  457,        445,  // NOLINT
+    458,        449,  459,        449,  460,        449,
+    461,        453,  462,        453,  463,        457,
+    464,        457,  465,        461,  // NOLINT
+    466,        461,  467,        465,  468,        465,
+    469,        469,  470,        469,  471,        473,
+    472,        473,  473,        477,  // NOLINT
+    474,        477,  475,        481,  476,        481,
+    477,        313,  478,        485,  479,        485,
+    480,        489,  481,        489,  // NOLINT
+    482,        493,  483,        493,  484,        497,
+    485,        497,  486,        501,  487,        501,
+    488,        505,  489,        505,  // NOLINT
+    490,        509,  491,        509,  492,        513,
+    493,        513,  494,        517,  495,        517,
+    497,        521,  498,        521,  // NOLINT
+    499,        521,  500,        525,  501,        525,
+    502,        337,  503,        437,  504,        529,
+    505,        529,  506,        533,  // NOLINT
+    507,        533,  508,        537,  509,        537,
+    510,        541,  511,        541,  512,        545,
+    513,        545,  514,        549,  // NOLINT
+    515,        549,  516,        553,  517,        553,
+    518,        557,  519,        557,  520,        561,
+    521,        561,  522,        565,  // NOLINT
+    523,        565,  524,        569,  525,        569,
+    526,        573,  527,        573,  528,        577,
+    529,        577,  530,        581,  // NOLINT
+    531,        581,  532,        585,  533,        585,
+    534,        589,  535,        589,  536,        593,
+    537,        593,  538,        597,  // NOLINT
+    539,        597,  540,        601,  541,        601,
+    542,        605,  543,        605,  544,        365,
+    546,        609,  547,        609,  // NOLINT
+    548,        613,  549,        613,  550,        617,
+    551,        617,  552,        621,  553,        621,
+    554,        625,  555,        625,  // NOLINT
+    556,        629,  557,        629,  558,        633,
+    559,        633,  560,        637,  561,        637,
+    562,        641,  563,        641,  // NOLINT
+    570,        645,  571,        649,  572,        649,
+    573,        353,  574,        653,  1073742399, 657,
+    576,        661,  577,        665,  // NOLINT
+    578,        665,  579,        277,  580,        669,
+    581,        673,  582,        677,  583,        677,
+    584,        681,  585,        681,  // NOLINT
+    586,        685,  587,        685,  588,        689,
+    589,        689,  590,        693,  591,        693,
+    592,        697,  593,        701,  // NOLINT
+    594,        705,  595,        281,  596,        293,
+    1073742422, 301,  599,        305,  601,        317,
+    603,        321,  604,        709,  // NOLINT
+    608,        329,  609,        713,  611,        333,
+    613,        717,  614,        721,  616,        345,
+    617,        341,  619,        725,  // NOLINT
+    620,        729,  623,        357,  625,        733,
+    626,        361,  629,        369,  637,        737,
+    640,        385,  643,        393,  // NOLINT
+    647,        741,  648,        401,  649,        669,
+    1073742474, 409,  651,        413,  652,        673,
+    658,        425,  670,        745,  // NOLINT
+    837,        749,  880,        753,  881,        753,
+    882,        757,  883,        757,  886,        761,
+    887,        761,  1073742715, 765,  // NOLINT
+    893,        769,  895,        773,  902,        777,
+    1073742728, 781,  906,        785,  908,        789,
+    1073742734, 793,  911,        797,  // NOLINT
+    913,        801,  914,        805,  1073742739, 809,
+    916,        813,  917,        817,  1073742742, 821,
+    919,        825,  920,        829,  // NOLINT
+    921,        749,  922,        833,  923,        837,
+    924,        9,    1073742749, 841,  927,        845,
+    928,        849,  929,        853,  // NOLINT
+    931,        857,  1073742756, 861,  933,        865,
+    934,        869,  1073742759, 873,  939,        877,
+    940,        777,  1073742765, 781,  // NOLINT
+    943,        785,  945,        801,  946,        805,
+    1073742771, 809,  948,        813,  949,        817,
+    1073742774, 821,  951,        825,  // NOLINT
+    952,        829,  953,        749,  954,        833,
+    955,        837,  956,        9,    1073742781, 841,
+    959,        845,  960,        849,  // NOLINT
+    961,        853,  962,        857,  963,        857,
+    1073742788, 861,  965,        865,  966,        869,
+    1073742791, 873,  971,        877,  // NOLINT
+    972,        789,  1073742797, 793,  974,        797,
+    975,        881,  976,        805,  977,        829,
+    981,        869,  982,        849,  // NOLINT
+    983,        881,  984,        885,  985,        885,
+    986,        889,  987,        889,  988,        893,
+    989,        893,  990,        897,  // NOLINT
+    991,        897,  992,        901,  993,        901,
+    994,        905,  995,        905,  996,        909,
+    997,        909,  998,        913,  // NOLINT
+    999,        913,  1000,       917,  1001,       917,
+    1002,       921,  1003,       921,  1004,       925,
+    1005,       925,  1006,       929,  // NOLINT
+    1007,       929,  1008,       833,  1009,       853,
+    1010,       933,  1011,       773,  1013,       817,
+    1015,       937,  1016,       937,  // NOLINT
+    1017,       933,  1018,       941,  1019,       941,
+    1073742845, 765,  1023,       769,  1073742848, 945,
+    1039,       949,  1073742864, 953,  // NOLINT
+    1071,       957,  1073742896, 953,  1103,       957,
+    1073742928, 945,  1119,       949,  1120,       961,
+    1121,       961,  1122,       965,  // NOLINT
+    1123,       965,  1124,       969,  1125,       969,
+    1126,       973,  1127,       973,  1128,       977,
+    1129,       977,  1130,       981,  // NOLINT
+    1131,       981,  1132,       985,  1133,       985,
+    1134,       989,  1135,       989,  1136,       993,
+    1137,       993,  1138,       997,  // NOLINT
+    1139,       997,  1140,       1001, 1141,       1001,
+    1142,       1005, 1143,       1005, 1144,       1009,
+    1145,       1009, 1146,       1013,  // NOLINT
+    1147,       1013, 1148,       1017, 1149,       1017,
+    1150,       1021, 1151,       1021, 1152,       1025,
+    1153,       1025, 1162,       1029,  // NOLINT
+    1163,       1029, 1164,       1033, 1165,       1033,
+    1166,       1037, 1167,       1037, 1168,       1041,
+    1169,       1041, 1170,       1045,  // NOLINT
+    1171,       1045, 1172,       1049, 1173,       1049,
+    1174,       1053, 1175,       1053, 1176,       1057,
+    1177,       1057, 1178,       1061,  // NOLINT
+    1179,       1061, 1180,       1065, 1181,       1065,
+    1182,       1069, 1183,       1069, 1184,       1073,
+    1185,       1073, 1186,       1077,  // NOLINT
+    1187,       1077, 1188,       1081, 1189,       1081,
+    1190,       1085, 1191,       1085, 1192,       1089,
+    1193,       1089, 1194,       1093,  // NOLINT
+    1195,       1093, 1196,       1097, 1197,       1097,
+    1198,       1101, 1199,       1101, 1200,       1105,
+    1201,       1105, 1202,       1109,  // NOLINT
+    1203,       1109, 1204,       1113, 1205,       1113,
+    1206,       1117, 1207,       1117, 1208,       1121,
+    1209,       1121, 1210,       1125,  // NOLINT
+    1211,       1125, 1212,       1129, 1213,       1129,
+    1214,       1133, 1215,       1133, 1216,       1137,
+    1217,       1141, 1218,       1141,  // NOLINT
+    1219,       1145, 1220,       1145, 1221,       1149,
+    1222,       1149, 1223,       1153, 1224,       1153,
+    1225,       1157, 1226,       1157,  // NOLINT
+    1227,       1161, 1228,       1161, 1229,       1165,
+    1230,       1165, 1231,       1137, 1232,       1169,
+    1233,       1169, 1234,       1173,  // NOLINT
+    1235,       1173, 1236,       1177, 1237,       1177,
+    1238,       1181, 1239,       1181, 1240,       1185,
+    1241,       1185, 1242,       1189,  // NOLINT
+    1243,       1189, 1244,       1193, 1245,       1193,
+    1246,       1197, 1247,       1197, 1248,       1201,
+    1249,       1201, 1250,       1205,  // NOLINT
+    1251,       1205, 1252,       1209, 1253,       1209,
+    1254,       1213, 1255,       1213, 1256,       1217,
+    1257,       1217, 1258,       1221,  // NOLINT
+    1259,       1221, 1260,       1225, 1261,       1225,
+    1262,       1229, 1263,       1229, 1264,       1233,
+    1265,       1233, 1266,       1237,  // NOLINT
+    1267,       1237, 1268,       1241, 1269,       1241,
+    1270,       1245, 1271,       1245, 1272,       1249,
+    1273,       1249, 1274,       1253,  // NOLINT
+    1275,       1253, 1276,       1257, 1277,       1257,
+    1278,       1261, 1279,       1261, 1280,       1265,
+    1281,       1265, 1282,       1269,  // NOLINT
+    1283,       1269, 1284,       1273, 1285,       1273,
+    1286,       1277, 1287,       1277, 1288,       1281,
+    1289,       1281, 1290,       1285,  // NOLINT
+    1291,       1285, 1292,       1289, 1293,       1289,
+    1294,       1293, 1295,       1293, 1296,       1297,
+    1297,       1297, 1298,       1301,  // NOLINT
+    1299,       1301, 1300,       1305, 1301,       1305,
+    1302,       1309, 1303,       1309, 1304,       1313,
+    1305,       1313, 1306,       1317,  // NOLINT
+    1307,       1317, 1308,       1321, 1309,       1321,
+    1310,       1325, 1311,       1325, 1312,       1329,
+    1313,       1329, 1314,       1333,  // NOLINT
+    1315,       1333, 1316,       1337, 1317,       1337,
+    1318,       1341, 1319,       1341, 1320,       1345,
+    1321,       1345, 1322,       1349,  // NOLINT
+    1323,       1349, 1324,       1353, 1325,       1353,
+    1326,       1357, 1327,       1357, 1073743153, 1361,
+    1366,       1365, 1073743201, 1361,  // NOLINT
+    1414,       1365, 1073746080, 1369, 4293,       1373,
+    4295,       1377, 4301,       1381, 7545,       1385,
+    7549,       1389, 7680,       1393,  // NOLINT
+    7681,       1393, 7682,       1397, 7683,       1397,
+    7684,       1401, 7685,       1401, 7686,       1405,
+    7687,       1405, 7688,       1409,  // NOLINT
+    7689,       1409, 7690,       1413, 7691,       1413,
+    7692,       1417, 7693,       1417, 7694,       1421,
+    7695,       1421, 7696,       1425,  // NOLINT
+    7697,       1425, 7698,       1429, 7699,       1429,
+    7700,       1433, 7701,       1433, 7702,       1437,
+    7703,       1437, 7704,       1441,  // NOLINT
+    7705,       1441, 7706,       1445, 7707,       1445,
+    7708,       1449, 7709,       1449, 7710,       1453,
+    7711,       1453, 7712,       1457,  // NOLINT
+    7713,       1457, 7714,       1461, 7715,       1461,
+    7716,       1465, 7717,       1465, 7718,       1469,
+    7719,       1469, 7720,       1473,  // NOLINT
+    7721,       1473, 7722,       1477, 7723,       1477,
+    7724,       1481, 7725,       1481, 7726,       1485,
+    7727,       1485, 7728,       1489,  // NOLINT
+    7729,       1489, 7730,       1493, 7731,       1493,
+    7732,       1497, 7733,       1497, 7734,       1501,
+    7735,       1501, 7736,       1505,  // NOLINT
+    7737,       1505, 7738,       1509, 7739,       1509,
+    7740,       1513, 7741,       1513, 7742,       1517,
+    7743,       1517, 7744,       1521,  // NOLINT
+    7745,       1521, 7746,       1525, 7747,       1525,
+    7748,       1529, 7749,       1529, 7750,       1533,
+    7751,       1533, 7752,       1537,  // NOLINT
+    7753,       1537, 7754,       1541, 7755,       1541,
+    7756,       1545, 7757,       1545, 7758,       1549,
+    7759,       1549, 7760,       1553,  // NOLINT
+    7761,       1553, 7762,       1557, 7763,       1557,
+    7764,       1561, 7765,       1561, 7766,       1565,
+    7767,       1565, 7768,       1569,  // NOLINT
+    7769,       1569, 7770,       1573, 7771,       1573,
+    7772,       1577, 7773,       1577, 7774,       1581,
+    7775,       1581, 7776,       1585,  // NOLINT
+    7777,       1585, 7778,       1589, 7779,       1589,
+    7780,       1593, 7781,       1593, 7782,       1597,
+    7783,       1597, 7784,       1601,  // NOLINT
+    7785,       1601, 7786,       1605, 7787,       1605,
+    7788,       1609, 7789,       1609, 7790,       1613,
+    7791,       1613, 7792,       1617,  // NOLINT
+    7793,       1617, 7794,       1621, 7795,       1621,
+    7796,       1625, 7797,       1625, 7798,       1629,
+    7799,       1629, 7800,       1633,  // NOLINT
+    7801,       1633, 7802,       1637, 7803,       1637,
+    7804,       1641, 7805,       1641, 7806,       1645,
+    7807,       1645, 7808,       1649,  // NOLINT
+    7809,       1649, 7810,       1653, 7811,       1653,
+    7812,       1657, 7813,       1657, 7814,       1661,
+    7815,       1661, 7816,       1665,  // NOLINT
+    7817,       1665, 7818,       1669, 7819,       1669,
+    7820,       1673, 7821,       1673, 7822,       1677,
+    7823,       1677, 7824,       1681,  // NOLINT
+    7825,       1681, 7826,       1685, 7827,       1685,
+    7828,       1689, 7829,       1689, 7835,       1585,
+    7840,       1693, 7841,       1693,  // NOLINT
+    7842,       1697, 7843,       1697, 7844,       1701,
+    7845,       1701, 7846,       1705, 7847,       1705,
+    7848,       1709, 7849,       1709,  // NOLINT
+    7850,       1713, 7851,       1713, 7852,       1717,
+    7853,       1717, 7854,       1721, 7855,       1721,
+    7856,       1725, 7857,       1725,  // NOLINT
+    7858,       1729, 7859,       1729, 7860,       1733,
+    7861,       1733, 7862,       1737, 7863,       1737,
+    7864,       1741, 7865,       1741,  // NOLINT
+    7866,       1745, 7867,       1745, 7868,       1749,
+    7869,       1749, 7870,       1753, 7871,       1753,
+    7872,       1757, 7873,       1757,  // NOLINT
+    7874,       1761, 7875,       1761, 7876,       1765,
+    7877,       1765, 7878,       1769, 7879,       1769,
+    7880,       1773, 7881,       1773,  // NOLINT
+    7882,       1777, 7883,       1777, 7884,       1781,
+    7885,       1781, 7886,       1785, 7887,       1785,
+    7888,       1789, 7889,       1789,  // NOLINT
+    7890,       1793, 7891,       1793, 7892,       1797,
+    7893,       1797, 7894,       1801, 7895,       1801,
+    7896,       1805, 7897,       1805,  // NOLINT
+    7898,       1809, 7899,       1809, 7900,       1813,
+    7901,       1813, 7902,       1817, 7903,       1817,
+    7904,       1821, 7905,       1821,  // NOLINT
+    7906,       1825, 7907,       1825, 7908,       1829,
+    7909,       1829, 7910,       1833, 7911,       1833,
+    7912,       1837, 7913,       1837,  // NOLINT
+    7914,       1841, 7915,       1841, 7916,       1845,
+    7917,       1845, 7918,       1849, 7919,       1849,
+    7920,       1853, 7921,       1853,  // NOLINT
+    7922,       1857, 7923,       1857, 7924,       1861,
+    7925,       1861, 7926,       1865, 7927,       1865,
+    7928,       1869, 7929,       1869,  // NOLINT
+    7930,       1873, 7931,       1873, 7932,       1877,
+    7933,       1877, 7934,       1881, 7935,       1881,
+    1073749760, 1885, 7943,       1889,  // NOLINT
+    1073749768, 1885, 7951,       1889, 1073749776, 1893,
+    7957,       1897, 1073749784, 1893, 7965,       1897,
+    1073749792, 1901, 7975,       1905,  // NOLINT
+    1073749800, 1901, 7983,       1905, 1073749808, 1909,
+    7991,       1913, 1073749816, 1909, 7999,       1913,
+    1073749824, 1917, 8005,       1921,  // NOLINT
+    1073749832, 1917, 8013,       1921, 8017,       1925,
+    8019,       1929, 8021,       1933, 8023,       1937,
+    8025,       1925, 8027,       1929,  // NOLINT
+    8029,       1933, 8031,       1937, 1073749856, 1941,
+    8039,       1945, 1073749864, 1941, 8047,       1945,
+    1073749872, 1949, 8049,       1953,  // NOLINT
+    1073749874, 1957, 8053,       1961, 1073749878, 1965,
+    8055,       1969, 1073749880, 1973, 8057,       1977,
+    1073749882, 1981, 8059,       1985,  // NOLINT
+    1073749884, 1989, 8061,       1993, 1073749936, 1997,
+    8113,       2001, 1073749944, 1997, 8121,       2001,
+    1073749946, 1949, 8123,       1953,  // NOLINT
+    8126,       749,  1073749960, 1957, 8139,       1961,
+    1073749968, 2005, 8145,       2009, 1073749976, 2005,
+    8153,       2009, 1073749978, 1965,  // NOLINT
+    8155,       1969, 1073749984, 2013, 8161,       2017,
+    8165,       2021, 1073749992, 2013, 8169,       2017,
+    1073749994, 1981, 8171,       1985,  // NOLINT
+    8172,       2021, 1073750008, 1973, 8185,       1977,
+    1073750010, 1989, 8187,       1993};                              // NOLINT
+static const uint16_t kEcma262UnCanonicalizeMultiStrings0Size = 507;  // NOLINT
+static const MultiCharacterSpecialCase<2> kEcma262UnCanonicalizeMultiStrings1[83] = {  // NOLINT
+  {{8498, 8526}}, {{8544, 8560}}, {{8559, 8575}}, {{8579, 8580}},  // NOLINT
+  {{9398, 9424}}, {{9423, 9449}}, {{11264, 11312}}, {{11310, 11358}},  // NOLINT
+  {{11360, 11361}}, {{619, 11362}}, {{7549, 11363}}, {{637, 11364}},  // NOLINT
+  {{570, 11365}}, {{574, 11366}}, {{11367, 11368}}, {{11369, 11370}},  // NOLINT
+  {{11371, 11372}}, {{593, 11373}}, {{625, 11374}}, {{592, 11375}},  // NOLINT
+  {{594, 11376}}, {{11378, 11379}}, {{11381, 11382}}, {{575, 11390}},  // NOLINT
+  {{576, 11391}}, {{11392, 11393}}, {{11394, 11395}}, {{11396, 11397}},  // NOLINT
+  {{11398, 11399}}, {{11400, 11401}}, {{11402, 11403}}, {{11404, 11405}},  // NOLINT
+  {{11406, 11407}}, {{11408, 11409}}, {{11410, 11411}}, {{11412, 11413}},  // NOLINT
+  {{11414, 11415}}, {{11416, 11417}}, {{11418, 11419}}, {{11420, 11421}},  // NOLINT
+  {{11422, 11423}}, {{11424, 11425}}, {{11426, 11427}}, {{11428, 11429}},  // NOLINT
+  {{11430, 11431}}, {{11432, 11433}}, {{11434, 11435}}, {{11436, 11437}},  // NOLINT
+  {{11438, 11439}}, {{11440, 11441}}, {{11442, 11443}}, {{11444, 11445}},  // NOLINT
+  {{11446, 11447}}, {{11448, 11449}}, {{11450, 11451}}, {{11452, 11453}},  // NOLINT
+  {{11454, 11455}}, {{11456, 11457}}, {{11458, 11459}}, {{11460, 11461}},  // NOLINT
+  {{11462, 11463}}, {{11464, 11465}}, {{11466, 11467}}, {{11468, 11469}},  // NOLINT
+  {{11470, 11471}}, {{11472, 11473}}, {{11474, 11475}}, {{11476, 11477}},  // NOLINT
+  {{11478, 11479}}, {{11480, 11481}}, {{11482, 11483}}, {{11484, 11485}},  // NOLINT
+  {{11486, 11487}}, {{11488, 11489}}, {{11490, 11491}}, {{11499, 11500}},  // NOLINT
+  {{11501, 11502}}, {{11506, 11507}}, {{4256, 11520}}, {{4293, 11557}},  // NOLINT
+  {{4295, 11559}}, {{4301, 11565}}, {{kSentinel}} }; // NOLINT
+static const uint16_t kEcma262UnCanonicalizeTable1Size = 149;  // NOLINT
+static const int32_t kEcma262UnCanonicalizeTable1[298] = {
+  306, 1, 334, 1, 1073742176, 5, 367, 9, 1073742192, 5, 383, 9, 387, 13, 388, 13,  // NOLINT
+  1073743030, 17, 1231, 21, 1073743056, 17, 1257, 21, 1073744896, 25, 3118, 29, 1073744944, 25, 3166, 29,  // NOLINT
+  3168, 33, 3169, 33, 3170, 37, 3171, 41, 3172, 45, 3173, 49, 3174, 53, 3175, 57,  // NOLINT
+  3176, 57, 3177, 61, 3178, 61, 3179, 65, 3180, 65, 3181, 69, 3182, 73, 3183, 77,  // NOLINT
+  3184, 81, 3186, 85, 3187, 85, 3189, 89, 3190, 89, 1073745022, 93, 3199, 97, 3200, 101,  // NOLINT
+  3201, 101, 3202, 105, 3203, 105, 3204, 109, 3205, 109, 3206, 113, 3207, 113, 3208, 117,  // NOLINT
+  3209, 117, 3210, 121, 3211, 121, 3212, 125, 3213, 125, 3214, 129, 3215, 129, 3216, 133,  // NOLINT
+  3217, 133, 3218, 137, 3219, 137, 3220, 141, 3221, 141, 3222, 145, 3223, 145, 3224, 149,  // NOLINT
+  3225, 149, 3226, 153, 3227, 153, 3228, 157, 3229, 157, 3230, 161, 3231, 161, 3232, 165,  // NOLINT
+  3233, 165, 3234, 169, 3235, 169, 3236, 173, 3237, 173, 3238, 177, 3239, 177, 3240, 181,  // NOLINT
+  3241, 181, 3242, 185, 3243, 185, 3244, 189, 3245, 189, 3246, 193, 3247, 193, 3248, 197,  // NOLINT
+  3249, 197, 3250, 201, 3251, 201, 3252, 205, 3253, 205, 3254, 209, 3255, 209, 3256, 213,  // NOLINT
+  3257, 213, 3258, 217, 3259, 217, 3260, 221, 3261, 221, 3262, 225, 3263, 225, 3264, 229,  // NOLINT
+  3265, 229, 3266, 233, 3267, 233, 3268, 237, 3269, 237, 3270, 241, 3271, 241, 3272, 245,  // NOLINT
+  3273, 245, 3274, 249, 3275, 249, 3276, 253, 3277, 253, 3278, 257, 3279, 257, 3280, 261,  // NOLINT
+  3281, 261, 3282, 265, 3283, 265, 3284, 269, 3285, 269, 3286, 273, 3287, 273, 3288, 277,  // NOLINT
+  3289, 277, 3290, 281, 3291, 281, 3292, 285, 3293, 285, 3294, 289, 3295, 289, 3296, 293,  // NOLINT
+  3297, 293, 3298, 297, 3299, 297, 3307, 301, 3308, 301, 3309, 305, 3310, 305, 3314, 309,  // NOLINT
+  3315, 309, 1073745152, 313, 3365, 317, 3367, 321, 3373, 325 };  // NOLINT
+static const uint16_t kEcma262UnCanonicalizeMultiStrings1Size = 83;  // NOLINT
+static const MultiCharacterSpecialCase<2>
+    kEcma262UnCanonicalizeMultiStrings5[104] = {  // NOLINT
+        {{42560, 42561}},
+        {{42562, 42563}},
+        {{42564, 42565}},
+        {{42566, 42567}},  // NOLINT
+        {{42568, 42569}},
+        {{42570, 42571}},
+        {{42572, 42573}},
+        {{42574, 42575}},  // NOLINT
+        {{42576, 42577}},
+        {{42578, 42579}},
+        {{42580, 42581}},
+        {{42582, 42583}},  // NOLINT
+        {{42584, 42585}},
+        {{42586, 42587}},
+        {{42588, 42589}},
+        {{42590, 42591}},  // NOLINT
+        {{42592, 42593}},
+        {{42594, 42595}},
+        {{42596, 42597}},
+        {{42598, 42599}},  // NOLINT
+        {{42600, 42601}},
+        {{42602, 42603}},
+        {{42604, 42605}},
+        {{42624, 42625}},  // NOLINT
+        {{42626, 42627}},
+        {{42628, 42629}},
+        {{42630, 42631}},
+        {{42632, 42633}},  // NOLINT
+        {{42634, 42635}},
+        {{42636, 42637}},
+        {{42638, 42639}},
+        {{42640, 42641}},  // NOLINT
+        {{42642, 42643}},
+        {{42644, 42645}},
+        {{42646, 42647}},
+        {{42648, 42649}},  // NOLINT
+        {{42650, 42651}},
+        {{42786, 42787}},
+        {{42788, 42789}},
+        {{42790, 42791}},  // NOLINT
+        {{42792, 42793}},
+        {{42794, 42795}},
+        {{42796, 42797}},
+        {{42798, 42799}},  // NOLINT
+        {{42802, 42803}},
+        {{42804, 42805}},
+        {{42806, 42807}},
+        {{42808, 42809}},  // NOLINT
+        {{42810, 42811}},
+        {{42812, 42813}},
+        {{42814, 42815}},
+        {{42816, 42817}},  // NOLINT
+        {{42818, 42819}},
+        {{42820, 42821}},
+        {{42822, 42823}},
+        {{42824, 42825}},  // NOLINT
+        {{42826, 42827}},
+        {{42828, 42829}},
+        {{42830, 42831}},
+        {{42832, 42833}},  // NOLINT
+        {{42834, 42835}},
+        {{42836, 42837}},
+        {{42838, 42839}},
+        {{42840, 42841}},  // NOLINT
+        {{42842, 42843}},
+        {{42844, 42845}},
+        {{42846, 42847}},
+        {{42848, 42849}},  // NOLINT
+        {{42850, 42851}},
+        {{42852, 42853}},
+        {{42854, 42855}},
+        {{42856, 42857}},  // NOLINT
+        {{42858, 42859}},
+        {{42860, 42861}},
+        {{42862, 42863}},
+        {{42873, 42874}},  // NOLINT
+        {{42875, 42876}},
+        {{7545, 42877}},
+        {{42878, 42879}},
+        {{42880, 42881}},  // NOLINT
+        {{42882, 42883}},
+        {{42884, 42885}},
+        {{42886, 42887}},
+        {{42891, 42892}},  // NOLINT
+        {{613, 42893}},
+        {{42896, 42897}},
+        {{42898, 42899}},
+        {{42902, 42903}},  // NOLINT
+        {{42904, 42905}},
+        {{42906, 42907}},
+        {{42908, 42909}},
+        {{42910, 42911}},  // NOLINT
+        {{42912, 42913}},
+        {{42914, 42915}},
+        {{42916, 42917}},
+        {{42918, 42919}},  // NOLINT
+        {{42920, 42921}},
+        {{614, 42922}},
+        {{604, 42923}},
+        {{609, 42924}},  // NOLINT
+        {{620, 42925}},
+        {{670, 42928}},
+        {{647, 42929}},
+        {{kSentinel}}};                                        // NOLINT
+static const uint16_t kEcma262UnCanonicalizeTable5Size = 198;  // NOLINT
+static const int32_t kEcma262UnCanonicalizeTable5
+    [396] = {1600, 1,   1601, 1,   1602, 5,   1603, 5,
+             1604, 9,   1605, 9,   1606, 13,  1607, 13,  // NOLINT
+             1608, 17,  1609, 17,  1610, 21,  1611, 21,
+             1612, 25,  1613, 25,  1614, 29,  1615, 29,  // NOLINT
+             1616, 33,  1617, 33,  1618, 37,  1619, 37,
+             1620, 41,  1621, 41,  1622, 45,  1623, 45,  // NOLINT
+             1624, 49,  1625, 49,  1626, 53,  1627, 53,
+             1628, 57,  1629, 57,  1630, 61,  1631, 61,  // NOLINT
+             1632, 65,  1633, 65,  1634, 69,  1635, 69,
+             1636, 73,  1637, 73,  1638, 77,  1639, 77,  // NOLINT
+             1640, 81,  1641, 81,  1642, 85,  1643, 85,
+             1644, 89,  1645, 89,  1664, 93,  1665, 93,  // NOLINT
+             1666, 97,  1667, 97,  1668, 101, 1669, 101,
+             1670, 105, 1671, 105, 1672, 109, 1673, 109,  // NOLINT
+             1674, 113, 1675, 113, 1676, 117, 1677, 117,
+             1678, 121, 1679, 121, 1680, 125, 1681, 125,  // NOLINT
+             1682, 129, 1683, 129, 1684, 133, 1685, 133,
+             1686, 137, 1687, 137, 1688, 141, 1689, 141,  // NOLINT
+             1690, 145, 1691, 145, 1826, 149, 1827, 149,
+             1828, 153, 1829, 153, 1830, 157, 1831, 157,  // NOLINT
+             1832, 161, 1833, 161, 1834, 165, 1835, 165,
+             1836, 169, 1837, 169, 1838, 173, 1839, 173,  // NOLINT
+             1842, 177, 1843, 177, 1844, 181, 1845, 181,
+             1846, 185, 1847, 185, 1848, 189, 1849, 189,  // NOLINT
+             1850, 193, 1851, 193, 1852, 197, 1853, 197,
+             1854, 201, 1855, 201, 1856, 205, 1857, 205,  // NOLINT
+             1858, 209, 1859, 209, 1860, 213, 1861, 213,
+             1862, 217, 1863, 217, 1864, 221, 1865, 221,  // NOLINT
+             1866, 225, 1867, 225, 1868, 229, 1869, 229,
+             1870, 233, 1871, 233, 1872, 237, 1873, 237,  // NOLINT
+             1874, 241, 1875, 241, 1876, 245, 1877, 245,
+             1878, 249, 1879, 249, 1880, 253, 1881, 253,  // NOLINT
+             1882, 257, 1883, 257, 1884, 261, 1885, 261,
+             1886, 265, 1887, 265, 1888, 269, 1889, 269,  // NOLINT
+             1890, 273, 1891, 273, 1892, 277, 1893, 277,
+             1894, 281, 1895, 281, 1896, 285, 1897, 285,  // NOLINT
+             1898, 289, 1899, 289, 1900, 293, 1901, 293,
+             1902, 297, 1903, 297, 1913, 301, 1914, 301,  // NOLINT
+             1915, 305, 1916, 305, 1917, 309, 1918, 313,
+             1919, 313, 1920, 317, 1921, 317, 1922, 321,  // NOLINT
+             1923, 321, 1924, 325, 1925, 325, 1926, 329,
+             1927, 329, 1931, 333, 1932, 333, 1933, 337,  // NOLINT
+             1936, 341, 1937, 341, 1938, 345, 1939, 345,
+             1942, 349, 1943, 349, 1944, 353, 1945, 353,  // NOLINT
+             1946, 357, 1947, 357, 1948, 361, 1949, 361,
+             1950, 365, 1951, 365, 1952, 369, 1953, 369,  // NOLINT
+             1954, 373, 1955, 373, 1956, 377, 1957, 377,
+             1958, 381, 1959, 381, 1960, 385, 1961, 385,  // NOLINT
+             1962, 389, 1963, 393, 1964, 397, 1965, 401,
+             1968, 405, 1969, 409};                                   // NOLINT
+static const uint16_t kEcma262UnCanonicalizeMultiStrings5Size = 104;  // NOLINT
+static const MultiCharacterSpecialCase<2> kEcma262UnCanonicalizeMultiStrings7[3] = {  // NOLINT
+  {{65313, 65345}}, {{65338, 65370}}, {{kSentinel}} }; // NOLINT
+static const uint16_t kEcma262UnCanonicalizeTable7Size = 4;  // NOLINT
+static const int32_t kEcma262UnCanonicalizeTable7[8] = {
+  1073749793, 1, 7994, 5, 1073749825, 1, 8026, 5 };  // NOLINT
+static const uint16_t kEcma262UnCanonicalizeMultiStrings7Size = 3;  // NOLINT
+int Ecma262UnCanonicalize::Convert(uchar c,
+                      uchar n,
+                      uchar* result,
+                      bool* allow_caching_ptr) {
+  int chunk_index = c >> 13;
+  switch (chunk_index) {
+    case 0: return LookupMapping<true>(kEcma262UnCanonicalizeTable0,
+                                           kEcma262UnCanonicalizeTable0Size,
+                                           kEcma262UnCanonicalizeMultiStrings0,
+                                           c,
+                                           n,
+                                           result,
+                                           allow_caching_ptr);
+    case 1: return LookupMapping<true>(kEcma262UnCanonicalizeTable1,
+                                           kEcma262UnCanonicalizeTable1Size,
+                                           kEcma262UnCanonicalizeMultiStrings1,
+                                           c,
+                                           n,
+                                           result,
+                                           allow_caching_ptr);
+    case 5: return LookupMapping<true>(kEcma262UnCanonicalizeTable5,
+                                           kEcma262UnCanonicalizeTable5Size,
+                                           kEcma262UnCanonicalizeMultiStrings5,
+                                           c,
+                                           n,
+                                           result,
+                                           allow_caching_ptr);
+    case 7: return LookupMapping<true>(kEcma262UnCanonicalizeTable7,
+                                           kEcma262UnCanonicalizeTable7Size,
+                                           kEcma262UnCanonicalizeMultiStrings7,
+                                           c,
+                                           n,
+                                           result,
+                                           allow_caching_ptr);
+    default: return 0;
+  }
+}
+
+static const MultiCharacterSpecialCase<1> kCanonicalizationRangeMultiStrings0[1] = {  // NOLINT
+  {{kSentinel}} }; // NOLINT
+static const uint16_t kCanonicalizationRangeTable0Size = 70;  // NOLINT
+static const int32_t kCanonicalizationRangeTable0[140] = {
+  1073741889, 100, 90, 0, 1073741921, 100, 122, 0, 1073742016, 88, 214, 0, 1073742040, 24, 222, 0,  // NOLINT
+  1073742048, 88, 246, 0, 1073742072, 24, 254, 0, 1073742715, 8, 893, 0, 1073742728, 8, 906, 0,  // NOLINT
+  1073742749, 8, 927, 0, 1073742759, 16, 939, 0, 1073742765, 8, 943, 0, 1073742781, 8, 959, 0,  // NOLINT
+  1073742791, 16, 971, 0, 1073742845, 8, 1023, 0, 1073742848, 60, 1039, 0, 1073742864, 124, 1071, 0,  // NOLINT
+  1073742896, 124, 1103, 0, 1073742928, 60, 1119, 0, 1073743153, 148, 1366, 0, 1073743201, 148, 1414, 0,  // NOLINT
+  1073746080, 148, 4293, 0, 1073749760, 28, 7943, 0, 1073749768, 28, 7951, 0, 1073749776, 20, 7957, 0,  // NOLINT
+  1073749784, 20, 7965, 0, 1073749792, 28, 7975, 0, 1073749800, 28, 7983, 0, 1073749808, 28, 7991, 0,  // NOLINT
+  1073749816, 28, 7999, 0, 1073749824, 20, 8005, 0, 1073749832, 20, 8013, 0, 1073749856, 28, 8039, 0,  // NOLINT
+  1073749864, 28, 8047, 0, 1073749874, 12, 8053, 0, 1073749960, 12, 8139, 0 };  // NOLINT
+static const uint16_t kCanonicalizationRangeMultiStrings0Size = 1;  // NOLINT
+static const MultiCharacterSpecialCase<1> kCanonicalizationRangeMultiStrings1[1] = {  // NOLINT
+  {{kSentinel}} }; // NOLINT
+static const uint16_t kCanonicalizationRangeTable1Size = 14;  // NOLINT
+static const int32_t kCanonicalizationRangeTable1[28] = {
+  1073742176, 60, 367, 0, 1073742192, 60, 383, 0, 1073743030, 100, 1231, 0, 1073743056, 100, 1257, 0,  // NOLINT
+  1073744896, 184, 3118, 0, 1073744944, 184, 3166, 0, 1073745152, 148, 3365, 0 };  // NOLINT
+static const uint16_t kCanonicalizationRangeMultiStrings1Size = 1;  // NOLINT
+static const MultiCharacterSpecialCase<1> kCanonicalizationRangeMultiStrings7[1] = {  // NOLINT
+  {{kSentinel}} }; // NOLINT
+static const uint16_t kCanonicalizationRangeTable7Size = 4;  // NOLINT
+static const int32_t kCanonicalizationRangeTable7[8] = {
+  1073749793, 100, 7994, 0, 1073749825, 100, 8026, 0 };  // NOLINT
+static const uint16_t kCanonicalizationRangeMultiStrings7Size = 1;  // NOLINT
+int CanonicalizationRange::Convert(uchar c,
+                      uchar n,
+                      uchar* result,
+                      bool* allow_caching_ptr) {
+  int chunk_index = c >> 13;
+  switch (chunk_index) {
+    case 0: return LookupMapping<false>(kCanonicalizationRangeTable0,
+                                           kCanonicalizationRangeTable0Size,
+                                           kCanonicalizationRangeMultiStrings0,
+                                           c,
+                                           n,
+                                           result,
+                                           allow_caching_ptr);
+    case 1: return LookupMapping<false>(kCanonicalizationRangeTable1,
+                                           kCanonicalizationRangeTable1Size,
+                                           kCanonicalizationRangeMultiStrings1,
+                                           c,
+                                           n,
+                                           result,
+                                           allow_caching_ptr);
+    case 7: return LookupMapping<false>(kCanonicalizationRangeTable7,
+                                           kCanonicalizationRangeTable7Size,
+                                           kCanonicalizationRangeMultiStrings7,
+                                           c,
+                                           n,
+                                           result,
+                                           allow_caching_ptr);
+    default: return 0;
+  }
+}
+
+
+const uchar UnicodeData::kMaxCodePoint = 65533;
+
+int UnicodeData::GetByteCount() {
+  return kUppercaseTable0Size * sizeof(int32_t)         // NOLINT
+         + kUppercaseTable1Size * sizeof(int32_t)       // NOLINT
+         + kUppercaseTable5Size * sizeof(int32_t)       // NOLINT
+         + kUppercaseTable7Size * sizeof(int32_t)       // NOLINT
+         + kLowercaseTable0Size * sizeof(int32_t)       // NOLINT
+         + kLowercaseTable1Size * sizeof(int32_t)       // NOLINT
+         + kLowercaseTable5Size * sizeof(int32_t)       // NOLINT
+         + kLowercaseTable7Size * sizeof(int32_t)       // NOLINT
+         + kLetterTable0Size * sizeof(int32_t)          // NOLINT
+         + kLetterTable1Size * sizeof(int32_t)          // NOLINT
+         + kLetterTable2Size * sizeof(int32_t)          // NOLINT
+         + kLetterTable3Size * sizeof(int32_t)          // NOLINT
+         + kLetterTable4Size * sizeof(int32_t)          // NOLINT
+         + kLetterTable5Size * sizeof(int32_t)          // NOLINT
+         + kLetterTable6Size * sizeof(int32_t)          // NOLINT
+         + kLetterTable7Size * sizeof(int32_t)          // NOLINT
+         + kID_StartTable0Size * sizeof(int32_t)        // NOLINT
+         + kID_StartTable1Size * sizeof(int32_t)        // NOLINT
+         + kID_StartTable2Size * sizeof(int32_t)        // NOLINT
+         + kID_StartTable3Size * sizeof(int32_t)        // NOLINT
+         + kID_StartTable4Size * sizeof(int32_t)        // NOLINT
+         + kID_StartTable5Size * sizeof(int32_t)        // NOLINT
+         + kID_StartTable6Size * sizeof(int32_t)        // NOLINT
+         + kID_StartTable7Size * sizeof(int32_t)        // NOLINT
+         + kID_ContinueTable0Size * sizeof(int32_t)     // NOLINT
+         + kID_ContinueTable1Size * sizeof(int32_t)     // NOLINT
+         + kID_ContinueTable5Size * sizeof(int32_t)     // NOLINT
+         + kID_ContinueTable7Size * sizeof(int32_t)     // NOLINT
+         + kWhiteSpaceTable0Size * sizeof(int32_t)      // NOLINT
+         + kWhiteSpaceTable1Size * sizeof(int32_t)      // NOLINT
+         + kWhiteSpaceTable7Size * sizeof(int32_t)      // NOLINT
+         + kLineTerminatorTable0Size * sizeof(int32_t)  // NOLINT
+         + kLineTerminatorTable1Size * sizeof(int32_t)  // NOLINT
+         +
+         kToLowercaseMultiStrings0Size *
+             sizeof(MultiCharacterSpecialCase<2>)  // NOLINT
+         +
+         kToLowercaseMultiStrings1Size *
+             sizeof(MultiCharacterSpecialCase<1>)  // NOLINT
+         +
+         kToLowercaseMultiStrings5Size *
+             sizeof(MultiCharacterSpecialCase<1>)  // NOLINT
+         +
+         kToLowercaseMultiStrings7Size *
+             sizeof(MultiCharacterSpecialCase<1>)  // NOLINT
+         +
+         kToUppercaseMultiStrings0Size *
+             sizeof(MultiCharacterSpecialCase<3>)  // NOLINT
+         +
+         kToUppercaseMultiStrings1Size *
+             sizeof(MultiCharacterSpecialCase<1>)  // NOLINT
+         +
+         kToUppercaseMultiStrings5Size *
+             sizeof(MultiCharacterSpecialCase<1>)  // NOLINT
+         +
+         kToUppercaseMultiStrings7Size *
+             sizeof(MultiCharacterSpecialCase<3>)  // NOLINT
+         +
+         kEcma262CanonicalizeMultiStrings0Size *
+             sizeof(MultiCharacterSpecialCase<1>)  // NOLINT
+         +
+         kEcma262CanonicalizeMultiStrings1Size *
+             sizeof(MultiCharacterSpecialCase<1>)  // NOLINT
+         +
+         kEcma262CanonicalizeMultiStrings5Size *
+             sizeof(MultiCharacterSpecialCase<1>)  // NOLINT
+         +
+         kEcma262CanonicalizeMultiStrings7Size *
+             sizeof(MultiCharacterSpecialCase<1>)  // NOLINT
+         +
+         kEcma262UnCanonicalizeMultiStrings0Size *
+             sizeof(MultiCharacterSpecialCase<4>)  // NOLINT
+         +
+         kEcma262UnCanonicalizeMultiStrings1Size *
+             sizeof(MultiCharacterSpecialCase<2>)  // NOLINT
+         +
+         kEcma262UnCanonicalizeMultiStrings5Size *
+             sizeof(MultiCharacterSpecialCase<2>)  // NOLINT
+         +
+         kEcma262UnCanonicalizeMultiStrings7Size *
+             sizeof(MultiCharacterSpecialCase<2>)  // NOLINT
+         +
+         kCanonicalizationRangeMultiStrings0Size *
+             sizeof(MultiCharacterSpecialCase<1>)  // NOLINT
+         +
+         kCanonicalizationRangeMultiStrings1Size *
+             sizeof(MultiCharacterSpecialCase<1>)  // NOLINT
+         +
+         kCanonicalizationRangeMultiStrings7Size *
+             sizeof(MultiCharacterSpecialCase<1>);  // NOLINT
+}
+
+}  // namespace unibrow
diff --git a/runtime/vm/unibrow.h b/runtime/vm/unibrow.h
new file mode 100644
index 0000000..d1f287d
--- /dev/null
+++ b/runtime/vm/unibrow.h
@@ -0,0 +1,76 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+#ifndef VM_UNIBROW_H_
+#define VM_UNIBROW_H_
+
+#include <sys/types.h>
+
+// SNIP
+
+/**
+ * \file
+ * Definitions and convenience functions for working with unicode.
+ */
+
+namespace unibrow {
+
+// SNIP
+
+// A cache used in case conversion.  It caches the value for characters
+// that either have no mapping or map to a single character independent
+// of context.  Characters that map to more than one character or that
+// map differently depending on context are always looked up.
+template <class T, int size = 256>
+class Mapping {
+ public:
+  inline Mapping() { }
+  inline int get(uchar c, uchar n, uchar* result);
+ private:
+  friend class Test;
+  int CalculateValue(uchar c, uchar n, uchar* result);
+  struct CacheEntry {
+    inline CacheEntry() : code_point_(kNoChar), offset_(0) { }
+    inline CacheEntry(uchar code_point, signed offset)
+      : code_point_(code_point),
+        offset_(offset) { }
+    uchar code_point_;
+    signed offset_;
+    static const int kNoChar = (1 << 21) - 1;
+  };
+  static const int kSize = size;
+  static const int kMask = kSize - 1;
+  CacheEntry entries_[kSize];
+};
+
+// SNIP
+
+struct Letter {
+  static bool Is(uchar c);
+};
+struct Ecma262Canonicalize {
+  static const int kMaxWidth = 1;
+  static int Convert(uchar c,
+                     uchar n,
+                     uchar* result,
+                     bool* allow_caching_ptr);
+};
+struct Ecma262UnCanonicalize {
+  static const int kMaxWidth = 4;
+  static int Convert(uchar c,
+                     uchar n,
+                     uchar* result,
+                     bool* allow_caching_ptr);
+};
+struct CanonicalizationRange {
+  static const int kMaxWidth = 1;
+  static int Convert(uchar c,
+                     uchar n,
+                     uchar* result,
+                     bool* allow_caching_ptr);
+};
+
+}  // namespace unibrow
+
+#endif  // VM_UNIBROW_H_
diff --git a/runtime/vm/unit_test.cc b/runtime/vm/unit_test.cc
index 6518b3a..1cb7ccf 100644
--- a/runtime/vm/unit_test.cc
+++ b/runtime/vm/unit_test.cc
@@ -217,11 +217,14 @@
 
 
 void CodeGenTest::Compile() {
+  if (function_.HasCode()) return;
   ParsedFunction* parsed_function =
       new ParsedFunction(Isolate::Current(), function_);
   parsed_function->SetNodeSequence(node_sequence_);
   parsed_function->set_instantiator(NULL);
   parsed_function->set_default_parameter_values(default_parameter_values_);
+  node_sequence_->scope()->AddVariable(
+      parsed_function->current_context_var());
   parsed_function->EnsureExpressionTemp();
   node_sequence_->scope()->AddVariable(parsed_function->expression_temp_var());
   parsed_function->AllocateVariables();
@@ -231,19 +234,6 @@
 }
 
 
-LocalVariable* CodeGenTest::CreateTempConstVariable(const char* name_part) {
-  char name[64];
-  OS::SNPrint(name, 64, ":%s", name_part);
-  LocalVariable* temp =
-      new LocalVariable(0,
-                        String::ZoneHandle(Symbols::New(name)),
-                        Type::ZoneHandle(Type::DynamicType()));
-  temp->set_is_final();
-  node_sequence_->scope()->AddVariable(temp);
-  return temp;
-}
-
-
 bool CompilerTest::TestCompileScript(const Library& library,
                                      const Script& script) {
   Isolate* isolate = Isolate::Current();
diff --git a/runtime/vm/unit_test.h b/runtime/vm/unit_test.h
index 39dfe59..ea4bdd7 100644
--- a/runtime/vm/unit_test.h
+++ b/runtime/vm/unit_test.h
@@ -349,8 +349,6 @@
   // Compile test and set code in function.
   void Compile();
 
-  LocalVariable* CreateTempConstVariable(const char* name_part);
-
  private:
   Function& function_;
   SequenceNode* node_sequence_;
diff --git a/runtime/vm/verified_memory.cc b/runtime/vm/verified_memory.cc
new file mode 100644
index 0000000..a3a3d9e
--- /dev/null
+++ b/runtime/vm/verified_memory.cc
@@ -0,0 +1,36 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for 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/verified_memory.h"
+
+namespace dart {
+
+#if defined(DEBUG)
+
+DEFINE_FLAG(bool, verified_mem, false,
+            "Enable write-barrier verification mode (slow, DEBUG only).");
+DEFINE_FLAG(int, verified_mem_max_reserve_mb, (kWordSize <= 4) ? 16 : 32,
+            "When verified_mem is true, largest supported reservation (MB).");
+
+
+VirtualMemory* VerifiedMemory::ReserveInternal(intptr_t size) {
+  if (size > offset()) {
+    FATAL1("Requested reservation of %" Pd " bytes exceeds the limit. "
+           "Use --verified_mem_max_reserve_mb to increase it.", size);
+  }
+  VirtualMemory* result = VirtualMemory::Reserve(size + offset());
+  if (result != NULL) {
+    // Commit the offset part of the reservation (writable, not executable).
+    result->Commit(result->start() + offset(), size, /* executable = */ false);
+    // Truncate without unmapping, so that the returned object looks like
+    // a normal 'size' bytes reservation (but VirtualMemory will correctly
+    // unmap the entire original reservation on destruction).
+    result->Truncate(size, /* try_unmap = */ false);
+  }
+  return result;
+}
+
+#endif  // DEBUG
+
+}  // namespace dart
diff --git a/runtime/vm/verified_memory.h b/runtime/vm/verified_memory.h
new file mode 100644
index 0000000..45c50e4
--- /dev/null
+++ b/runtime/vm/verified_memory.h
@@ -0,0 +1,88 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+#ifndef VM_VERIFIED_MEMORY_H_
+#define VM_VERIFIED_MEMORY_H_
+
+#include "vm/allocation.h"
+#include "vm/flags.h"
+#include "vm/virtual_memory.h"
+
+namespace dart {
+
+#if defined(DEBUG)
+DECLARE_FLAG(bool, verified_mem);
+DECLARE_FLAG(int, verified_mem_max_reserve_mb);
+#endif
+
+
+// A wrapper around VirtualMemory for verifying that a particular class of
+// memory writes are only performed through a particular interface.
+//
+// The main use case is verifying that storing pointers into objects is only
+// performed by code aware of the GC write barrier.
+//
+// NOTE: Verification is enabled only if 'verified_mem' is true, and this flag
+// only exists in DEBUG builds.
+class VerifiedMemory : public AllStatic {
+ public:
+  // Reserves a block of memory for which all methods in this class may
+  // be called. Returns NULL if out of memory.
+  static VirtualMemory* Reserve(intptr_t size) {
+    return enabled() ? ReserveInternal(size) : VirtualMemory::Reserve(size);
+  }
+
+  // Verifies that [start, start + size) has only been mutated through
+  // methods in this class (or explicitly accepted by calling Accept).
+  static void Verify(uword start, intptr_t size) {
+    if (!enabled()) return;
+    ASSERT(size <= offset());
+    ASSERT(memcmp(reinterpret_cast<void*>(start + offset()),
+                  reinterpret_cast<void*>(start),
+                  size) == 0);
+  }
+
+  // Assigns value to *ptr after verifying previous content at that location.
+  template<typename T>
+  static void Write(T* ptr, const T& value) {
+    if (enabled()) {
+      uword addr = reinterpret_cast<uword>(ptr);
+      Verify(addr, sizeof(T));
+      T* offset_ptr = reinterpret_cast<T*>(addr + offset());
+      *offset_ptr = value;
+    }
+    *ptr = value;
+  }
+
+  // Accepts the current state of [start, start + size), even if it has been
+  // mutated by other means.
+  static void Accept(uword start, intptr_t size) {
+    if (!enabled()) return;
+    ASSERT(size <= offset());
+    memmove(reinterpret_cast<void*>(start + offset()),
+            reinterpret_cast<void*>(start),
+            size);
+  }
+
+ private:
+#if defined(DEBUG)
+  static bool enabled() { return FLAG_verified_mem; }
+  static intptr_t offset() { return FLAG_verified_mem_max_reserve_mb * MB; }
+  static VirtualMemory* ReserveInternal(intptr_t size);
+#else
+  // In release mode, most code in this class is optimized away.
+  static bool enabled() { return false; }
+  static intptr_t offset() { UNREACHABLE(); return -1; }
+  static VirtualMemory* ReserveInternal(intptr_t size) {
+    UNREACHABLE();
+    return NULL;
+  }
+#endif
+
+  friend class Assembler;  // To use enabled/offset when generating code.
+};
+
+}  // namespace dart
+
+#endif  // VM_VERIFIED_MEMORY_H_
diff --git a/runtime/vm/verified_memory_test.cc b/runtime/vm/verified_memory_test.cc
new file mode 100644
index 0000000..681228d
--- /dev/null
+++ b/runtime/vm/verified_memory_test.cc
@@ -0,0 +1,85 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for 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 "platform/assert.h"
+#include "vm/unit_test.h"
+#include "vm/verified_memory.h"
+
+namespace dart {
+
+void Init() {
+#if defined(DEBUG)
+  FLAG_verified_mem = true;
+#endif
+}
+
+
+UNIT_TEST_CASE(VerifiedMemoryBasic) {
+  Init();
+  const intptr_t kReservationSize = 64 * KB;
+  VirtualMemory* vm = VerifiedMemory::Reserve(kReservationSize);
+  EXPECT_EQ(kReservationSize, vm->size());
+  vm->Commit(false);
+  double* addr = reinterpret_cast<double*>(vm->address());
+  VerifiedMemory::Write(&addr[0], 0.5);
+  EXPECT_EQ(0.5, addr[0]);
+  VerifiedMemory::Write(&addr[1], 1.5);
+  VerifiedMemory::Write(&addr[2], 2.5);
+  VerifiedMemory::Write(&addr[0], 0.25);
+  static const double kNaN = NAN;
+  VerifiedMemory::Write(&addr[0], kNaN);  // Bitwise comparison should be used.
+  VerifiedMemory::Write(&addr[0], 0.5);
+  int64_t* unverified = reinterpret_cast<int64_t*>(&addr[3]);
+  *unverified = 123;
+  VerifiedMemory::Verify(reinterpret_cast<uword>(addr), 3 * sizeof(double));
+}
+
+
+UNIT_TEST_CASE(VerifiedMemoryAccept) {
+  Init();
+  const intptr_t kReservationSize = 64 * KB;
+  VirtualMemory* vm = VerifiedMemory::Reserve(kReservationSize);
+  EXPECT_EQ(kReservationSize, vm->size());
+  vm->Commit(false);
+  double* addr = reinterpret_cast<double*>(vm->address());
+  VerifiedMemory::Write(&addr[0], 0.5);
+  VerifiedMemory::Write(&addr[1], 1.5);
+  VerifiedMemory::Write(&addr[2], 2.5);
+  VerifiedMemory::Write(&addr[0], 0.25);
+  // Unverified write followed by Accept ("I know what I'm doing").
+  memset(addr, 0xf3, 2 * sizeof(double));
+  VerifiedMemory::Accept(reinterpret_cast<uword>(addr), 2 * sizeof(double));
+  VerifiedMemory::Verify(reinterpret_cast<uword>(addr), 3 * sizeof(double));
+}
+
+
+// Negative tests below.
+
+UNIT_TEST_CASE(VerifyImplicit_Crash) {
+  Init();
+  const intptr_t kReservationSize = 64 * KB;
+  VirtualMemory* vm = VerifiedMemory::Reserve(kReservationSize);
+  EXPECT_EQ(kReservationSize, vm->size());
+  vm->Commit(false);
+  double* addr = reinterpret_cast<double*>(vm->address());
+  addr[0] = 0.5;  // Forget to use Write.
+  VerifiedMemory::Write(&addr[0], 1.5);
+}
+
+
+UNIT_TEST_CASE(VerifyExplicit_Crash) {
+  Init();
+  const intptr_t kReservationSize = 64 * KB;
+  VirtualMemory* vm = VerifiedMemory::Reserve(kReservationSize);
+  EXPECT_EQ(kReservationSize, vm->size());
+  vm->Commit(false);
+  double* addr = reinterpret_cast<double*>(vm->address());
+  VerifiedMemory::Write(&addr[0], 0.5);
+  VerifiedMemory::Write(&addr[1], 1.5);
+  addr[1] = 3.5;  // Forget to use Write.
+  VerifiedMemory::Write(&addr[2], 2.5);
+  VerifiedMemory::Verify(reinterpret_cast<uword>(addr), 3 * sizeof(double));
+}
+
+}  // namespace dart
diff --git a/runtime/vm/virtual_memory.h b/runtime/vm/virtual_memory.h
index 4f39c80..7909a6e 100644
--- a/runtime/vm/virtual_memory.h
+++ b/runtime/vm/virtual_memory.h
@@ -60,9 +60,14 @@
 
   static bool InSamePage(uword address0, uword address1);
 
-  // Truncate this virtual memory segment.
+  // Truncate this virtual memory segment. If try_unmap is false, the
+  // memory beyond the new end is still accessible, but will be returned
+  // upon destruction.
   void Truncate(intptr_t new_size, bool try_unmap = true);
 
+  // Commit a reserved memory area, so that the memory can be accessed.
+  bool Commit(uword addr, intptr_t size, bool is_executable);
+
  private:
   static VirtualMemory* ReserveInternal(intptr_t size);
 
@@ -76,9 +81,6 @@
       region_(region.pointer(), region.size()),
       reserved_size_(region.size()) { }
 
-  // Commit a reserved memory area, so that the memory can be accessed.
-  bool Commit(uword addr, intptr_t size, bool is_executable);
-
   MemoryRegion region_;
 
   // The size of the underlying reservation not yet given back to the OS.
diff --git a/runtime/vm/vm_sources.gypi b/runtime/vm/vm_sources.gypi
index a490cdd..241b95e 100644
--- a/runtime/vm/vm_sources.gypi
+++ b/runtime/vm/vm_sources.gypi
@@ -436,6 +436,9 @@
     'unit_test.cc',
     'unit_test.h',
     'utils_test.cc',
+    'verified_memory.cc',
+    'verified_memory.h',
+    'verified_memory_test.cc',
     'verifier.cc',
     'verifier.h',
     'virtual_memory.cc',
diff --git a/sdk/lib/_internal/compiler/implementation/apiimpl.dart b/sdk/lib/_internal/compiler/implementation/apiimpl.dart
index 5670d49..fdabf68 100644
--- a/sdk/lib/_internal/compiler/implementation/apiimpl.dart
+++ b/sdk/lib/_internal/compiler/implementation/apiimpl.dart
@@ -77,7 +77,8 @@
             hasIncrementalSupport:
                 forceIncrementalSupport ||
                 hasOption(options, '--incremental-support'),
-            suppressWarnings: hasOption(options, '--suppress-warnings')) {
+            suppressWarnings: hasOption(options, '--suppress-warnings'),
+            enableAsyncAwait: hasOption(options, '--enable-async')) {
     tasks.addAll([
         userHandlerTask = new leg.GenericTask('Diagnostic handler', this),
         userProviderTask = new leg.GenericTask('Input provider', this),
@@ -88,6 +89,10 @@
     if (packageRoot != null && !packageRoot.path.endsWith("/")) {
       throw new ArgumentError("packageRoot must end with a /");
     }
+    if (enableAsyncAwait && !analyzeOnly) {
+      throw new ArgumentError(
+          "--enable-async is currently only supported with --analyze-only");
+    }
   }
 
   static String extractStringOption(List<String> options,
diff --git a/sdk/lib/_internal/compiler/implementation/compiler.dart b/sdk/lib/_internal/compiler/implementation/compiler.dart
index 589baba..fad4298 100644
--- a/sdk/lib/_internal/compiler/implementation/compiler.dart
+++ b/sdk/lib/_internal/compiler/implementation/compiler.dart
@@ -718,6 +718,9 @@
 
   final bool suppressWarnings;
 
+  /// `true` if async/await features are supported.
+  final bool enableAsyncAwait;
+
   /// If `true`, some values are cached for reuse in incremental compilation.
   /// Incremental compilation is basically calling [run] more than once.
   final bool hasIncrementalSupport;
@@ -761,6 +764,9 @@
   ClassElement symbolClass;
   ClassElement stackTraceClass;
   ClassElement typedDataClass;
+  ClassElement futureClass;
+  ClassElement iterableClass;
+  ClassElement streamClass;
 
   /// The constant for the [proxy] variable defined in dart:core.
   ConstantValue proxyConstant;
@@ -958,6 +964,7 @@
             this.useContentSecurityPolicy: false,
             this.suppressWarnings: false,
             bool hasIncrementalSupport: false,
+            this.enableAsyncAwait: false,
             api.CompilerOutputProvider outputProvider,
             List<String> strips: const []})
       : this.disableTypeInferenceFlag =
@@ -1075,6 +1082,8 @@
       return node;
     } else if (node is Node) {
       return spanFromNode(node);
+    } else if (node is TokenPair) {
+      return spanFromTokens(node.begin, node.end);
     } else if (node is Token) {
       return spanFromTokens(node, node);
     } else if (node is HInstruction) {
@@ -1190,6 +1199,8 @@
       mirrorsUsedClass = findRequiredElement(library, 'MirrorsUsed');
     } else if (uri == DART_ASYNC) {
       deferredLibraryClass = findRequiredElement(library, 'DeferredLibrary');
+      futureClass = findRequiredElement(library, 'Future');
+      streamClass = findRequiredElement(library, 'Stream');
     } else if (uri == DART_NATIVE_TYPED_DATA) {
       typedDataClass = findRequiredElement(library, 'NativeTypedData');
     } else if (uri == js_backend.JavaScriptBackend.DART_JS_HELPER) {
@@ -1286,6 +1297,7 @@
     mapClass = lookupCoreClass('Map');
     nullClass = lookupCoreClass('Null');
     stackTraceClass = lookupCoreClass('StackTrace');
+    iterableClass = lookupCoreClass('Iterable');
     symbolClass = lookupCoreClass('Symbol');
     if (!missingCoreClasses.isEmpty) {
       internalError(coreLibrary,
diff --git a/sdk/lib/_internal/compiler/implementation/cps_ir/constant_propagation.dart b/sdk/lib/_internal/compiler/implementation/cps_ir/constant_propagation.dart
index 7944c03..985cd27 100644
--- a/sdk/lib/_internal/compiler/implementation/cps_ir/constant_propagation.dart
+++ b/sdk/lib/_internal/compiler/implementation/cps_ir/constant_propagation.dart
@@ -492,7 +492,7 @@
       setValue(returnValue, updateValue);
     }
 
-    if (node.operator != "is") {
+    if (node.isTypeCast) {
       // TODO(jgruber): Add support for `as` casts.
       setValues(_ConstnessLattice.NonConst);
     }
diff --git a/sdk/lib/_internal/compiler/implementation/cps_ir/cps_ir_builder.dart b/sdk/lib/_internal/compiler/implementation/cps_ir/cps_ir_builder.dart
index 5a006dc..d1605c8 100644
--- a/sdk/lib/_internal/compiler/implementation/cps_ir/cps_ir_builder.dart
+++ b/sdk/lib/_internal/compiler/implementation/cps_ir/cps_ir_builder.dart
@@ -127,6 +127,9 @@
   }
 }
 
+/// Function for building a node in the context of the current builder.
+typedef ir.Node BuildFunction(node);
+
 /// Function for building nodes in the context of the provided [builder].
 typedef ir.Node SubbuildFunction(IrBuilder builder);
 
@@ -340,7 +343,7 @@
     }
   }
 
-  ir.Primitive continueWithExpression(ir.Expression build(ir.Continuation k)) {
+  ir.Primitive _continueWithExpression(ir.Expression build(ir.Continuation k)) {
     ir.Parameter v = new ir.Parameter(null);
     ir.Continuation k = new ir.Continuation([v]);
     ir.Expression expression = build(k);
@@ -348,6 +351,30 @@
     return v;
   }
 
+  ir.Primitive _buildInvokeStatic(Element element,
+                                  Selector selector,
+                                  List<ir.Definition> arguments) {
+    assert(isOpen);
+    return _continueWithExpression(
+        (k) => new ir.InvokeStatic(element, selector, k, arguments));
+  }
+
+  ir.Primitive _buildInvokeSuper(Selector selector,
+                                 List<ir.Definition> arguments) {
+    assert(isOpen);
+    return _continueWithExpression(
+        (k) => new ir.InvokeSuperMethod(selector, k, arguments));
+  }
+
+  ir.Primitive _buildInvokeDynamic(ir.Primitive receiver,
+                                   Selector selector,
+                                   List<ir.Definition> arguments) {
+    assert(isOpen);
+    return _continueWithExpression(
+        (k) => new ir.InvokeMethod(receiver, selector, k, arguments));
+  }
+
+
   /// Create a constant literal from [constant].
   ir.Constant buildConstantLiteral(ConstantExpression constant) {
     assert(isOpen);
@@ -387,6 +414,36 @@
         state.constantSystem.createString(new ast.DartString.literal(value)));
   }
 
+  /// Creates a non-constant list literal of the provided [type] and with the
+  /// provided [values].
+  ir.Primitive buildListLiteral(InterfaceType type,
+                                Iterable<ir.Primitive> values) {
+    assert(isOpen);
+    ir.Primitive result = new ir.LiteralList(type, values);
+    add(new ir.LetPrim(result));
+    return result;
+  }
+
+  /// Creates a non-constant map literal of the provided [type] and with the
+  /// entries build from the [keys] and [values] using [build].
+  ir.Primitive buildMapLiteral(InterfaceType type,
+                               Iterable keys,
+                               Iterable values,
+                               BuildFunction build) {
+    assert(isOpen);
+    List<ir.LiteralMapEntry> entries = <ir.LiteralMapEntry>[];
+    Iterator key = keys.iterator;
+    Iterator value = values.iterator;
+    while (key.moveNext() && value.moveNext()) {
+      entries.add(new ir.LiteralMapEntry(
+          build(key.current), build(value.current)));
+    }
+    assert(!key.moveNext() && !value.moveNext());
+    ir.Primitive result = new ir.LiteralMap(type, entries);
+    add(new ir.LetPrim(result));
+    return result;
+  }
+
   /// Creates a conditional expression with the provided [condition] where the
   /// then and else expression are created through the [buildThenExpression] and
   /// [buildElseExpression] functions, respectively.
@@ -437,55 +494,12 @@
 
   }
 
-  /// Create a read access of [local].
-  ir.Primitive buildLocalGet(LocalElement local) {
-    assert(isOpen);
-    if (isClosureVariable(local)) {
-      ir.Primitive result = new ir.GetClosureVariable(local);
-      add(new ir.LetPrim(result));
-      return result;
-    } else {
-      return environment.lookup(local);
-    }
-  }
-
-  /// Create a write access to [local].
-  ir.Primitive buildLocalSet(LocalElement local, ir.Primitive valueToStore) {
-    assert(isOpen);
-    if (isClosureVariable(local)) {
-      add(new ir.SetClosureVariable(local, valueToStore));
-    } else {
-      valueToStore.useElementAsHint(local);
-      environment.update(local, valueToStore);
-    }
-    return valueToStore;
-  }
-
-  /// Create a get access of the static [element].
-  ir.Primitive buildStaticGet(Element element, Selector selector) {
-    assert(isOpen);
-    assert(selector.isGetter);
-    return continueWithExpression(
-        (k) => new ir.InvokeStatic(
-            element, selector, k, const <ir.Definition>[]));
-  }
-
-  /// Create a dynamic get access on [receiver] where the property is defined
-  /// by the getter [selector].
-  ir.Primitive buildDynamicGet(ir.Primitive receiver, Selector selector) {
-    assert(isOpen);
-    assert(selector.isGetter);
-    return continueWithExpression(
-        (k) => new ir.InvokeMethod(
-            receiver, selector, k, const <ir.Definition>[]));
-  }
-
   /**
    * Add an explicit `return null` for functions that don't have a return
    * statement on each branch. This includes functions with an empty body,
    * such as `foo(){ }`.
    */
-  void ensureReturn() {
+  void _ensureReturn() {
     if (!isOpen) return;
     ir.Constant constant = buildNullLiteral();
     add(new ir.InvokeContinuation(state.returnContinuation, [constant]));
@@ -500,7 +514,7 @@
       FunctionElement element,
       List<ConstantExpression> defaults) {
     if (!element.isAbstract) {
-      ensureReturn();
+      _ensureReturn();
       return new ir.FunctionDefinition(
           element, state.returnContinuation, _parameters, _root,
           state.localConstants, defaults);
@@ -516,48 +530,141 @@
   }
 
 
-  /// Create a super invocation with method name and arguments structure defined
-  /// by [selector] and argument values defined by [arguments].
+  /// Create a super invocation where the method name and the argument structure
+  /// are defined by [selector] and the argument values are defined by
+  /// [arguments].
   ir.Primitive buildSuperInvocation(Selector selector,
                                     List<ir.Definition> arguments) {
-    assert(isOpen);
-    return continueWithExpression(
-        (k) => new ir.InvokeSuperMethod(selector, k, arguments));
-
+    return _buildInvokeSuper(selector, arguments);
   }
 
-  /// Create a dynamic invocation on [receiver] with method name and argument
-  /// structure defined by [selector] and argument values defined by
-  /// [arguments].
+  /// Create a getter invocation on the super class where the getter name is
+  /// defined by [selector].
+  ir.Primitive buildSuperGet(Selector selector) {
+    assert(selector.isGetter);
+    return _buildInvokeSuper(selector, const <ir.Definition>[]);
+  }
+
+  /// Create a setter invocation on the super class where the setter name and
+  /// argument are defined by [selector] and [value], respectively.
+  ir.Primitive buildSuperSet(Selector selector, ir.Primitive value) {
+    assert(selector.isSetter);
+    _buildInvokeSuper(selector, <ir.Definition>[value]);
+    return value;
+  }
+
+  /// Create an index set invocation on the super class with the provided
+  /// [index] and [value].
+  ir.Primitive buildSuperIndexSet(ir.Primitive index,
+                                  ir.Primitive value) {
+    _buildInvokeSuper(new Selector.indexSet(), <ir.Definition>[index, value]);
+    return value;
+  }
+
+  /// Create a dynamic invocation on [receiver] where the method name and
+  /// argument structure are defined by [selector] and the argument values are
+  /// defined by [arguments].
   ir.Primitive buildDynamicInvocation(ir.Definition receiver,
                                       Selector selector,
                                       List<ir.Definition> arguments) {
-    assert(isOpen);
-    return continueWithExpression(
-        (k) => new ir.InvokeMethod(receiver, selector, k, arguments));
+    return _buildInvokeDynamic(receiver, selector, arguments);
   }
 
-  /// Create a static invocation of [element] with argument structure defined
-  /// by [selector] and argument values defined by [arguments].
+  /// Create a dynamic getter invocation on [receiver] where the getter name is
+  /// defined by [selector].
+  ir.Primitive buildDynamicGet(ir.Primitive receiver, Selector selector) {
+    assert(selector.isGetter);
+    return _buildInvokeDynamic(receiver, selector, const <ir.Definition>[]);
+  }
+
+  /// Create a dynamic setter invocation on [receiver] where the setter name and
+  /// argument are defined by [selector] and [value], respectively.
+  ir.Primitive buildDynamicSet(ir.Primitive receiver,
+                               Selector selector,
+                               ir.Primitive value) {
+    assert(selector.isSetter);
+    _buildInvokeDynamic(receiver, selector, <ir.Definition>[value]);
+    return value;
+  }
+
+  /// Create a dynamic index set invocation on [receiver] with the provided
+  /// [index] and [value].
+  ir.Primitive  buildDynamicIndexSet(ir.Primitive receiver,
+                                     ir.Primitive index,
+                                     ir.Primitive value) {
+    _buildInvokeDynamic(
+        receiver, new Selector.indexSet(), <ir.Definition>[index, value]);
+    return value;
+  }
+
+  /// Create a static invocation of [element] where argument structure is
+  /// defined by [selector] and the argument values are defined by [arguments].
   ir.Primitive buildStaticInvocation(Element element,
                                      Selector selector,
                                      List<ir.Definition> arguments) {
-    return continueWithExpression(
-        (k) => new ir.InvokeStatic(element, selector, k, arguments));
+    return _buildInvokeStatic(element, selector, arguments);
   }
 
-  /// Create a constructor invocation of [element] on [type] with argument
-  /// structure defined by [selector] and argument values defined by
-  /// [arguments].
+  /// Create a static getter invocation of [element] where the getter name is
+  /// defined by [selector].
+  ir.Primitive buildStaticGet(Element element, Selector selector) {
+    assert(selector.isGetter);
+    return _buildInvokeStatic(element, selector, const <ir.Definition>[]);
+  }
+
+  /// Create a static setter invocation of [element] where the setter name and
+  /// argument are defined by [selector] and [value], respectively.
+  ir.Primitive buildStaticSet(Element element,
+                              Selector selector,
+                              ir.Primitive value) {
+    assert(selector.isSetter);
+    _buildInvokeStatic(element, selector, <ir.Definition>[value]);
+    return value;
+  }
+
+  /// Create a constructor invocation of [element] on [type] where the
+  /// constructor name and argument structure are defined by [selector] and the
+  /// argument values are defined by [arguments].
   ir.Primitive buildConstructorInvocation(FunctionElement element,
-                                         Selector selector,
-                                         DartType type,
-                                         List<ir.Definition> arguments) {
+                                          Selector selector,
+                                          DartType type,
+                                          List<ir.Definition> arguments) {
     assert(isOpen);
-    return continueWithExpression(
+    return _continueWithExpression(
         (k) => new ir.InvokeConstructor(type, element, selector, k, arguments));
   }
 
+  /// Create a string concatenation of the [arguments].
+  ir.Primitive buildStringConcatenation(List<ir.Definition> arguments) {
+    assert(isOpen);
+    return _continueWithExpression(
+        (k) => new ir.ConcatenateStrings(k, arguments));
+  }
+
+  /// Create a read access of [local].
+  ir.Primitive buildLocalGet(LocalElement local) {
+    assert(isOpen);
+    if (isClosureVariable(local)) {
+      ir.Primitive result = new ir.GetClosureVariable(local);
+      add(new ir.LetPrim(result));
+      return result;
+    } else {
+      return environment.lookup(local);
+    }
+  }
+
+  /// Create a write access to [local] with the provided [value].
+  ir.Primitive buildLocalSet(LocalElement local, ir.Primitive value) {
+    assert(isOpen);
+    if (isClosureVariable(local)) {
+      add(new ir.SetClosureVariable(local, value));
+    } else {
+      value.useElementAsHint(local);
+      environment.update(local, value);
+    }
+    return value;
+  }
+
   /// Creates an if-then-else statement with the provided [condition] where the
   /// then and else branches are created through the [buildThenPart] and
   /// [buildElsePart] functions, respectively.
@@ -777,6 +884,217 @@
     }
   }
 
+  /// Creates a for-in loop, `for (v in e) b`.
+  ///
+  /// [buildExpression] creates the expression, `e`. The variable, `v`, can
+  /// take one of three forms:
+  ///     1) `v` can be declared within the for-in statement, like in
+  ///        `for (var v in e)`, in which case, [buildVariableDeclaration]
+  ///        creates its declaration and [variableElement] is the element for
+  ///        the declared variable,
+  ///     2) `v` is predeclared statically known variable, that is top-level,
+  ///        static, or local variable, in which case [variableElement] is the
+  ///        variable element, and [variableSelector] defines its write access,
+  ///     3) `v` is an instance variable in which case [variableSelector]
+  ///        defines its write access.
+  /// [buildBody] creates the body, `b`, of the loop. The jump [target] is used
+  /// to identify which `break` and `continue` statements that have this for-in
+  /// statement as their target.
+  void buildForIn({SubbuildFunction buildExpression,
+                   SubbuildFunction buildVariableDeclaration,
+                   Element variableElement,
+                   Selector variableSelector,
+                   SubbuildFunction buildBody,
+                   JumpTarget target}) {
+    // The for-in loop
+    //
+    // for (a in e) s;
+    //
+    // Is compiled analogously to:
+    //
+    // a = e.iterator;
+    // while (a.moveNext()) {
+    //   var n0 = a.current;
+    //   s;
+    // }
+
+    // The condition and body are delimited.
+    IrBuilder condBuilder = new IrBuilder.recursive(this);
+
+    ir.Primitive expressionReceiver = buildExpression(this);
+    List<ir.Primitive> emptyArguments = new List<ir.Primitive>();
+
+    ir.Parameter iterator = new ir.Parameter(null);
+    ir.Continuation iteratorInvoked = new ir.Continuation([iterator]);
+    add(new ir.LetCont(iteratorInvoked,
+        new ir.InvokeMethod(expressionReceiver,
+            new Selector.getter("iterator", null), iteratorInvoked,
+            emptyArguments)));
+
+    ir.Parameter condition = new ir.Parameter(null);
+    ir.Continuation moveNextInvoked = new ir.Continuation([condition]);
+    condBuilder.add(new ir.LetCont(moveNextInvoked,
+        new ir.InvokeMethod(iterator,
+            new Selector.call("moveNext", null, 0),
+            moveNextInvoked, emptyArguments)));
+
+    JumpCollector breakCollector = new JumpCollector(target);
+    JumpCollector continueCollector = new JumpCollector(target);
+    state.breakCollectors.add(breakCollector);
+    state.continueCollectors.add(continueCollector);
+
+    IrBuilder bodyBuilder = new IrBuilder.delimited(condBuilder);
+    if (buildVariableDeclaration != null) {
+      buildVariableDeclaration(bodyBuilder);
+    }
+
+    ir.Parameter currentValue = new ir.Parameter(null);
+    ir.Continuation currentInvoked = new ir.Continuation([currentValue]);
+    bodyBuilder.add(new ir.LetCont(currentInvoked,
+        new ir.InvokeMethod(iterator, new Selector.getter("current", null),
+            currentInvoked, emptyArguments)));
+    if (Elements.isLocal(variableElement)) {
+      bodyBuilder.buildLocalSet(variableElement, currentValue);
+    } else if (Elements.isStaticOrTopLevel(variableElement)) {
+      bodyBuilder.buildStaticSet(
+          variableElement, variableSelector, currentValue);
+    } else {
+      ir.Primitive receiver = bodyBuilder.buildThis();
+      bodyBuilder.buildDynamicSet(receiver, variableSelector, currentValue);
+    }
+
+    buildBody(bodyBuilder);
+    assert(state.breakCollectors.last == breakCollector);
+    assert(state.continueCollectors.last == continueCollector);
+    state.breakCollectors.removeLast();
+    state.continueCollectors.removeLast();
+
+    // Create body entry and loop exit continuations and a branch to them.
+    ir.Continuation bodyContinuation = new ir.Continuation([]);
+    ir.Continuation exitContinuation = new ir.Continuation([]);
+    ir.LetCont branch =
+        new ir.LetCont(exitContinuation,
+            new ir.LetCont(bodyContinuation,
+                new ir.Branch(new ir.IsTrue(condition),
+                              bodyContinuation,
+                              exitContinuation)));
+    // If there are breaks in the body, then there must be a join-point
+    // continuation for the normal exit and the breaks.
+    bool hasBreaks = !breakCollector.isEmpty;
+    ir.LetCont letJoin;
+    if (hasBreaks) {
+      letJoin = new ir.LetCont(null, branch);
+      condBuilder.add(letJoin);
+      condBuilder._current = branch;
+    } else {
+      condBuilder.add(branch);
+    }
+    ir.Continuation loopContinuation =
+        new ir.Continuation(condBuilder._parameters);
+    if (bodyBuilder.isOpen) continueCollector.addJump(bodyBuilder);
+    invokeFullJoin(
+        loopContinuation, continueCollector, recursive: true);
+    bodyContinuation.body = bodyBuilder._root;
+
+    loopContinuation.body = condBuilder._root;
+    add(new ir.LetCont(loopContinuation,
+            new ir.InvokeContinuation(loopContinuation,
+                                      environment.index2value)));
+    if (hasBreaks) {
+      _current = branch;
+      environment = condBuilder.environment;
+      breakCollector.addJump(this);
+      letJoin.continuation = createJoin(environment.length, breakCollector);
+      _current = letJoin;
+    } else {
+      _current = condBuilder._current;
+      environment = condBuilder.environment;
+    }
+  }
+
+  /// Creates a while loop in which the condition and body are created by
+  /// [buildCondition] and [buildBody], respectively.
+  ///
+  /// The jump [target] is used to identify which `break` and `continue`
+  /// statements that have this `while` statement as their target.
+  void buildWhile({SubbuildFunction buildCondition,
+                   SubbuildFunction buildBody,
+                   JumpTarget target}) {
+    assert(isOpen);
+    // While loops use four named continuations: the entry to the body, the
+    // loop exit, the loop back edge (continue), and the loop exit (break).
+    // The CPS translation of [[while (condition) body; successor]] is:
+    //
+    // let cont continue(x, ...) =
+    //     let prim cond = [[condition]] in
+    //     let cont break() = [[successor]] in
+    //     let cont exit() = break(v, ...) in
+    //     let cont body() = [[body]]; continue(v, ...) in
+    //     branch cond (body, exit) in
+    // continue(v, ...)
+    //
+    // If there are no breaks in the body, the break continuation is inlined
+    // in the exit continuation (i.e., the translation of the successor
+    // statement occurs in the exit continuation).
+
+    // The condition and body are delimited.
+    IrBuilder condBuilder = new IrBuilder.recursive(this);
+    ir.Primitive condition = buildCondition(condBuilder);
+
+    JumpCollector breakCollector = new JumpCollector(target);
+    JumpCollector continueCollector = new JumpCollector(target);
+    state.breakCollectors.add(breakCollector);
+    state.continueCollectors.add(continueCollector);
+
+    IrBuilder bodyBuilder = new IrBuilder.delimited(condBuilder);
+    buildBody(bodyBuilder);
+    assert(state.breakCollectors.last == breakCollector);
+    assert(state.continueCollectors.last == continueCollector);
+    state.breakCollectors.removeLast();
+    state.continueCollectors.removeLast();
+
+    // Create body entry and loop exit continuations and a branch to them.
+    ir.Continuation bodyContinuation = new ir.Continuation([]);
+    ir.Continuation exitContinuation = new ir.Continuation([]);
+    ir.LetCont branch =
+        new ir.LetCont(exitContinuation,
+            new ir.LetCont(bodyContinuation,
+                new ir.Branch(new ir.IsTrue(condition),
+                              bodyContinuation,
+                              exitContinuation)));
+    // If there are breaks in the body, then there must be a join-point
+    // continuation for the normal exit and the breaks.
+    bool hasBreaks = !breakCollector.isEmpty;
+    ir.LetCont letJoin;
+    if (hasBreaks) {
+      letJoin = new ir.LetCont(null, branch);
+      condBuilder.add(letJoin);
+      condBuilder._current = branch;
+    } else {
+      condBuilder.add(branch);
+    }
+    ir.Continuation loopContinuation =
+        new ir.Continuation(condBuilder._parameters);
+    if (bodyBuilder.isOpen) continueCollector.addJump(bodyBuilder);
+    invokeFullJoin(loopContinuation, continueCollector, recursive: true);
+    bodyContinuation.body = bodyBuilder._root;
+
+    loopContinuation.body = condBuilder._root;
+    add(new ir.LetCont(loopContinuation,
+            new ir.InvokeContinuation(loopContinuation,
+                                      environment.index2value)));
+    if (hasBreaks) {
+      _current = branch;
+      environment = condBuilder.environment;
+      breakCollector.addJump(this);
+      letJoin.continuation = createJoin(environment.length, breakCollector);
+      _current = letJoin;
+    } else {
+      _current = condBuilder._current;
+      environment = condBuilder.environment;
+    }
+  }
+
   /// Create a return statement `return value;` or `return;` if [value] is
   /// null.
   void buildReturn([ir.Primitive value]) {
@@ -796,7 +1114,7 @@
   /// statements. The first statement is assumed to be reachable.
   // TODO(johnniwinther): Type [statements] as `Iterable` when `NodeList` uses
   // `List` instead of `Link`.
-  void buildBlock(var statements, build(statement)) {
+  void buildBlock(var statements, BuildFunction build) {
     // Build(Block(stamements), C) = C'
     //   where C' = statements.fold(Build, C)
     assert(isOpen);
@@ -808,7 +1126,7 @@
   /// The first node in the sequence does not need to be reachable.
   // TODO(johnniwinther): Type [nodes] as `Iterable` when `NodeList` uses
   // `List` instead of `Link`.
-  void buildSequence(var nodes, build(node)) {
+  void buildSequence(var nodes, BuildFunction build) {
     for (var node in nodes) {
       if (!isOpen) return;
       build(node);
@@ -877,6 +1195,23 @@
     return resultParameter;
   }
 
+  /// Creates a type test or type cast of [receiver] against [type].
+  ///
+  /// Set [isTypeTest] to `true` to create a type test and furthermore set
+  /// [isNotCheck] to `true` to create a negated type test.
+  ir.Primitive buildTypeOperator(ir.Primitive receiver,
+                                 DartType type,
+                                 {bool isTypeTest: false,
+                                  bool isNotCheck: false}) {
+    assert(isOpen);
+    assert(isTypeTest != null);
+    assert(!isNotCheck || isTypeTest);
+    ir.Primitive check = _continueWithExpression(
+        (k) => new ir.TypeOperator(receiver, type, k, isTypeTest: isTypeTest));
+    return isNotCheck ? buildNegation(check) : check;
+
+  }
+
   /// Create a lazy and/or expression. [leftValue] is the value of the left
   /// operand and [buildRightValue] is called to process the value of the right
   /// operand in the context of its own [IrBuilder].
@@ -962,6 +1297,14 @@
     return joinContinuation.parameters.last;
   }
 
+  /// Creates an access to `this`.
+  ir.Primitive buildThis() {
+    assert(isOpen);
+    ir.Primitive result = new ir.This();
+    add(new ir.LetPrim(result));
+    return result;
+  }
+
   /// Create a non-recursive join-point continuation.
   ///
   /// Given the environment length at the join point and a list of
diff --git a/sdk/lib/_internal/compiler/implementation/cps_ir/cps_ir_builder_visitor.dart b/sdk/lib/_internal/compiler/implementation/cps_ir/cps_ir_builder_visitor.dart
index 085a1c6..162c38a 100644
--- a/sdk/lib/_internal/compiler/implementation/cps_ir/cps_ir_builder_visitor.dart
+++ b/sdk/lib/_internal/compiler/implementation/cps_ir/cps_ir_builder_visitor.dart
@@ -245,206 +245,30 @@
         : giveup(node, 'labeled statement');
   }
 
-  ir.Primitive visitWhile(ast.While node) {
-    assert(irBuilder.isOpen);
-    // While loops use four named continuations: the entry to the body, the
-    // loop exit, the loop back edge (continue), and the loop exit (break).
-    // The CPS translation of [[while (condition) body; successor]] is:
-    //
-    // let cont continue(x, ...) =
-    //     let prim cond = [[condition]] in
-    //     let cont break() = [[successor]] in
-    //     let cont exit() = break(v, ...) in
-    //     let cont body() = [[body]]; continue(v, ...) in
-    //     branch cond (body, exit) in
-    // continue(v, ...)
-    //
-    // If there are no breaks in the body, the break continuation is inlined
-    // in the exit continuation (i.e., the translation of the successor
-    // statement occurs in the exit continuation).
-
-    // The condition and body are delimited.
-    IrBuilder condBuilder = new IrBuilder.recursive(irBuilder);
-    ir.Primitive condition =
-        withBuilder(condBuilder, () => visit(node.condition));
-
-    JumpTarget target = elements.getTargetDefinition(node);
-    JumpCollector breakCollector = new JumpCollector(target);
-    JumpCollector continueCollector = new JumpCollector(target);
-    irBuilder.state.breakCollectors.add(breakCollector);
-    irBuilder.state.continueCollectors.add(continueCollector);
-
-    IrBuilder bodyBuilder = new IrBuilder.delimited(condBuilder);
-    withBuilder(bodyBuilder, () => visit(node.body));
-    assert(irBuilder.state.breakCollectors.last == breakCollector);
-    assert(irBuilder.state.continueCollectors.last == continueCollector);
-    irBuilder.state.breakCollectors.removeLast();
-    irBuilder.state.continueCollectors.removeLast();
-
-    // Create body entry and loop exit continuations and a branch to them.
-    ir.Continuation bodyContinuation = new ir.Continuation([]);
-    ir.Continuation exitContinuation = new ir.Continuation([]);
-    ir.LetCont branch =
-        new ir.LetCont(exitContinuation,
-            new ir.LetCont(bodyContinuation,
-                new ir.Branch(new ir.IsTrue(condition),
-                              bodyContinuation,
-                              exitContinuation)));
-    // If there are breaks in the body, then there must be a join-point
-    // continuation for the normal exit and the breaks.
-    bool hasBreaks = !breakCollector.isEmpty;
-    ir.LetCont letJoin;
-    if (hasBreaks) {
-      letJoin = new ir.LetCont(null, branch);
-      condBuilder.add(letJoin);
-      condBuilder._current = branch;
-    } else {
-      condBuilder.add(branch);
-    }
-    ir.Continuation loopContinuation =
-        new ir.Continuation(condBuilder._parameters);
-    if (bodyBuilder.isOpen) continueCollector.addJump(bodyBuilder);
-    irBuilder.invokeFullJoin(
-        loopContinuation, continueCollector, recursive: true);
-    bodyContinuation.body = bodyBuilder._root;
-
-    loopContinuation.body = condBuilder._root;
-    irBuilder.add(new ir.LetCont(loopContinuation,
-            new ir.InvokeContinuation(loopContinuation,
-                                      irBuilder.environment.index2value)));
-    if (hasBreaks) {
-      irBuilder._current = branch;
-      irBuilder.environment = condBuilder.environment;
-      breakCollector.addJump(irBuilder);
-      letJoin.continuation =
-          irBuilder.createJoin(irBuilder.environment.length, breakCollector);
-      irBuilder._current = letJoin;
-    } else {
-      irBuilder._current = condBuilder._current;
-      irBuilder.environment = condBuilder.environment;
-    }
-    return null;
+  visitWhile(ast.While node) {
+    irBuilder.buildWhile(
+        buildCondition: subbuild(node.condition),
+        buildBody: subbuild(node.body),
+        target: elements.getTargetDefinition(node));
   }
 
-  ir.Primitive visitForIn(ast.ForIn node) {
-    // The for-in loop
-    //
-    // for (a in e) s;
-    //
-    // Is compiled analogously to:
-    //
-    // a = e.iterator;
-    // while (a.moveNext()) {
-    //   var n0 = a.current;
-    //   s;
-    // }
-
-    // The condition and body are delimited.
-    IrBuilder condBuilder = new IrBuilder.recursive(irBuilder);
-
-    ir.Primitive expressionReceiver = visit(node.expression);
-    List<ir.Primitive> emptyArguments = new List<ir.Primitive>();
-
-    ir.Parameter iterator = new ir.Parameter(null);
-    ir.Continuation iteratorInvoked = new ir.Continuation([iterator]);
-    irBuilder.add(new ir.LetCont(iteratorInvoked,
-        new ir.InvokeMethod(expressionReceiver,
-            new Selector.getter("iterator", null), iteratorInvoked,
-            emptyArguments)));
-
-    ir.Parameter condition = new ir.Parameter(null);
-    ir.Continuation moveNextInvoked = new ir.Continuation([condition]);
-    condBuilder.add(new ir.LetCont(moveNextInvoked,
-        new ir.InvokeMethod(iterator,
-            new Selector.call("moveNext", null, 0),
-            moveNextInvoked, emptyArguments)));
-
-    JumpTarget target = elements.getTargetDefinition(node);
-    JumpCollector breakCollector = new JumpCollector(target);
-    JumpCollector continueCollector = new JumpCollector(target);
-    irBuilder.state.breakCollectors.add(breakCollector);
-    irBuilder.state.continueCollectors.add(continueCollector);
-
-    IrBuilder bodyBuilder = new IrBuilder.delimited(condBuilder);
+  visitForIn(ast.ForIn node) {
+    // [node.declaredIdentifier] can be either an [ast.VariableDefinitions]
+    // (defining a new local variable) or a send designating some existing
+    // variable.
     ast.Node identifier = node.declaredIdentifier;
+    ast.VariableDefinitions variableDeclaration =
+        identifier.asVariableDefinitions();
     Element variableElement = elements.getForInVariable(node);
     Selector selector = elements.getSelector(identifier);
 
-    // node.declaredIdentifier can be either an ast.VariableDefinitions
-    // (defining a new local variable) or a send designating some existing
-    // variable.
-    ast.Node declaredIdentifier = node.declaredIdentifier;
-
-    if (declaredIdentifier is ast.VariableDefinitions) {
-      withBuilder(bodyBuilder, () => visit(declaredIdentifier));
-    }
-
-    ir.Parameter currentValue = new ir.Parameter(null);
-    ir.Continuation currentInvoked = new ir.Continuation([currentValue]);
-    bodyBuilder.add(new ir.LetCont(currentInvoked,
-        new ir.InvokeMethod(iterator, new Selector.getter("current", null),
-            currentInvoked, emptyArguments)));
-    if (Elements.isLocal(variableElement)) {
-      bodyBuilder.buildLocalSet(variableElement, currentValue);
-    } else if (Elements.isStaticOrTopLevel(variableElement)) {
-      withBuilder(bodyBuilder,
-          () => setStatic(variableElement, selector, currentValue));
-    } else {
-      ir.Primitive receiver =
-          withBuilder(bodyBuilder, () => lookupThis());
-      withBuilder(bodyBuilder,
-          () => setDynamic(null, receiver, selector, currentValue));
-    }
-
-    withBuilder(bodyBuilder, () => visit(node.body));
-    assert(irBuilder.state.breakCollectors.last == breakCollector);
-    assert(irBuilder.state.continueCollectors.last == continueCollector);
-    irBuilder.state.breakCollectors.removeLast();
-    irBuilder.state.continueCollectors.removeLast();
-
-    // Create body entry and loop exit continuations and a branch to them.
-    ir.Continuation bodyContinuation = new ir.Continuation([]);
-    ir.Continuation exitContinuation = new ir.Continuation([]);
-    ir.LetCont branch =
-        new ir.LetCont(exitContinuation,
-            new ir.LetCont(bodyContinuation,
-                new ir.Branch(new ir.IsTrue(condition),
-                              bodyContinuation,
-                              exitContinuation)));
-    // If there are breaks in the body, then there must be a join-point
-    // continuation for the normal exit and the breaks.
-    bool hasBreaks = !breakCollector.isEmpty;
-    ir.LetCont letJoin;
-    if (hasBreaks) {
-      letJoin = new ir.LetCont(null, branch);
-      condBuilder.add(letJoin);
-      condBuilder._current = branch;
-    } else {
-      condBuilder.add(branch);
-    }
-    ir.Continuation loopContinuation =
-        new ir.Continuation(condBuilder._parameters);
-    if (bodyBuilder.isOpen) continueCollector.addJump(bodyBuilder);
-    irBuilder.invokeFullJoin(
-        loopContinuation, continueCollector, recursive: true);
-    bodyContinuation.body = bodyBuilder._root;
-
-    loopContinuation.body = condBuilder._root;
-    irBuilder.add(new ir.LetCont(loopContinuation,
-            new ir.InvokeContinuation(loopContinuation,
-                                      irBuilder.environment.index2value)));
-    if (hasBreaks) {
-      irBuilder._current = branch;
-      irBuilder.environment = condBuilder.environment;
-      breakCollector.addJump(irBuilder);
-      letJoin.continuation =
-          irBuilder.createJoin(irBuilder.environment.length, breakCollector);
-      irBuilder._current = letJoin;
-    } else {
-      irBuilder._current = condBuilder._current;
-      irBuilder.environment = condBuilder.environment;
-    }
-    return null;
+    irBuilder.buildForIn(
+        buildExpression: subbuild(node.expression),
+        buildVariableDeclaration: subbuild(variableDeclaration),
+        variableElement: variableElement,
+        variableSelector: selector,
+        buildBody: subbuild(node.body),
+        target: elements.getTargetDefinition(node));
   }
 
   ir.Primitive visitVariableDefinitions(ast.VariableDefinitions node) {
@@ -539,32 +363,24 @@
   }
 
   ir.Primitive visitLiteralList(ast.LiteralList node) {
-    assert(irBuilder.isOpen);
     if (node.isConst) {
       return translateConstant(node);
     }
     List<ir.Primitive> values = node.elements.nodes.mapToList(visit);
-    GenericType type = elements.getType(node);
-    ir.Primitive result = new ir.LiteralList(type, values);
-    irBuilder.add(new ir.LetPrim(result));
-    return result;
+    InterfaceType type = elements.getType(node);
+    return irBuilder.buildListLiteral(type, values);
   }
 
   ir.Primitive visitLiteralMap(ast.LiteralMap node) {
-    assert(irBuilder.isOpen);
     if (node.isConst) {
       return translateConstant(node);
     }
-    List<ir.Primitive> keys = new List<ir.Primitive>();
-    List<ir.Primitive> values = new List<ir.Primitive>();
-    node.entries.nodes.forEach((ast.LiteralMapEntry node) {
-      keys.add(visit(node.key));
-      values.add(visit(node.value));
-    });
-    GenericType type = elements.getType(node);
-    ir.Primitive result = new ir.LiteralMap(type, keys, values);
-    irBuilder.add(new ir.LetPrim(result));
-    return result;
+    InterfaceType type = elements.getType(node);
+    return irBuilder.buildMapLiteral(
+        type,
+        node.entries.nodes.map((e) => e.key),
+        node.entries.nodes.map((e) => e.value),
+        build);
   }
 
   ir.Primitive visitLiteralSymbol(ast.LiteralSymbol node) {
@@ -573,10 +389,9 @@
   }
 
   ir.Primitive visitIdentifier(ast.Identifier node) {
-    assert(irBuilder.isOpen);
     // "this" is the only identifier that should be met by the visitor.
     assert(node.isThis());
-    return lookupThis();
+    return irBuilder.buildThis();
   }
 
   ir.Primitive visitParenthesizedExpression(
@@ -605,12 +420,6 @@
     return receiver;
   }
 
-  ir.Primitive lookupThis() {
-    ir.Primitive result = new ir.This();
-    irBuilder.add(new ir.LetPrim(result));
-    return result;
-  }
-
   // ==== Sends ====
   ir.Primitive visitAssert(ast.Send node) {
     assert(irBuilder.isOpen);
@@ -631,8 +440,7 @@
                      closureSelector.argumentCount,
                      closureSelector.namedArguments);
     List<ir.Primitive> args = arguments.nodes.mapToList(visit, growable:false);
-    return irBuilder.continueWithExpression(
-        (k) => new ir.InvokeMethod(receiver, namedCallSelector, k, args));
+    return irBuilder.buildDynamicInvocation(receiver, namedCallSelector, args);
   }
 
   ir.Primitive visitClosureSend(ast.Send node) {
@@ -658,21 +466,15 @@
   /// If [node] is super, returns null (for special handling)
   /// Otherwise visits [node] and returns the result.
   ir.Primitive visitReceiver(ast.Expression node) {
-    if (node == null) return lookupThis();
+    if (node == null) return irBuilder.buildThis();
     if (node.isSuper()) return null;
     return visit(node);
   }
 
-  /// Makes an [InvokeMethod] unless [node.receiver.isSuper()], in that case
-  /// makes an [InvokeSuperMethod] ignoring [receiver].
-  ir.Expression createDynamicInvoke(ast.Send node,
-                                    Selector selector,
-                                    ir.Definition receiver,
-                                    ir.Continuation k,
-                                    List<ir.Definition> arguments) {
-    return node != null && node.receiver != null && node.receiver.isSuper()
-        ? new ir.InvokeSuperMethod(selector, k, arguments)
-        : new ir.InvokeMethod(receiver, selector, k, arguments);
+  /// Returns `true` if [node] is a super call.
+  // TODO(johnniwinther): Remove the need for this.
+  bool isSuperCall(ast.Send node) {
+    return node != null && node.receiver != null && node.receiver.isSuper();
   }
 
   ir.Primitive visitDynamicSend(ast.Send node) {
@@ -718,8 +520,12 @@
 
       assert(selector.kind == SelectorKind.GETTER ||
              selector.kind == SelectorKind.INDEX);
-      result = irBuilder.continueWithExpression(
-          (k) => createDynamicInvoke(node, selector, receiver, k, arguments));
+      if (isSuperCall(node)) {
+        result = irBuilder.buildSuperInvocation(selector, arguments);
+      } else {
+        result =
+            irBuilder.buildDynamicInvocation(receiver, selector, arguments);
+      }
     } else if (element.isField || element.isGetter || element.isErroneous ||
                element.isSetter) {
       // TODO(johnniwinther): Change handling of setter selectors.
@@ -785,9 +591,10 @@
            message: "unexpected operator $op"));
     DartType type = elements.getType(node.typeAnnotationFromIsCheckOrCast);
     ir.Primitive receiver = visit(node.receiver);
-    ir.Primitive check = irBuilder.continueWithExpression(
-        (k) => new ir.TypeOperator(op.source, receiver, type, k));
-    return node.isIsNotCheck ? irBuilder.buildNegation(check) : check;
+    return irBuilder.buildTypeOperator(
+        receiver, type,
+        isTypeTest: op.source == "is",
+        isNotCheck: node.isIsNotCheck);
   }
 
   // Build(StaticSend(f, arguments), C) = C[C'[InvokeStatic(f, xs)]]
@@ -809,7 +616,6 @@
     return irBuilder.buildStaticInvocation(element, selector, arguments);
   }
 
-
   ir.Primitive visitSuperSend(ast.Send node) {
     assert(irBuilder.isOpen);
     if (node.isPropertyAccess) {
@@ -847,32 +653,6 @@
     }
   }
 
-  void setStatic(Element element,
-                 Selector selector,
-                 ir.Primitive valueToStore) {
-    assert(element.isErroneous || element.isField || element.isSetter);
-    irBuilder.continueWithExpression(
-        (k) => new ir.InvokeStatic(element, selector, k, [valueToStore]));
-  }
-
-  void setDynamic(ast.Node node,
-                  ir.Primitive receiver, Selector selector,
-                  ir.Primitive valueToStore) {
-    List<ir.Definition> arguments = [valueToStore];
-    irBuilder.continueWithExpression(
-        (k) => createDynamicInvoke(node, selector, receiver, k, arguments));
-  }
-
-  void setIndex(ast.Node node,
-                ir.Primitive receiver,
-                Selector selector,
-                ir.Primitive index,
-                ir.Primitive valueToStore) {
-    List<ir.Definition> arguments = [index, valueToStore];
-    irBuilder.continueWithExpression(
-        (k) => createDynamicInvoke(node, selector, receiver, k, arguments));
-  }
-
   ir.Primitive visitSendSet(ast.SendSet node) {
     assert(irBuilder.isOpen);
     Element element = elements[node];
@@ -940,16 +720,25 @@
       irBuilder.buildLocalSet(element, valueToStore);
     } else if ((!node.isSuperCall && Elements.isErroneousElement(element)) ||
                 Elements.isStaticOrTopLevel(element)) {
-      setStatic(element, elements.getSelector(node), valueToStore);
+      irBuilder.buildStaticSet(
+          element, elements.getSelector(node), valueToStore);
     } else {
       // Setter or index-setter invocation
       Selector selector = elements.getSelector(node);
       assert(selector.kind == SelectorKind.SETTER ||
           selector.kind == SelectorKind.INDEX);
       if (selector.isIndexSet) {
-        setIndex(node, receiver, selector, index, valueToStore);
+        if (isSuperCall(node)) {
+          irBuilder.buildSuperIndexSet(index, valueToStore);
+        } else {
+          irBuilder.buildDynamicIndexSet(receiver, index, valueToStore);
+        }
       } else {
-        setDynamic(node, receiver, selector, valueToStore);
+        if (isSuperCall(node)) {
+          irBuilder.buildSuperSet(selector, valueToStore);
+        } else {
+          irBuilder.buildDynamicSet(receiver, selector, valueToStore);
+        }
       }
     }
 
@@ -973,15 +762,13 @@
         node.send.arguments.mapToList(visit, growable:false);
     return irBuilder.buildConstructorInvocation(
         element, selector, type, arguments);
-
   }
 
   ir.Primitive visitStringJuxtaposition(ast.StringJuxtaposition node) {
     assert(irBuilder.isOpen);
     ir.Primitive first = visit(node.first);
     ir.Primitive second = visit(node.second);
-    return irBuilder.continueWithExpression(
-        (k) => new ir.ConcatenateStrings(k, [first, second]));
+    return irBuilder.buildStringConcatenation([first, second]);
   }
 
   ir.Primitive visitStringInterpolation(ast.StringInterpolation node) {
@@ -994,8 +781,7 @@
       arguments.add(visit(part.expression));
       arguments.add(visitLiteralString(part.string));
     }
-    return irBuilder.continueWithExpression(
-        (k) => new ir.ConcatenateStrings(k, arguments));
+    return irBuilder.buildStringConcatenation(arguments);
   }
 
   ir.Primitive translateConstant(ast.Node node, [ConstantExpression constant]) {
diff --git a/sdk/lib/_internal/compiler/implementation/cps_ir/cps_ir_nodes.dart b/sdk/lib/_internal/compiler/implementation/cps_ir/cps_ir_nodes.dart
index 5cf7f04..4ea9beb 100644
--- a/sdk/lib/_internal/compiler/implementation/cps_ir/cps_ir_nodes.dart
+++ b/sdk/lib/_internal/compiler/implementation/cps_ir/cps_ir_nodes.dart
@@ -283,17 +283,20 @@
   final Reference receiver;
   final DartType type;
   final Reference continuation;
-  final String operator;
+  // TODO(johnniwinther): Use `Operator` class to encapsule the operator type.
+  final bool isTypeTest;
 
-  TypeOperator(this.operator,
-                Primitive receiver,
-                this.type,
-                Continuation cont)
+  TypeOperator(Primitive receiver,
+               this.type,
+               Continuation cont,
+               {bool this.isTypeTest})
       : this.receiver = new Reference(receiver),
         this.continuation = new Reference(cont) {
-    assert(operator == "is" || operator == "as");
+    assert(isTypeTest != null);
   }
 
+  bool get isTypeCast => !isTypeTest;
+
   accept(Visitor visitor) => visitor.visitTypeOperator(this);
 }
 
@@ -481,20 +484,26 @@
   final GenericType type;
   final List<Reference> values;
 
-  LiteralList(this.type, List<Primitive> values)
+  LiteralList(this.type, Iterable<Primitive> values)
       : this.values = _referenceList(values);
 
   accept(Visitor visitor) => visitor.visitLiteralList(this);
 }
 
+class LiteralMapEntry {
+  final Reference key;
+  final Reference value;
+
+  LiteralMapEntry(Primitive key, Primitive value)
+      : this.key = new Reference(key),
+        this.value = new Reference(value);
+}
+
 class LiteralMap extends Primitive {
   final GenericType type;
-  final List<Reference> keys;
-  final List<Reference> values;
+  final List<LiteralMapEntry> entries;
 
-  LiteralMap(this.type, List<Primitive> keys, List<Primitive> values)
-      : this.keys = _referenceList(keys),
-        this.values = _referenceList(values);
+  LiteralMap(this.type, this.entries);
 
   accept(Visitor visitor) => visitor.visitLiteralMap(this);
 }
@@ -566,7 +575,7 @@
   bool get isAbstract => body == null;
 }
 
-List<Reference> _referenceList(List<Definition> definitions) {
+List<Reference> _referenceList(Iterable<Definition> definitions) {
   return definitions.map((e) => new Reference(e)).toList();
 }
 
@@ -731,9 +740,9 @@
   processLiteralMap(LiteralMap node) {}
   visitLiteralMap(LiteralMap node) {
     processLiteralMap(node);
-    for (int i = 0; i < node.keys.length; i++) {
-      processReference(node.keys[i]);
-      processReference(node.values[i]);
+    for (LiteralMapEntry entry in node.entries) {
+      processReference(entry.key);
+      processReference(entry.value);
     }
   }
 
@@ -886,9 +895,9 @@
   }
 
   void visitLiteralMap(LiteralMap node) {
-    for (int i = 0; i < node.keys.length; ++i) {
-      visitReference(node.keys[i]);
-      visitReference(node.values[i]);
+    for (LiteralMapEntry entry in node.entries) {
+      visitReference(entry.key);
+      visitReference(entry.value);
     }
   }
 
diff --git a/sdk/lib/_internal/compiler/implementation/cps_ir/cps_ir_nodes_sexpr.dart b/sdk/lib/_internal/compiler/implementation/cps_ir/cps_ir_nodes_sexpr.dart
index 2b17918..c4621cb 100644
--- a/sdk/lib/_internal/compiler/implementation/cps_ir/cps_ir_nodes_sexpr.dart
+++ b/sdk/lib/_internal/compiler/implementation/cps_ir/cps_ir_nodes_sexpr.dart
@@ -28,8 +28,8 @@
         })
         .join(' ');
     String body = indentBlock(() => visit(node.body));
-    return '$indentation(FunctionDefinition $name ($parameters return)\n' +
-                 '$body)';
+    return '$indentation(FunctionDefinition $name ($parameters return)\n'
+           '$body)';
   }
 
   String visitLetPrim(LetPrim node) {
@@ -53,8 +53,8 @@
     String contBody = indentBlock(() => visit(node.continuation.body));
     String body = visit(node.body);
     String op = node.continuation.isRecursive ? 'LetCont*' : 'LetCont';
-    return '$indentation($op ($cont$parameters)\n' +
-               '$contBody)\n' +
+    return '$indentation($op ($cont$parameters)\n'
+           '$contBody)\n'
            '$body';
   }
 
@@ -160,15 +160,15 @@
   String visitSetClosureVariable(SetClosureVariable node) {
     String value = names[node.value.definition];
     String body = indentBlock(() => visit(node.body));
-    return '$indentation(SetClosureVariable ${node.variable.name} $value\n' +
-                '$body)';
+    return '$indentation(SetClosureVariable ${node.variable.name} $value\n'
+           '$body)';
   }
 
   String visitTypeOperator(TypeOperator node) {
     String receiver = names[node.receiver.definition];
     String cont = names[node.continuation.definition];
-    return '$indentation(TypeOperator ${node.operator} $receiver ' +
-                        '${node.type} $cont)';
+    String operator = node.isTypeTest ? 'is' : 'as';
+    return '$indentation(TypeOperator $operator $receiver ${node.type} $cont)';
   }
 
   String visitLiteralList(LiteralList node) {
@@ -177,17 +177,18 @@
   }
 
   String visitLiteralMap(LiteralMap node) {
-    String keys = node.keys.map((v) => names[v.definition]).join(' ');
-    String values = node.values.map((v) => names[v.definition]).join(' ');
+    String keys = node.entries.map((e) => names[e.key.definition]).join(' ');
+    String values =
+        node.entries.map((e) => names[e.value.definition]).join(' ');
     return '(LiteralMap ($keys) ($values))';
   }
 
   String visitDeclareFunction(DeclareFunction node) {
     String function = indentBlock(() => visit(node.definition));
     String body = indentBlock(() => visit(node.body));
-    return '$indentation(DeclareFunction ${node.variable.name} =\n' +
-                '$function in\n' +
-                '$body)';
+    return '$indentation(DeclareFunction ${node.variable.name} =\n'
+           '$function in\n'
+           '$body)';
   }
 
   String visitIsTrue(IsTrue node) {
diff --git a/sdk/lib/_internal/compiler/implementation/cps_ir/cps_ir_tracer.dart b/sdk/lib/_internal/compiler/implementation/cps_ir/cps_ir_tracer.dart
index a588bc9..5c69e59 100644
--- a/sdk/lib/_internal/compiler/implementation/cps_ir/cps_ir_tracer.dart
+++ b/sdk/lib/_internal/compiler/implementation/cps_ir/cps_ir_tracer.dart
@@ -156,9 +156,9 @@
   visitLiteralMap(cps_ir.LiteralMap node) {
     String dummy = names.name(node);
     List<String> entries = new List<String>();
-    for (int i = 0; i < node.values.length; ++i) {
-      String key = formatReference(node.keys[i]);
-      String value = formatReference(node.values[i]);
+    for (cps_ir.LiteralMapEntry entry in node.entries) {
+      String key = formatReference(entry.key);
+      String value = formatReference(entry.value);
       entries.add("$key: $value");
     }
     printStmt(dummy, "LiteralMap (${entries.join(', ')})");
@@ -166,7 +166,7 @@
 
   visitTypeOperator(cps_ir.TypeOperator node) {
     String dummy = names.name(node);
-    String operator = node.operator;
+    String operator = node.isTypeTest ? 'is' : 'as';
     List<String> entries = new List<String>();
     String receiver = formatReference(node.receiver);
     printStmt(dummy, "TypeOperator ($operator $receiver ${node.type})");
diff --git a/sdk/lib/_internal/compiler/implementation/cps_ir/shrinking_reductions.dart b/sdk/lib/_internal/compiler/implementation/cps_ir/shrinking_reductions.dart
index 82aead1..f14ece5 100644
--- a/sdk/lib/_internal/compiler/implementation/cps_ir/shrinking_reductions.dart
+++ b/sdk/lib/_internal/compiler/implementation/cps_ir/shrinking_reductions.dart
@@ -371,8 +371,10 @@
   }
 
   processLiteralMap(LiteralMap node) {
-    node.values.forEach((Reference ref) => ref.parent = node);
-    node.keys.forEach((Reference ref) => ref.parent = node);
+    node.entries.forEach((LiteralMapEntry entry) {
+      entry.key.parent = node;
+      entry.value.parent = node;
+    });
   }
 
   processCreateFunction(CreateFunction node) {
diff --git a/sdk/lib/_internal/compiler/implementation/dart2js.dart b/sdk/lib/_internal/compiler/implementation/dart2js.dart
index 99c6754..2359ad2 100644
--- a/sdk/lib/_internal/compiler/implementation/dart2js.dart
+++ b/sdk/lib/_internal/compiler/implementation/dart2js.dart
@@ -6,6 +6,7 @@
 
 import 'dart:async'
     show Future, EventSink;
+import 'dart:convert' show UTF8, LineSplitter;
 import 'dart:io'
     show exit, File, FileMode, Platform, RandomAccessFile, FileSystemException,
          stdin, stderr;
@@ -113,6 +114,7 @@
   bool stripArgumentSet = false;
   bool analyzeOnly = false;
   bool analyzeAll = false;
+  bool enableAsyncAwait = false;
   bool trustTypeAnnotations = false;
   bool checkedMode = false;
   // List of provided options that imply that output is expected.
@@ -188,6 +190,11 @@
     passThrough(argument);
   }
 
+  setEnableAsync(String argument) {
+    enableAsyncAwait = true;
+    passThrough(argument);
+  }
+
   setVerbose(_) {
     diagnosticHandler.verbose = true;
     passThrough('--verbose');
@@ -316,6 +323,7 @@
                       (_) => hasDisallowUnsafeEval = true),
     new OptionHandler('--show-package-warnings', passThrough),
     new OptionHandler('--csp', passThrough),
+    new OptionHandler('--enable-async', setEnableAsync),
     new OptionHandler('-D.+=.*', addInEnvironment),
 
     // The following two options must come last.
@@ -376,6 +384,10 @@
         api.Diagnostic.INFO);
   }
   if (analyzeAll) analyzeOnly = true;
+  if (enableAsyncAwait && !analyzeOnly) {
+    helpAndFail("Option '--enable-async' is currently only supported in "
+                "combination with the '--analyze-only' option.");
+  }
 
   diagnosticHandler.info('Package root is $packageRoot');
 
@@ -635,7 +647,6 @@
 
 void batchMain(List<String> batchArguments) {
   int exitCode;
-
   exitFunc = (errorCode) {
     // Since we only throw another part of the compiler might intercept our
     // exception and try to exit with a different code.
@@ -645,24 +656,24 @@
     throw _EXIT_SIGNAL;
   };
 
-  runJob() {
+  var stream = stdin.transform(UTF8.decoder).transform(new LineSplitter());
+  var subscription;
+  subscription = stream.listen((line) {
     new Future.sync(() {
+      subscription.pause();
       exitCode = 0;
-      String line = stdin.readLineSync();
       if (line == null) exit(0);
       List<String> args = <String>[];
       args.addAll(batchArguments);
       args.addAll(splitLine(line, windows: Platform.isWindows));
       return internalMain(args);
-    })
-    .catchError((exception, trace) {
+    }).catchError((exception, trace) {
       if (!identical(exception, _EXIT_SIGNAL)) {
         exitCode = 253;
       }
-    })
-    .whenComplete(() {
-      // The testing framework waits for a status line on stdout and stderr
-      // before moving to the next test.
+    }).whenComplete(() {
+      // The testing framework waits for a status line on stdout and
+      // stderr before moving to the next test.
       if (exitCode == 0){
         print(">>> TEST OK");
       } else if (exitCode == 253) {
@@ -671,9 +682,7 @@
         print(">>> TEST FAIL");
       }
       stderr.writeln(">>> EOF STDERR");
-      runJob();
+      subscription.resume();
     });
-  }
-
-  runJob();
+  });
 }
diff --git a/sdk/lib/_internal/compiler/implementation/dart_backend/backend_ast_emitter.dart b/sdk/lib/_internal/compiler/implementation/dart_backend/backend_ast_emitter.dart
index 86632ad..7ceefa6 100644
--- a/sdk/lib/_internal/compiler/implementation/dart_backend/backend_ast_emitter.dart
+++ b/sdk/lib/_internal/compiler/implementation/dart_backend/backend_ast_emitter.dart
@@ -331,7 +331,7 @@
     // Synthesize an element for the variable
     if (variable.element == null || name != variable.element.name) {
       // TODO(johnniwinther): Replace by synthetic [Entity].
-      variable.element = new modelx.LocalVariableElementX.synthetic(
+      variable.element = new _SyntheticLocalVariableElement(
           name,
           functionElement,
           variableList);
@@ -514,12 +514,13 @@
 
   Expression visitLiteralMap(tree.LiteralMap exp) {
     List<LiteralMapEntry> entries = new List<LiteralMapEntry>.generate(
-        exp.values.length,
-        (i) => new LiteralMapEntry(visitExpression(exp.keys[i]),
-                                   visitExpression(exp.values[i])));
+        exp.entries.length,
+        (i) => new LiteralMapEntry(visitExpression(exp.entries[i].key),
+                                   visitExpression(exp.entries[i].value)));
     List<TypeAnnotation> typeArguments = exp.type.treatAsRaw
         ? null
-        : exp.type.typeArguments.map(createTypeAnnotation).toList(growable: false);
+        : exp.type.typeArguments.map(createTypeAnnotation)
+             .toList(growable: false);
     return new LiteralMap(entries, typeArguments: typeArguments);
   }
 
@@ -897,3 +898,22 @@
   }
 
 }
+
+// TODO(johnniwinther): Remove this when the dart `backend_ast` does not need
+// [Element] for entities.
+class _SyntheticLocalVariableElement extends modelx.VariableElementX
+    implements LocalVariableElement {
+
+  _SyntheticLocalVariableElement(String name,
+                                 ExecutableElement enclosingElement,
+                                 modelx.VariableList variables)
+      : super(name, ElementKind.VARIABLE, enclosingElement, variables, null);
+
+  ExecutableElement get executableContext => enclosingElement;
+
+  ExecutableElement get memberContext => executableContext.memberContext;
+
+  bool get isLocal => true;
+
+  LibraryElement get implementationLibrary => enclosingElement.library;
+}
diff --git a/sdk/lib/_internal/compiler/implementation/dart_backend/backend_ast_to_frontend_ast.dart b/sdk/lib/_internal/compiler/implementation/dart_backend/backend_ast_to_frontend_ast.dart
index 2004237..d314f54 100644
--- a/sdk/lib/_internal/compiler/implementation/dart_backend/backend_ast_to_frontend_ast.dart
+++ b/sdk/lib/_internal/compiler/implementation/dart_backend/backend_ast_to_frontend_ast.dart
@@ -23,7 +23,8 @@
 /// If true, the unparser will insert a coment in front of every function
 /// it emits. This helps indicate which functions were translated by the new
 /// backend.
-bool INSERT_NEW_BACKEND_COMMENT = false;
+bool INSERT_NEW_BACKEND_COMMENT =
+    const bool.fromEnvironment('USE_NEW_BACKEND', defaultValue: false);
 
 /// Converts backend ASTs to frontend ASTs.
 class TreePrinter {
@@ -92,6 +93,7 @@
   final Token whileToken = makeIdToken('while');
   final Token ifToken = makeIdToken('if');
   final Token elseToken = makeIdToken('else');
+  final Token awaitToken = makeIdToken('await');
   final Token forToken = makeIdToken('for');
   final Token inToken = makeIdToken('in');
   final Token returnToken = makeIdToken('return');
@@ -415,7 +417,8 @@
             : makeType(exp.returnType),
           makeFunctionModifiers(exp),
           null,  // initializers
-          getOrSet);
+          getOrSet,  // get/set
+          null); // async modifier
       setElement(result, exp.element, exp);
     } else if (exp is Identifier) {
       precedence = CALLEE;
@@ -701,6 +704,7 @@
           left,
           makeExpression(stmt.expression),
           makeStatement(stmt.body, shortIf: shortIf),
+          awaitToken,
           forToken,
           inToken);
     } else if (stmt is FunctionDeclaration) {
@@ -711,7 +715,8 @@
           stmt.returnType != null ? makeType(stmt.returnType) : null,
           makeEmptyModifiers(),
           null,  // initializers
-          null);  // get/set
+          null,  // get/set
+          null); // async modifier
       setElement(function, stmt.function.element, stmt);
       return new tree.FunctionDeclaration(function);
     } else if (stmt is If) {
@@ -885,8 +890,9 @@
           null, // body
           param.type == null ? null : makeType(param.type),
           makeEmptyModifiers(), // TODO: Function parameter modifiers?
-          null, // initializers
-          null); // get/set
+          null,  // initializers
+          null,  // get/set
+          null); // async modifier
       if (param.element != null) {
         setElement(definition, param.element, param);
       }
diff --git a/sdk/lib/_internal/compiler/implementation/dart_backend/logical_rewriter.dart b/sdk/lib/_internal/compiler/implementation/dart_backend/logical_rewriter.dart
index aa463f4..8689aaa 100644
--- a/sdk/lib/_internal/compiler/implementation/dart_backend/logical_rewriter.dart
+++ b/sdk/lib/_internal/compiler/implementation/dart_backend/logical_rewriter.dart
@@ -197,8 +197,10 @@
   }
 
   Expression visitLiteralMap(LiteralMap node) {
-    _rewriteList(node.keys);
-    _rewriteList(node.values);
+    node.entries.forEach((LiteralMapEntry entry) {
+      entry.key = visitExpression(entry.key);
+      entry.value = visitExpression(entry.value);
+    });
     return node;
   }
 
diff --git a/sdk/lib/_internal/compiler/implementation/dart_backend/statement_rewriter.dart b/sdk/lib/_internal/compiler/implementation/dart_backend/statement_rewriter.dart
index 4151d2d..8733f93 100644
--- a/sdk/lib/_internal/compiler/implementation/dart_backend/statement_rewriter.dart
+++ b/sdk/lib/_internal/compiler/implementation/dart_backend/statement_rewriter.dart
@@ -357,9 +357,9 @@
 
   Expression visitLiteralMap(LiteralMap node) {
     // Process arguments right-to-left, the opposite of evaluation order.
-    for (int i = node.values.length - 1; i >= 0; --i) {
-      node.values[i] = visitExpression(node.values[i]);
-      node.keys[i] = visitExpression(node.keys[i]);
+    for (LiteralMapEntry entry in node.entries.reversed) {
+      entry.value = visitExpression(entry.value);
+      entry.key = visitExpression(entry.key);
     }
     return node;
   }
diff --git a/sdk/lib/_internal/compiler/implementation/dart_backend/tree_ir_builder.dart b/sdk/lib/_internal/compiler/implementation/dart_backend/tree_ir_builder.dart
index 14c9fd2..d4ba56e 100644
--- a/sdk/lib/_internal/compiler/implementation/dart_backend/tree_ir_builder.dart
+++ b/sdk/lib/_internal/compiler/implementation/dart_backend/tree_ir_builder.dart
@@ -346,7 +346,8 @@
 
   Statement visitTypeOperator(cps_ir.TypeOperator node) {
     Expression receiver = getVariableReference(node.receiver);
-    Expression concat = new TypeOperator(receiver, node.type, node.operator);
+    Expression concat =
+        new TypeOperator(receiver, node.type, isTypeTest: node.isTypeTest);
     return continueWithExpression(node.continuation, concat);
   }
 
@@ -430,8 +431,12 @@
   Expression visitLiteralMap(cps_ir.LiteralMap node) {
     return new LiteralMap(
         node.type,
-        translateArguments(node.keys),
-        translateArguments(node.values));
+        new List<LiteralMapEntry>.generate(node.entries.length, (int index) {
+          return new LiteralMapEntry(
+              getVariableReference(node.entries[index].key),
+              getVariableReference(node.entries[index].value));
+        })
+    );
   }
 
   FunctionDefinition makeSubFunction(cps_ir.FunctionDefinition function) {
diff --git a/sdk/lib/_internal/compiler/implementation/dart_backend/tree_ir_nodes.dart b/sdk/lib/_internal/compiler/implementation/dart_backend/tree_ir_nodes.dart
index 07866a0..c076940 100644
--- a/sdk/lib/_internal/compiler/implementation/dart_backend/tree_ir_nodes.dart
+++ b/sdk/lib/_internal/compiler/implementation/dart_backend/tree_ir_nodes.dart
@@ -223,12 +223,18 @@
   accept(ExpressionVisitor visitor) => visitor.visitLiteralList(this);
 }
 
+class LiteralMapEntry {
+  Expression key;
+  Expression value;
+
+  LiteralMapEntry(this.key, this.value);
+}
+
 class LiteralMap extends Expression {
   final GenericType type;
-  final List<Expression> keys;
-  final List<Expression> values;
+  final List<LiteralMapEntry> entries;
 
-  LiteralMap(this.type, this.keys, this.values);
+  LiteralMap(this.type, this.entries);
 
   accept(ExpressionVisitor visitor) => visitor.visitLiteralMap(this);
 }
@@ -236,11 +242,13 @@
 class TypeOperator extends Expression {
   Expression receiver;
   final DartType type;
-  final String operator;
+  final bool isTypeTest;
 
-  TypeOperator(this.receiver, this.type, this.operator) ;
+  TypeOperator(this.receiver, this.type, {bool this.isTypeTest});
 
   accept(ExpressionVisitor visitor) => visitor.visitTypeOperator(this);
+
+  String get operator => isTypeTest ? 'is' : 'as';
 }
 
 /// A conditional expression.
@@ -595,10 +603,10 @@
   }
 
   visitLiteralMap(LiteralMap node) {
-    for (int i=0; i<node.keys.length; i++) {
-      visitExpression(node.keys[i]);
-      visitExpression(node.values[i]);
-    }
+    node.entries.forEach((LiteralMapEntry entry) {
+      visitExpression(entry.key);
+      visitExpression(entry.value);
+    });
   }
 
   visitTypeOperator(TypeOperator node) {
diff --git a/sdk/lib/_internal/compiler/implementation/dart_backend/tree_ir_tracer.dart b/sdk/lib/_internal/compiler/implementation/dart_backend/tree_ir_tracer.dart
index 2310733..bcd02f5 100644
--- a/sdk/lib/_internal/compiler/implementation/dart_backend/tree_ir_tracer.dart
+++ b/sdk/lib/_internal/compiler/implementation/dart_backend/tree_ir_tracer.dart
@@ -330,11 +330,11 @@
 
   String visitLiteralMap(LiteralMap node) {
     List<String> entries = new List<String>();
-    for (int i = 0; i < node.values.length; ++i) {
-      String key = visitExpression(node.keys[i]);
-      String value = visitExpression(node.values[i]);
+    node.entries.forEach((LiteralMapEntry entry) {
+      String key = visitExpression(entry.key);
+      String value = visitExpression(entry.value);
       entries.add("$key: $value");
-    }
+    });
     return "map [${entries.join(', ')}]";
   }
 
diff --git a/sdk/lib/_internal/compiler/implementation/elements/elements.dart b/sdk/lib/_internal/compiler/implementation/elements/elements.dart
index 9f6dcfc..442e12b 100644
--- a/sdk/lib/_internal/compiler/implementation/elements/elements.dart
+++ b/sdk/lib/_internal/compiler/implementation/elements/elements.dart
@@ -1137,6 +1137,39 @@
 
   /// The type of this function.
   FunctionType get type;
+
+  /// The synchronous/asynchronous marker on this function.
+  AsyncMarker get asyncMarker;
+}
+
+/// Enum for the synchronous/asynchronous function body modifiers.
+class AsyncMarker {
+  /// The default function body marker.
+  static AsyncMarker SYNC = const AsyncMarker._();
+
+  /// The `sync*` function body marker.
+  static AsyncMarker SYNC_STAR = const AsyncMarker._(isYielding: true);
+
+  /// The `async` function body marker.
+  static AsyncMarker ASYNC = const AsyncMarker._(isAsync: true);
+
+  /// The `async*` function body marker.
+  static AsyncMarker ASYNC_STAR =
+      const AsyncMarker._(isAsync: true, isYielding: true);
+
+  /// Is `true` if this marker defines the function body to have an
+  /// asynchronous result, that is, either a [Future] or a [Stream].
+  final bool isAsync;
+
+  /// Is `true` if this marker defines the function body to have a plural
+  /// result, that is, either an [Iterable] or a [Stream].
+  final bool isYielding;
+
+  const AsyncMarker._({this.isAsync: false, this.isYielding: false});
+
+  String toString() {
+    return '${isAsync ? 'async' : 'sync'}${isYielding ? '*' : ''}';
+  }
 }
 
 /// A top level, static or instance function.
diff --git a/sdk/lib/_internal/compiler/implementation/elements/modelx.dart b/sdk/lib/_internal/compiler/implementation/elements/modelx.dart
index df1d98f..d435f4a 100644
--- a/sdk/lib/_internal/compiler/implementation/elements/modelx.dart
+++ b/sdk/lib/_internal/compiler/implementation/elements/modelx.dart
@@ -287,6 +287,7 @@
     throw 'unsupported operation on erroneous element';
   }
 
+  get asyncMarker => AsyncMarker.SYNC;
   Link<MetadataAnnotation> get metadata => unsupported();
   bool get hasNode => false;
   get node => unsupported();
@@ -1231,13 +1232,6 @@
     createDefinitions(variables.definitions);
   }
 
-  // TODO(johnniwinther): Remove this when the dart `backend_ast` does not need
-  // [Element] for entities.
-  LocalVariableElementX.synthetic(String name,
-                                  ExecutableElement enclosingElement,
-                                  VariableList variables)
-      : super(name, ElementKind.VARIABLE, enclosingElement, variables, null);
-
   ExecutableElement get executableContext => enclosingElement;
 
   ExecutableElement get memberContext => executableContext.memberContext;
@@ -1547,6 +1541,8 @@
 
   AbstractFieldElement abstractField;
 
+  AsyncMarker asyncMarker = AsyncMarker.SYNC;
+
   BaseFunctionElementX(String name,
                        ElementKind kind,
                        Modifiers this.modifiers,
diff --git a/sdk/lib/_internal/compiler/implementation/inferrer/concrete_types_inferrer.dart b/sdk/lib/_internal/compiler/implementation/inferrer/concrete_types_inferrer.dart
index 4d9a704..129f49c 100644
--- a/sdk/lib/_internal/compiler/implementation/inferrer/concrete_types_inferrer.dart
+++ b/sdk/lib/_internal/compiler/implementation/inferrer/concrete_types_inferrer.dart
@@ -475,6 +475,12 @@
   }
 
   @override
+  ConcreteType allocateLoopPhi(Node node, Local variable,
+                               ConcreteType inputType) {
+    return inputType;
+  }
+
+  @override
   ConcreteType computeLUB(ConcreteType firstType, ConcreteType secondType) {
     if (firstType == null) {
       return secondType;
diff --git a/sdk/lib/_internal/compiler/implementation/inferrer/inferrer_visitor.dart b/sdk/lib/_internal/compiler/implementation/inferrer/inferrer_visitor.dart
index 1e603a9..65ea6bc 100644
--- a/sdk/lib/_internal/compiler/implementation/inferrer/inferrer_visitor.dart
+++ b/sdk/lib/_internal/compiler/implementation/inferrer/inferrer_visitor.dart
@@ -79,6 +79,16 @@
    */
   T allocatePhi(Node node, Local variable, T inputType);
 
+
+  /**
+   * Returns a new type for holding the potential types of [element].
+   * [inputType] is the first incoming type of the phi. [allocateLoopPhi]
+   * only differs from [allocatePhi] in that it allows the underlying
+   * implementation of [TypeSystem] to differentiate Phi nodes due to loops
+   * from other merging uses.
+   */
+  T allocateLoopPhi(Node node, Local variable, T inputType);
+
   /**
    * Simplies the phi representing [element] and of the type
    * [phiType]. For example, if this phi has one incoming input, an
@@ -605,7 +615,7 @@
 
   void startLoop(Node loop) {
     locals.forEachLocal((Local variable, T type) {
-      T newType = types.allocatePhi(loop, variable, type);
+      T newType = types.allocateLoopPhi(loop, variable, type);
       if (newType != type) {
         locals[variable] = newType;
       }
diff --git a/sdk/lib/_internal/compiler/implementation/inferrer/simple_types_inferrer.dart b/sdk/lib/_internal/compiler/implementation/inferrer/simple_types_inferrer.dart
index 5ba65f1..f06b1cc 100644
--- a/sdk/lib/_internal/compiler/implementation/inferrer/simple_types_inferrer.dart
+++ b/sdk/lib/_internal/compiler/implementation/inferrer/simple_types_inferrer.dart
@@ -137,6 +137,12 @@
     return inputType;
   }
 
+  TypeMask allocateLoopPhi(ast.Node node,
+                           Local variable,
+                           TypeMask inputType) {
+    return inputType;
+  }
+
   TypeMask simplifyPhi(ast.Node node,
                        Local variable,
                        TypeMask phiType) {
diff --git a/sdk/lib/_internal/compiler/implementation/inferrer/type_graph_inferrer.dart b/sdk/lib/_internal/compiler/implementation/inferrer/type_graph_inferrer.dart
index 53107a1..ae3427a 100644
--- a/sdk/lib/_internal/compiler/implementation/inferrer/type_graph_inferrer.dart
+++ b/sdk/lib/_internal/compiler/implementation/inferrer/type_graph_inferrer.dart
@@ -26,7 +26,8 @@
 import '../native/native.dart' as native;
 import '../tree/tree.dart' as ast
     show DartString,
-         Node;
+         Node,
+         TryStatement;
 import '../types/types.dart'
     show ContainerTypeMask,
          DictionaryTypeMask,
@@ -439,6 +440,17 @@
     return result;
   }
 
+  PhiElementTypeInformation _addPhi(ast.Node node,
+                                    Local variable,
+                                    inputType,
+                                    bool isLoop) {
+    PhiElementTypeInformation result =
+        new PhiElementTypeInformation(currentMember, node, isLoop, variable);
+    allocatedTypes.add(result);
+    result.addAssignment(inputType);
+    return result;
+  }
+
   PhiElementTypeInformation allocatePhi(ast.Node node,
                                         Local variable,
                                         inputType) {
@@ -446,19 +458,23 @@
     // the try/catch block [node]. If it is, no need to allocate a new
     // phi.
     if (inputType is PhiElementTypeInformation &&
-        inputType.branchNode == node) {
+        inputType.branchNode == node &&
+        inputType.branchNode is ast.TryStatement) {
       return inputType;
     }
-    PhiElementTypeInformation result =
-        new PhiElementTypeInformation(currentMember, node, true, variable);
-    allocatedTypes.add(result);
-    result.addAssignment(inputType);
-    return result;
+    return _addPhi(node, variable, inputType, false);
+  }
+
+  PhiElementTypeInformation allocateLoopPhi(ast.Node node,
+                                            Local variable,
+                                            inputType) {
+    return _addPhi(node, variable, inputType, true);
   }
 
   TypeInformation simplifyPhi(ast.Node node,
                               Local variable,
                               PhiElementTypeInformation phiType) {
+    assert(phiType.branchNode == node);
     if (phiType.assignments.length == 1) return phiType.assignments.first;
     return phiType;
   }
diff --git a/sdk/lib/_internal/compiler/implementation/js/template.dart b/sdk/lib/_internal/compiler/implementation/js/template.dart
index 1c56d37..5b574d0 100644
--- a/sdk/lib/_internal/compiler/implementation/js/template.dart
+++ b/sdk/lib/_internal/compiler/implementation/js/template.dart
@@ -10,11 +10,6 @@
 
   TemplateManager();
 
-  // TODO(18886): Remove this function once the memory-leak in the VM is fixed.
-  void clear() {
-    expressionTemplates.clear();
-    statementTemplates.clear();
-  }
 
   Template lookupExpressionTemplate(String source) {
     return expressionTemplates[source];
diff --git a/sdk/lib/_internal/compiler/implementation/js_emitter/code_emitter_task.dart b/sdk/lib/_internal/compiler/implementation/js_emitter/code_emitter_task.dart
index 2ae131f..de0592b 100644
--- a/sdk/lib/_internal/compiler/implementation/js_emitter/code_emitter_task.dart
+++ b/sdk/lib/_internal/compiler/implementation/js_emitter/code_emitter_task.dart
@@ -54,9 +54,6 @@
         : oldEmitter;
     nativeEmitter = new NativeEmitter(this);
     typeTestEmitter.emitter = this.oldEmitter;
-    // TODO(18886): Remove this call (and the show in the import) once the
-    // memory-leak in the VM is fixed.
-    templateManager.clear();
   }
 
 
diff --git a/sdk/lib/_internal/compiler/implementation/js_emitter/js_emitter.dart b/sdk/lib/_internal/compiler/implementation/js_emitter/js_emitter.dart
index dedd083..825eaa0 100644
--- a/sdk/lib/_internal/compiler/implementation/js_emitter/js_emitter.dart
+++ b/sdk/lib/_internal/compiler/implementation/js_emitter/js_emitter.dart
@@ -33,7 +33,7 @@
 
 import '../js/js.dart' as jsAst;
 import '../js/js.dart' show
-    js, templateManager;
+    js;
 
 import '../js_backend/js_backend.dart' show
     CheckedModeHelper,
diff --git a/sdk/lib/_internal/compiler/implementation/mirrors/analyze.dart b/sdk/lib/_internal/compiler/implementation/mirrors/analyze.dart
index fe10b0f..4ba7616 100644
--- a/sdk/lib/_internal/compiler/implementation/mirrors/analyze.dart
+++ b/sdk/lib/_internal/compiler/implementation/mirrors/analyze.dart
@@ -38,6 +38,7 @@
   options.add('--analyze-signatures-only');
   options.add('--analyze-all');
   options.add('--categories=Client,Server');
+  options.add('--enable-async');
 
   bool compilationFailed = false;
   void internalDiagnosticHandler(Uri uri, int begin, int end,
diff --git a/sdk/lib/_internal/compiler/implementation/resolution/members.dart b/sdk/lib/_internal/compiler/implementation/resolution/members.dart
index 4c5a6a9..937d308 100644
--- a/sdk/lib/_internal/compiler/implementation/resolution/members.dart
+++ b/sdk/lib/_internal/compiler/implementation/resolution/members.dart
@@ -616,6 +616,44 @@
     }
   }
 
+  static void processAsyncMarker(Compiler compiler,
+                                 BaseFunctionElementX element) {
+    FunctionExpression functionExpression = element.node;
+    AsyncModifier asyncModifier = functionExpression.asyncModifier;
+    if (asyncModifier != null) {
+      if (!compiler.enableAsyncAwait) {
+        compiler.reportError(asyncModifier,
+            MessageKind.EXPERIMENTAL_ASYNC_AWAIT,
+            {'modifier': element.asyncMarker});
+      } else if (!compiler.analyzeOnly) {
+        compiler.reportError(asyncModifier,
+            MessageKind.EXPERIMENTAL_ASYNC_AWAIT,
+            {'modifier': element.asyncMarker});
+      }
+
+      if (asyncModifier.isAsynchronous) {
+        element.asyncMarker = asyncModifier.isYielding
+            ? AsyncMarker.ASYNC_STAR : AsyncMarker.ASYNC;
+      } else {
+        element.asyncMarker = AsyncMarker.SYNC_STAR;
+      }
+      if (element.isAbstract) {
+        compiler.reportError(asyncModifier,
+            MessageKind.ASYNC_MODIFIER_ON_ABSTRACT_METHOD,
+            {'modifier': element.asyncMarker});
+      } else if (element.isConstructor) {
+        compiler.reportError(asyncModifier,
+            MessageKind.ASYNC_MODIFIER_ON_CONSTRUCTOR,
+            {'modifier': element.asyncMarker});
+      } else if (functionExpression.body.asReturn() != null &&
+                 element.asyncMarker.isYielding) {
+        compiler.reportError(asyncModifier,
+            MessageKind.YIELDING_MODIFIER_ON_ARROW_BODY,
+            {'modifier': element.asyncMarker});
+      }
+    }
+  }
+
   TreeElements resolveMethodElement(FunctionElementX element) {
     assert(invariant(element, element.isDeclaration));
     return compiler.withCurrentElement(element, () {
@@ -651,6 +689,7 @@
       }
       element.parseNode(compiler);
       element.computeType(compiler);
+      processAsyncMarker(compiler, element);
       if (element.isPatched) {
         FunctionElementX patch = element.patch;
         compiler.withCurrentElement(patch, () {
@@ -659,6 +698,7 @@
         });
         checkMatchingPatchSignatures(element, patch);
         element = patch;
+        processAsyncMarker(compiler, element);
       }
       return compiler.withCurrentElement(element, () {
         FunctionExpression tree = element.node;
@@ -2104,6 +2144,8 @@
       : typeResolver = new TypeResolver(compiler),
         super(compiler);
 
+  AsyncMarker get currentAsyncMarker => AsyncMarker.SYNC;
+
   /// Add [element] to the current scope and check for duplicate definitions.
   void addToScope(Element element) {
     Element existing = scope.add(element);
@@ -2112,9 +2154,23 @@
     }
   }
 
+  void checkLocalDefinitionName(Node node, Element element) {
+    if (currentAsyncMarker != AsyncMarker.SYNC) {
+      if (element.name == 'yield' ||
+          element.name == 'async' ||
+          element.name == 'await') {
+        compiler.reportError(
+            node, MessageKind.ASYNC_KEYWORD_AS_IDENTIFIER,
+            {'keyword': element.name,
+             'modifier': currentAsyncMarker});
+      }
+    }
+  }
+
   /// Register [node] as the definition of [element].
   void defineLocalVariable(Node node, LocalVariableElement element) {
     invariant(node, element != null);
+    checkLocalDefinitionName(node, element);
     registry.defineElement(node, element);
   }
 
@@ -2223,6 +2279,14 @@
       inCatchBlock = false,
       super(compiler, registry);
 
+  AsyncMarker get currentAsyncMarker {
+    if (enclosingElement is FunctionElement) {
+      FunctionElement function = enclosingElement;
+      return function.asyncMarker;
+    }
+    return AsyncMarker.SYNC;
+  }
+
   Element reportLookupErrorIfAny(Element result, Node node, String name) {
     if (!Elements.isUnresolved(result)) {
       if (!inInstanceContext && result.isInstanceMember) {
@@ -2518,6 +2582,8 @@
     function.functionSignatureCache =
         SignatureResolver.analyze(compiler, node.parameters, node.returnType,
             function, registry, createRealParameters: true);
+    ResolverTask.processAsyncMarker(compiler, function);
+    checkLocalDefinitionName(node, function);
     registry.defineFunction(node, function);
     if (doAddToScope) {
       addToScope(function);
@@ -3143,6 +3209,12 @@
     visit(node.expression);
   }
 
+  visitYield(Yield node) {
+    compiler.streamClass.ensureResolved(compiler);
+    compiler.iterableClass.ensureResolved(compiler);
+    visit(node.expression);
+  }
+
   visitRedirectingFactoryBody(RedirectingFactoryBody node) {
     final isSymbolConstructor = enclosingElement == compiler.symbolConstructor;
     if (!enclosingElement.isFactoryConstructor) {
@@ -3213,6 +3285,11 @@
     visit(node.expression);
   }
 
+  visitAwait(Await node) {
+    compiler.futureClass.ensureResolved(compiler);
+    visit(node.expression);
+  }
+
   visitVariableDefinitions(VariableDefinitions node) {
     DartType type;
     if (node.type != null) {
diff --git a/sdk/lib/_internal/compiler/implementation/resolution/resolution.dart b/sdk/lib/_internal/compiler/implementation/resolution/resolution.dart
index bafa0b9..217b3eb 100644
--- a/sdk/lib/_internal/compiler/implementation/resolution/resolution.dart
+++ b/sdk/lib/_internal/compiler/implementation/resolution/resolution.dart
@@ -15,6 +15,7 @@
 import '../elements/elements.dart';
 import '../elements/modelx.dart'
     show BaseClassElementX,
+         BaseFunctionElementX,
          ConstructorElementX,
          ErroneousElementX,
          FieldElementX,
diff --git a/sdk/lib/_internal/compiler/implementation/scanner/keyword.dart b/sdk/lib/_internal/compiler/implementation/scanner/keyword.dart
index 4bf9695..1e01efb 100644
--- a/sdk/lib/_internal/compiler/implementation/scanner/keyword.dart
+++ b/sdk/lib/_internal/compiler/implementation/scanner/keyword.dart
@@ -67,7 +67,11 @@
       const Keyword("on", isPseudo: true),
       const Keyword("show", isPseudo: true),
       const Keyword("source", isPseudo: true),
-      const Keyword("deferred", isPseudo: true)];
+      const Keyword("deferred", isPseudo: true),
+      const Keyword("async", isPseudo: true),
+      const Keyword("sync", isPseudo: true),
+      const Keyword("await", isPseudo: true),
+      const Keyword("yield", isPseudo: true)];
 
   final String syntax;
   final bool isPseudo;
diff --git a/sdk/lib/_internal/compiler/implementation/scanner/listener.dart b/sdk/lib/_internal/compiler/implementation/scanner/listener.dart
index 2b69193..89f20d4 100644
--- a/sdk/lib/_internal/compiler/implementation/scanner/listener.dart
+++ b/sdk/lib/_internal/compiler/implementation/scanner/listener.dart
@@ -20,6 +20,16 @@
   void endArguments(int count, Token beginToken, Token endToken) {
   }
 
+  /// Handle async modifiers `async`, `async*`, `sync`.
+  void handleAsyncModifier(Token asyncToken, Token startToken) {
+  }
+
+  void beginAwaitExpression(Token token) {
+  }
+
+  void endAwaitExpression(Token beginToken, Token endToken) {
+  }
+
   void beginBlock(Token token) {
   }
 
@@ -115,7 +125,8 @@
                        Token beginToken, Token endToken) {
   }
 
-  void endForIn(Token beginToken, Token inKeyword, Token endToken) {
+  void endForIn(Token awaitToken, Token forToken,
+                Token inKeyword, Token endToken) {
   }
 
   void beginFunction(Token token) {
@@ -393,10 +404,10 @@
   void endTypeVariables(int count, Token beginToken, Token endToken) {
   }
 
-  void beginUnamedFunction(Token token) {
+  void beginUnnamedFunction(Token token) {
   }
 
-  void endUnamedFunction(Token token) {
+  void endUnnamedFunction(Token token) {
   }
 
   void beginVariablesDeclaration(Token token) {
@@ -546,6 +557,12 @@
   void handleVoidKeyword(Token token) {
   }
 
+  void beginYieldStatement(Token token) {
+  }
+
+  void endYieldStatement(Token yieldToken, Token starToken, Token endToken) {
+  }
+
   Token expected(String string, Token token) {
     if (token is ErrorToken) {
       reportErrorToken(token);
@@ -1623,6 +1640,11 @@
     pushNode(new Return(beginToken, endToken, expression));
   }
 
+  void endYieldStatement(Token yieldToken, Token starToken, Token endToken) {
+    Expression expression = popNode();
+    pushNode(new Yield(yieldToken, starToken, expression, endToken));
+  }
+
   void endExpressionStatement(Token token) {
     pushNode(new ExpressionStatement(popNode(), token));
   }
@@ -1770,6 +1792,14 @@
     }
   }
 
+  void handleAsyncModifier(Token asyncToken, Token starToken) {
+    if (asyncToken != null) {
+      pushNode(new AsyncModifier(asyncToken, starToken));
+    } else {
+      pushNode(null);
+    }
+  }
+
   void skippedFunctionBody(Token token) {
     pushNode(new Block(new NodeList.empty()));
   }
@@ -1780,6 +1810,7 @@
 
   void endFunction(Token getOrSet, Token endToken) {
     Statement body = popNode();
+    AsyncModifier asyncModifier = popNode();
     NodeList initializers = popNode();
     NodeList formals = popNode();
     // The name can be an identifier or a send in case of named constructors.
@@ -1787,7 +1818,8 @@
     TypeAnnotation type = popNode();
     Modifiers modifiers = popNode();
     pushNode(new FunctionExpression(name, formals, body, type,
-                                    modifiers, initializers, getOrSet));
+                                    modifiers, initializers, getOrSet,
+                                    asyncModifier));
   }
 
   void endFunctionDeclaration(Token endToken) {
@@ -1854,6 +1886,11 @@
     pushNode(new Throw(expression, throwToken, endToken));
   }
 
+  void endAwaitExpression(Token awaitToken, Token endToken) {
+    Expression expression = popNode();
+    pushNode(new Await(awaitToken, expression));
+  }
+
   void endRethrowStatement(Token throwToken, Token endToken) {
     pushNode(new Rethrow(throwToken, endToken));
     if (identical(throwToken.stringValue, 'throw')) {
@@ -1920,13 +1957,15 @@
 
   void endMethod(Token getOrSet, Token beginToken, Token endToken) {
     Statement body = popNode();
+    AsyncModifier asyncModifier = popNode();
     NodeList initializers = popNode();
     NodeList formalParameters = popNode();
     Expression name = popNode();
     TypeAnnotation returnType = popNode();
     Modifiers modifiers = popNode();
     pushNode(new FunctionExpression(name, formalParameters, body, returnType,
-                                    modifiers, initializers, getOrSet));
+                                    modifiers, initializers, getOrSet,
+                                    asyncModifier));
   }
 
   void handleLiteralMap(int count, Token beginToken, Token constKeyword,
@@ -1996,7 +2035,7 @@
     TypeAnnotation returnType = popNode();
     pushNode(null); // Signal "no type" to endFormalParameter.
     pushNode(new FunctionExpression(name, formals, null, returnType,
-                                    Modifiers.EMPTY, null, null));
+                                    Modifiers.EMPTY, null, null, null));
   }
 
   void handleValuedFormalParameter(Token equals, Token token) {
@@ -2079,6 +2118,7 @@
   void endFactoryMethod(Token beginToken, Token endToken) {
     super.endFactoryMethod(beginToken, endToken);
     Statement body = popNode();
+    AsyncModifier asyncModifier = popNode();
     NodeList formals = popNode();
     Node name = popNode();
 
@@ -2102,15 +2142,16 @@
     Modifiers modifiers = popNode();
 
     pushNode(new FunctionExpression(name, formals, body, null,
-                                    modifiers, null, null));
+                                    modifiers, null, null, asyncModifier));
   }
 
-  void endForIn(Token beginToken, Token inKeyword, Token endToken) {
+  void endForIn(Token awaitToken, Token forToken,
+                Token inKeyword, Token endToken) {
     Statement body = popNode();
     Expression expression = popNode();
     Node declaredIdentifier = popNode();
     pushNode(new ForIn(declaredIdentifier, expression, body,
-                                beginToken, inKeyword));
+                       awaitToken, forToken, inKeyword));
   }
 
   void endMetadataStar(int count, bool forParameter) {
@@ -2169,11 +2210,13 @@
     pushNode(new ExpressionStatement(send, semicolonToken));
   }
 
-  void endUnamedFunction(Token token) {
+  void endUnnamedFunction(Token token) {
     Statement body = popNode();
+    AsyncModifier asyncModifier = popNode();
     NodeList formals = popNode();
     pushNode(new FunctionExpression(null, formals, body, null,
-                                    Modifiers.EMPTY, null, null));
+                                    Modifiers.EMPTY, null, null,
+                                    asyncModifier));
   }
 
   void handleIsOperator(Token operathor, Token not, Token endToken) {
diff --git a/sdk/lib/_internal/compiler/implementation/scanner/parser.dart b/sdk/lib/_internal/compiler/implementation/scanner/parser.dart
index 33fbfeb..b13a7b5 100644
--- a/sdk/lib/_internal/compiler/implementation/scanner/parser.dart
+++ b/sdk/lib/_internal/compiler/implementation/scanner/parser.dart
@@ -41,6 +41,8 @@
 class Parser {
   final Listener listener;
   bool mayParseFunctionExpressions = true;
+  bool yieldIsKeyword = false;
+  bool awaitIsKeyword = false;
 
   Parser(this.listener);
 
@@ -864,7 +866,12 @@
     Token token = parseIdentifier(name);
 
     token = parseFormalParametersOpt(token);
+    bool previousYieldIsKeyword = yieldIsKeyword;
+    bool previousAwaitIsKeyword = awaitIsKeyword;
+    token = parseAsyncModifier(token);
     token = parseFunctionBody(token, false, externalModifier != null);
+    yieldIsKeyword = previousYieldIsKeyword;
+    awaitIsKeyword = previousAwaitIsKeyword;
     listener.endTopLevelMethod(start, getOrSet, token);
     return token.next;
   }
@@ -1206,12 +1213,17 @@
     token = parseQualifiedRestOpt(token);
     token = parseFormalParametersOpt(token);
     token = parseInitializersOpt(token);
+    bool previousYieldIsKeyword = yieldIsKeyword;
+    bool previousAwaitIsKeyword = awaitIsKeyword;
+    token = parseAsyncModifier(token);
     if (optional('=', token)) {
       token = parseRedirectingFactoryBody(token);
     } else {
       token = parseFunctionBody(
           token, false, staticModifier == null || externalModifier != null);
     }
+    yieldIsKeyword = previousYieldIsKeyword;
+    awaitIsKeyword = previousAwaitIsKeyword;
     listener.endMethod(getOrSet, start, token);
     return token.next;
   }
@@ -1234,6 +1246,9 @@
     token = token.next; // Skip 'factory'.
     token = parseConstructorReference(token);
     token = parseFormalParameters(token);
+    bool previousYieldIsKeyword = yieldIsKeyword;
+    bool previousAwaitIsKeyword = awaitIsKeyword;
+    token = parseAsyncModifier(token);
     if (optional('=', token)) {
       token = parseRedirectingFactoryBody(token);
     } else {
@@ -1277,21 +1292,31 @@
     listener.endFunctionName(token);
     token = parseFormalParametersOpt(token);
     token = parseInitializersOpt(token);
+    bool previousYieldIsKeyword = yieldIsKeyword;
+    bool previousAwaitIsKeyword = awaitIsKeyword;
+    token = parseAsyncModifier(token);
     if (optional('=', token)) {
       token = parseRedirectingFactoryBody(token);
     } else {
       token = parseFunctionBody(token, false, true);
     }
+    yieldIsKeyword = previousYieldIsKeyword;
+    awaitIsKeyword = previousAwaitIsKeyword;
     listener.endFunction(getOrSet, token);
     return token.next;
   }
 
-  Token parseUnamedFunction(Token token) {
-    listener.beginUnamedFunction(token);
+  Token parseUnnamedFunction(Token token) {
+    listener.beginUnnamedFunction(token);
     token = parseFormalParameters(token);
+    bool previousYieldIsKeyword = yieldIsKeyword;
+    bool previousAwaitIsKeyword = awaitIsKeyword;
+    token = parseAsyncModifier(token);
     bool isBlock = optional('{', token);
     token = parseFunctionBody(token, true, false);
-    listener.endUnamedFunction(token);
+    yieldIsKeyword = previousYieldIsKeyword;
+    awaitIsKeyword = previousAwaitIsKeyword;
+    listener.endUnnamedFunction(token);
     return isBlock ? token.next : token;
   }
 
@@ -1311,8 +1336,13 @@
     listener.endFunctionName(token);
     token = parseFormalParameters(token);
     listener.handleNoInitializers();
+    bool previousYieldIsKeyword = yieldIsKeyword;
+    bool previousAwaitIsKeyword = awaitIsKeyword;
+    token = parseAsyncModifier(token);
     bool isBlock = optional('{', token);
     token = parseFunctionBody(token, true, false);
+    yieldIsKeyword = previousYieldIsKeyword;
+    awaitIsKeyword = previousAwaitIsKeyword;
     listener.endFunction(null, token);
     return isBlock ? token.next : token;
   }
@@ -1378,6 +1408,48 @@
     return token;
   }
 
+  /// `async*` and `sync*` are parsed a two tokens, [token] and [star]. This
+  /// method checks that there is no whitespace between [token] and [star].
+  void checkStarredModifier(Token token, Token star, String name) {
+    if (star.charOffset > token.charOffset + token.charCount) {
+      listener.reportError(new TokenPair(token, star),
+          MessageKind.INVALID_STARRED_KEYWORD, {'keyword': name});
+    }
+  }
+
+  Token parseAsyncModifier(Token token) {
+    Token async;
+    Token star;
+    awaitIsKeyword = false;
+    yieldIsKeyword = false;
+    if (optional('async', token)) {
+      awaitIsKeyword = true;
+      async = token;
+      token = token.next;
+      if (optional('*', token)) {
+        yieldIsKeyword = true;
+        star = token;
+        token = token.next;
+        checkStarredModifier(async, star, 'async*');
+      }
+    } else if (optional('sync', token)) {
+      async = token;
+      token = token.next;
+      if (optional('*', token)) {
+        yieldIsKeyword = true;
+        star = token;
+        token = token.next;
+
+        checkStarredModifier(async, star, 'sync*');
+      } else {
+        listener.reportError(async,
+            MessageKind.INVALID_SYNC_MODIFIER);
+      }
+    }
+    listener.handleAsyncModifier(async, star);
+    return token;
+  }
+
   Token parseStatement(Token token) {
     final value = token.stringValue;
     if (identical(token.kind, IDENTIFIER_TOKEN)) {
@@ -1390,8 +1462,14 @@
       return parseVariablesDeclaration(token);
     } else if (identical(value, 'if')) {
       return parseIfStatement(token);
+    } else if (awaitIsKeyword && identical(value, 'await')) {
+      if (identical(token.next.stringValue, 'for')) {
+        return parseForStatement(token, token.next);
+      } else {
+        return parseExpressionStatement(token);
+      }
     } else if (identical(value, 'for')) {
-      return parseForStatement(token);
+      return parseForStatement(null, token);
     } else if (identical(value, 'rethrow')) {
       return parseRethrowStatement(token);
     } else if (identical(value, 'throw') && optional(';', token.next)) {
@@ -1415,6 +1493,8 @@
       return parseAssertStatement(token);
     } else if (identical(value, ';')) {
       return parseEmptyStatement(token);
+    } else if (yieldIsKeyword && identical(value, 'yield')) {
+      return parseYieldStatement(token);
     } else if (identical(value, 'const')) {
       return parseExpressionStatementOrConstDeclaration(token);
     } else if (token.isIdentifier()) {
@@ -1424,6 +1504,23 @@
     }
   }
 
+  Token parseYieldStatement(Token token) {
+    Token begin = token;
+    listener.beginYieldStatement(begin);
+    assert(identical('yield', token.stringValue));
+    token = token.next;
+    Token starToken;
+    if (optional('*', token)) {
+      starToken = token;
+      token = token.next;
+      checkStarredModifier(begin, starToken, 'yield*');
+    }
+    token = parseExpression(token);
+    listener.endYieldStatement(begin, starToken, token);
+    return expectSemicolon(token);
+  }
+
+
   Token parseReturnStatement(Token token) {
     Token begin = token;
     listener.beginReturnStatement(begin);
@@ -1478,7 +1575,10 @@
         BeginGroupToken beginParen = afterId;
         Token endParen = beginParen.endGroup;
         Token afterParens = endParen.next;
-        if (optional('{', afterParens) || optional('=>', afterParens)) {
+        if (optional('{', afterParens) ||
+            optional('=>', afterParens) ||
+            optional('async', afterParens) ||
+            optional('sync', afterParens)) {
           // We are looking at "type identifier '(' ... ')'" followed
           // by '=>' or '{'.
           return parseFunctionDeclaration(token);
@@ -1491,7 +1591,10 @@
       } else if (optional('(', token.next)) {
         BeginGroupToken begin = token.next;
         String afterParens = begin.endGroup.next.stringValue;
-        if (identical(afterParens, '{') || identical(afterParens, '=>')) {
+        if (identical(afterParens, '{') ||
+            identical(afterParens, '=>') ||
+            identical(afterParens, 'async') ||
+            identical(afterParens, 'sync')) {
           return parseFunctionDeclaration(token);
         }
       }
@@ -1672,7 +1775,9 @@
   Token parseUnaryExpression(Token token, bool allowCascades) {
     String value = token.stringValue;
     // Prefix:
-    if (identical(value, '+')) {
+    if (awaitIsKeyword && optional('await', token)) {
+      return parseAwaitExpression(token, allowCascades);
+    } else if (identical(value, '+')) {
       // Dart no longer allows prefix-plus.
       listener.reportError(token, MessageKind.UNSUPPORTED_PREFIX_PLUS);
       return parseUnaryExpression(token.next, allowCascades);
@@ -1767,11 +1872,14 @@
 
   Token parseParenthesizedExpressionOrFunctionLiteral(Token token) {
     BeginGroupToken beginGroup = token;
-    int kind = beginGroup.endGroup.next.kind;
+    Token nextToken = beginGroup.endGroup.next;
+    int kind = nextToken.kind;
     if (mayParseFunctionExpressions &&
-        (identical(kind, FUNCTION_TOKEN)
-            || identical(kind, OPEN_CURLY_BRACKET_TOKEN))) {
-      return parseUnamedFunction(token);
+        (identical(kind, FUNCTION_TOKEN) ||
+         identical(kind, OPEN_CURLY_BRACKET_TOKEN) ||
+         (identical(kind, KEYWORD_TOKEN) &&
+             (nextToken.value == 'async' || nextToken.value == 'sync')))) {
+      return parseUnnamedFunction(token);
     } else {
       bool old = mayParseFunctionExpressions;
       mayParseFunctionExpressions = true;
@@ -1893,7 +2001,10 @@
     if (optional('(', token)) {
       BeginGroupToken begin = token;
       String afterParens = begin.endGroup.next.stringValue;
-      if (identical(afterParens, '{') || identical(afterParens, '=>')) {
+      if (identical(afterParens, '{') ||
+          identical(afterParens, '=>') ||
+          identical(afterParens, 'async') ||
+          identical(afterParens, 'sync')) {
         return true;
       }
     }
@@ -2151,15 +2262,18 @@
     return token;
   }
 
-  Token parseForStatement(Token token) {
+  Token parseForStatement(Token awaitToken, Token token) {
     Token forToken = token;
     listener.beginForStatement(forToken);
     token = expect('for', token);
     token = expect('(', token);
     token = parseVariablesDeclarationOrExpressionOpt(token);
     if (optional('in', token)) {
-      return parseForInRest(forToken, token);
+      return parseForInRest(awaitToken, forToken, token);
     } else {
+      if (awaitToken != null) {
+        listener.reportError(awaitToken, MessageKind.INVALID_AWAIT_FOR);
+      }
       return parseForRest(forToken, token);
     }
   }
@@ -2206,13 +2320,13 @@
     return token;
   }
 
-  Token parseForInRest(Token forToken, Token token) {
+  Token parseForInRest(Token awaitToken, Token forToken, Token token) {
     assert(optional('in', token));
     Token inKeyword = token;
     token = parseExpression(token.next);
     token = expect(')', token);
     token = parseStatement(token);
-    listener.endForIn(forToken, inKeyword, token);
+    listener.endForIn(awaitToken, forToken, inKeyword, token);
     return token;
   }
 
@@ -2251,6 +2365,15 @@
     return expect('}', token);
   }
 
+  Token parseAwaitExpression(Token token, bool allowCascades) {
+    Token awaitToken = token;
+    listener.beginAwaitExpression(awaitToken);
+    token = expect('await', token);
+    token = parseUnaryExpression(token, allowCascades);
+    listener.endAwaitExpression(awaitToken, token);
+    return token;
+  }
+
   Token parseThrowExpression(Token token, bool allowCascades) {
     Token throwToken = token;
     listener.beginThrowExpression(throwToken);
diff --git a/sdk/lib/_internal/compiler/implementation/scanner/partial_parser.dart b/sdk/lib/_internal/compiler/implementation/scanner/partial_parser.dart
index 98fc1ab..c6ccbf4 100644
--- a/sdk/lib/_internal/compiler/implementation/scanner/partial_parser.dart
+++ b/sdk/lib/_internal/compiler/implementation/scanner/partial_parser.dart
@@ -103,8 +103,29 @@
     return endGroup;
   }
 
+  Token skipAsyncModifier(Token token) {
+    String value = token.stringValue;
+    if (identical(value, 'async')) {
+      token = token.next;
+      value = token.stringValue;
+
+      if (identical(value, '*')) {
+        token = token.next;
+      }
+    } else if (identical(value, 'sync')) {
+      token = token.next;
+      value = token.stringValue;
+
+      if (identical(value, '*')) {
+        token = token.next;
+      }
+    }
+    return token;
+  }
+
   Token parseFunctionBody(Token token, bool isExpression, bool allowAbstract) {
     assert(!isExpression);
+    token = skipAsyncModifier(token);
     String value = token.stringValue;
     if (identical(value, ';')) {
       if (!allowAbstract) {
diff --git a/sdk/lib/_internal/compiler/implementation/scanner/token.dart b/sdk/lib/_internal/compiler/implementation/scanner/token.dart
index 0b474d4..483eda9 100644
--- a/sdk/lib/_internal/compiler/implementation/scanner/token.dart
+++ b/sdk/lib/_internal/compiler/implementation/scanner/token.dart
@@ -169,6 +169,15 @@
   int get hashCode => computeHashCode(charOffset, info, value);
 }
 
+/// A pair of tokens marking the beginning and the end of a span. Use for error
+/// reporting.
+class TokenPair implements Spannable {
+  final Token begin;
+  final Token end;
+
+  TokenPair(this.begin, this.end);
+}
+
 /**
  * A [SymbolToken] represents the symbol in its precendence info.
  * Also used for end of file with EOF_INFO.
diff --git a/sdk/lib/_internal/compiler/implementation/ssa/builder.dart b/sdk/lib/_internal/compiler/implementation/ssa/builder.dart
index 923b6e5..abd5e29 100644
--- a/sdk/lib/_internal/compiler/implementation/ssa/builder.dart
+++ b/sdk/lib/_internal/compiler/implementation/ssa/builder.dart
@@ -5058,6 +5058,17 @@
     }
   }
 
+  visitYield(ast.Yield node) {
+    // Dummy implementation.
+    visit(node.expression);
+    pop();
+  }
+
+  visitAwait(ast.Await node) {
+    // Dummy implementation.
+    visit(node.expression);
+  }
+
   visitTypeAnnotation(ast.TypeAnnotation node) {
     compiler.internalError(node,
         'Visiting type annotation in SSA builder.');
diff --git a/sdk/lib/_internal/compiler/implementation/ssa/interceptor_simplifier.dart b/sdk/lib/_internal/compiler/implementation/ssa/interceptor_simplifier.dart
index b247730..3f17758 100644
--- a/sdk/lib/_internal/compiler/implementation/ssa/interceptor_simplifier.dart
+++ b/sdk/lib/_internal/compiler/implementation/ssa/interceptor_simplifier.dart
@@ -167,8 +167,24 @@
   bool visitInterceptor(HInterceptor node) {
     if (node.isConstant()) return false;
 
-    // If the interceptor is used by multiple instructions, specialize
-    // it with a set of classes it intercepts.
+    // Specialize the interceptor with set of classes it intercepts, considering
+    // all uses.  (The specialized interceptor has a shorter dispatch chain).
+    // This operation applies only where the interceptor is used to dispatch a
+    // method.  Other uses, e.g. as an ordinary argument or a HIs check use the
+    // most general interceptor.
+    //
+    // TODO(sra): Take into account the receiver type at each call.  e.g:
+    //
+    //     (a) => a.length + a.hashCode
+    //
+    // Currently we use the most general interceptor since all intercepted types
+    // implement `hashCode`. But in this example, `a.hashCode` is only reached
+    // if `a.length` succeeds, which is indicated by the hashCode receiver being
+    // a HTypeKnown instruction.
+
+    int useCount(HInstruction user, HInstruction used) =>
+        user.inputs.where((input) => input == used).length;
+
     Set<ClassElement> interceptedClasses;
     JavaScriptBackend backend = compiler.backend;
     HInstruction dominator = findDominator(node.usedBy);
@@ -176,7 +192,8 @@
     // selector of that instruction.
     if (dominator is HInvokeDynamic &&
         dominator.isCallOnInterceptor(compiler) &&
-        node == dominator.receiver) {
+        node == dominator.receiver &&
+        useCount(dominator, node) == 1) {
       interceptedClasses =
             backend.getInterceptedClassesOn(dominator.selector.name);
 
@@ -202,7 +219,14 @@
       for (HInstruction user in node.usedBy) {
         if (user is HInvokeDynamic &&
             user.isCallOnInterceptor(compiler) &&
-            node == user.receiver) {
+            node == user.receiver &&
+            useCount(user, node) == 1) {
+          interceptedClasses.addAll(
+              backend.getInterceptedClassesOn(user.selector.name));
+        } else if (user is HInvokeSuper &&
+                   user.isCallOnInterceptor(compiler) &&
+                   node == user.receiver &&
+                   useCount(user, node) == 1) {
           interceptedClasses.addAll(
               backend.getInterceptedClassesOn(user.selector.name));
         } else {
@@ -215,6 +239,7 @@
     }
 
     HInstruction receiver = node.receiver;
+
     if (canUseSelfForInterceptor(receiver, interceptedClasses)) {
       return rewriteToUseSelfAsInterceptor(node, receiver);
     }
diff --git a/sdk/lib/_internal/compiler/implementation/ssa/nodes.dart b/sdk/lib/_internal/compiler/implementation/ssa/nodes.dart
index 172de7f..2973145 100644
--- a/sdk/lib/_internal/compiler/implementation/ssa/nodes.dart
+++ b/sdk/lib/_internal/compiler/implementation/ssa/nodes.dart
@@ -1498,7 +1498,20 @@
                type,
                {this.isSetter})
       : super(element, inputs, type);
-  toString() => 'invoke super: ${element.name}';
+
+  HInstruction get receiver => inputs[0];
+  HInstruction getDartReceiver(Compiler compiler) {
+    return isCallOnInterceptor(compiler) ? inputs[1] : inputs[0];
+  }
+
+  /**
+   * Returns whether this call is on an interceptor object.
+   */
+  bool isCallOnInterceptor(Compiler compiler) {
+    return isInterceptedCall && receiver.isInterceptor(compiler);
+  }
+
+  toString() => 'invoke super: $element';
   accept(HVisitor visitor) => visitor.visitInvokeSuper(this);
 
   HInstruction get value {
diff --git a/sdk/lib/_internal/compiler/implementation/tree/nodes.dart b/sdk/lib/_internal/compiler/implementation/tree/nodes.dart
index 5bb147e..1e4b75d 100644
--- a/sdk/lib/_internal/compiler/implementation/tree/nodes.dart
+++ b/sdk/lib/_internal/compiler/implementation/tree/nodes.dart
@@ -9,6 +9,8 @@
 
   R visitNode(Node node);
 
+  R visitAsyncModifier(AsyncModifier node) => visitNode(node);
+  R visitAwait(Await node) => visitExpression(node);
   R visitBlock(Block node) => visitStatement(node);
   R visitBreakStatement(BreakStatement node) => visitGotoStatement(node);
   R visitCascade(Cascade node) => visitExpression(node);
@@ -88,6 +90,7 @@
   R visitTypeVariable(TypeVariable node) => visitNode(node);
   R visitVariableDefinitions(VariableDefinitions node) => visitStatement(node);
   R visitWhile(While node) => visitLoop(node);
+  R visitYield(Yield node) => visitStatement(node);
 }
 
 Token firstBeginToken(Node first, Node second) {
@@ -141,6 +144,8 @@
 
   Token getEndToken();
 
+  AsyncModifier asAsyncModifier() => null;
+  Await asAwait() => null;
   Block asBlock() => null;
   BreakStatement asBreakStatement() => null;
   Cascade asCascade() => null;
@@ -207,6 +212,7 @@
   Typedef asTypedef() => null;
   VariableDefinitions asVariableDefinitions() => null;
   While asWhile() => null;
+  Yield asYield() => null;
 
   bool isValidBreakTarget() => false;
   bool isValidContinueTarget() => false;
@@ -707,6 +713,34 @@
   Token getEndToken() => function.getEndToken();
 }
 
+/// Node representing the method implementation modifiers `sync*`, `async`, and
+/// `async*` or the invalid modifier `sync`.
+class AsyncModifier extends Node {
+  /// The `async` or `sync` token.
+  final Token asyncToken;
+
+  /// The `*` token.
+  final Token starToken;
+
+  AsyncModifier(this.asyncToken, this.starToken);
+
+  AsyncModifier asAsyncModifier() => this;
+
+  accept(Visitor visitor) => visitor.visitAsyncModifier(this);
+
+  visitChildren(Visitor visitor) {}
+
+  Token getBeginToken() => asyncToken;
+
+  Token getEndToken() => starToken != null ? starToken : asyncToken;
+
+  /// Is `true` if this modifier is either `async` or `async*`.
+  bool get isAsynchronous => asyncToken.value == 'async';
+
+  /// Is `true` if this modifier is either `sync*` or `async*`.
+  bool get isYielding => starToken != null;
+}
+
 class FunctionExpression extends Expression with StoredTreeElementMixin {
   final Node name;
 
@@ -723,9 +757,11 @@
   final NodeList initializers;
 
   final Token getOrSet;
+  final AsyncModifier asyncModifier;
 
   FunctionExpression(this.name, this.parameters, this.body, this.returnType,
-                     this.modifiers, this.initializers, this.getOrSet) {
+                     this.modifiers, this.initializers, this.getOrSet,
+                     this.asyncModifier) {
     assert(modifiers != null);
   }
 
@@ -743,6 +779,7 @@
     if (name != null) name.accept(visitor);
     if (parameters != null) parameters.accept(visitor);
     if (initializers != null) initializers.accept(visitor);
+    if (asyncModifier != null) asyncModifier.accept(visitor);
     if (body != null) body.accept(visitor);
   }
 
@@ -1041,6 +1078,29 @@
   }
 }
 
+class Yield extends Statement {
+  final Node expression;
+  final Token yieldToken;
+  final Token starToken;
+  final Token endToken;
+
+  Yield(this.yieldToken, this.starToken, this.expression, this.endToken);
+
+  Yield asYield() => this;
+
+  bool get hasStar => starToken != null;
+
+  accept(Visitor visitor) => visitor.visitYield(this);
+
+  visitChildren(Visitor visitor) {
+    expression.accept(visitor);
+  }
+
+  Token getBeginToken() => yieldToken;
+
+  Token getEndToken() => endToken;
+}
+
 class RedirectingFactoryBody extends Statement with StoredTreeElementMixin {
   final Node constructorReference;
   final Token beginToken;
@@ -1102,6 +1162,26 @@
   Token getEndToken() => endToken;
 }
 
+class Await extends Expression {
+  final Expression expression;
+
+  final Token awaitToken;
+
+  Await(this.awaitToken, this.expression);
+
+  Await asAwait() => this;
+
+  accept(Visitor visitor) => visitor.visitAwait(this);
+
+  visitChildren(Visitor visitor) {
+    expression.accept(visitor);
+  }
+
+  Token getBeginToken() => awaitToken;
+
+  Token getEndToken() => expression.getEndToken();
+}
+
 class Rethrow extends Statement {
   final Token throwToken;
   final Token endToken;
@@ -1694,11 +1774,15 @@
   final Node declaredIdentifier;
   final Expression expression;
 
+  final Token awaitToken;
   final Token forToken;
   final Token inToken;
 
   ForIn(this.declaredIdentifier, this.expression,
-        Statement body, this.forToken, this.inToken) : super(body);
+        Statement body, this.awaitToken, this.forToken, this.inToken)
+      : super(body);
+
+  bool get isAsync => awaitToken != null;
 
   Expression get condition => null;
 
@@ -1712,7 +1796,7 @@
     body.accept(visitor);
   }
 
-  Token getBeginToken() => forToken;
+  Token getBeginToken() => awaitToken != null ? awaitToken : forToken;
 
   Token getEndToken() => body.getEndToken();
 }
@@ -2168,6 +2252,7 @@
   bool get isErroneous => true;
 
   // FunctionExpression.
+  get asyncModifier => null;
   get parameters => null;
   get body => null;
   get returnType => null;
diff --git a/sdk/lib/_internal/compiler/implementation/tree/prettyprint.dart b/sdk/lib/_internal/compiler/implementation/tree/prettyprint.dart
index 93a3212..b0b1de1 100644
--- a/sdk/lib/_internal/compiler/implementation/tree/prettyprint.dart
+++ b/sdk/lib/_internal/compiler/implementation/tree/prettyprint.dart
@@ -121,6 +121,12 @@
     closeNode();
   }
 
+  visitAsyncModifier(AsyncModifier node) {
+    openAndCloseNode(node, "AsyncModifier",
+        {'asyncToken': node.asyncToken,
+         'starToken': node.starToken});
+  }
+
   visitBlock(Block node) {
     visitNodeWithChildren(node, "Block");
   }
@@ -181,7 +187,9 @@
   }
 
   visitForIn(ForIn node) {
-    visitNodeWithChildren(node, "ForIn");
+    openNode(node, "ForIn", {'await': node.awaitToken});
+    node.visitChildren(this);
+    closeNode();
   }
 
   visitFunctionDeclaration(FunctionDeclaration node) {
@@ -318,6 +326,12 @@
     closeNode();
   }
 
+  visitYield(Yield node) {
+    openNode(node, "Yield", {'star': node.starToken});
+    visitChildNode(node.expression, "expression");
+    closeNode();
+  }
+
   visitChildNode(Node node, String fieldName) {
     if (node == null) return;
     addCurrentIndent();
@@ -381,6 +395,10 @@
     visitNodeWithChildren(node, "Throw");
   }
 
+  visitAwait(Await node) {
+    visitNodeWithChildren(node, "Await");
+  }
+
   visitTryStatement(TryStatement node) {
     visitNodeWithChildren(node, "TryStatement");
   }
diff --git a/sdk/lib/_internal/compiler/implementation/tree/unparser.dart b/sdk/lib/_internal/compiler/implementation/tree/unparser.dart
index 288b31a..b4ce89d 100644
--- a/sdk/lib/_internal/compiler/implementation/tree/unparser.dart
+++ b/sdk/lib/_internal/compiler/implementation/tree/unparser.dart
@@ -217,6 +217,13 @@
     }
   }
 
+  visitAsyncModifier(AsyncModifier node) {
+    write(node.asyncToken.value);
+    if (node.starToken != null) {
+      write(node.starToken.value);
+    }
+  }
+
   visitFunctionExpression(FunctionExpression node) {
     if (!node.modifiers.nodes.isEmpty) {
       visit(node.modifiers);
@@ -239,6 +246,7 @@
       unparseNodeListFrom(node.initializers, node.initializers.nodes,
           spaces: true);
     }
+    visit(node.asyncModifier);
     if (node.body != null && node.body is! EmptyStatement) space();
     visit(node.body);
   }
@@ -378,6 +386,15 @@
     if (node.endToken != null) write(node.endToken.value);
   }
 
+  visitYield(Yield node) {
+    write(node.yieldToken);
+    write(node.starToken);
+    space();
+    visit(node.expression);
+    write(node.endToken);
+  }
+
+
   unparseSendReceiver(Send node, {bool spacesNeeded: false}) {
     if (node.receiver == null) return;
     visit(node.receiver);
@@ -488,6 +505,12 @@
     visit(node.expression);
   }
 
+  visitAwait(Await node) {
+    write(node.awaitToken.value);
+    write(' ');
+    visit(node.expression);
+  }
+
   visitTypeAnnotation(TypeAnnotation node) {
     visit(node.typeName);
     visit(node.typeArguments);
@@ -582,6 +605,10 @@
   }
 
   visitForIn(ForIn node) {
+    if (node.awaitToken != null) {
+      write(node.awaitToken.value);
+      write(' ');
+    }
     write(node.forToken.value);
     space();
     write('(');
diff --git a/sdk/lib/_internal/compiler/implementation/typechecker.dart b/sdk/lib/_internal/compiler/implementation/typechecker.dart
index 7cef548..b1fb8cd 100644
--- a/sdk/lib/_internal/compiler/implementation/typechecker.dart
+++ b/sdk/lib/_internal/compiler/implementation/typechecker.dart
@@ -250,6 +250,7 @@
 
   Node lastSeenNode;
   DartType expectedReturnType;
+  AsyncMarker currentAsyncMarker = AsyncMarker.SYNC;
 
   final ClassElement currentClass;
 
@@ -604,10 +605,13 @@
       returnType = functionType.returnType;
       type = functionType;
     }
-    DartType previous = expectedReturnType;
+    DartType previousReturnType = expectedReturnType;
     expectedReturnType = returnType;
+    AsyncMarker previousAsyncMarker = currentAsyncMarker;
+    currentAsyncMarker = element.asyncMarker;
     analyze(node.body);
-    expectedReturnType = previous;
+    expectedReturnType = previousReturnType;
+    currentAsyncMarker = previousAsyncMarker;
     return type;
   }
 
@@ -1589,6 +1593,36 @@
     return const DynamicType();
   }
 
+  DartType visitAwait(Await node) {
+    DartType expressionType = analyze(node.expression);
+    DartType resultType = expressionType;
+    if (expressionType is InterfaceType) {
+      InterfaceType futureType =
+          expressionType.asInstanceOf(compiler.futureClass);
+      if (futureType != null) {
+        resultType = futureType.typeArguments.first;
+      }
+    }
+    return resultType;
+  }
+
+  DartType visitYield(Yield node) {
+    DartType resultType = analyze(node.expression);
+    if (!node.hasStar) {
+      if (currentAsyncMarker.isAsync) {
+        resultType =
+            compiler.streamClass.thisType.createInstantiation(
+                <DartType>[resultType]);
+      } else {
+        resultType =
+            compiler.iterableClass.thisType.createInstantiation(
+                 <DartType>[resultType]);
+      }
+    }
+    checkAssignable(node, resultType, expectedReturnType);
+    return const StatementType();
+  }
+
   DartType visitTypeAnnotation(TypeAnnotation node) {
     return elements.getType(node);
   }
diff --git a/sdk/lib/_internal/compiler/implementation/use_unused_api.dart b/sdk/lib/_internal/compiler/implementation/use_unused_api.dart
index 354d710..a381aaa 100644
--- a/sdk/lib/_internal/compiler/implementation/use_unused_api.dart
+++ b/sdk/lib/_internal/compiler/implementation/use_unused_api.dart
@@ -72,6 +72,8 @@
 
 void useNode(tree.Node node) {
   node
+    ..asAsyncModifier()
+    ..asAwait()
     ..asBreakStatement()
     ..asCascade()
     ..asCatchBlock()
@@ -110,7 +112,8 @@
     ..asTypeAnnotation()
     ..asTypeVariable()
     ..asTypedef()
-    ..asWhile();
+    ..asWhile()
+    ..asYield();
 }
 
 void useUtil(util.Link link) {
@@ -233,7 +236,8 @@
     ..buildBooleanLiteral(null)
     ..buildNullLiteral()
     ..buildStringLiteral(null)
-    ..buildDynamicGet(null, null);
+    ..buildDynamicGet(null, null)
+    ..buildSuperGet(null);
 }
 
 useCompiler(dart2jslib.Compiler compiler) {
diff --git a/sdk/lib/_internal/compiler/implementation/warnings.dart b/sdk/lib/_internal/compiler/implementation/warnings.dart
index 42da42c3..d6945d2 100644
--- a/sdk/lib/_internal/compiler/implementation/warnings.dart
+++ b/sdk/lib/_internal/compiler/implementation/warnings.dart
@@ -82,7 +82,13 @@
    */
   final List examples;
 
-  const MessageKind(this.template, {this.howToFix, this.examples});
+  /// Additional options needed for the examples to work.
+  final List<String> options;
+
+  const MessageKind(this.template,
+                    {this.howToFix,
+                     this.examples,
+                     this.options: const <String>[]});
 
   /// Do not use this. It is here for legacy and debugging. It violates item 4
   /// above.
@@ -1976,6 +1982,105 @@
     " require a preamble file located in:\n"
     "  <sdk>/lib/_internal/compiler/js_lib/preambles.");
 
+
+  static const MessageKind EXPERIMENTAL_ASYNC_AWAIT = const MessageKind(
+      "Experimental language feature 'async/await' is not supported.");
+
+  static const MessageKind INVALID_STARRED_KEYWORD = const MessageKind(
+      "Invalid '#{keyword}' keyword.",
+      options: const ['--enable-async'],
+      howToFix: "Try removing whitespace between '#{keyword}' and '*'.",
+      examples: const [
+        "main() async * {}",
+        "main() sync * {}",
+        "main() async* { yield * 0; }"
+      ]);
+
+  static const MessageKind INVALID_SYNC_MODIFIER = const MessageKind(
+      "Invalid modifier 'sync'.",
+      options: const ['--enable-async'],
+      howToFix: "Try replacing 'sync' with 'sync*'.",
+      examples: const [
+        "main() sync {}"
+      ]);
+
+  static const MessageKind INVALID_AWAIT_FOR = const MessageKind(
+      "'await' is only supported on for-in loops.",
+      options: const ['--enable-async'],
+      howToFix: "Try rewriting the loop as a for-in loop or removing the "
+                "'await' keyword.",
+      examples: const ["""
+main() async* {
+  await for (int i = 0; i < 10; i++) {}
+}
+"""]);
+
+  static const MessageKind ASYNC_MODIFIER_ON_ABSTRACT_METHOD =
+      const MessageKind(
+          "The modifier '#{modifier}' is not allowed on an abstract method.",
+          options: const ['--enable-async'],
+          howToFix: "Try removing the '#{modifier}' modifier or adding a "
+                    "body to the method.",
+          examples: const ["""
+abstract class A {
+  method() async;
+}
+class B extends A {
+  method() {}
+}
+main() {
+  A a = new B();
+  a.method();
+}
+"""]);
+
+  static const MessageKind ASYNC_MODIFIER_ON_CONSTRUCTOR =
+      const MessageKind(
+          "The modifier '#{modifier}' is not allowed on constructors.",
+          options: const ['--enable-async'],
+          howToFix: "Try removing the '#{modifier}' modifier.",
+          examples: const ["""
+class A {
+  A() async;
+}
+main() => new A();""",
+
+"""
+class A {
+  A();
+  factory A.a() async* => new A();
+}
+main() => new A.a();"""]);
+
+  static const MessageKind YIELDING_MODIFIER_ON_ARROW_BODY =
+      const MessageKind(
+          "The modifier '#{modifier}' is not allowed on methods implemented "
+          "using '=>'.",
+          options: const ['--enable-async'],
+          howToFix: "Try removing the '#{modifier}' modifier or implementing "
+                    "the method body using a block: '{ ... }'.",
+          examples: const ["main() sync* => null;", "main() async* => null;"]);
+
+  // TODO(johnniwinther): Check for 'async' as identifier.
+  static const MessageKind ASYNC_KEYWORD_AS_IDENTIFIER = const MessageKind(
+      "'#{keyword}' cannot be used as an identifier in a function body marked "
+      "with '#{modifier}'.",
+      options: const ['--enable-async'],
+      howToFix: "Try removing the '#{modifier}' modifier or renaming the "
+                "identifier.",
+      examples: const ["""
+main() async {
+ var await;
+}""",
+"""
+main() async* {
+ var yield;
+}""",
+"""
+main() sync* {
+ var yield;
+}"""]);
+
   //////////////////////////////////////////////////////////////////////////////
   // Patch errors start.
   //////////////////////////////////////////////////////////////////////////////
diff --git a/sdk/lib/_internal/compiler/js_lib/convert_patch.dart b/sdk/lib/_internal/compiler/js_lib/convert_patch.dart
index 2686ca6..bd8816f 100644
--- a/sdk/lib/_internal/compiler/js_lib/convert_patch.dart
+++ b/sdk/lib/_internal/compiler/js_lib/convert_patch.dart
@@ -369,3 +369,10 @@
     _sink.close();
   }
 }
+
+@patch class Utf8Decoder {
+  @patch
+  Converter<List<int>,dynamic> fuse(Converter<String, dynamic> next) {
+    return super.fuse(next);
+  }
+}
diff --git a/sdk/lib/_internal/pub/lib/src/barback/asset_environment.dart b/sdk/lib/_internal/pub/lib/src/barback/asset_environment.dart
index 4343536..035dbe6 100644
--- a/sdk/lib/_internal/pub/lib/src/barback/asset_environment.dart
+++ b/sdk/lib/_internal/pub/lib/src/barback/asset_environment.dart
@@ -70,8 +70,8 @@
     if (hostname == null) hostname = "localhost";
     if (basePort == null) basePort = 0;
 
-    return entrypoint.loadPackageGraph().then((graph) {
-      log.fine("Loaded package graph.");
+    return log.progress("Loading asset environment", () async {
+      var graph = await entrypoint.loadPackageGraph();
       graph = _adjustPackageGraph(graph, mode, packages);
       var barback = new Barback(new PubPackageProvider(graph));
       barback.log.listen(_log);
@@ -79,9 +79,9 @@
       var environment = new AssetEnvironment._(graph, barback, mode,
           watcherType, hostname, basePort);
 
-      return environment._load(entrypoints: entrypoints, useDart2JS: useDart2JS)
-          .then((_) => environment);
-    });
+      await environment._load(entrypoints: entrypoints, useDart2JS: useDart2JS);
+      return environment;
+    }, fine: true);
   }
 
   /// Return a version of [graph] that's restricted to [packages] (if passed)
diff --git a/sdk/lib/_internal/pub/lib/src/barback/transformer_config.dart b/sdk/lib/_internal/pub/lib/src/barback/transformer_config.dart
index e6f9912..c6906dd 100644
--- a/sdk/lib/_internal/pub/lib/src/barback/transformer_config.dart
+++ b/sdk/lib/_internal/pub/lib/src/barback/transformer_config.dart
@@ -4,6 +4,7 @@
 
 library pub.barback.transformer_config;
 
+import 'package:glob/glob.dart';
 import 'package:path/path.dart' as p;
 import 'package:source_span/source_span.dart';
 import 'package:yaml/yaml.dart';
@@ -38,7 +39,7 @@
   /// This is processed before [excludes]. If a transformer has both includes
   /// and excludes, then the set of included assets is determined and assets
   /// are excluded from that resulting set.
-  final Set<String> includes;
+  final Set<Glob> includes;
 
   /// The primary input exclusions.
   ///
@@ -48,7 +49,7 @@
   /// This is processed after [includes]. If a transformer has both includes
   /// and excludes, then the set of included assets is determined and assets
   /// are excluded from that resulting set.
-  final Set<String> excludes;
+  final Set<Glob> excludes;
 
   /// Returns whether this config excludes certain asset ids from being
   /// processed.
@@ -58,8 +59,17 @@
   /// the package's dependers.
   bool get canTransformPublicFiles {
     if (includes == null) return true;
-    return includes.any((path) =>
-        p.url.isWithin('lib', path) || p.url.isWithin('bin', path));
+    return includes.any((glob) {
+      // Check whether the first path component of the glob is "lib", "bin", or
+      // contains wildcards that may cause it to match "lib" or "bin".
+      var first = p.posix.split(glob.toString()).first;
+      if (first.contains('{') || first.contains('*') || first.contains('[') ||
+          first.contains('?')) {
+        return true;
+      }
+
+      return first == 'lib' || first == 'bin';
+    });
   }
 
   /// Parses [identifier] as a [TransformerId] with [configuration].
@@ -76,20 +86,23 @@
       var fieldNode = configurationNode.nodes[key];
       var field = fieldNode.value;
 
-      if (field is String) return new Set.from([field]);
+      if (field is String) {
+        return new Set.from([new Glob(field, context: p.url, recursive: true)]);
+      }
 
-      if (field is List) {
-        for (var node in field.nodes) {
-          if (node.value is String) continue;
-          throw new SourceSpanFormatException(
-              '"$key" field may contain only strings.', node.span);
-        }
-
-        return new Set.from(field);
-      } else {
+      if (field is! List) {
         throw new SourceSpanFormatException(
             '"$key" field must be a string or list.', fieldNode.span);
       }
+
+      return new Set.from(field.nodes.map((node) {
+        if (node.value is String) {
+          return new Glob(node.value, context: p.url, recursive: true);
+        }
+
+        throw new SourceSpanFormatException(
+            '"$key" field may contain only strings.', node.span);
+      }));
     }
 
     var includes = null;
@@ -133,13 +146,15 @@
   /// [pathWithinPackage] must be a URL-style path relative to the containing
   /// package's root directory.
   bool canTransform(String pathWithinPackage) {
-    // TODO(rnystrom): Support globs in addition to paths. See #17093.
     if (excludes != null) {
       // If there are any excludes, it must not match any of them.
-      if (excludes.contains(pathWithinPackage)) return false;
+      for (var exclude in excludes) {
+        if (exclude.matches(pathWithinPackage)) return false;
+      }
     }
 
     // If there are any includes, it must match one of them.
-    return includes == null || includes.contains(pathWithinPackage);
+    return includes == null ||
+        includes.any((include) => include.matches(pathWithinPackage));
   }
 }
diff --git a/sdk/lib/_internal/pub/lib/src/entrypoint.dart b/sdk/lib/_internal/pub/lib/src/entrypoint.dart
index 32c42af..940efab 100644
--- a/sdk/lib/_internal/pub/lib/src/entrypoint.dart
+++ b/sdk/lib/_internal/pub/lib/src/entrypoint.dart
@@ -432,35 +432,34 @@
   /// If [result] is passed, this loads the graph from it without re-parsing the
   /// lockfile or any pubspecs. Otherwise, before loading, this makes sure the
   /// lockfile and dependencies are installed and up to date.
-  Future<PackageGraph> loadPackageGraph([SolveResult result]) {
-    if (_packageGraph != null) return new Future.value(_packageGraph);
+  Future<PackageGraph> loadPackageGraph([SolveResult result]) async {
+    if (_packageGraph != null) return _packageGraph;
 
-    return new Future.sync(() {
+    var graph = await log.progress("Loading package graph", () async {
       if (result != null) {
-        return Future.wait(result.packages.map((id) {
-          return cache.sources[id.source].getDirectory(id)
-              .then((dir) => new Package(result.pubspecs[id.name], dir));
-        })).then((packages) {
-          return new PackageGraph(this, new LockFile(result.packages),
-              new Map.fromIterable(packages, key: (package) => package.name));
-        });
-      } else {
-        return ensureLockFileIsUpToDate().then((_) {
-          return Future.wait(lockFile.packages.values.map((id) {
-            var source = cache.sources[id.source];
-            return source.getDirectory(id)
-                .then((dir) => new Package.load(id.name, dir, cache.sources));
-          })).then((packages) {
-            var packageMap = new Map.fromIterable(packages, key: (p) => p.name);
-            packageMap[root.name] = root;
-            return new PackageGraph(this, lockFile, packageMap);
-          });
-        });
+        var packages = await Future.wait(result.packages.map((id) async {
+          var dir = await cache.sources[id.source].getDirectory(id);
+          return new Package(result.pubspecs[id.name], dir);
+        }));
+
+        return new PackageGraph(this, new LockFile(result.packages),
+            new Map.fromIterable(packages, key: (package) => package.name));
       }
-    }).then((graph) {
-      _packageGraph = graph;
-      return graph;
-    });
+
+      await ensureLockFileIsUpToDate();
+      var packages = await Future.wait(lockFile.packages.values.map((id) async {
+        var source = cache.sources[id.source];
+        var dir = await source.getDirectory(id);
+        return new Package.load(id.name, dir, cache.sources);
+      }));
+
+      var packageMap = new Map.fromIterable(packages, key: (p) => p.name);
+      packageMap[root.name] = root;
+      return new PackageGraph(this, lockFile, packageMap);
+    }, fine: true);
+
+    _packageGraph = graph;
+    return graph;
   }
 
   /// Saves a list of concrete package versions to the `pubspec.lock` file.
diff --git a/sdk/lib/_internal/pub/lib/src/utils.dart b/sdk/lib/_internal/pub/lib/src/utils.dart
index aea0401..4daec90 100644
--- a/sdk/lib/_internal/pub/lib/src/utils.dart
+++ b/sdk/lib/_internal/pub/lib/src/utils.dart
@@ -163,6 +163,16 @@
   return result.toString();
 }
 
+/// Pads [source] to [length] by adding [char]s at the beginning.
+///
+/// If [char] is `null`, it defaults to a space.
+String padLeft(String source, int length, [String char]) {
+  if (char == null) char = ' ';
+  if (source.length >= length) return source;
+
+  return char * (length - source.length) + source;
+}
+
 /// Returns a labelled sentence fragment starting with [name] listing the
 /// elements [iter].
 ///
@@ -707,8 +717,17 @@
   var result = duration.inMinutes > 0 ? "${duration.inMinutes}:" : "";
 
   var s = duration.inSeconds % 59;
-  var ms = (duration.inMilliseconds % 1000) ~/ 100;
-  return result + "$s.${ms}s";
+  var ms = duration.inMilliseconds % 1000;
+
+  // If we're using verbose logging, be more verbose but more accurate when
+  // reporting timing information.
+  if (log.verbosity.isLevelVisible(log.Level.FINE)) {
+    ms = padLeft(ms.toString(), 3, '0');
+  } else {
+    ms ~/= 100;
+  }
+
+  return "$result$s.${ms}s";
 }
 
 /// Decodes a URL-encoded string.
diff --git a/sdk/lib/_internal/pub/test/transformer/exclusion/exclude_asset_glob_test.dart b/sdk/lib/_internal/pub/test/transformer/exclusion/exclude_asset_glob_test.dart
new file mode 100644
index 0000000..812e7b4
--- /dev/null
+++ b/sdk/lib/_internal/pub/test/transformer/exclusion/exclude_asset_glob_test.dart
@@ -0,0 +1,47 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS d.file
+// for 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 pub_tests;
+
+import '../../descriptor.dart' as d;
+import '../../test_pub.dart';
+import '../../serve/utils.dart';
+
+main() {
+  initConfig();
+  withBarbackVersions("any", () {
+    integration("allows a glob to exclude", () {
+      d.dir(appPath, [
+        d.pubspec({
+          "name": "myapp",
+          "transformers": [
+            {
+              "myapp/src/transformer": {
+                "\$exclude": "**/foo.txt"
+              }
+            }
+          ]
+        }),
+        d.dir("lib", [d.dir("src", [
+          d.file("transformer.dart", REWRITE_TRANSFORMER)
+        ])]),
+        d.dir("web", [
+          d.file("foo.txt", "foo"),
+          d.file("bar.txt", "bar"),
+          d.dir("sub", [
+            d.file("foo.txt", "foo"),
+          ])
+        ])
+      ]).create();
+
+      createLockFile('myapp', pkg: ['barback']);
+
+      pubServe();
+      requestShould404("foo.out");
+      requestShouldSucceed("bar.out", "bar.out");
+      requestShould404("sub/foo.out");
+      endPubServe();
+    });
+  });
+}
diff --git a/sdk/lib/_internal/pub/test/transformer/exclusion/exclude_asset_prefix_test.dart b/sdk/lib/_internal/pub/test/transformer/exclusion/exclude_asset_prefix_test.dart
new file mode 100644
index 0000000..6e2cfac
--- /dev/null
+++ b/sdk/lib/_internal/pub/test/transformer/exclusion/exclude_asset_prefix_test.dart
@@ -0,0 +1,51 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS d.file
+// for 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 pub_tests;
+
+import '../../descriptor.dart' as d;
+import '../../test_pub.dart';
+import '../../serve/utils.dart';
+
+main() {
+  initConfig();
+  withBarbackVersions("any", () {
+    integration("allows a directory prefix to exclude", () {
+      d.dir(appPath, [
+        d.pubspec({
+          "name": "myapp",
+          "transformers": [
+            {
+              "myapp/src/transformer": {
+                "\$exclude": "web/sub"
+              }
+            }
+          ]
+        }),
+        d.dir("lib", [d.dir("src", [
+          d.file("transformer.dart", REWRITE_TRANSFORMER)
+        ])]),
+        d.dir("web", [
+          d.file("foo.txt", "foo"),
+          d.file("bar.txt", "bar"),
+          d.dir("sub", [
+            d.file("foo.txt", "foo"),
+          ]),
+          d.dir("subbub", [
+            d.file("foo.txt", "foo"),
+          ])
+        ])
+      ]).create();
+
+      createLockFile('myapp', pkg: ['barback']);
+
+      pubServe();
+      requestShouldSucceed("foo.out", "foo.out");
+      requestShouldSucceed("bar.out", "bar.out");
+      requestShouldSucceed("subbub/foo.out", "foo.out");
+      requestShould404("sub/foo.out");
+      endPubServe();
+    });
+  });
+}
diff --git a/sdk/lib/_internal/pub/test/transformer/exclusion/include_asset_glob_test.dart b/sdk/lib/_internal/pub/test/transformer/exclusion/include_asset_glob_test.dart
new file mode 100644
index 0000000..f153420
--- /dev/null
+++ b/sdk/lib/_internal/pub/test/transformer/exclusion/include_asset_glob_test.dart
@@ -0,0 +1,47 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS d.file
+// for 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 pub_tests;
+
+import '../../descriptor.dart' as d;
+import '../../test_pub.dart';
+import '../../serve/utils.dart';
+
+main() {
+  initConfig();
+  withBarbackVersions("any", () {
+    integration("allows a glob to include", () {
+      d.dir(appPath, [
+        d.pubspec({
+          "name": "myapp",
+          "transformers": [
+            {
+              "myapp/src/transformer": {
+                "\$include": "**/foo.txt"
+              }
+            }
+          ]
+        }),
+        d.dir("lib", [d.dir("src", [
+          d.file("transformer.dart", REWRITE_TRANSFORMER)
+        ])]),
+        d.dir("web", [
+          d.file("foo.txt", "foo"),
+          d.file("bar.txt", "bar"),
+          d.dir("sub", [
+            d.file("foo.txt", "foo"),
+          ])
+        ])
+      ]).create();
+
+      createLockFile('myapp', pkg: ['barback']);
+
+      pubServe();
+      requestShouldSucceed("foo.out", "foo.out");
+      requestShould404("bar.out");
+      requestShouldSucceed("sub/foo.out", "foo.out");
+      endPubServe();
+    });
+  });
+}
diff --git a/sdk/lib/_internal/pub/test/transformer/exclusion/include_asset_prefix_test.dart b/sdk/lib/_internal/pub/test/transformer/exclusion/include_asset_prefix_test.dart
new file mode 100644
index 0000000..6434b64
--- /dev/null
+++ b/sdk/lib/_internal/pub/test/transformer/exclusion/include_asset_prefix_test.dart
@@ -0,0 +1,51 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS d.file
+// for 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 pub_tests;
+
+import '../../descriptor.dart' as d;
+import '../../test_pub.dart';
+import '../../serve/utils.dart';
+
+main() {
+  initConfig();
+  withBarbackVersions("any", () {
+    integration("allows a directory prefix to include", () {
+      d.dir(appPath, [
+        d.pubspec({
+          "name": "myapp",
+          "transformers": [
+            {
+              "myapp/src/transformer": {
+                "\$include": "web/sub"
+              }
+            }
+          ]
+        }),
+        d.dir("lib", [d.dir("src", [
+          d.file("transformer.dart", REWRITE_TRANSFORMER)
+        ])]),
+        d.dir("web", [
+          d.file("foo.txt", "foo"),
+          d.file("bar.txt", "bar"),
+          d.dir("sub", [
+            d.file("foo.txt", "foo"),
+          ]),
+          d.dir("subbub", [
+            d.file("foo.txt", "foo"),
+          ])
+        ])
+      ]).create();
+
+      createLockFile('myapp', pkg: ['barback']);
+
+      pubServe();
+      requestShould404("foo.out");
+      requestShould404("bar.out");
+      requestShouldSucceed("sub/foo.out", "foo.out");
+      requestShould404("subbub/foo.out");
+      endPubServe();
+    });
+  });
+}
diff --git a/sdk/lib/_internal/pub_generated/lib/src/barback/asset_environment.dart b/sdk/lib/_internal/pub_generated/lib/src/barback/asset_environment.dart
index 27c2593..5a6000b 100644
--- a/sdk/lib/_internal/pub_generated/lib/src/barback/asset_environment.dart
+++ b/sdk/lib/_internal/pub_generated/lib/src/barback/asset_environment.dart
@@ -70,19 +70,38 @@
     if (hostname == null) hostname = "localhost";
     if (basePort == null) basePort = 0;
 
-    return entrypoint.loadPackageGraph().then((graph) {
-      log.fine("Loaded package graph.");
-      graph = _adjustPackageGraph(graph, mode, packages);
-      var barback = new Barback(new PubPackageProvider(graph));
-      barback.log.listen(_log);
-
-      var environment =
-          new AssetEnvironment._(graph, barback, mode, watcherType, hostname, basePort);
-
-      return environment._load(
-          entrypoints: entrypoints,
-          useDart2JS: useDart2JS).then((_) => environment);
-    });
+    return log.progress("Loading asset environment", () {
+      final completer0 = new Completer();
+      scheduleMicrotask(() {
+        try {
+          entrypoint.loadPackageGraph().then((x0) {
+            try {
+              var graph = x0;
+              graph = _adjustPackageGraph(graph, mode, packages);
+              var barback = new Barback(new PubPackageProvider(graph));
+              barback.log.listen(_log);
+              var environment =
+                  new AssetEnvironment._(graph, barback, mode, watcherType, hostname, basePort);
+              environment._load(
+                  entrypoints: entrypoints,
+                  useDart2JS: useDart2JS).then((x1) {
+                try {
+                  x1;
+                  completer0.complete(environment);
+                } catch (e0, s0) {
+                  completer0.completeError(e0, s0);
+                }
+              }, onError: completer0.completeError);
+            } catch (e1, s1) {
+              completer0.completeError(e1, s1);
+            }
+          }, onError: completer0.completeError);
+        } catch (e, s) {
+          completer0.completeError(e, s);
+        }
+      });
+      return completer0.future;
+    }, fine: true);
   }
 
   /// Return a version of [graph] that's restricted to [packages] (if passed)
diff --git a/sdk/lib/_internal/pub_generated/lib/src/barback/transformer_config.dart b/sdk/lib/_internal/pub_generated/lib/src/barback/transformer_config.dart
index 1d2b52b..11d9594 100644
--- a/sdk/lib/_internal/pub_generated/lib/src/barback/transformer_config.dart
+++ b/sdk/lib/_internal/pub_generated/lib/src/barback/transformer_config.dart
@@ -4,6 +4,7 @@
 
 library pub.barback.transformer_config;
 
+import 'package:glob/glob.dart';
 import 'package:path/path.dart' as p;
 import 'package:source_span/source_span.dart';
 import 'package:yaml/yaml.dart';
@@ -38,7 +39,7 @@
   /// This is processed before [excludes]. If a transformer has both includes
   /// and excludes, then the set of included assets is determined and assets
   /// are excluded from that resulting set.
-  final Set<String> includes;
+  final Set<Glob> includes;
 
   /// The primary input exclusions.
   ///
@@ -48,7 +49,7 @@
   /// This is processed after [includes]. If a transformer has both includes
   /// and excludes, then the set of included assets is determined and assets
   /// are excluded from that resulting set.
-  final Set<String> excludes;
+  final Set<Glob> excludes;
 
   /// Returns whether this config excludes certain asset ids from being
   /// processed.
@@ -58,8 +59,19 @@
   /// the package's dependers.
   bool get canTransformPublicFiles {
     if (includes == null) return true;
-    return includes.any(
-        (path) => p.url.isWithin('lib', path) || p.url.isWithin('bin', path));
+    return includes.any((glob) {
+      // Check whether the first path component of the glob is "lib", "bin", or
+      // contains wildcards that may cause it to match "lib" or "bin".
+      var first = p.posix.split(glob.toString()).first;
+      if (first.contains('{') ||
+          first.contains('*') ||
+          first.contains('[') ||
+          first.contains('?')) {
+        return true;
+      }
+
+      return first == 'lib' || first == 'bin';
+    });
   }
 
   /// Parses [identifier] as a [TransformerId] with [configuration].
@@ -77,22 +89,25 @@
       var fieldNode = configurationNode.nodes[key];
       var field = fieldNode.value;
 
-      if (field is String) return new Set.from([field]);
+      if (field is String) {
+        return new Set.from([new Glob(field, context: p.url, recursive: true)]);
+      }
 
-      if (field is List) {
-        for (var node in field.nodes) {
-          if (node.value is String) continue;
-          throw new SourceSpanFormatException(
-              '"$key" field may contain only strings.',
-              node.span);
-        }
-
-        return new Set.from(field);
-      } else {
+      if (field is! List) {
         throw new SourceSpanFormatException(
             '"$key" field must be a string or list.',
             fieldNode.span);
       }
+
+      return new Set.from(field.nodes.map((node) {
+        if (node.value is String) {
+          return new Glob(node.value, context: p.url, recursive: true);
+        }
+
+        throw new SourceSpanFormatException(
+            '"$key" field may contain only strings.',
+            node.span);
+      }));
     }
 
     var includes = null;
@@ -137,13 +152,15 @@
   /// [pathWithinPackage] must be a URL-style path relative to the containing
   /// package's root directory.
   bool canTransform(String pathWithinPackage) {
-    // TODO(rnystrom): Support globs in addition to paths. See #17093.
     if (excludes != null) {
       // If there are any excludes, it must not match any of them.
-      if (excludes.contains(pathWithinPackage)) return false;
+      for (var exclude in excludes) {
+        if (exclude.matches(pathWithinPackage)) return false;
+      }
     }
 
     // If there are any includes, it must match one of them.
-    return includes == null || includes.contains(pathWithinPackage);
+    return includes == null ||
+        includes.any((include) => include.matches(pathWithinPackage));
   }
 }
diff --git a/sdk/lib/_internal/pub_generated/lib/src/entrypoint.dart b/sdk/lib/_internal/pub_generated/lib/src/entrypoint.dart
index c020d15..ee16741 100644
--- a/sdk/lib/_internal/pub_generated/lib/src/entrypoint.dart
+++ b/sdk/lib/_internal/pub_generated/lib/src/entrypoint.dart
@@ -646,36 +646,117 @@
   /// lockfile or any pubspecs. Otherwise, before loading, this makes sure the
   /// lockfile and dependencies are installed and up to date.
   Future<PackageGraph> loadPackageGraph([SolveResult result]) {
-    if (_packageGraph != null) return new Future.value(_packageGraph);
-
-    return new Future.sync(() {
-      if (result != null) {
-        return Future.wait(result.packages.map((id) {
-          return cache.sources[id.source].getDirectory(
-              id).then((dir) => new Package(result.pubspecs[id.name], dir));
-        })).then((packages) {
-          return new PackageGraph(
-              this,
-              new LockFile(result.packages),
-              new Map.fromIterable(packages, key: (package) => package.name));
-        });
-      } else {
-        return ensureLockFileIsUpToDate().then((_) {
-          return Future.wait(lockFile.packages.values.map((id) {
-            var source = cache.sources[id.source];
-            return source.getDirectory(
-                id).then((dir) => new Package.load(id.name, dir, cache.sources));
-          })).then((packages) {
-            var packageMap = new Map.fromIterable(packages, key: (p) => p.name);
-            packageMap[root.name] = root;
-            return new PackageGraph(this, lockFile, packageMap);
-          });
-        });
+    final completer0 = new Completer();
+    scheduleMicrotask(() {
+      try {
+        join0() {
+          log.progress("Loading package graph", (() {
+            final completer0 = new Completer();
+            scheduleMicrotask(() {
+              try {
+                join0() {
+                  ensureLockFileIsUpToDate().then((x0) {
+                    try {
+                      x0;
+                      Future.wait(lockFile.packages.values.map(((id) {
+                        final completer0 = new Completer();
+                        scheduleMicrotask(() {
+                          try {
+                            var source = cache.sources[id.source];
+                            source.getDirectory(id).then((x0) {
+                              try {
+                                var dir = x0;
+                                completer0.complete(
+                                    new Package.load(id.name, dir, cache.sources));
+                              } catch (e0, s0) {
+                                completer0.completeError(e0, s0);
+                              }
+                            }, onError: completer0.completeError);
+                          } catch (e, s) {
+                            completer0.completeError(e, s);
+                          }
+                        });
+                        return completer0.future;
+                      }))).then((x1) {
+                        try {
+                          var packages = x1;
+                          var packageMap =
+                              new Map.fromIterable(packages, key: ((p) {
+                            return p.name;
+                          }));
+                          packageMap[root.name] = root;
+                          completer0.complete(
+                              new PackageGraph(this, lockFile, packageMap));
+                        } catch (e0, s0) {
+                          completer0.completeError(e0, s0);
+                        }
+                      }, onError: completer0.completeError);
+                    } catch (e1, s1) {
+                      completer0.completeError(e1, s1);
+                    }
+                  }, onError: completer0.completeError);
+                }
+                if (result != null) {
+                  Future.wait(result.packages.map(((id) {
+                    final completer0 = new Completer();
+                    scheduleMicrotask(() {
+                      try {
+                        cache.sources[id.source].getDirectory(id).then((x0) {
+                          try {
+                            var dir = x0;
+                            completer0.complete(
+                                new Package(result.pubspecs[id.name], dir));
+                          } catch (e0, s0) {
+                            completer0.completeError(e0, s0);
+                          }
+                        }, onError: completer0.completeError);
+                      } catch (e, s) {
+                        completer0.completeError(e, s);
+                      }
+                    });
+                    return completer0.future;
+                  }))).then((x2) {
+                    try {
+                      var packages = x2;
+                      completer0.complete(
+                          new PackageGraph(
+                              this,
+                              new LockFile(result.packages),
+                              new Map.fromIterable(packages, key: ((package) {
+                        return package.name;
+                      }))));
+                    } catch (e2, s2) {
+                      completer0.completeError(e2, s2);
+                    }
+                  }, onError: completer0.completeError);
+                } else {
+                  join0();
+                }
+              } catch (e, s) {
+                completer0.completeError(e, s);
+              }
+            });
+            return completer0.future;
+          }), fine: true).then((x0) {
+            try {
+              var graph = x0;
+              _packageGraph = graph;
+              completer0.complete(graph);
+            } catch (e0, s0) {
+              completer0.completeError(e0, s0);
+            }
+          }, onError: completer0.completeError);
+        }
+        if (_packageGraph != null) {
+          completer0.complete(_packageGraph);
+        } else {
+          join0();
+        }
+      } catch (e, s) {
+        completer0.completeError(e, s);
       }
-    }).then((graph) {
-      _packageGraph = graph;
-      return graph;
     });
+    return completer0.future;
   }
 
   /// Saves a list of concrete package versions to the `pubspec.lock` file.
diff --git a/sdk/lib/_internal/pub_generated/lib/src/utils.dart b/sdk/lib/_internal/pub_generated/lib/src/utils.dart
index 1558dac..3804e13 100644
--- a/sdk/lib/_internal/pub_generated/lib/src/utils.dart
+++ b/sdk/lib/_internal/pub_generated/lib/src/utils.dart
@@ -163,6 +163,16 @@
   return result.toString();
 }
 
+/// Pads [source] to [length] by adding [char]s at the beginning.
+///
+/// If [char] is `null`, it defaults to a space.
+String padLeft(String source, int length, [String char]) {
+  if (char == null) char = ' ';
+  if (source.length >= length) return source;
+
+  return char * (length - source.length) + source;
+}
+
 /// Returns a labelled sentence fragment starting with [name] listing the
 /// elements [iter].
 ///
@@ -708,8 +718,17 @@
   var result = duration.inMinutes > 0 ? "${duration.inMinutes}:" : "";
 
   var s = duration.inSeconds % 59;
-  var ms = (duration.inMilliseconds % 1000) ~/ 100;
-  return result + "$s.${ms}s";
+  var ms = duration.inMilliseconds % 1000;
+
+  // If we're using verbose logging, be more verbose but more accurate when
+  // reporting timing information.
+  if (log.verbosity.isLevelVisible(log.Level.FINE)) {
+    ms = padLeft(ms.toString(), 3, '0');
+  } else {
+    ms ~/= 100;
+  }
+
+  return "$result$s.${ms}s";
 }
 
 /// Decodes a URL-encoded string.
diff --git a/sdk/lib/_internal/pub_generated/test/transformer/exclusion/exclude_asset_glob_test.dart b/sdk/lib/_internal/pub_generated/test/transformer/exclusion/exclude_asset_glob_test.dart
new file mode 100644
index 0000000..9bf9100
--- /dev/null
+++ b/sdk/lib/_internal/pub_generated/test/transformer/exclusion/exclude_asset_glob_test.dart
@@ -0,0 +1,40 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS d.file
+// for 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 pub_tests;
+
+import '../../descriptor.dart' as d;
+import '../../test_pub.dart';
+import '../../serve/utils.dart';
+
+main() {
+  initConfig();
+  withBarbackVersions("any", () {
+    integration("allows a glob to exclude", () {
+      d.dir(appPath, [d.pubspec({
+          "name": "myapp",
+          "transformers": [{
+              "myapp/src/transformer": {
+                "\$exclude": "**/foo.txt"
+              }
+            }]
+        }),
+            d.dir("lib", [d.dir("src", [d.file("transformer.dart", REWRITE_TRANSFORMER)])]),
+            d.dir(
+                "web",
+                [
+                    d.file("foo.txt", "foo"),
+                    d.file("bar.txt", "bar"),
+                    d.dir("sub", [d.file("foo.txt", "foo"),])])]).create();
+
+      createLockFile('myapp', pkg: ['barback']);
+
+      pubServe();
+      requestShould404("foo.out");
+      requestShouldSucceed("bar.out", "bar.out");
+      requestShould404("sub/foo.out");
+      endPubServe();
+    });
+  });
+}
diff --git a/sdk/lib/_internal/pub_generated/test/transformer/exclusion/exclude_asset_prefix_test.dart b/sdk/lib/_internal/pub_generated/test/transformer/exclusion/exclude_asset_prefix_test.dart
new file mode 100644
index 0000000..12bbfd2c
--- /dev/null
+++ b/sdk/lib/_internal/pub_generated/test/transformer/exclusion/exclude_asset_prefix_test.dart
@@ -0,0 +1,42 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS d.file
+// for 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 pub_tests;
+
+import '../../descriptor.dart' as d;
+import '../../test_pub.dart';
+import '../../serve/utils.dart';
+
+main() {
+  initConfig();
+  withBarbackVersions("any", () {
+    integration("allows a directory prefix to exclude", () {
+      d.dir(appPath, [d.pubspec({
+          "name": "myapp",
+          "transformers": [{
+              "myapp/src/transformer": {
+                "\$exclude": "web/sub"
+              }
+            }]
+        }),
+            d.dir("lib", [d.dir("src", [d.file("transformer.dart", REWRITE_TRANSFORMER)])]),
+            d.dir(
+                "web",
+                [
+                    d.file("foo.txt", "foo"),
+                    d.file("bar.txt", "bar"),
+                    d.dir("sub", [d.file("foo.txt", "foo"),]),
+                    d.dir("subbub", [d.file("foo.txt", "foo"),])])]).create();
+
+      createLockFile('myapp', pkg: ['barback']);
+
+      pubServe();
+      requestShouldSucceed("foo.out", "foo.out");
+      requestShouldSucceed("bar.out", "bar.out");
+      requestShouldSucceed("subbub/foo.out", "foo.out");
+      requestShould404("sub/foo.out");
+      endPubServe();
+    });
+  });
+}
diff --git a/sdk/lib/_internal/pub_generated/test/transformer/exclusion/include_asset_glob_test.dart b/sdk/lib/_internal/pub_generated/test/transformer/exclusion/include_asset_glob_test.dart
new file mode 100644
index 0000000..07a4702
--- /dev/null
+++ b/sdk/lib/_internal/pub_generated/test/transformer/exclusion/include_asset_glob_test.dart
@@ -0,0 +1,40 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS d.file
+// for 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 pub_tests;
+
+import '../../descriptor.dart' as d;
+import '../../test_pub.dart';
+import '../../serve/utils.dart';
+
+main() {
+  initConfig();
+  withBarbackVersions("any", () {
+    integration("allows a glob to include", () {
+      d.dir(appPath, [d.pubspec({
+          "name": "myapp",
+          "transformers": [{
+              "myapp/src/transformer": {
+                "\$include": "**/foo.txt"
+              }
+            }]
+        }),
+            d.dir("lib", [d.dir("src", [d.file("transformer.dart", REWRITE_TRANSFORMER)])]),
+            d.dir(
+                "web",
+                [
+                    d.file("foo.txt", "foo"),
+                    d.file("bar.txt", "bar"),
+                    d.dir("sub", [d.file("foo.txt", "foo"),])])]).create();
+
+      createLockFile('myapp', pkg: ['barback']);
+
+      pubServe();
+      requestShouldSucceed("foo.out", "foo.out");
+      requestShould404("bar.out");
+      requestShouldSucceed("sub/foo.out", "foo.out");
+      endPubServe();
+    });
+  });
+}
diff --git a/sdk/lib/_internal/pub_generated/test/transformer/exclusion/include_asset_prefix_test.dart b/sdk/lib/_internal/pub_generated/test/transformer/exclusion/include_asset_prefix_test.dart
new file mode 100644
index 0000000..22f2c7e
--- /dev/null
+++ b/sdk/lib/_internal/pub_generated/test/transformer/exclusion/include_asset_prefix_test.dart
@@ -0,0 +1,42 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS d.file
+// for 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 pub_tests;
+
+import '../../descriptor.dart' as d;
+import '../../test_pub.dart';
+import '../../serve/utils.dart';
+
+main() {
+  initConfig();
+  withBarbackVersions("any", () {
+    integration("allows a directory prefix to include", () {
+      d.dir(appPath, [d.pubspec({
+          "name": "myapp",
+          "transformers": [{
+              "myapp/src/transformer": {
+                "\$include": "web/sub"
+              }
+            }]
+        }),
+            d.dir("lib", [d.dir("src", [d.file("transformer.dart", REWRITE_TRANSFORMER)])]),
+            d.dir(
+                "web",
+                [
+                    d.file("foo.txt", "foo"),
+                    d.file("bar.txt", "bar"),
+                    d.dir("sub", [d.file("foo.txt", "foo"),]),
+                    d.dir("subbub", [d.file("foo.txt", "foo"),])])]).create();
+
+      createLockFile('myapp', pkg: ['barback']);
+
+      pubServe();
+      requestShould404("foo.out");
+      requestShould404("bar.out");
+      requestShouldSucceed("sub/foo.out", "foo.out");
+      requestShould404("subbub/foo.out");
+      endPubServe();
+    });
+  });
+}
diff --git a/sdk/lib/collection/queue.dart b/sdk/lib/collection/queue.dart
index 72c4e95..9e8580d 100644
--- a/sdk/lib/collection/queue.dart
+++ b/sdk/lib/collection/queue.dart
@@ -587,7 +587,7 @@
    */
   static int _nextPowerOf2(int number) {
     assert(number > 0);
-    number = (number << 2) - 1;
+    number = (number << 1) - 1;
     for(;;) {
       int nextNumber = number & (number - 1);
       if (nextNumber == 0) return number;
@@ -678,6 +678,10 @@
   /** Grows the table even if it is not full. */
   void _preGrow(int newElementCount) {
     assert(newElementCount >= length);
+
+    // Add some extra room to ensure that there's room for more elements after
+    // expansion.
+    newElementCount += newElementCount >> 1;
     int newCapacity = _nextPowerOf2(newElementCount);
     List<E> newTable = new List<E>(newCapacity);
     _tail = _writeToList(newTable);
diff --git a/sdk/lib/convert/json.dart b/sdk/lib/convert/json.dart
index 4b7817f..fa0886d 100644
--- a/sdk/lib/convert/json.dart
+++ b/sdk/lib/convert/json.dart
@@ -167,7 +167,11 @@
    */
   final String indent;
 
-  final _toEncodableFunction;
+  /**
+   * Function called on non-encodable objects to return a replacement
+   * encodable object that will be encoded in the orignal's place.
+   */
+  final Function _toEncodable;
 
   /**
    * Creates a JSON encoder.
@@ -183,7 +187,7 @@
    */
   const JsonEncoder([Object toEncodable(Object nonSerializable)])
       : this.indent = null,
-        this._toEncodableFunction = toEncodable;
+        this._toEncodable = toEncodable;
 
   /**
    * Creates a JSON encoder that creates multi-line JSON.
@@ -205,7 +209,7 @@
    */
   const JsonEncoder.withIndent(this.indent,
       [Object toEncodable(Object nonSerializable)])
-      : this._toEncodableFunction = toEncodable;
+      : this._toEncodable = toEncodable;
 
   /**
    * Converts [object] to a JSON [String].
@@ -236,7 +240,7 @@
    * first serialized, the new values may not be reflected in the result.
    */
   String convert(Object object) =>
-      _JsonStringifier.stringify(object, _toEncodableFunction, indent);
+      _JsonStringStringifier.stringify(object, _toEncodable, indent);
 
   /**
    * Starts a chunked conversion.
@@ -250,12 +254,146 @@
   ChunkedConversionSink<Object> startChunkedConversion(Sink<String> sink) {
     if (sink is! StringConversionSink) {
       sink = new StringConversionSink.from(sink);
+    } else if (sink is _Utf8EncoderSink) {
+      return new _JsonUtf8EncoderSink(sink._sink, _toEncodable,
+                                      JsonUtf8Encoder._utf8Encode(indent),
+                                      JsonUtf8Encoder.DEFAULT_BUFFER_SIZE);
     }
-    return new _JsonEncoderSink(sink, _toEncodableFunction, indent);
+    return new _JsonEncoderSink(sink, _toEncodable, indent);
   }
 
   // Override the base-classes bind, to provide a better type.
   Stream<String> bind(Stream<Object> stream) => super.bind(stream);
+
+  Converter<Object, dynamic> fuse(Converter<String, dynamic> other) {
+    if (other is Utf8Encoder) {
+      return new JsonUtf8Encoder(indent, _toEncodable);
+    }
+    return super.fuse(other);
+  }
+}
+
+/**
+ * Encoder that encodes a single object as a UTF-8 encoded JSON string.
+ *
+ * This encoder works equivalently to first converting the object to
+ * a JSON string, and then UTF-8 encoding the string, but without
+ * creating an intermediate string.
+ */
+class JsonUtf8Encoder extends Converter<Object, List<int>> {
+  /** Default buffer size used by the JSON-to-UTF-8 encoder. */
+  static const int DEFAULT_BUFFER_SIZE = 256;
+  /** Indentation used in pretty-print mode, `null` if not pretty. */
+  final List<int> _indent;
+  /** Function called with each un-encodable object encountered. */
+  final Function _toEncodable;
+  /** UTF-8 buffer size. */
+  final int _bufferSize;
+
+  /**
+   * Create converter.
+   *
+   * If [indent] is non-`null`, the converter attempts to "pretty-print" the
+   * JSON, and uses `indent` as the indentation. Otherwise the result has no
+   * whitespace outside of string literals.
+   * If `indent` contains characters that are not valid JSON whitespace
+   * characters, the result will not be valid JSON. JSON whitespace characters
+   * are space (U+0020), tab (U+0009), line feed (U+000a) and carriage return
+   * (U+000d) (ECMA 404).
+   *
+   * The [bufferSize] is the size of the internal buffers used to collect
+   * UTF-8 code units.
+   * If using [startChunkedConversion], it will be the size of the chunks.
+   *
+   * The JSON encoder handles numbers, strings, booleans, null, lists and
+   * maps directly.
+   *
+   * Any other object is attempted converted by [toEncodable] to an
+   * object that is of one of the convertible types.
+   *
+   * If [toEncodable] is omitted, it defaults to calling `.toJson()` on
+   * the object.
+   */
+  JsonUtf8Encoder([String indent,
+                   toEncodable(Object object),
+                   int bufferSize = DEFAULT_BUFFER_SIZE])
+      : _indent = _utf8Encode(indent),
+        _toEncodable = toEncodable,
+        _bufferSize = bufferSize;
+
+  static List<int> _utf8Encode(String string) {
+    if (string == null) return null;
+    if (string.isEmpty) return new Uint8List(0);
+    checkAscii: {
+      for (int i = 0; i < string.length; i++) {
+        if (string.codeUnitAt(i) >= 0x80) break checkAscii;
+      }
+      return string.codeUnits;
+    }
+    return UTF8.encode(string);
+  }
+
+  /** Convert [object] into UTF-8 encoded JSON. */
+  List<int> convert(Object object) {
+    List<List<int>> bytes = [];
+    // The `stringify` function always converts into chunks.
+    // Collect the chunks into the `bytes` list, then combine them afterwards.
+    void addChunk(Uint8List chunk, int start, int end) {
+      if (start > 0 || end < chunk.length) {
+        int length = end - start;
+        chunk = new Uint8List.view(chunk.buffer,
+                                   chunk.offsetInBytes + start,
+                                   length);
+      }
+      bytes.add(chunk);
+    }
+    _JsonUtf8Stringifier.stringify(object,
+                                   _indent,
+                                   _toEncodable,
+                                   _bufferSize,
+                                   addChunk);
+    if (bytes.length == 1) return bytes[0];
+    int length = 0;
+    for (int i = 0; i < bytes.length; i++) {
+      length += bytes[i].length;
+    }
+    Uint8List result = new Uint8List(length);
+    for (int i = 0, offset = 0; i < bytes.length; i++) {
+      var byteList = bytes[i];
+      int end = offset + byteList.length;
+      result.setRange(offset, end, byteList);
+      offset = end;
+    }
+    return result;
+  }
+
+  /**
+   * Start a chunked conversion.
+   *
+   * Only one object can be passed into the returned sink.
+   *
+   * The argument [sink] will receive byte lists in sizes depending on the
+   * `bufferSize` passed to the constructor when creating this encoder.
+   */
+  ChunkedConversionSink<Object> startChunkedConversion(Sink<List<int>> sink) {
+    ByteConversionSink byteSink;
+    if (sink is ByteConversionSink) {
+      byteSink = sink;
+    } else {
+      byteSink = new ByteConversionSink.from(sink);
+    }
+    return new _JsonUtf8EncoderSink(byteSink, _toEncodable,
+                                    _indent, _bufferSize);
+  }
+
+  // Override the base-classes bind, to provide a better type.
+  Stream<List<int>> bind(Stream<Object> stream) {
+    return super.bind(stream);
+  }
+
+  Converter<Object, dynamic> fuse(Converter<List<int>, dynamic> other) {
+    return super.fuse(other);
+  }
 }
 
 /**
@@ -265,11 +403,11 @@
  */
 class _JsonEncoderSink extends ChunkedConversionSink<Object> {
   final String _indent;
-  final Function _toEncodableFunction;
+  final Function _toEncodable;
   final StringConversionSink _sink;
   bool _isDone = false;
 
-  _JsonEncoderSink(this._sink, this._toEncodableFunction, this._indent);
+  _JsonEncoderSink(this._sink, this._toEncodable, this._indent);
 
   /**
    * Encodes the given object [o].
@@ -284,7 +422,7 @@
     }
     _isDone = true;
     ClosableStringSink stringSink = _sink.asStringSink();
-    _JsonStringifier.printOn(o, stringSink, _toEncodableFunction, _indent);
+    _JsonStringStringifier.printOn(o, stringSink, _toEncodable, _indent);
     stringSink.close();
   }
 
@@ -292,6 +430,43 @@
 }
 
 /**
+ * Sink returned when starting a chunked conversion from object to bytes.
+ */
+class _JsonUtf8EncoderSink extends ChunkedConversionSink<Object> {
+  /** The byte sink receiveing the encoded chunks. */
+  final ByteConversionSink _sink;
+  final List<int> _indent;
+  final Function _toEncodable;
+  final int _bufferSize;
+  bool _isDone = false;
+  _JsonUtf8EncoderSink(this._sink, this._toEncodable, this._indent,
+                       this._bufferSize);
+
+  /** Callback called for each slice of result bytes. */
+  void _addChunk(Uint8List chunk, int start, int end) {
+    _sink.addSlice(chunk, start, end, false);
+  }
+
+  void add(Object object) {
+    if (_isDone) {
+      throw new StateError("Only one call to add allowed");
+    }
+    _isDone = true;
+    _JsonUtf8Stringifier.stringify(object, _indent, _toEncodable,
+                                   _bufferSize,
+                                   _addChunk);
+    _sink.close();
+  }
+
+  void close() {
+    if (!_isDone) {
+      _isDone = true;
+      _sink.close();
+    }
+  }
+}
+
+/**
  * This class parses JSON strings and builds the corresponding objects.
  */
 class JsonDecoder extends Converter<String, Object> {
@@ -340,7 +515,13 @@
 
 Object _defaultToEncodable(object) => object.toJson();
 
-class _JsonStringifier {
+/**
+ * JSON encoder that traverses an object structure and writes JSON source.
+ *
+ * This is an abstract implementation that doesn't decide on the output
+ * format, but writes the JSON through abstract methods like [writeString].
+ */
+abstract class _JsonStringifier {
   // Character code constants.
   static const int BACKSPACE       = 0x08;
   static const int TAB             = 0x09;
@@ -357,87 +538,86 @@
   static const int CHAR_t          = 0x74;
   static const int CHAR_u          = 0x75;
 
+  /** List of objects currently being traversed. Used to detect cycles. */
+  final List _seen = new List();
+  /** Function called for each un-encodable object encountered. */
   final Function _toEncodable;
-  final StringSink _sink;
-  final List _seen;
 
-  factory _JsonStringifier(StringSink sink, Function toEncodable,
-      String indent) {
-    if (indent == null) return new _JsonStringifier._(sink, toEncodable);
-    return new _JsonStringifierPretty(sink, toEncodable, indent);
-  }
+  _JsonStringifier(Object _toEncodable(Object o))
+      : _toEncodable = (_toEncodable != null) ? _toEncodable
+                                              : _defaultToEncodable;
 
-  _JsonStringifier._(this._sink, this._toEncodable)
-      : this._seen = new List();
-
-  static String stringify(object, toEncodable(object), String indent) {
-    if (toEncodable == null) toEncodable = _defaultToEncodable;
-    StringBuffer output = new StringBuffer();
-    printOn(object, output, toEncodable, indent);
-    return output.toString();
-  }
-
-  static void printOn(object, StringSink output, toEncodable(object),
-      String indent) {
-    new _JsonStringifier(output, toEncodable, indent).stringifyValue(object);
-  }
-
-  static String numberToString(num x) {
-    return x.toString();
-  }
+  /** Append a string to the JSON output. */
+  void writeString(String characters);
+  /** Append part of a string to the JSON output. */
+  void writeStringSlice(String characters, int start, int end);
+  /** Append a single character, given by its code point, to the JSON output. */
+  void writeCharCode(int charCode);
+  /** Write a number to the JSON output. */
+  void writeNumber(num number);
 
   // ('0' + x) or ('a' + x - 10)
   static int hexDigit(int x) => x < 10 ? 48 + x : 87 + x;
 
-  void escape(String s) {
+  /**
+   * Write, and suitably escape, a string's content as a JSON string literal.
+   */
+  void writeStringContent(String s) {
     int offset = 0;
     final int length = s.length;
     for (int i = 0; i < length; i++) {
       int charCode = s.codeUnitAt(i);
       if (charCode > BACKSLASH) continue;
       if (charCode < 32) {
-        if (i > offset) _sink.write(s.substring(offset, i));
+        if (i > offset) writeStringSlice(s, offset, i);
         offset = i + 1;
-        _sink.writeCharCode(BACKSLASH);
+        writeCharCode(BACKSLASH);
         switch (charCode) {
         case BACKSPACE:
-          _sink.writeCharCode(CHAR_b);
+          writeCharCode(CHAR_b);
           break;
         case TAB:
-          _sink.writeCharCode(CHAR_t);
+          writeCharCode(CHAR_t);
           break;
         case NEWLINE:
-          _sink.writeCharCode(CHAR_n);
+          writeCharCode(CHAR_n);
           break;
         case FORM_FEED:
-          _sink.writeCharCode(CHAR_f);
+          writeCharCode(CHAR_f);
           break;
         case CARRIAGE_RETURN:
-          _sink.writeCharCode(CHAR_r);
+          writeCharCode(CHAR_r);
           break;
         default:
-          _sink.writeCharCode(CHAR_u);
-          _sink.writeCharCode(CHAR_0);
-          _sink.writeCharCode(CHAR_0);
-          _sink.writeCharCode(hexDigit((charCode >> 4) & 0xf));
-          _sink.writeCharCode(hexDigit(charCode & 0xf));
+          writeCharCode(CHAR_u);
+          writeCharCode(CHAR_0);
+          writeCharCode(CHAR_0);
+          writeCharCode(hexDigit((charCode >> 4) & 0xf));
+          writeCharCode(hexDigit(charCode & 0xf));
           break;
         }
       } else if (charCode == QUOTE || charCode == BACKSLASH) {
-        if (i > offset) _sink.write(s.substring(offset, i));
+        if (i > offset) writeStringSlice(s, offset, i);
         offset = i + 1;
-        _sink.writeCharCode(BACKSLASH);
-        _sink.writeCharCode(charCode);
+        writeCharCode(BACKSLASH);
+        writeCharCode(charCode);
       }
     }
     if (offset == 0) {
-      _sink.write(s);
+      writeString(s);
     } else if (offset < length) {
-      _sink.write(s.substring(offset, length));
+      writeStringSlice(s, offset, length);
     }
   }
 
-  void checkCycle(object) {
+  /**
+   * Check if an encountered object is already being traversed.
+   *
+   * Records the object if it isn't already seen.
+   * Should have a matching call to [_removeSeen] when the object
+   * is no longer being traversed.
+   */
+  void _checkCycle(object) {
     for (int i = 0; i < _seen.length; i++) {
       if (identical(object, _seen[i])) {
         throw new JsonCyclicError(object);
@@ -446,21 +626,38 @@
     _seen.add(object);
   }
 
-  void stringifyValue(object) {
+  /**
+   * Removes object from the list of currently traversed objects.
+   *
+   * Should be called in the opposite order of the matching [_checkCycle]
+   * calls.
+   */
+  void _removeSeen(object) {
+    assert(!_seen.isEmpty);
+    assert(identical(_seen.last, object));
+    _seen.removeLast();
+  }
+
+  /**
+   * Writes an object.
+   *
+   * If the object isn't directly encodable, the [_toEncodable] function
+   * gets one chance to return a replacement which is encodable.
+   */
+  void writeObject(object) {
     // Tries stringifying object directly. If it's not a simple value, List or
     // Map, call toJson() to get a custom representation and try serializing
     // that.
-    if (!stringifyJsonValue(object)) {
-      checkCycle(object);
-      try {
-        var customJson = _toEncodable(object);
-        if (!stringifyJsonValue(customJson)) {
-          throw new JsonUnsupportedObjectError(object);
-        }
-        _removeSeen(object);
-      } catch (e) {
-        throw new JsonUnsupportedObjectError(object, cause: e);
+    if (writeJsonValue(object)) return;
+    _checkCycle(object);
+    try {
+      var customJson = _toEncodable(object);
+      if (!writeJsonValue(customJson)) {
+        throw new JsonUnsupportedObjectError(object);
       }
+      _removeSeen(object);
+    } catch (e) {
+      throw new JsonUnsupportedObjectError(object, cause: e);
     }
   }
 
@@ -470,52 +667,33 @@
    * Returns true if the value is one of these types, and false if not.
    * If a value is both a [List] and a [Map], it's serialized as a [List].
    */
-  bool stringifyJsonValue(object) {
+  bool writeJsonValue(object) {
     if (object is num) {
       if (!object.isFinite) return false;
-      _sink.write(numberToString(object));
+      writeNumber(object);
       return true;
     } else if (identical(object, true)) {
-      _sink.write('true');
+      writeString('true');
       return true;
     } else if (identical(object, false)) {
-      _sink.write('false');
+      writeString('false');
        return true;
     } else if (object == null) {
-      _sink.write('null');
+      writeString('null');
       return true;
     } else if (object is String) {
-      _sink.write('"');
-      escape(object);
-      _sink.write('"');
+      writeString('"');
+      writeStringContent(object);
+      writeString('"');
       return true;
     } else if (object is List) {
-      checkCycle(object);
-      List a = object;
-      _sink.write('[');
-      if (a.length > 0) {
-        stringifyValue(a[0]);
-        for (int i = 1; i < a.length; i++) {
-          _sink.write(',');
-          stringifyValue(a[i]);
-        }
-      }
-      _sink.write(']');
+      _checkCycle(object);
+      writeList(object);
       _removeSeen(object);
       return true;
     } else if (object is Map) {
-      checkCycle(object);
-      Map<String, Object> m = object;
-      _sink.write('{');
-      String separator = '"';
-      m.forEach((String key, value) {
-        _sink.write(separator);
-        separator = ',"';
-        escape(key);
-        _sink.write('":');
-        stringifyValue(value);
-      });
-      _sink.write('}');
+      _checkCycle(object);
+      writeMap(object);
       _removeSeen(object);
       return true;
     } else {
@@ -523,85 +701,338 @@
     }
   }
 
-  void _removeSeen(object) {
-    assert(!_seen.isEmpty);
-    assert(identical(_seen.last, object));
-    _seen.removeLast();
+  /** Serializes a [List]. */
+  void writeList(List list) {
+    writeString('[');
+    if (list.length > 0) {
+      writeObject(list[0]);
+      for (int i = 1; i < list.length; i++) {
+        writeString(',');
+        writeObject(list[i]);
+      }
+    }
+    writeString(']');
+  }
+
+  /** Serializes a [Map]. */
+  void writeMap(Map<String, Object> map) {
+    writeString('{');
+    String separator = '"';
+    map.forEach((String key, value) {
+      writeString(separator);
+      separator = ',"';
+      writeStringContent(key);
+      writeString('":');
+      writeObject(value);
+    });
+    writeString('}');
   }
 }
 
 /**
- * A subclass of [_JsonStringifier] which indents the contents of [List] and
+ * A modification of [_JsonStringifier] which indents the contents of [List] and
  * [Map] objects using the specified indent value.
+ *
+ * Subclasses should implement [writeIndentation].
  */
-class _JsonStringifierPretty extends _JsonStringifier {
-  final String _indent;
-
+abstract class _JsonPrettyPrintMixin implements _JsonStringifier {
   int _indentLevel = 0;
 
-  _JsonStringifierPretty(_sink, _toEncodable, this._indent)
-      : super._(_sink, _toEncodable);
+  /**
+   * Add [indentLevel] indentations to the JSON output.
+   */
+  void writeIndentation(indentLevel);
 
-  void _write([String value = '']) {
-    _sink.write(_indent * _indentLevel);
-    _sink.write(value);
+  void writeList(List list) {
+    if (list.isEmpty) {
+      writeString('[]');
+    } else {
+      writeString('[\n');
+      _indentLevel++;
+      writeIndentation(_indentLevel);
+      writeObject(list[0]);
+      for (int i = 1; i < list.length; i++) {
+        writeString(',\n');
+        writeIndentation(_indentLevel);
+        writeObject(list[i]);
+      }
+      writeString('\n');
+      _indentLevel--;
+      writeIndentation(_indentLevel);
+      writeString(']');
+    }
+  }
+
+  void writeMap(Map map) {
+    if (map.isEmpty) {
+      writeString('{}');
+    } else {
+      writeString('{\n');
+      _indentLevel++;
+      bool first = true;
+      map.forEach((String key, Object value) {
+        if (!first) {
+          writeString(",\n");
+        }
+        writeIndentation(_indentLevel);
+        writeString('"');
+        writeStringContent(key);
+        writeString('": ');
+        writeObject(value);
+        first = false;
+      });
+      writeString('\n');
+      _indentLevel--;
+      writeIndentation(_indentLevel);
+      writeString('}');
+    }
+  }
+}
+
+/**
+ * A specialziation of [_JsonStringifier] that writes its JSON to a string.
+ */
+class _JsonStringStringifier extends _JsonStringifier {
+  final StringSink _sink;
+
+  _JsonStringStringifier(this._sink, _toEncodable) : super(_toEncodable);
+
+  /**
+   * Convert object to a string.
+   *
+   * The [toEncodable] function is used to convert non-encodable objects
+   * to encodable ones.
+   *
+   * If [indent] is not `null`, the resulting JSON will be "pretty-printed"
+   * with newlines and indentation. The `indent` string is added as indentation
+   * for each indentation level. It should only contain valid JSON whitespace
+   * characters (space, tab, carriage return or line feed).
+   */
+  static String stringify(object, toEncodable(object), String indent) {
+    StringBuffer output = new StringBuffer();
+    printOn(object, output, toEncodable, indent);
+    return output.toString();
   }
 
   /**
-   * Serializes a [num], [String], [bool], [Null], [List] or [Map] value.
+   * Convert object to a string, and write the result to the [output] sink.
    *
-   * Returns true if the value is one of these types, and false if not.
-   * If a value is both a [List] and a [Map], it's serialized as a [List].
+   * The result is written piecemally to the sink.
    */
-  bool stringifyJsonValue(final object) {
-    if (object is List) {
-      checkCycle(object);
-      List a = object;
-      if (a.isEmpty) {
-        _sink.write('[]');
-      } else {
-        _sink.writeln('[');
-        _indentLevel++;
-        _write();
-        stringifyValue(a[0]);
-        for (int i = 1; i < a.length; i++) {
-          _sink.writeln(',');
-          _write();
-          stringifyValue(a[i]);
-        }
-        _sink.writeln();
-        _indentLevel--;
-        _write(']');
-      }
-      _seen.remove(object);
-      return true;
-    } else if (object is Map) {
-      checkCycle(object);
-      Map<String, Object> m = object;
-      if (m.isEmpty) {
-        _sink.write('{}');
-      } else {
-        _sink.write('{');
-        _sink.writeln();
-        _indentLevel++;
-        bool first = true;
-        m.forEach((String key, Object value) {
-          if (!first) {
-            _sink.writeln(',');
-          }
-          _write('"');
-          escape(key);
-          _sink.write('": ');
-          stringifyValue(value);
-          first = false;
-        });
-        _sink.writeln();
-        _indentLevel--;
-        _write('}');
-      }
-      _seen.remove(object);
-      return true;
+  static void printOn(object, StringSink output, toEncodable(object),
+                      String indent) {
+    var stringifier;
+    if (indent == null) {
+      stringifier = new _JsonStringStringifier(output, toEncodable);
+    } else {
+      stringifier =
+          new _JsonStringStringifierPretty(output, toEncodable, indent);
     }
-    return super.stringifyJsonValue(object);
+    stringifier.writeObject(object);
+  }
+
+  void writeNumber(num number) {
+    _sink.write(number.toString());
+  }
+  void writeString(String string) {
+    _sink.write(string);
+  }
+  void writeStringSlice(String string, int start, int end) {
+    _sink.write(string.substring(start, end));
+  }
+  void writeCharCode(int charCode) {
+    _sink.writeCharCode(charCode);
+  }
+}
+
+class _JsonStringStringifierPretty extends _JsonStringStringifier
+                                   with _JsonPrettyPrintMixin {
+  final String _indent;
+
+  _JsonStringStringifierPretty(StringSink sink, Function toEncodable,
+                               this._indent)
+      : super(sink, toEncodable);
+
+  void writeIndentation(int count) {
+    for (int i = 0; i < count; i++) writeString(_indent);
+  }
+}
+
+/**
+ * Specialization of [_JsonStringifier] that writes the JSON as UTF-8.
+ *
+ * The JSON text is UTF-8 encoded and written to [Uint8List] buffers.
+ * The buffers are then passed back to a user provided callback method.
+ */
+class _JsonUtf8Stringifier extends _JsonStringifier {
+  final int bufferSize;
+  final Function addChunk;
+  Uint8List buffer;
+  int index = 0;
+
+  _JsonUtf8Stringifier(toEncodable, int bufferSize, this.addChunk)
+      : super(toEncodable),
+        this.bufferSize = bufferSize,
+        buffer = new Uint8List(bufferSize);
+
+  /**
+   * Convert [object] to UTF-8 encoded JSON.
+   *
+   * Calls [addChunk] with slices of UTF-8 code units.
+   * These will typically have size [bufferSize], but may be shorter.
+   * The buffers are not reused, so the [addChunk] call may keep and reuse
+   * the chunks.
+   *
+   * If [indent] is non-`null`, the result will be "pretty-printed" with
+   * extra newlines and indentation, using [indent] as the indentation.
+   */
+  static void stringify(Object object,
+                        List<int> indent,
+                        toEncodableFunction(Object o),
+                        int bufferSize,
+                        void addChunk(Uint8List chunk, int start, int end)) {
+    _JsonUtf8Stringifier stringifier;
+    if (indent != null) {
+      stringifier = new _JsonUtf8StringifierPretty(toEncodableFunction, indent,
+                                                   bufferSize, addChunk);
+    } else {
+      stringifier = new _JsonUtf8Stringifier(toEncodableFunction,
+                                             bufferSize, addChunk);
+    }
+    stringifier.writeObject(object);
+    stringifier.flush();
+  }
+
+  /**
+   * Must be called at the end to push the last chunk to the [addChunk]
+   * callback.
+   */
+  void flush() {
+    if (index > 0) {
+      addChunk(buffer, 0, index);
+    }
+    buffer = null;
+    index = 0;
+  }
+
+  void writeNumber(num number) {
+    writeAsciiString(number.toString());
+  }
+
+  /** Write a string that is known to not have non-ASCII characters. */
+  void writeAsciiString(String string) {
+    // TODO(lrn): Optimize by copying directly into buffer instead of going
+    // through writeCharCode;
+    for (int i = 0; i < string.length; i++) {
+      int char = string.codeUnitAt(i);
+      assert(char <= 0x7f);
+      writeByte(char);
+    }
+  }
+
+  void writeString(String string) {
+    writeStringSlice(string, 0, string.length);
+  }
+
+  void writeStringSlice(String string, int start, int end) {
+    // TODO(lrn): Optimize by copying directly into buffer instead of going
+    // through writeCharCode/writeByte. Assumption is the most characters
+    // in starings are plain ASCII.
+    for (int i = start; i < end; i++) {
+      int char = string.codeUnitAt(i);
+      if (char <= 0x7f) {
+        writeByte(char);
+      } else {
+        if ((char & 0xFC00) == 0xD800 && i + 1 < end) {
+          // Lead surrogate.
+          int nextChar = string.codeUnitAt(i + 1);
+          if ((nextChar & 0xFC00) == 0xDC00) {
+            // Tail surrogate.
+            char = 0x10000 + ((char & 0x3ff) << 10) + (nextChar & 0x3ff);
+            writeFourByteCharCode(char);
+            i++;
+            continue;
+          }
+        }
+        writeMultiByteCharCode(char);
+      }
+    }
+  }
+
+  void writeCharCode(int charCode) {
+    if (charCode <= 0x7f) {
+      writeByte(charCode);
+      return;
+    }
+    writeMultiByteCharCode(charCode);
+  }
+
+  void writeMultiByteCharCode(int charCode) {
+    if (charCode <= 0x7ff) {
+      writeByte(0xC0 | (charCode >> 6));
+      writeByte(0x80 | (charCode & 0x3f));
+      return;
+    }
+    if (charCode <= 0xffff) {
+      writeByte(0xE0 | (charCode >> 12));
+      writeByte(0x80 | ((charCode >> 6) & 0x3f));
+      writeByte(0x80 | (charCode & 0x3f));
+      return;
+    }
+    writeFourByteCharCode(charCode);
+  }
+
+  void writeFourByteCharCode(int charCode) {
+    assert(charCode <= 0x10ffff);
+    writeByte(0xF0 | (charCode >> 18));
+    writeByte(0x80 | ((charCode >> 12) & 0x3f));
+    writeByte(0x80 | ((charCode >> 6) & 0x3f));
+    writeByte(0x80 | (charCode & 0x3f));
+  }
+
+  void writeByte(int byte) {
+    assert(byte <= 0xff);
+    if (index == buffer.length) {
+      addChunk(buffer, 0, index);
+      buffer = new Uint8List(bufferSize);
+      index = 0;
+    }
+    buffer[index++] = byte;
+  }
+}
+
+/**
+ * Pretty-printing version of [_JsonUtf8Stringifier].
+ */
+class _JsonUtf8StringifierPretty extends _JsonUtf8Stringifier
+                                 with _JsonPrettyPrintMixin {
+  final List<int> indent;
+  _JsonUtf8StringifierPretty(toEncodableFunction, this.indent,
+                             bufferSize, addChunk)
+      : super(toEncodableFunction, bufferSize, addChunk);
+
+  void writeIndentation(int count) {
+    List<int> indent = this.indent;
+    int indentLength = indent.length;
+    if (indentLength == 1) {
+      int char = indent[0];
+      while (count > 0) {
+        writeByte(char);
+        count -= 1;
+      }
+      return;
+    }
+    while (count > 0) {
+      count--;
+      int end = index + indentLength;
+      if (end <= buffer.length) {
+        buffer.setRange(index, end, indent);
+        index = end;
+      } else {
+        for (int i = 0; i < indentLength; i++) {
+          writeByte(indent[i]);
+        }
+      }
+    }
   }
 }
diff --git a/sdk/lib/convert/utf.dart b/sdk/lib/convert/utf.dart
index df7551a..2fcb915 100644
--- a/sdk/lib/convert/utf.dart
+++ b/sdk/lib/convert/utf.dart
@@ -342,6 +342,8 @@
 
   // Override the base-classes bind, to provide a better type.
   Stream<String> bind(Stream<List<int>> stream) => super.bind(stream);
+
+  external Converter<List<int>,dynamic> fuse(Converter<String, dynamic> next);
 }
 
 // UTF-8 constants.
diff --git a/sdk/lib/io/file_impl.dart b/sdk/lib/io/file_impl.dart
index cd1ad33..61ed003 100644
--- a/sdk/lib/io/file_impl.dart
+++ b/sdk/lib/io/file_impl.dart
@@ -176,6 +176,11 @@
     _openFuture = _file.open(mode: mode);
   }
 
+  _FileStreamConsumer.fromStdio(int fd) {
+    assert(1 <= fd && fd <= 2);
+    _openFuture = new Future.value(_File._openStdioSync(fd));
+  }
+
   Future<File> addStream(Stream<List<int>> stream) {
     Completer<File> completer = new Completer<File>.sync();
     _openFuture
diff --git a/sdk/lib/io/http.dart b/sdk/lib/io/http.dart
index d908338..d00f629 100644
--- a/sdk/lib/io/http.dart
+++ b/sdk/lib/io/http.dart
@@ -750,8 +750,9 @@
    * sub type. The charset and additional parameters can also be set
    * using [charset] and [parameters]. If charset is passed and
    * [parameters] contains charset as well the passed [charset] will
-   * override the value in parameters. Keys and values passed in
-   * parameters will be converted to lower case.
+   * override the value in parameters. Keys passed in parameters will be
+   * converted to lower case. The `charset` entry, whether passed as `charset`
+   * or in `parameters`, will have its value converted to lower-case.
    */
   factory ContentType(String primaryType,
                       String subType,
diff --git a/sdk/lib/io/http_headers.dart b/sdk/lib/io/http_headers.dart
index 5ecddca..4700128 100644
--- a/sdk/lib/io/http_headers.dart
+++ b/sdk/lib/io/http_headers.dart
@@ -747,6 +747,10 @@
         expect("=");
         skipWS();
         String value = parseParameterValue();
+        if (name == 'charset' && this is _ContentType) {
+          // Charset parameter of ContentTypes are always lower-case.
+          value = value.toLowerCase();
+        }
         parameters[name] = value;
         skipWS();
         if (done()) return;
@@ -779,7 +783,11 @@
     if (parameters != null) {
       _ensureParameters();
       parameters.forEach((String key, String value) {
-        this._parameters[key.toLowerCase()] = value.toLowerCase();
+        String lowerCaseKey = key.toLowerCase();
+        if (lowerCaseKey == "charset") {
+          value = value.toLowerCase();
+        }
+        this._parameters[lowerCaseKey] = value;
       });
     }
     if (charset != null) {
diff --git a/sdk/lib/io/stdio.dart b/sdk/lib/io/stdio.dart
index f36dd83..e4bdf01 100644
--- a/sdk/lib/io/stdio.dart
+++ b/sdk/lib/io/stdio.dart
@@ -191,36 +191,6 @@
 }
 
 
-class _StdConsumer implements StreamConsumer<List<int>> {
-  final _file;
-
-  _StdConsumer(int fd) : _file = _File._openStdioSync(fd);
-
-  Future addStream(Stream<List<int>> stream) {
-    var completer = new Completer();
-    var sub;
-    sub = stream.listen(
-        (data) {
-          try {
-            _file.writeFromSync(data);
-          } catch (e, s) {
-            sub.cancel();
-            completer.completeError(e, s);
-          }
-        },
-        onError: completer.completeError,
-        onDone: completer.complete,
-        cancelOnError: true);
-    return completer.future;
-  }
-
-  Future close() {
-    _file.closeSync();
-    return new Future.value();
-  }
-}
-
-
 class _StdSink implements IOSink {
   final IOSink _sink;
 
diff --git a/tests/_chrome/sample_test.dart b/tests/_chrome/sample_test.dart
index 85448ff..b25a94b 100644
--- a/tests/_chrome/sample_test.dart
+++ b/tests/_chrome/sample_test.dart
@@ -17,7 +17,7 @@
   test('fails from browser', () {
     // APIs should not work in standard browser apps.
     expect(() {
-      _chrome.app.window.create('foo.html');
+      _chrome.app.window.create('IntentionallyMissingFile.html');
     }, throws);
   });
 }
diff --git a/tests/co19/co19-dartium.status b/tests/co19/co19-dartium.status
index 2da9167..4b68427 100644
--- a/tests/co19/co19-dartium.status
+++ b/tests/co19/co19-dartium.status
@@ -35,17 +35,12 @@
 LibTest/html/Window/document_A01_t01: RuntimeError # Issue 20146
 LibTest/html/Window/postMessage_A01_t02: RuntimeError # Issue 20146
 LibTest/html/Window/moveBy_A01_t01: RuntimeError # Issue 20146
-LayoutTests/fast/dom: Skip # Unknown tests are breaking the test infrastructure. Issue 18558
-LayoutTests/fast/filesystem: Skip # Unknown tests are breaking the test infrastructure. Issue 18558
-LayoutTests/fast/css-generated-content/malformed-url_t01.dart: Skip # Breaks the test infrastructure. Issue 18558.
-LayoutTests/fast/css-generated-content/bug91547_t01.dart: Skip # Breaks the test infrastructure. Issue 18558.
-LayoutTests/fast/dom/HTMLButtonElement/change-type_t01: Skip # Breaks the test infrastructure. Issue 18558
-LayoutTests/fast/dom/shadow/form-in-shadow_t01: Skip # Breaks the test infrastructure. Issue 18558.
-# Only one of the next two causes the problem - not sure which.
-LayoutTests/fast/dom/Range/create-contextual-fragment-script-not-ran_t01: Skip # Breaks the test infrastructure. Issue 18558.
-LayoutTests/fast/dom/Range/bug-19527_t01: Skip # Breaks the test infrastructure. Issue 18558.
-LayoutTests/fast/dom/MutationObserver/database-callback-delivery_t01: Skip # Breaks the test infrastructure. Issue 18558.
-LayoutTests/fast/filesystem/file-after-reload-crash_t01.dart: Skip # Breaks the test infrastructure. Issue 18558.
+LayoutTests/fast/css-generated-content/bug91547_t01: Skip # Test reloads itself. Issue 18558.
+LayoutTests/fast/filesystem/file-after-reload-crash_t01: Skip # Test reloads itself. Issue 18558.
+LayoutTests/fast/dom/StyleSheet/discarded-sheet-owner-null_t01: Skip # Test reloads itself. Issue 18558.
+LayoutTests/fast/dom/css-cached-import-rule_t01: Skip # Test reloads itself. Issue 18558.
+LayoutTests/fast/dom/cssTarget-crash_t01: Skip # Test reloads itself. Issue 18558.
+LayoutTests/fast/dom/empty-hash-and-search_t01: Skip # Test reloads itself. Issue 18558.
 
 Language/07_Classes/6_Constructors/1_Generative_Constructors_A09_t01: Pass, Fail # Issue 13719: Please triage this failure.
 Language/14_Libraries_and_Scripts/3_Parts_A02_t02: Skip # Issue 13719: Please triage this failure.
@@ -157,7 +152,7 @@
 LayoutTests/fast/dom/Document/CaretRangeFromPoint/basic_t01: RuntimeError # Issue 17758.  Please triage this failure.
 LayoutTests/fast/dom/Document/CaretRangeFromPoint/caretRangeFromPoint-in-zoom-and-scroll_t01: RuntimeError # Issue 17758.  Please triage this failure.
 LayoutTests/fast/dom/Document/CaretRangeFromPoint/hittest-relative-to-viewport_t01: RuntimeError # Issue 17758.  Please triage this failure.
-LayoutTests/fast/dom/Document/CaretRangeFromPoint/replace-element_t01: RuntimeError # Issue 17758.  Please triage this failure.
+LayoutTests/fast/dom/Document/CaretRangeFromPoint/replace-element_t01: Pass, RuntimeError # Issue 17758.  Please triage this failure.
 LayoutTests/fast/dom/Document/createElementNS-namespace-err_t01: RuntimeError # Issue 17758.  Please triage this failure.
 LayoutTests/fast/dom/Element/attribute-uppercase_t01: RuntimeError # Issue 17758.  Please triage this failure.
 LayoutTests/fast/dom/Element/getClientRects_t01: RuntimeError # Issue 17758.  Please triage this failure.
@@ -237,13 +232,8 @@
 LayoutTests/fast/dom/HTMLAnchorElement/set-href-attribute-protocol_t01: RuntimeError # co19-roll r722: Please triage this failure.
 LayoutTests/fast/dom/HTMLAnchorElement/set-href-attribute-search_t01: RuntimeError, Pass # co19-roll r722: Please triage this failure.
 LayoutTests/fast/dom/HTMLDialogElement/dialog-autofocus_t01: RuntimeError # co19-roll r722: Please triage this failure.
-LayoutTests/fast/dom/HTMLDialogElement/dialog-close-event_t01: RuntimeError # co19-roll r722: Please triage this failure.
-LayoutTests/fast/dom/HTMLDialogElement/dialog-enabled_t01: RuntimeError # co19-roll r722: Please triage this failure.
-LayoutTests/fast/dom/HTMLDialogElement/dialog-open_t01: RuntimeError # co19-roll r722: Please triage this failure.
-LayoutTests/fast/dom/HTMLDialogElement/dialog-return-value_t01: RuntimeError # co19-roll r722: Please triage this failure.
 LayoutTests/fast/dom/HTMLDialogElement/dialog-scrolled-viewport_t01: RuntimeError # co19-roll r722: Please triage this failure.
 LayoutTests/fast/dom/HTMLDialogElement/dialog-show-modal_t01: RuntimeError, Pass # co19-roll r722: Please triage this failure.
-LayoutTests/fast/dom/HTMLDialogElement/inert-does-not-match-disabled-selector_t01: RuntimeError # co19-roll r722: Please triage this failure.
 LayoutTests/fast/dom/HTMLDialogElement/inert-node-is-unfocusable_t01: RuntimeError # co19-roll r722: Please triage this failure.
 LayoutTests/fast/dom/HTMLDialogElement/inert-node-is-unselectable_t01: RuntimeError # co19-roll r722: Please triage this failure.
 LayoutTests/fast/dom/HTMLDialogElement/multiple-centered-dialogs_t01: RuntimeError # co19-roll r722: Please triage this failure.
@@ -251,10 +241,6 @@
 LayoutTests/fast/dom/HTMLOutputElement/dom-settable-token-list_t01: RuntimeError # Issue 18931
 LayoutTests/fast/dom/HTMLObjectElement/set-type-to-null-crash_t01: RuntimeError # Issue 18931
 LayoutTests/fast/dom/HTMLDialogElement/show-modal-focusing-steps_t01: RuntimeError # co19-roll r722: Please triage this failure.
-LayoutTests/fast/dom/HTMLDialogElement/submit-dialog-close-event_t01: RuntimeError # co19-roll r722: Please triage this failure.
-LayoutTests/fast/dom/HTMLDialogElement/synthetic-click-inert_t01: RuntimeError # co19-roll r722: Please triage this failure.
-LayoutTests/fast/dom/HTMLDialogElement/top-layer-position-relative_t01: RuntimeError # co19-roll r722: Please triage this failure.
-LayoutTests/fast/dom/HTMLDialogElement/top-layer-position-static_t01: RuntimeError # co19-roll r722: Please triage this failure.
 LayoutTests/fast/dom/HTMLElement/set-inner-outer-optimization_t01: RuntimeError # co19-roll r722: Please triage this failure.
 LayoutTests/fast/dom/HTMLElement/spellcheck_t01: RuntimeError # co19-roll r722: Please triage this failure.
 LayoutTests/fast/dom/HTMLFormElement/move-option-between-documents_t01: RuntimeError # co19-roll r722: Please triage this failure.
@@ -267,7 +253,6 @@
 LayoutTests/fast/dom/HTMLLinkElement/prefetch_t01: Skip # co19-roll r722: Please triage this failure.
 LayoutTests/fast/dom/HTMLLinkElement/resolve-url-on-insertion_t01: RuntimeError # co19-roll r722: Please triage this failure.
 LayoutTests/fast/dom/HTMLObjectElement/beforeload-set-text-crash_t01: Skip # co19-roll r722: Please triage this failure.
-LayoutTests/fast/dom/HTMLObjectElement/children-changed_t01: RuntimeError # co19-roll r722: Please triage this failure.
 LayoutTests/fast/dom/HTMLScriptElement/script-set-src_t01: RuntimeError, Pass # co19-roll r722: Please triage this failure.
 LibTest/html/IFrameElement/outerHtml_setter_A01_t01: RuntimeError # co19-roll r722: Please triage this failure.
 LibTest/html/IFrameElement/paddingEdge_A01_t01: RuntimeError # co19-roll r722: Please triage this failure.
@@ -414,9 +399,7 @@
 LayoutTests/fast/dom/focus-contenteditable_t01: RuntimeError, Pass # co19-roll r738: Please triage this failure.
 LayoutTests/fast/dom/horizontal-scrollbar-in-rtl-doesnt-fire-onscroll_t01: RuntimeError # co19-roll r738: Please triage this failure.
 LayoutTests/fast/dom/horizontal-scrollbar-when-dir-change_t01: RuntimeError # co19-roll r738: Please triage this failure.
-LayoutTests/fast/dom/importNode-null_t01: RuntimeError # co19-roll r738: Please triage this failure.
-LayoutTests/fast/dom/importNode-unsupported-node-type_t01: RuntimeError # co19-roll r738: Please triage this failure.
-LayoutTests/fast/dom/location-hash_t01: RuntimeError # co19-roll r738: Please triage this failure.
+LayoutTests/fast/dom/location-hash_t01: Pass, RuntimeError # co19-roll r738: Please triage this failure.
 LayoutTests/fast/dom/option-properties_t01: RuntimeError # co19-roll r738: Please triage this failure.
 LayoutTests/fast/dom/partial-layout-overlay-scrollbars_t01: RuntimeError # co19-roll r738: Please triage this failure.
 LayoutTests/fast/dom/set-innerHTML_t01: RuntimeError # co19-roll r738: Please triage this failure.
@@ -616,6 +599,7 @@
 # co19-roll r786
 Language/14_Libraries_and_Scripts/4_Scripts_A03_t03: RuntimeError # co19-roll r786: Please triage this failure.
 LayoutTests/fast/css/font-face-insert-link_t01: Pass, RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/css/font-face-multiple-ranges-for-unicode-range_t01: Pass, RuntimeError # co19-roll r786: Please triage this failure.
 LayoutTests/fast/css-generated-content/malformed-url_t01: RuntimeError # co19-roll r786: Please triage this failure.
 LayoutTests/fast/css-generated-content/pseudo-animation_t01: Pass, RuntimeError # co19-roll r786: Please triage this failure.
 LayoutTests/fast/css-generated-content/pseudo-element-events_t01: Skip # Timeout. co19-roll r786: Please triage this failure.
@@ -798,6 +782,20 @@
 LayoutTests/fast/xsl/default-html_t01: RuntimeError # co19-roll r786: Please triage this failure.
 WebPlatformTest/html/semantics/forms/the-input-element/password_t01: RuntimeError # co19-roll r786: Please triage this failure.
 WebPlatformTest/html/syntax/parsing/Document.getElementsByTagName-foreign_t02: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/dom/52776_t01: RuntimeError # Re-enable fast/dom tests: Please triage this failure.
+LayoutTests/fast/dom/DOMException/XPathException_t01: RuntimeError # Re-enable fast/dom tests: Please triage this failure.
+LayoutTests/fast/dom/Node/fragment-mutation_t01: RuntimeError # Re-enable fast/dom tests: Please triage this failure.
+LayoutTests/fast/dom/Range/bug-19527_t01: RuntimeError # Re-enable fast/dom tests: Please triage this failure.
+LayoutTests/fast/dom/Range/insertNode-empty-fragment-crash_t01: RuntimeError # Re-enable fast/dom tests: Please triage this failure.
+LayoutTests/fast/dom/Range/mutation_t01: RuntimeError # Re-enable fast/dom tests: Please triage this failure.
+LayoutTests/fast/dom/Range/range-constructor_t01: RuntimeError # Re-enable fast/dom tests: Please triage this failure.
+LayoutTests/fast/dom/Range/range-expand_t01: RuntimeError # Re-enable fast/dom tests: Please triage this failure.
+LayoutTests/fast/dom/Range/range-insertNode-separate-endContainer_t01: RuntimeError # Re-enable fast/dom tests: Please triage this failure.
+LayoutTests/fast/dom/Range/range-insertNode-splittext_t01: RuntimeError # Re-enable fast/dom tests: Please triage this failure.
+LayoutTests/fast/dom/document-importNode-arguments_t01: RuntimeError # Re-enable fast/dom tests: Please triage this failure.
+LayoutTests/fast/dom/domparser-parsefromstring-mimetype-support_t01: RuntimeError # Re-enable fast/dom tests: Please triage this failure.
+LayoutTests/fast/dom/horizontal-scrollbar-in-rtl_t01: RuntimeError # Re-enable fast/dom tests: Please triage this failure.
+LayoutTests/fast/dom/text-api-arguments_t01: RuntimeError # Re-enable fast/dom tests: Please triage this failure.
 
 [ $compiler == none && ($runtime == dartium || $runtime == ContentShellOnAndroid ) && $checked ]
 # New Dartium checked failures on new co19 browser tests in co19 revision 706.
@@ -866,6 +864,8 @@
 LayoutTests/fast/url/trivial_t01: RuntimeError # co19-roll r786: Please triage this failure.
 LayoutTests/fast/xmlhttprequest/xmlhttprequest-bad-mimetype_t01: RuntimeError # co19-roll r786: Please triage this failure.
 LayoutTests/fast/xmlhttprequest/xmlhttprequest-invalid-values_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/dom/HTMLDialogElement/top-layer-position-relative_t01: RuntimeError # Reenable fast/dom tests: Please triage this failure.
+LayoutTests/fast/dom/HTMLDialogElement/top-layer-position-static_t01: RuntimeError # Reenable fast/dom tests: Please triage this failure.
 
 [ $compiler == none && ($runtime == dartium || $runtime == ContentShellOnAndroid) && $mode == debug ]
 WebPlatformTest/html/semantics/embedded-content/media-elements/interfaces/TextTrack/mode_t01: Skip # Issue 19495.
@@ -896,6 +896,11 @@
 LayoutTests/fast/text/international/listbox-width-rtl_t01: RuntimeError # co19-roll r786: Please triage this failure.
 LayoutTests/fast/text-autosizing/text-removal_t01: RuntimeError # co19-roll r786: Please triage this failure.
 LayoutTests/fast/transforms/scrollIntoView-transformed_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/dom/partial-layout-overlay-scrollbars_t01: Pass, RuntimeError # Reenable fast/dom tests: Please triage this failure.
+LayoutTests/fast/dom/partial-layout-non-overlay-scrollbars_t01: RuntimeError # Reenable fast/dom tests: Please triage this failure.
+LayoutTests/fast/dom/shadow/shadowdom-for-input-type-change_t01: RuntimeError # Reenable fast/dom tests: Please triage this failure.
+LayoutTests/fast/dom/jsDevicePixelRatio_t01: RuntimeError # Reenable fast/dom tests: Please triage this failure.
+LayoutTests/fast/dom/HTMLLinkElement/prefetch-beforeload_t01: Pass, RuntimeError # Reenable fast/dom tests: Please triage this failure.
 
 [ $compiler == none && $runtime == dartium && ($mode != debug || $system != macos) ]
 LayoutTests/fast/canvas/webgl/WebGLContextEvent_t01: RuntimeError # co19-roll r761: Please triage this failure.
diff --git a/tests/compiler/dart2js/async_await_syntax.dart b/tests/compiler/dart2js/async_await_syntax.dart
new file mode 100644
index 0000000..8c461cf
--- /dev/null
+++ b/tests/compiler/dart2js/async_await_syntax.dart
@@ -0,0 +1,182 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Test async/await syntax.
+
+var yield = 0;
+var await = 0;
+
+a01a() async => null;                        /// a01a: ok
+a01b() async* => null;                       /// a01b: compile-time error
+a01c() sync* => null;                        /// a01c: compile-time error
+a02a() async {}                              /// a02a: ok
+a03a() async* {}                             /// a03a: ok
+a03b() async * {}                            /// a03b: compile-time error
+a04a() sync* {}                              /// a04a: ok
+a04b() sync {}                               /// a04b: compile-time error
+a04c() sync * {}                             /// a04c: compile-time error
+a05a() async { await 0; }                    /// a05a: ok
+a05b() async {                               /// a05b: ok
+  await(a) {};                               /// a05b: continued
+  await(0);                                  /// a05b: continued
+}                                            /// a05b: continued
+a05c() {                                     /// a05c: ok
+  await(a) {};                               /// a05c: continued
+  await(0);                                  /// a05c: continued
+}                                            /// a05c: continued
+a05d() async {                               /// a05d: compile-time error
+  await(a) {}                                /// a05d: continued
+  await(0);                                  /// a05d: continued
+}                                            /// a05d: continued
+a05e() {                                     /// a05e: ok
+  await(a) {}                                /// a05e: continued
+  await(0);                                  /// a05e: continued
+}                                            /// a05e: continued
+a05f() async {                               /// a05f: compile-time error
+  var await = (a) {};                        /// a05f: continued
+  await(0);                                  /// a05f: continued
+}                                            /// a05f: continued
+a06a() async { await for (var o in []) {} }  /// a06a: ok
+a06b() sync* { await for (var o in []) {} }  /// a06b: compile-time error
+a07a() sync* { yield 0; }                    /// a07a: ok
+a07b() sync { yield 0; }                     /// a07b: compile-time error
+a08a() sync* { yield* []; }                  /// a08a: ok
+a08b() sync { yield 0; }                     /// a08b: compile-time error
+a09a() async* { yield 0; }                   /// a09a: ok
+a10a() async* { yield* []; }                 /// a10a: ok
+
+abstract class B {
+  b00a() async;   /// b00a: compile-time error
+  b00b() async*;  /// b00b: compile-time error
+  b00c() sync*;   /// b00c: compile-time error
+  b00d() sync;    /// b00d: compile-time error
+}
+
+class C extends B {
+  C();
+
+  factory C.e1() async { return null; }   /// e1: compile-time error
+  factory C.e2() async* { return null; }  /// e2: compile-time error
+  factory C.e3() sync* { return null; }   /// e3: compile-time error
+  factory C.e4() async = C;               /// e4: compile-time error
+  factory C.e5() async* = C;              /// e5: compile-time error
+  factory C.e6() sync* = C;               /// e6: compile-time error
+  C.e7() async {}                         /// e7: compile-time error
+  C.e8() async* {}                        /// e8: compile-time error
+  C.e9() sync* {}                         /// e9: compile-time error
+
+  b00a() {}   /// b00a: continued
+  b00b() {}   /// b00b: continued
+  b00c() {}   /// b00c: continued
+  b00d() {}   /// b00d: continued
+
+  b01a() async => null;                        /// b01a: ok
+  b01b() async* => null;                       /// b01b: compile-time error
+  b01c() sync* => null;                        /// b01c: compile-time error
+  b02a() async {}                              /// b02a: ok
+  b03a() async* {}                             /// b03a: ok
+  b04a() sync* {}                              /// b04a: ok
+  b04b() sync {}                               /// b04b: compile-time error
+  b05a() async { await 0; }                    /// b05a: ok
+  b06a() async { await for (var o in []) {} }  /// b06a: ok
+  b06b() async { await for ( ; ; ) {} }        /// b06b: compile-time error
+  b07a() sync* { yield 0; }                    /// b07a: ok
+  b08a() sync* { yield* []; }                  /// b08a: ok
+  b09a() async* { yield 0; }                   /// b09a: ok
+  b10a() async* { yield* []; }                 /// b10a: ok
+}
+
+method1() {
+  c01a() async => null; c01a();                        /// c01a: ok
+  c01b() async* => null; c01b();                       /// c01b: compile-time error
+  c01c() sync* => null; c01c();                        /// c01c: compile-time error
+  c02a() async {} c02a();                              /// c02a: ok
+  c03a() async* {} c03a();                             /// c03a: ok
+  c04a() sync* {} c04a();                              /// c04a: ok
+  c04b() sync {} c04b();                               /// c04b: compile-time error
+  c05a() async { await 0; } c05a();                    /// c05a: ok
+  c06a() async { await for (var o in []) {} } c06a();  /// c06a: ok
+  c07a() sync* { yield 0; } c07a();                    /// c07a: ok
+  c08a() sync* { yield* []; } c08a();                  /// c08a: ok
+  c09a() async* { yield 0; } c09a();                   /// c09a: ok
+  c10a() async* { yield* []; } c10a();                 /// c10a: ok
+}
+
+method2() {
+  var d01a = () async => null; d01a();                         /// d01a: ok
+  var d01b = () async* => null; d01b();                        /// d01b: compile-time error
+  var d01c = () sync* => null; d01c();                         /// d01c: compile-time error
+  var d02a = () async {}; d02a();                              /// d02a: ok
+  var d03a = () async* {}; d03a();                             /// d03a: ok
+  var d04a = () sync* {}; d04a();                              /// d04a: ok
+  var d04b = () sync {}; d04b();                               /// d04b: compile-time error
+  var d05a = () async { await 0; }; d05a();                    /// d05a: ok
+  var d06a = () async { await for (var o in []) {} }; d06a();  /// d06a: ok
+  var d07a = () sync* { yield 0; }; d07a();                    /// d07a: ok
+  var d08a = () sync* { yield* []; }; d08a();                  /// d08a: ok
+  var d08b = () sync* { yield*0+1; }; d08b();                  /// d08b: ok
+  var d08c = () { yield*0+1; }; d08c();                        /// d08c: ok
+  var d09a = () async* { yield 0; }; d09a();                   /// d09a: ok
+  var d10a = () async* { yield* []; }; d10a();                 /// d10a: ok
+}
+
+
+void main() {
+  var c = new C();
+  c = new C.e1(); /// e1: continued
+  c = new C.e2(); /// e2: continued
+  c = new C.e3(); /// e3: continued
+  c = new C.e4(); /// e4: continued
+  c = new C.e5(); /// e5: continued
+  c = new C.e6(); /// e6: continued
+  c = new C.e7(); /// e7: continued
+  c = new C.e8(); /// e8: continued
+  c = new C.e9(); /// e9: continued
+
+  a01a();     /// a01a: continued
+  a01b();     /// a01b: continued
+  a01c();     /// a01c: continued
+  a02a();     /// a02a: continued
+  a03a();     /// a03a: continued
+  a03b();     /// a03b: continued
+  a04a();     /// a04a: continued
+  a04b();     /// a04b: continued
+  a04c();     /// a04c: continued
+  a05a();     /// a05a: continued
+  a05b();     /// a05b: continued
+  a05c();     /// a05c: continued
+  a05d();     /// a05d: continued
+  a05e();     /// a05e: continued
+  a05f();     /// a05f: continued
+  a06a();     /// a06a: continued
+  a06b();     /// a06b: continued
+  a07a();     /// a07a: continued
+  a07b();     /// a07b: continued
+  a08a();     /// a08a: continued
+  a08b();     /// a08b: continued
+  a09a();     /// a09a: continued
+  a10a();     /// a10a: continued
+
+  c.b00a();   /// b00a: continued
+  c.b00b();   /// b00b: continued
+  c.b00c();   /// b00c: continued
+  c.b00d();   /// b00d: continued
+  c.b01a();   /// b01a: continued
+  c.b01b();   /// b01b: continued
+  c.b01c();   /// b01c: continued
+  c.b02a();   /// b02a: continued
+  c.b03a();   /// b03a: continued
+  c.b04a();   /// b04a: continued
+  c.b04b();   /// b04b: continued
+  c.b05a();   /// b05a: continued
+  c.b06a();   /// b06a: continued
+  c.b06b();   /// b06b: continued
+  c.b07a();   /// b07a: continued
+  c.b08a();   /// b08a: continued
+  c.b09a();   /// b09a: continued
+  c.b10a();   /// b10a: continued
+
+  method1();
+  method2();
+}
diff --git a/tests/compiler/dart2js/async_await_syntax_test.dart b/tests/compiler/dart2js/async_await_syntax_test.dart
new file mode 100644
index 0000000..e42bda0
--- /dev/null
+++ b/tests/compiler/dart2js/async_await_syntax_test.dart
@@ -0,0 +1,16 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file

+// for details. All rights reserved. Use of this source code is governed by a

+// BSD-style license that can be found in the LICENSE file.

+

+// Test that dart2js produces the expected static type warnings and

+// compile-time errors for these tests.

+

+import 'frontend_checker.dart';

+

+const List<String> TESTS = const <String>[

+  'compiler/dart2js/async_await_syntax.dart',

+];

+

+void main(List<String> arguments) {

+  check(TESTS, arguments: arguments, options: ['--enable-async']);

+}

diff --git a/tests/compiler/dart2js/backend_dart/dart_printer_test.dart b/tests/compiler/dart2js/backend_dart/dart_printer_test.dart
index 180870f..f278080 100644
--- a/tests/compiler/dart2js/backend_dart/dart_printer_test.dart
+++ b/tests/compiler/dart2js/backend_dart/dart_printer_test.dart
@@ -417,11 +417,13 @@
   handleNoFormalParameters(tok) {
     push(new Parameters([]));
   }
-  endUnamedFunction(t) {
+
+  endUnnamedFunction(t) {
     Statement body = pop();
     Parameters parameters = pop();
     push(new FunctionExpression(parameters, body));
   }
+
   handleNoType(Token token) {
     push(null);
   }
@@ -572,7 +574,7 @@
     push(null);
   }
 
-  endForIn(Token begin, Token inKeyword, Token end) {
+  endForIn(Token await, Token begin, Token inKeyword, Token end) {
     Statement body = pop();
     Expression exp = pop();
     Node declaredIdentifier = pop();
diff --git a/tests/compiler/dart2js/backend_dart/sexpr_unstringifier.dart b/tests/compiler/dart2js/backend_dart/sexpr_unstringifier.dart
index f0954c6..8ba1a38 100644
--- a/tests/compiler/dart2js/backend_dart/sexpr_unstringifier.dart
+++ b/tests/compiler/dart2js/backend_dart/sexpr_unstringifier.dart
@@ -502,7 +502,7 @@
     assert(cont != null);
 
     tokens.consumeEnd();
-    return new TypeOperator(operator, recv, type, cont);
+    return new TypeOperator(recv, type, cont, isTypeTest: operator == 'is');
   }
 
   /// (LetPrim name (primitive)) body
@@ -659,8 +659,13 @@
     List<Primitive> keys   = parsePrimitiveList();
     List<Primitive> values = parsePrimitiveList();
 
+    List<LiteralMapEntry> entries = <LiteralMapEntry>[];
+    for (int i = 0; i < keys.length; i++) {
+      entries.add(new LiteralMapEntry(keys[i], values[i]));
+    }
+
     tokens.consumeEnd();
-    return new LiteralMap(null, keys, values);
+    return new LiteralMap(null, entries);
   }
 
   /// (ReifyTypeVar type)
diff --git a/tests/compiler/dart2js/frontend_checker.dart b/tests/compiler/dart2js/frontend_checker.dart
new file mode 100644
index 0000000..c3fc633
--- /dev/null
+++ b/tests/compiler/dart2js/frontend_checker.dart
@@ -0,0 +1,71 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file

+// for details. All rights reserved. Use of this source code is governed by a

+// BSD-style license that can be found in the LICENSE file.

+

+// Checks that dart2js produces the expected static type warnings and

+// compile-time errors for the provided multitests.

+

+import 'dart:async';

+

+import 'package:expect/expect.dart';

+import 'package:async_helper/async_helper.dart';

+

+import 'memory_compiler.dart';

+

+import '../../../tools/testing/dart/multitest.dart'

+    show ExtractTestsFromMultitest;

+import '../../../tools/testing/dart/utils.dart'

+    show Path;

+

+void check(List<String> testFiles,

+           {List<String> arguments: const <String>[],

+            List<String> options: const <String>[]}) {

+  bool outcomeMismatch = false;

+  bool verbose = arguments.contains('-v');

+  var cachedCompiler;

+  asyncTest(() => Future.forEach(testFiles, (String testFile) {

+    Map<String, String> testSources = {};

+    Map<String, Set<String>> testOutcomes = {};

+    String fileName = 'tests/$testFile';

+    ExtractTestsFromMultitest(new Path(fileName), testSources, testOutcomes);

+    return Future.forEach(testSources.keys, (String testName) {

+      String testFileName = '$fileName/$testName';

+      Set<String> expectedOutcome = testOutcomes[testName];

+      DiagnosticCollector collector = new DiagnosticCollector();

+      var compiler = compilerFor(

+           {testFileName: testSources[testName]},

+           diagnosticHandler: collector,

+           options: ['--analyze-only']..addAll(options),

+           showDiagnostics: verbose,

+           cachedCompiler: cachedCompiler);

+      return compiler.run(Uri.parse('memory:$testFileName')).then((_) {

+        if (expectedOutcome.contains('compile-time error')) {

+          if (collector.errors.isEmpty) {

+            print('$testFileName: Missing compile-time error.');

+            outcomeMismatch = true;

+          }

+        } else if (expectedOutcome.contains('static type warning')) {

+          if (collector.warnings.isEmpty) {

+            print('$testFileName: Missing static type warning.');

+            outcomeMismatch = true;

+          }

+        } else {

+          // Expect ok.

+          if (!collector.errors.isEmpty ||

+              !collector.warnings.isEmpty) {

+            collector.errors.forEach((message) {

+              print('$testFileName: Unexpected error: ${message.message}');

+            });

+            collector.warnings.forEach((message) {

+              print('$testFileName: Unexpected warning: ${message.message}');

+            });

+            outcomeMismatch = true;

+          }

+        }

+        cachedCompiler = compiler;

+      });

+    });

+  }).then((_) {

+    Expect.isFalse(outcomeMismatch, 'Outcome mismatch');

+  }));

+}

diff --git a/tests/compiler/dart2js/message_kind_helper.dart b/tests/compiler/dart2js/message_kind_helper.dart
index dfadfb2..e6b3129 100644
--- a/tests/compiler/dart2js/message_kind_helper.dart
+++ b/tests/compiler/dart2js/message_kind_helper.dart
@@ -83,7 +83,7 @@
     Compiler compiler = compilerFor(
         example,
         diagnosticHandler: collect,
-        options: ['--analyze-only'],
+        options: ['--analyze-only']..addAll(kind.options),
         cachedCompiler: cachedCompiler);
 
     return compiler.run(Uri.parse('memory:main.dart')).then((_) {
diff --git a/tests/compiler/dart2js/message_kind_test.dart b/tests/compiler/dart2js/message_kind_test.dart
index 6482f53..9f68cb3 100644
--- a/tests/compiler/dart2js/message_kind_test.dart
+++ b/tests/compiler/dart2js/message_kind_test.dart
@@ -13,7 +13,7 @@
 
 import 'dart:mirrors';
 
-main() {
+main(List<String> arguments) {
   ClassMirror cls = reflectClass(MessageKind);
   Map<String, MessageKind> kinds = <String, MessageKind>{};
   cls.declarations.forEach((Symbol name, DeclarationMirror declaration) {
@@ -31,6 +31,7 @@
   List<String> names = kinds.keys.toList()..sort();
   List<String> examples = <String>[];
   for (String name in names) {
+    if (!arguments.isEmpty && !arguments.contains(name)) continue;
     MessageKind kind = kinds[name];
     if (name == 'GENERIC' // Shouldn't be used.
         // We can't provoke a crash.
diff --git a/tests/compiler/dart2js/mock_compiler.dart b/tests/compiler/dart2js/mock_compiler.dart
index dbc5087..703fada 100644
--- a/tests/compiler/dart2js/mock_compiler.dart
+++ b/tests/compiler/dart2js/mock_compiler.dart
@@ -107,6 +107,8 @@
                    buildLibrarySource(DEFAULT_ISOLATE_HELPER_LIBRARY));
     registerSource(Compiler.DART_MIRRORS,
                    buildLibrarySource(DEFAULT_MIRRORS_LIBRARY));
+    registerSource(Compiler.DART_ASYNC,
+                   buildLibrarySource(DEFAULT_ASYNC_LIBRARY));
   }
 
   /// Initialize the mock compiler with an empty main library.
diff --git a/tests/compiler/dart2js/mock_libraries.dart b/tests/compiler/dart2js/mock_libraries.dart
index 5f5cc74..f0d2b72 100644
--- a/tests/compiler/dart2js/mock_libraries.dart
+++ b/tests/compiler/dart2js/mock_libraries.dart
@@ -42,6 +42,7 @@
   'Function': 'class Function {}',
   'identical': 'bool identical(Object a, Object b) { return true; }',
   'int': 'abstract class int extends num { }',
+  'Iterable': 'abstract class Iterable {}',
   'LinkedHashMap': r'''
       class LinkedHashMap {
         factory LinkedHashMap._empty() => null;
@@ -357,6 +358,11 @@
   '_WorkerBase': 'class _WorkerBase {}',
 };
 
+const Map<String, String> DEFAULT_ASYNC_LIBRARY = const <String, String>{
+  'Future': 'class Future<T> {}',
+  'Stream': 'class Stream<T> {}',
+};
+
 const Map<String, String> DEFAULT_MIRRORS_LIBRARY = const <String, String>{
   'Comment': 'class Comment {}',
   'MirrorSystem': 'class MirrorSystem {}',
diff --git a/tests/compiler/dart2js_extra/21351_test.dart b/tests/compiler/dart2js_extra/21351_test.dart
new file mode 100644
index 0000000..3f1d00e
--- /dev/null
+++ b/tests/compiler/dart2js_extra/21351_test.dart
@@ -0,0 +1,30 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for 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 {
+  bool _flag = false;
+  bool get flag => _flag;
+}
+
+main () {
+  var value1, value2; 
+  var count = 0;
+
+  for (var x = 0; x < 10; x++) {
+    var otherThing = new A();
+    for (var dummy = 0; dummy < x; dummy++) {
+      otherThing._flag = !otherThing._flag;
+    }
+
+    value1 = value2;
+    value2 = otherThing;
+
+    if (value1 == null) continue;
+
+    if (value1.flag) count++;
+  }
+
+  if (count == 0) throw "FAIL";
+}
+
diff --git a/tests/corelib/corelib.status b/tests/corelib/corelib.status
index 831c989..743832b 100644
--- a/tests/corelib/corelib.status
+++ b/tests/corelib/corelib.status
@@ -124,10 +124,12 @@
 
 [ $compiler == dart2js && ($runtime == firefox || $runtime == safari || $runtime == chrome || $runtime == drt) ]
 
+[ $compiler == dart2js && ($runtime == safari || $runtime == safarimobilesim) ]
+string_split_test: RuntimeError # Issue 21431
+
 [ $compiler == dart2js && (($runtime == safari && $builder_tag == mac10_7) || $runtime == safarimobilesim) ]
 list_test/01: Fail # Safari bug: Array(-2) seen as dead code.
 string_trimlr_test/none: Fail
-string_split_test: RuntimeError # Issue 21431
 
 [ $compiler == dart2js && $runtime == ie10 ]
 string_case_test/01: Fail, OK  # Bug in IE.
@@ -218,3 +220,8 @@
 
 [ $system == windows && $arch == x64 ]
 stopwatch_test: Skip  # Flaky test due to expected performance behaviour.
+
+[ $runtime != d8 ]
+# JSCRE does not pass all of the tests ported for irregexp.
+# Ignore all of the tests until irregexp is fully ported.
+regexp/*: Skip
diff --git a/tests/corelib/regexp/UC16_test.dart b/tests/corelib/regexp/UC16_test.dart
new file mode 100644
index 0000000..c8a16de
--- /dev/null
+++ b/tests/corelib/regexp/UC16_test.dart
@@ -0,0 +1,53 @@
+// Copyright (c) 2014, the Dart project authors. All rights reserved.
+// Copyright 2008 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+//       copyright notice, this list of conditions and the following
+//       disclaimer in the documentation and/or other materials provided
+//       with the distribution.
+//     * Neither the name of Google Inc. nor the names of its
+//       contributors may be used to endorse or promote products derived
+//       from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+import 'v8_regexp_utils.dart';
+import 'package:expect/expect.dart';
+
+void main() {
+  // UC16
+  // Characters used:
+  // "\u03a3\u03c2\u03c3\u039b\u03bb" - Sigma, final sigma, sigma, Lambda, lamda
+  shouldBe(new RegExp(r"x(.)\1x", caseSensitive: false).firstMatch("x\u03a3\u03c3x"),
+      ["x\u03a3\u03c3x", "\u03a3"], "backref-UC16");
+  assertFalse(new RegExp(r"x(...)\1", caseSensitive: false).hasMatch("x\u03a3\u03c2\u03c3\u03c2\u03c3"),
+              "\1 ASCII, string short");
+  assertTrue(new RegExp(r"\u03a3((?:))\1\1x", caseSensitive: false).hasMatch("\u03c2x"), "backref-UC16-empty");
+  assertTrue(new RegExp(r"x(?:...|(...))\1x", caseSensitive: false).hasMatch("x\u03a3\u03c2\u03c3x"),
+            "backref-UC16-uncaptured");
+  assertTrue(new RegExp(r"x(?:...|(...))\1x", caseSensitive: false).hasMatch("x\u03c2\u03c3\u039b\u03a3\u03c2\u03bbx"),
+            "backref-UC16-backtrack");
+  var longUC16String = "x\u03a3\u03c2\u039b\u03c2\u03c3\u03bb\u03c3\u03a3\u03bb";
+  shouldBe(new RegExp(r"x(...)\1\1", caseSensitive: false).firstMatch(longUC16String),
+          [longUC16String, longUC16String.substring(1,4)],
+          "backref-UC16-twice");
+
+  assertFalse(new RegExp(r"\xc1", caseSensitive: false).hasMatch('fooA'), "quickcheck-uc16-pattern-ascii-subject");
+  assertFalse(new RegExp(r"[\xe9]").hasMatch('i'), "charclass-uc16-pattern-ascii-subject");
+  assertFalse(new RegExp(r"\u5e74|\u6708").hasMatch('t'), "alternation-uc16-pattern-ascii-subject");
+}
diff --git a/tests/corelib/regexp/alternative-length-miscalculation_test.dart b/tests/corelib/regexp/alternative-length-miscalculation_test.dart
new file mode 100644
index 0000000..33ec7b2
--- /dev/null
+++ b/tests/corelib/regexp/alternative-length-miscalculation_test.dart
@@ -0,0 +1,38 @@
+// Copyright (c) 2014, the Dart project authors. All rights reserved.
+// Copyright 2013 the V8 project authors. All rights reserved.
+// Copyright (C) 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1.  Redistributions of source code must retain the above copyright
+//     notice, this list of conditions and the following disclaimer.
+// 2.  Redistributions in binary form must reproduce the above copyright
+//     notice, this list of conditions and the following disclaimer in the
+//     documentation and/or other materials provided with the distribution.
+//
+// THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
+// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+import 'v8_regexp_utils.dart';
+import 'package:expect/expect.dart';
+
+void main() {
+  description(
+  "This page tests for length miscalculations in regular expression processing."
+  );
+
+  var re = new RegExp(r"b|[^b]");
+  assertEquals('a'.indexOf(re, 1), -1);
+
+  var re2 = new RegExp(r"[^a]|ab");
+  shouldBeFalse(re2.hasMatch(''));
+}
diff --git a/tests/corelib/regexp/alternatives_test.dart b/tests/corelib/regexp/alternatives_test.dart
new file mode 100644
index 0000000..9d2cc4a
--- /dev/null
+++ b/tests/corelib/regexp/alternatives_test.dart
@@ -0,0 +1,48 @@
+// Copyright (c) 2014, the Dart project authors. All rights reserved.
+// Copyright 2013 the V8 project authors. All rights reserved.
+// Copyright (C) 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1.  Redistributions of source code must retain the above copyright
+//     notice, this list of conditions and the following disclaimer.
+// 2.  Redistributions in binary form must reproduce the above copyright
+//     notice, this list of conditions and the following disclaimer in the
+//     documentation and/or other materials provided with the distribution.
+//
+// THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
+// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+import 'v8_regexp_utils.dart';
+import 'package:expect/expect.dart';
+
+void main() {
+  description(
+  'Test regular expression processing with alternatives.'
+  );
+
+  var s1 = "<p>content</p>";
+  shouldBe(firstMatch(s1, new RegExp(r"<((\\/([^>]+)>)|(([^>]+)>))")), ["<p>","p>",null,null,"p>","p"]);
+  shouldBe(firstMatch(s1, new RegExp(r"<((ABC>)|(\\/([^>]+)>)|(([^>]+)>))")), ["<p>","p>",null,null,null,"p>","p"]);
+  shouldBe(firstMatch(s1, new RegExp(r"<(a|\\/p|.+?)>")), ["<p>","p"]);
+
+  // Force YARR to use Interpreter by using iterative parentheses
+  shouldBe(firstMatch(s1, new RegExp(r"<((\\/([^>]+)>)|((([^>])+)>))")), ["<p>","p>",null,null,"p>","p","p"]);
+  shouldBe(firstMatch(s1, new RegExp(r"<((ABC>)|(\\/([^>]+)>)|((([^>])+)>))")), ["<p>","p>",null,null,null,"p>","p","p"]);
+  shouldBe(firstMatch(s1, new RegExp(r"<(a|\\/p|(.)+?)>")), ["<p>","p","p"]);
+
+  // Force YARR to use Interpreter by using backreference
+  var s2 = "<p>p</p>";
+  shouldBe(firstMatch(s2, new RegExp(r"<((\\/([^>]+)>)|(([^>]+)>))\5")), ["<p>p","p>",null,null,"p>","p"]);
+  shouldBe(firstMatch(s2, new RegExp(r"<((ABC>)|(\\/([^>]+)>)|(([^>]+)>))\6")), ["<p>p","p>",null,null,null,"p>","p"]);
+  shouldBe(firstMatch(s2, new RegExp(r"<(a|\\/p|.+?)>\1")), ["<p>p","p"]);
+}
diff --git a/tests/corelib/regexp/ascii-regexp-subject_test.dart b/tests/corelib/regexp/ascii-regexp-subject_test.dart
new file mode 100644
index 0000000..67ff607
--- /dev/null
+++ b/tests/corelib/regexp/ascii-regexp-subject_test.dart
@@ -0,0 +1,54 @@
+// Copyright (c) 2014, the Dart project authors. All rights reserved.
+// Copyright 2008 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+//       copyright notice, this list of conditions and the following
+//       disclaimer in the documentation and/or other materials provided
+//       with the distribution.
+//     * Neither the name of Google Inc. nor the names of its
+//       contributors may be used to endorse or promote products derived
+//       from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+/**
+* @fileoverview Check that an initial ^ will result in a faster match fail.
+*/
+
+import 'v8_regexp_utils.dart';
+import 'package:expect/expect.dart';
+
+void main() {
+  var s = "foo";
+  var i;
+
+  for (i = 0; i < 18; i++) {
+    s = s + s;
+  }
+
+  dynamic repeatRegexp(re) {
+    for (i = 0; i < 1000; i++) {
+      re.hasMatch(s);
+    }
+  }
+
+  repeatRegexp(new RegExp(r"^bar"));
+  repeatRegexp(new RegExp(r"^foo|^bar|^baz"));
+  repeatRegexp(new RegExp(r"(^bar)"));
+  repeatRegexp(new RegExp(r"(?=^bar)\w+"));
+}
diff --git a/tests/corelib/regexp/assertion_test.dart b/tests/corelib/regexp/assertion_test.dart
new file mode 100644
index 0000000..9899a85
--- /dev/null
+++ b/tests/corelib/regexp/assertion_test.dart
@@ -0,0 +1,115 @@
+// Copyright (c) 2014, the Dart project authors. All rights reserved.
+// Copyright 2013 the V8 project authors. All rights reserved.
+// Copyright (C) 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1.  Redistributions of source code must retain the above copyright
+//     notice, this list of conditions and the following disclaimer.
+// 2.  Redistributions in binary form must reproduce the above copyright
+//     notice, this list of conditions and the following disclaimer in the
+//     documentation and/or other materials provided with the distribution.
+//
+// THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
+// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+import 'v8_regexp_utils.dart';
+import 'package:expect/expect.dart';
+
+void main() {
+  description("This page tests handling of parenthetical assertions.");
+
+  var regex1 = new RegExp(r"(x)(?=\1)x");
+  shouldBe(regex1.firstMatch('xx'), ['xx','x']);
+
+  var regex2 = new RegExp(r"(.*?)a(?!(a+)b\2c)\2(.*)");
+  shouldBe(regex2.firstMatch('baaabaac'), ['baaabaac','ba',null,'abaac']);
+
+  var regex3 = new RegExp(r"(?=(a+?))(\1ab)");
+  shouldBe(regex3.firstMatch('aaab'), ['aab','a','aab']);
+
+  var regex4 = new RegExp(r"(?=(a+?))(\1ab)");
+  shouldBe(regex4.firstMatch('aaab'), ['aab','a','aab']);
+
+  var regex5 = new RegExp(r"^P([1-6])(?=\1)([1-6])$");
+  shouldBe(regex5.firstMatch('P11'), ['P11','1','1']);
+
+  var regex6 = new RegExp(r"(([a-c])b*?\2)*");
+  shouldBe(regex6.firstMatch('ababbbcbc'), ['ababb','bb','b']);
+
+  var regex7 = new RegExp(r"(x)(?=x)x");
+  shouldBe(regex7.firstMatch('xx'), ['xx','x']);
+
+  var regex8 = new RegExp(r"(x)(\1)");
+  shouldBe(regex8.firstMatch('xx'), ['xx','x','x']);
+
+  var regex9 = new RegExp(r"(x)(?=\1)x");
+  shouldBeNull(regex9.firstMatch('xy'));
+
+  var regex10 = new RegExp(r"(x)(?=x)x");
+  shouldBeNull(regex10.firstMatch('xy'));
+
+  var regex11 = new RegExp(r"(x)(\1)");
+  shouldBeNull(regex11.firstMatch('xy'));
+
+  var regex12 = new RegExp(r"(x)(?=\1)x");
+  shouldBeNull(regex12.firstMatch('x'));
+  shouldBe(regex12.firstMatch('xx'), ['xx','x']);
+  shouldBe(regex12.firstMatch('xxy'), ['xx','x']);
+
+  var regex13 = new RegExp(r"(x)zzz(?=\1)x");
+  shouldBe(regex13.firstMatch('xzzzx'), ['xzzzx','x']);
+  shouldBe(regex13.firstMatch('xzzzxy'), ['xzzzx','x']);
+
+  var regex14 = new RegExp(r"(a)\1(?=(b*c))bc");
+  shouldBe(regex14.firstMatch('aabc'), ['aabc','a','bc']);
+  shouldBe(regex14.firstMatch('aabcx'), ['aabc','a','bc']);
+
+  var regex15 = new RegExp(r"(a)a(?=(b*c))bc");
+  shouldBe(regex15.firstMatch('aabc'), ['aabc','a','bc']);
+  shouldBe(regex15.firstMatch('aabcx'), ['aabc','a','bc']);
+
+  var regex16 = new RegExp(r"a(?=(b*c))bc");
+  shouldBeNull(regex16.firstMatch('ab'));
+  shouldBe(regex16.firstMatch('abc'), ['abc','bc']);
+
+  var regex17 = new RegExp(r"(?=((?:ab)*))a");
+  shouldBe(regex17.firstMatch('ab'), ['a','ab']);
+  shouldBe(regex17.firstMatch('abc'), ['a','ab']);
+
+  var regex18 = new RegExp(r"(?=((?:xx)*))x");
+  shouldBe(regex18.firstMatch('x'), ['x','']);
+  shouldBe(regex18.firstMatch('xx'), ['x','xx']);
+  shouldBe(regex18.firstMatch('xxx'), ['x','xx']);
+
+  var regex19 = new RegExp(r"(?=((xx)*))x");
+  shouldBe(regex19.firstMatch('x'), ['x','',null]);
+  shouldBe(regex19.firstMatch('xx'), ['x','xx','xx']);
+  shouldBe(regex19.firstMatch('xxx'), ['x','xx','xx']);
+
+  var regex20 = new RegExp(r"(?=(xx))+x");
+  shouldBeNull(regex20.firstMatch('x'));
+  shouldBe(regex20.firstMatch('xx'), ['x','xx']);
+  shouldBe(regex20.firstMatch('xxx'), ['x','xx']);
+
+  var regex21 = new RegExp(r"(?=a+b)aab");
+  shouldBe(regex21.firstMatch('aab'), ['aab']);
+
+  var regex22 = new RegExp(r"(?!(u|m{0,}g+)u{1,}|2{2,}!1%n|(?!K|(?=y)|(?=ip))+?)(?=(?=(((?:7))*?)*?))p", multiLine: true);
+  shouldBeNull(regex22.firstMatch('55up'));
+
+  var regex23 = new RegExp(r"(?=(a)b|c?)()*d");
+  shouldBeNull(regex23.firstMatch('ax'));
+
+  var regex24 = new RegExp(r"(?=a|b?)c");
+  shouldBeNull(regex24.firstMatch('x'));
+}
diff --git a/tests/corelib/regexp/backreferences_test.dart b/tests/corelib/regexp/backreferences_test.dart
new file mode 100644
index 0000000..5e5cac9
--- /dev/null
+++ b/tests/corelib/regexp/backreferences_test.dart
@@ -0,0 +1,46 @@
+// Copyright (c) 2014, the Dart project authors. All rights reserved.
+// Copyright 2013 the V8 project authors. All rights reserved.
+// Copyright (C) 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1.  Redistributions of source code must retain the above copyright
+//     notice, this list of conditions and the following disclaimer.
+// 2.  Redistributions in binary form must reproduce the above copyright
+//     notice, this list of conditions and the following disclaimer in the
+//     documentation and/or other materials provided with the distribution.
+//
+// THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
+// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+import 'v8_regexp_utils.dart';
+import 'package:expect/expect.dart';
+
+void main() {
+  description("Test to ensure correct behaviour when using backreferences in a RegExp");
+
+  shouldBeTrue(new RegExp(r"(...)\1$").hasMatch('abcabc'));
+  shouldBeFalse(new RegExp(r"(...)\1$").hasMatch('abcdef'));
+  shouldBeFalse(new RegExp(r"(...)\2$").hasMatch('abcabc'));
+  shouldBeFalse(new RegExp(r"(...)\2$").hasMatch('abc'));
+  shouldBeTrue(new RegExp(r"\1(...)$").hasMatch('abcabc'));
+  shouldBeTrue(new RegExp(r"\1(...)$").hasMatch('abcdef'));
+  shouldBeFalse(new RegExp(r"\2(...)$").hasMatch('abcabc'));
+  shouldBeFalse(new RegExp(r"\2(...)$").hasMatch('abc'));
+  shouldBeTrue(new RegExp(r"\1?(...)$").hasMatch('abc'));
+  shouldBeTrue(new RegExp(r"\1?(...)$").hasMatch('abc'));
+
+  var re = new RegExp(r"[^b]*((..)|(\2))+Sz", caseSensitive: false);
+
+  shouldBeFalse(re.hasMatch('axabcd'));
+  shouldBeTrue(re.hasMatch('axabcsz'));
+}
diff --git a/tests/corelib/regexp/bol-with-multiline_test.dart b/tests/corelib/regexp/bol-with-multiline_test.dart
new file mode 100644
index 0000000..46b0ea5
--- /dev/null
+++ b/tests/corelib/regexp/bol-with-multiline_test.dart
@@ -0,0 +1,39 @@
+// Copyright (c) 2014, the Dart project authors. All rights reserved.
+// Copyright 2013 the V8 project authors. All rights reserved.
+// Copyright (C) 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1.  Redistributions of source code must retain the above copyright
+//     notice, this list of conditions and the following disclaimer.
+// 2.  Redistributions in binary form must reproduce the above copyright
+//     notice, this list of conditions and the following disclaimer in the
+//     documentation and/or other materials provided with the distribution.
+//
+// THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
+// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+import 'v8_regexp_utils.dart';
+import 'package:expect/expect.dart';
+
+void main() {
+  description(
+  'Test for beginning of line (BOL or ^) matching in a multiline string</a>'
+  );
+
+  var s = "aced\nabc";
+  shouldBeNull(firstMatch(s, new RegExp(r"^abc")));
+  shouldBe(firstMatch(s, new RegExp(r"^abc", multiLine: true)), ["abc"]);
+  shouldBeNull(firstMatch(s, new RegExp(r"(^|X)abc")));
+  shouldBe(firstMatch(s, new RegExp(r"(^|X)abc", multiLine: true)), ["abc",""]);
+  shouldBe(firstMatch(s, new RegExp(r"(^a|Xa)bc", multiLine: true)), ["abc","a"]);
+}
diff --git a/tests/corelib/regexp/bol_test.dart b/tests/corelib/regexp/bol_test.dart
new file mode 100644
index 0000000..d2a479e
--- /dev/null
+++ b/tests/corelib/regexp/bol_test.dart
@@ -0,0 +1,55 @@
+// Copyright (c) 2014, the Dart project authors. All rights reserved.
+// Copyright 2013 the V8 project authors. All rights reserved.
+// Copyright (C) 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1.  Redistributions of source code must retain the above copyright
+//     notice, this list of conditions and the following disclaimer.
+// 2.  Redistributions in binary form must reproduce the above copyright
+//     notice, this list of conditions and the following disclaimer in the
+//     documentation and/or other materials provided with the distribution.
+//
+// THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
+// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+import 'v8_regexp_utils.dart';
+import 'package:expect/expect.dart';
+
+void main() {
+  description(
+  'Test for beginning of line (BOL or ^) matching</a>'
+  );
+
+  var s = "abc123def456xyzabc789abc999";
+  shouldBeNull(firstMatch(s, new RegExp(r"^notHere")));
+  shouldBe(firstMatch(s, new RegExp(r"^abc")), ["abc"]);
+  shouldBe(firstMatch(s, new RegExp(r"(^|X)abc")), ["abc",""]);
+  shouldBe(firstMatch(s, new RegExp(r"^longer|123")), ["123"]);
+  shouldBe(firstMatch(s, new RegExp(r"(^abc|c)123")), ["abc123","abc"]);
+  shouldBe(firstMatch(s, new RegExp(r"(c|^abc)123")), ["abc123","abc"]);
+  shouldBe(firstMatch(s, new RegExp(r"(^ab|abc)123")), ["abc123","abc"]);
+  shouldBe(firstMatch(s, new RegExp(r"(bc|^abc)([0-9]*)a")), ["bc789a","bc","789"]);
+  shouldBeNull(new RegExp(r"(?:(Y)X)|(X)").firstMatch("abc"));
+  shouldBeNull(new RegExp(r"(?:(?:^|Y)X)|(X)").firstMatch("abc"));
+  shouldBeNull(new RegExp(r"(?:(?:^|Y)X)|(X)").firstMatch("abcd"));
+  shouldBe(new RegExp(r"(?:(?:^|Y)X)|(X)").firstMatch("Xabcd"), ["X",null]);
+  shouldBe(new RegExp(r"(?:(?:^|Y)X)|(X)").firstMatch("aXbcd"), ["X","X"]);
+  shouldBe(new RegExp(r"(?:(?:^|Y)X)|(X)").firstMatch("abXcd"), ["X","X"]);
+  shouldBe(new RegExp(r"(?:(?:^|Y)X)|(X)").firstMatch("abcXd"), ["X","X"]);
+  shouldBe(new RegExp(r"(?:(?:^|Y)X)|(X)").firstMatch("abcdX"), ["X","X"]);
+  shouldBe(new RegExp(r"(?:(?:^|Y)X)|(X)").firstMatch("YXabcd"), ["YX",null]);
+  shouldBe(new RegExp(r"(?:(?:^|Y)X)|(X)").firstMatch("aYXbcd"), ["YX",null]);
+  shouldBe(new RegExp(r"(?:(?:^|Y)X)|(X)").firstMatch("abYXcd"), ["YX",null]);
+  shouldBe(new RegExp(r"(?:(?:^|Y)X)|(X)").firstMatch("abcYXd"), ["YX",null]);
+  shouldBe(new RegExp(r"(?:(?:^|Y)X)|(X)").firstMatch("abcdYX"), ["YX",null]);
+}
diff --git a/tests/corelib/regexp/capture-3_test.dart b/tests/corelib/regexp/capture-3_test.dart
new file mode 100644
index 0000000..be935ef
--- /dev/null
+++ b/tests/corelib/regexp/capture-3_test.dart
@@ -0,0 +1,118 @@
+// Copyright (c) 2014, the Dart project authors. All rights reserved.
+// Copyright 2009 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+//       copyright notice, this list of conditions and the following
+//       disclaimer in the documentation and/or other materials provided
+//       with the distribution.
+//     * Neither the name of Google Inc. nor the names of its
+//       contributors may be used to endorse or promote products derived
+//       from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+import 'v8_regexp_utils.dart';
+import 'package:expect/expect.dart';
+
+void main() {
+  dynamic oneMatch(re) {
+    assertEquals("acd", "abcd".replaceAll(re, ""));
+  }
+
+  oneMatch(new RegExp(r"b"));
+  oneMatch(new RegExp(r"b"));
+
+  assertEquals("acdacd", "abcdabcd".replaceAll(new RegExp(r"b"), ""));
+
+  dynamic captureMatch(re) {
+    var match = firstMatch("abcd", re);
+    assertEquals("b", match.group(1));
+    assertEquals("c", match.group(2));
+  }
+
+  captureMatch(new RegExp(r"(b)(c)"));
+  captureMatch(new RegExp(r"(b)(c)"));
+
+  // A test that initially does a zero width match, but later does a non-zero
+  // width match.
+  var a = "foo bar baz".replaceAll(new RegExp(r"^|bar"), "");
+  assertEquals("foo  baz", a);
+
+  a = "foo bar baz".replaceAll(new RegExp(r"^|bar"), "*");
+  assertEquals("*foo * baz", a);
+
+  // We test FilterASCII using regexps that will backtrack forever.  Since
+  // a regexp with a non-ASCII character in it can never match an ASCII
+  // string we can test that the relevant node is removed by verifying that
+  // there is no hang.
+  dynamic NoHang(re) {
+    firstMatch("This is an ASCII string that could take forever", re);
+  }
+
+  NoHang(new RegExp(r"(((.*)*)*x)Ä€"));  // Continuation after loop is filtered, so is loop.
+  NoHang(new RegExp(r"(((.*)*)*Ä€)foo"));  // Body of loop filtered.
+  NoHang(new RegExp(r"Ä€(((.*)*)*x)"));   // Everything after a filtered character is filtered.
+  NoHang(new RegExp(r"(((.*)*)*x)Ä€"));   // Everything before a filtered character is filtered.
+  NoHang(new RegExp(r"[ćăĀ](((.*)*)*x)"));   // Everything after a filtered class is filtered.
+  NoHang(new RegExp(r"(((.*)*)*x)[ćăĀ]"));   // Everything before a filtered class is filtered.
+  NoHang(new RegExp(r"[^\x00-\xff](((.*)*)*x)"));   // After negated class.
+  NoHang(new RegExp(r"(((.*)*)*x)[^\x00-\xff]"));   // Before negated class.
+  NoHang(new RegExp(r"(?!(((.*)*)*x)Ä€)foo"));  // Negative lookahead is filtered.
+  NoHang(new RegExp(r"(?!(((.*)*)*x))Ä€"));  // Continuation branch of negative lookahead.
+  NoHang(new RegExp(r"(?=(((.*)*)*x)Ä€)foo"));  // Positive lookahead is filtered.
+  NoHang(new RegExp(r"(?=(((.*)*)*x))Ä€"));  // Continuation branch of positive lookahead.
+  NoHang(new RegExp(r"(?=Ä€)(((.*)*)*x)"));  // Positive lookahead also prunes continuation.
+  NoHang(new RegExp(r"(æ|ø|Ä€)(((.*)*)*x)"));  // All branches of alternation are filtered.
+  NoHang(new RegExp(r"(a|b|(((.*)*)*x))Ä€"));  // 1 out of 3 branches pruned.
+  NoHang(new RegExp(r"(a|(((.*)*)*x)ă|(((.*)*)*x)Ā)"));  // 2 out of 3 branches pruned.
+
+  var s = "Don't prune based on a repetition of length 0";
+  assertEquals(null, firstMatch(s, new RegExp(r"å{1,1}prune")));
+  assertEquals("prune", (firstMatch(s, new RegExp(r"å{0,0}prune"))[0]));
+
+  // Some very deep regexps where FilterASCII gives up in order not to make the
+  // stack overflow.
+  var regex6 = new RegExp(r"a*\u0100*\w");
+  var input0 = "a";
+  regex6.firstMatch(input0);
+
+  var re = "\u0100*\\w";
+
+  for (var i = 0; i < 200; i++) re = "a*" + re;
+
+  var regex7 = new RegExp(re);
+  regex7.firstMatch(input0);
+
+  var regex8 = new RegExp(re, caseSensitive: false);
+  regex8.firstMatch(input0);
+
+  re = "[\u0100]*\\w";
+  for (var i = 0; i < 200; i++) re = "a*" + re;
+
+  var regex9 = new RegExp(re);
+  regex9.firstMatch(input0);
+
+  var regex10 = new RegExp(re, caseSensitive: false);
+  regex10.firstMatch(input0);
+
+  var regex11 = new RegExp(r"^(?:[^\u0000-\u0080]|[0-9a-z?,.!&\s#()])+$", caseSensitive: false);
+  regex11.firstMatch(input0);
+
+  var regex12 = new RegExp(r"u(\xf0{8}?\D*?|( ? !)$h??(|)*?(||)+?\6((?:\W\B|--\d-*-|)?$){0, }?|^Y( ? !1)\d+)+a");
+  regex12.firstMatch("");
+}
diff --git a/tests/corelib/regexp/capture_test.dart b/tests/corelib/regexp/capture_test.dart
new file mode 100644
index 0000000..fa7391a
--- /dev/null
+++ b/tests/corelib/regexp/capture_test.dart
@@ -0,0 +1,53 @@
+// Copyright (c) 2014, the Dart project authors. All rights reserved.
+// Copyright 2009 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+//       copyright notice, this list of conditions and the following
+//       disclaimer in the documentation and/or other materials provided
+//       with the distribution.
+//     * Neither the name of Google Inc. nor the names of its
+//       contributors may be used to endorse or promote products derived
+//       from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+import 'v8_regexp_utils.dart';
+import 'package:expect/expect.dart';
+
+void main() {
+  // Tests from http://blog.stevenlevithan.com/archives/npcg-javascript
+
+  assertEquals(true, new RegExp(r"(x)?\1y").hasMatch("y"));
+  shouldBe(new RegExp(r"(x)?\1y").firstMatch("y"), ["y", null]);
+  shouldBe(new RegExp(r"(x)?y").firstMatch("y"), ["y", null]);
+  shouldBe(firstMatch("y", new RegExp(r"(x)?\1y")), ["y", null]);
+  shouldBe(firstMatch("y", new RegExp(r"(x)?y")), ["y", null]);
+  shouldBe(firstMatch("y", new RegExp(r"(x)?\1y")), ["y", null]);
+  Expect.listEquals(["", ""], "y".split(new RegExp(r"(x)?\1y")));
+  Expect.listEquals(["", ""], "y".split(new RegExp(r"(x)?y")));
+  assertEquals(0, "y".indexOf(new RegExp(r"(x)?\1y")));
+  assertEquals("z", "y".replaceAll(new RegExp(r"(x)?\1y"), "z"));
+
+  // See https://bugzilla.mozilla.org/show_bug.cgi?id=476146
+  shouldBe(new RegExp(r"^(b+|a){1,2}?bc").firstMatch("bbc"), ["bbc", "b"]);
+  shouldBe(new RegExp(r"((\3|b)\2(a)){2,}").firstMatch("bbaababbabaaaaabbaaaabba"),
+      ["bbaa", "a", "", "a"]);
+
+  // From crbug.com/128821 - don't hang:
+  firstMatch("", new RegExp(r"((a|i|A|I|u|o|U|O)(s|c|b|c|d|f|g|h|j|k|l|m|n|p|q|r|s|t|v|w|x|y|z|B|C|D|F|G|H|J|K|L|M|N|P|Q|R|S|T|V|W|X|Y|Z)*) de\/da([.,!?\s]|$)"));
+}
diff --git a/tests/corelib/regexp/captures_test.dart b/tests/corelib/regexp/captures_test.dart
new file mode 100644
index 0000000..be91e2b
--- /dev/null
+++ b/tests/corelib/regexp/captures_test.dart
@@ -0,0 +1,36 @@
+// Copyright (c) 2014, the Dart project authors. All rights reserved.
+// Copyright 2009 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+//       copyright notice, this list of conditions and the following
+//       disclaimer in the documentation and/or other materials provided
+//       with the distribution.
+//     * Neither the name of Google Inc. nor the names of its
+//       contributors may be used to endorse or promote products derived
+//       from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+import 'v8_regexp_utils.dart';
+import 'package:expect/expect.dart';
+
+void main() {
+  var re = new RegExp(r"^(((N({)?)|(R)|(U)|(V)|(B)|(H)|(n((n)|(r)|(v)|(h))?)|(r(r)?)|(v)|(b((n)|(b))?)|(h))|((Y)|(A)|(E)|(o(u)?)|(p(u)?)|(q(u)?)|(s)|(t)|(u)|(w)|(x(u)?)|(y)|(z)|(a((T)|(A)|(L))?)|(c)|(e)|(f(u)?)|(g(u)?)|(i)|(j)|(l)|(m(u)?)))+");
+  var str = "Avtnennan gunzvmu pubExnY nEvln vaTxh rmuhguhaTxnY";
+  assertTrue(re.hasMatch(str));
+}
diff --git a/tests/corelib/regexp/char-insensitive_test.dart b/tests/corelib/regexp/char-insensitive_test.dart
new file mode 100644
index 0000000..95a550e
--- /dev/null
+++ b/tests/corelib/regexp/char-insensitive_test.dart
@@ -0,0 +1,53 @@
+// Copyright (c) 2014, the Dart project authors. All rights reserved.
+// Copyright 2013 the V8 project authors. All rights reserved.
+// Copyright (C) 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1.  Redistributions of source code must retain the above copyright
+//     notice, this list of conditions and the following disclaimer.
+// 2.  Redistributions in binary form must reproduce the above copyright
+//     notice, this list of conditions and the following disclaimer in the
+//     documentation and/or other materials provided with the distribution.
+//
+// THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
+// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+import 'v8_regexp_utils.dart';
+import 'package:expect/expect.dart';
+
+void main() {
+  description(
+  "This test checks the case-insensitive matching of character literals."
+  );
+
+  shouldBeTrue(new RegExp(r"\u00E5", caseSensitive: false).hasMatch('new RegExp(r"\u00E5")'));
+  shouldBeTrue(new RegExp(r"\u00E5", caseSensitive: false).hasMatch('new RegExp(r"\u00C5")'));
+  shouldBeTrue(new RegExp(r"\u00C5", caseSensitive: false).hasMatch('new RegExp(r"\u00E5")'));
+  shouldBeTrue(new RegExp(r"\u00C5", caseSensitive: false).hasMatch('new RegExp(r"\u00C5")'));
+
+  shouldBeFalse(new RegExp(r"\u00E5", caseSensitive: false).hasMatch('P'));
+  shouldBeFalse(new RegExp(r"\u00E5", caseSensitive: false).hasMatch('PASS'));
+  shouldBeFalse(new RegExp(r"\u00C5", caseSensitive: false).hasMatch('P'));
+  shouldBeFalse(new RegExp(r"\u00C5", caseSensitive: false).hasMatch('PASS'));
+
+  shouldBeNull(firstMatch('PASS', new RegExp(r"\u00C5", caseSensitive: false)));
+  shouldBeNull(firstMatch('PASS', new RegExp(r"\u00C5", caseSensitive: false)));
+
+  assertEquals('PAS\u00E5'.replaceAll(new RegExp(r"\u00E5", caseSensitive: false), 'S'), 'PASS');
+  assertEquals('PAS\u00E5'.replaceAll(new RegExp(r"\u00C5", caseSensitive: false), 'S'), 'PASS');
+  assertEquals('PAS\u00C5'.replaceAll(new RegExp(r"\u00E5", caseSensitive: false), 'S'), 'PASS');
+  assertEquals('PAS\u00C5'.replaceAll(new RegExp(r"\u00C5", caseSensitive: false), 'S'), 'PASS');
+
+  assertEquals('PASS'.replaceAll(new RegExp(r"\u00E5", caseSensitive: false), '%C3%A5'), 'PASS');
+  assertEquals('PASS'.replaceAll(new RegExp(r"\u00C5", caseSensitive: false), '%C3%A5'), 'PASS');
+}
diff --git a/tests/corelib/regexp/character-match-out-of-order_test.dart b/tests/corelib/regexp/character-match-out-of-order_test.dart
new file mode 100644
index 0000000..75a2a67
--- /dev/null
+++ b/tests/corelib/regexp/character-match-out-of-order_test.dart
@@ -0,0 +1,32 @@
+// Copyright (c) 2014, the Dart project authors. All rights reserved.
+// Copyright 2013 the V8 project authors. All rights reserved.
+// Copyright (C) 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1.  Redistributions of source code must retain the above copyright
+//     notice, this list of conditions and the following disclaimer.
+// 2.  Redistributions in binary form must reproduce the above copyright
+//     notice, this list of conditions and the following disclaimer in the
+//     documentation and/or other materials provided with the distribution.
+//
+// THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
+// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+import 'v8_regexp_utils.dart';
+import 'package:expect/expect.dart';
+
+void main() {
+  description('Test to ensure RegExp generates single character matches in the correct order');
+
+  shouldBe(new RegExp(r"[\w']+").firstMatch("'_'"), ["'_'"]);
+}
diff --git a/tests/corelib/regexp/compile-crash_test.dart b/tests/corelib/regexp/compile-crash_test.dart
new file mode 100644
index 0000000..ffc7a06
--- /dev/null
+++ b/tests/corelib/regexp/compile-crash_test.dart
@@ -0,0 +1,37 @@
+// Copyright (c) 2014, the Dart project authors. All rights reserved.
+// Copyright 2013 the V8 project authors. All rights reserved.
+// Copyright (C) 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1.  Redistributions of source code must retain the above copyright
+//     notice, this list of conditions and the following disclaimer.
+// 2.  Redistributions in binary form must reproduce the above copyright
+//     notice, this list of conditions and the following disclaimer in the
+//     documentation and/or other materials provided with the distribution.
+//
+// THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
+// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+import 'v8_regexp_utils.dart';
+import 'package:expect/expect.dart';
+
+void main() {
+  description('Test regexp compiling to make sure it doens\'t crash like bug <a href="https://bugs.webkit.org/show_bug.cgi?id=16127">16127</a>');
+
+  shouldBeTrue(new RegExp(r"\)[;\s]+") != null);
+  assertThrows(() => new RegExp(r"["));
+  assertThrows(() => new RegExp(r"[a"));
+  assertThrows(() => new RegExp(r"[-"));
+  shouldBeTrue(new RegExp(r"(a)\1") != null);
+  shouldBeTrue(new RegExp(r"(a)\1{1,3}") != null);
+}
diff --git a/tests/corelib/regexp/compile_test.dart b/tests/corelib/regexp/compile_test.dart
new file mode 100644
index 0000000..18f96c9
--- /dev/null
+++ b/tests/corelib/regexp/compile_test.dart
@@ -0,0 +1,44 @@
+// Copyright (c) 2014, the Dart project authors. All rights reserved.
+// Copyright 2013 the V8 project authors. All rights reserved.
+// Copyright (C) 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1.  Redistributions of source code must retain the above copyright
+//     notice, this list of conditions and the following disclaimer.
+// 2.  Redistributions in binary form must reproduce the above copyright
+//     notice, this list of conditions and the following disclaimer in the
+//     documentation and/or other materials provided with the distribution.
+//
+// THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
+// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+import 'v8_regexp_utils.dart';
+import 'package:expect/expect.dart';
+
+void main() {
+  description(
+  'Test RegExp.compile method.'
+  );
+
+  var re = new RegExp("a", caseSensitive: false);
+  shouldBeTrue(re.hasMatch('A'));
+  shouldBeFalse(re.isMultiLine);
+  shouldBeFalse(re.isCaseSensitive);
+
+  re = new RegExp("a");
+  shouldBeFalse(re.isMultiLine);
+  shouldBeTrue(re.isCaseSensitive);
+  shouldBeFalse(re.hasMatch('A'));
+
+  assertThrows(() => new RegExp('+'));
+}
diff --git a/tests/corelib/regexp/constructor_test.dart b/tests/corelib/regexp/constructor_test.dart
new file mode 100644
index 0000000..54d8df1
--- /dev/null
+++ b/tests/corelib/regexp/constructor_test.dart
@@ -0,0 +1,40 @@
+// Copyright (c) 2014, the Dart project authors. All rights reserved.
+// Copyright 2013 the V8 project authors. All rights reserved.
+// Copyright (C) 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1.  Redistributions of source code must retain the above copyright
+//     notice, this list of conditions and the following disclaimer.
+// 2.  Redistributions in binary form must reproduce the above copyright
+//     notice, this list of conditions and the following disclaimer in the
+//     documentation and/or other materials provided with the distribution.
+//
+// THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
+// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+import 'v8_regexp_utils.dart';
+import 'package:expect/expect.dart';
+
+void main() {
+  description("This test checks use of the regexp constructor.");
+
+  var re = new RegExp(r"abc");
+
+  // We do not guarantee that the same regular expression will or will not be shared.
+  // shouldBeTrue(identical(re, new RegExp(r"abc")));
+  // shouldBeTrue(identical(re, new RegExp(r"abc", caseSensitive: true, multiLine: false)));
+
+  shouldBeFalse(identical(re, new RegExp(r"abc", caseSensitive: false, multiLine: true)));
+  shouldBeFalse(identical(re, new RegExp(r"abc", caseSensitive: true, multiLine: true)));
+  shouldBeFalse(identical(re, new RegExp(r"abc", caseSensitive: false, multiLine: false)));
+}
diff --git a/tests/corelib/regexp/dotstar_test.dart b/tests/corelib/regexp/dotstar_test.dart
new file mode 100644
index 0000000..16f63f0
--- /dev/null
+++ b/tests/corelib/regexp/dotstar_test.dart
@@ -0,0 +1,165 @@
+// Copyright (c) 2014, the Dart project authors. All rights reserved.
+// Copyright 2013 the V8 project authors. All rights reserved.
+// Copyright (C) 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1.  Redistributions of source code must retain the above copyright
+//     notice, this list of conditions and the following disclaimer.
+// 2.  Redistributions in binary form must reproduce the above copyright
+//     notice, this list of conditions and the following disclaimer in the
+//     documentation and/or other materials provided with the distribution.
+//
+// THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
+// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+import 'v8_regexp_utils.dart';
+import 'package:expect/expect.dart';
+
+void main() {
+  description("This page tests handling of parentheses subexpressions.");
+
+  var regexp1 = new RegExp(r".*blah.*");
+  shouldBeNull(regexp1.firstMatch('test'));
+  shouldBe(regexp1.firstMatch('blah'), ['blah']);
+  shouldBe(regexp1.firstMatch('1blah'), ['1blah']);
+  shouldBe(regexp1.firstMatch('blah1'), ['blah1']);
+  shouldBe(regexp1.firstMatch('blah blah blah'), ['blah blah blah']);
+  shouldBe(regexp1.firstMatch('blah\nsecond'), ['blah']);
+  shouldBe(regexp1.firstMatch('first\nblah'), ['blah']);
+  shouldBe(regexp1.firstMatch('first\nblah\nthird'), ['blah']);
+  shouldBe(regexp1.firstMatch('first\nblah2\nblah3'), ['blah2']);
+
+  var regexp2 = new RegExp(r"^.*blah.*");
+  shouldBeNull(regexp2.firstMatch('test'));
+  shouldBe(regexp2.firstMatch('blah'), ['blah']);
+  shouldBe(regexp2.firstMatch('1blah'), ['1blah']);
+  shouldBe(regexp2.firstMatch('blah1'), ['blah1']);
+  shouldBe(regexp2.firstMatch('blah blah blah'), ['blah blah blah']);
+  shouldBe(regexp2.firstMatch('blah\nsecond'), ['blah']);
+  shouldBeNull(regexp2.firstMatch('first\nblah'));
+  shouldBeNull(regexp2.firstMatch('first\nblah\nthird'));
+  shouldBeNull(regexp2.firstMatch('first\nblah2\nblah3'));
+
+  var regexp3 = new RegExp(r".*blah.*$");
+  shouldBeNull(regexp3.firstMatch('test'));
+  shouldBe(regexp3.firstMatch('blah'), ['blah']);
+  shouldBe(regexp3.firstMatch('1blah'), ['1blah']);
+  shouldBe(regexp3.firstMatch('blah1'), ['blah1']);
+  shouldBe(regexp3.firstMatch('blah blah blah'), ['blah blah blah']);
+  shouldBeNull(regexp3.firstMatch('blah\nsecond'));
+  shouldBe(regexp3.firstMatch('first\nblah'), ['blah']);
+  shouldBeNull(regexp3.firstMatch('first\nblah\nthird'));
+  shouldBe(regexp3.firstMatch('first\nblah2\nblah3'), ['blah3']);
+
+  var regexp4 = new RegExp(r"^.*blah.*$");
+  shouldBeNull(regexp4.firstMatch('test'));
+  shouldBe(regexp4.firstMatch('blah'), ['blah']);
+  shouldBe(regexp4.firstMatch('1blah'), ['1blah']);
+  shouldBe(regexp4.firstMatch('blah1'), ['blah1']);
+  shouldBe(regexp4.firstMatch('blah blah blah'), ['blah blah blah']);
+  shouldBeNull(regexp4.firstMatch('blah\nsecond'));
+  shouldBeNull(regexp4.firstMatch('first\nblah'));
+  shouldBeNull(regexp4.firstMatch('first\nblah\nthird'));
+  shouldBeNull(regexp4.firstMatch('first\nblah2\nblah3'));
+
+  var regexp5 = new RegExp(r".*?blah.*");
+  shouldBeNull(regexp5.firstMatch('test'));
+  shouldBe(regexp5.firstMatch('blah'), ['blah']);
+  shouldBe(regexp5.firstMatch('1blah'), ['1blah']);
+  shouldBe(regexp5.firstMatch('blah1'), ['blah1']);
+  shouldBe(regexp5.firstMatch('blah blah blah'), ['blah blah blah']);
+  shouldBe(regexp5.firstMatch('blah\nsecond'), ['blah']);
+  shouldBe(regexp5.firstMatch('first\nblah'), ['blah']);
+  shouldBe(regexp5.firstMatch('first\nblah\nthird'), ['blah']);
+  shouldBe(regexp5.firstMatch('first\nblah2\nblah3'), ['blah2']);
+
+  var regexp6 = new RegExp(r".*blah.*?");
+  shouldBeNull(regexp6.firstMatch('test'));
+  shouldBe(regexp6.firstMatch('blah'), ['blah']);
+  shouldBe(regexp6.firstMatch('1blah'), ['1blah']);
+  shouldBe(regexp6.firstMatch('blah1'), ['blah']);
+  shouldBe(regexp6.firstMatch('blah blah blah'), ['blah blah blah']);
+  shouldBe(regexp6.firstMatch('blah\nsecond'), ['blah']);
+  shouldBe(regexp6.firstMatch('first\nblah'), ['blah']);
+  shouldBe(regexp6.firstMatch('first\nblah\nthird'), ['blah']);
+  shouldBe(regexp6.firstMatch('first\nblah2\nblah3'), ['blah']);
+
+  var regexp7 = new RegExp(r"^.*?blah.*?$");
+  shouldBeNull(regexp7.firstMatch('test'));
+  shouldBe(regexp7.firstMatch('blah'), ['blah']);
+  shouldBe(regexp7.firstMatch('1blah'), ['1blah']);
+  shouldBe(regexp7.firstMatch('blah1'), ['blah1']);
+  shouldBe(regexp7.firstMatch('blah blah blah'), ['blah blah blah']);
+  shouldBeNull(regexp7.firstMatch('blah\nsecond'));
+  shouldBeNull(regexp7.firstMatch('first\nblah'));
+  shouldBeNull(regexp7.firstMatch('first\nblah\nthird'));
+  shouldBeNull(regexp7.firstMatch('first\nblah2\nblah3'));
+
+  var regexp8 = new RegExp(r"^(.*)blah.*$");
+  shouldBeNull(regexp8.firstMatch('test'));
+  shouldBe(regexp8.firstMatch('blah'), ['blah','']);
+  shouldBe(regexp8.firstMatch('1blah'), ['1blah','1']);
+  shouldBe(regexp8.firstMatch('blah1'), ['blah1','']);
+  shouldBe(regexp8.firstMatch('blah blah blah'), ['blah blah blah','blah blah ']);
+  shouldBeNull(regexp8.firstMatch('blah\nsecond'));
+  shouldBeNull(regexp8.firstMatch('first\nblah'));
+  shouldBeNull(regexp8.firstMatch('first\nblah\nthird'));
+  shouldBeNull(regexp8.firstMatch('first\nblah2\nblah3'));
+
+  var regexp9 = new RegExp(r".*blah.*", multiLine: true);
+  shouldBeNull(regexp9.firstMatch('test'));
+  shouldBe(regexp9.firstMatch('blah'), ['blah']);
+  shouldBe(regexp9.firstMatch('1blah'), ['1blah']);
+  shouldBe(regexp9.firstMatch('blah1'), ['blah1']);
+  shouldBe(regexp9.firstMatch('blah blah blah'), ['blah blah blah']);
+  shouldBe(regexp9.firstMatch('blah\nsecond'), ['blah']);
+  shouldBe(regexp9.firstMatch('first\nblah'), ['blah']);
+  shouldBe(regexp9.firstMatch('first\nblah\nthird'), ['blah']);
+  shouldBe(regexp9.firstMatch('first\nblah2\nblah3'), ['blah2']);
+
+  var regexp10 = new RegExp(r"^.*blah.*", multiLine: true);
+  shouldBeNull(regexp10.firstMatch('test'));
+  shouldBe(regexp10.firstMatch('blah'), ['blah']);
+  shouldBe(regexp10.firstMatch('1blah'), ['1blah']);
+  shouldBe(regexp10.firstMatch('blah1'), ['blah1']);
+  shouldBe(regexp10.firstMatch('blah blah blah'), ['blah blah blah']);
+  shouldBe(regexp10.firstMatch('blah\nsecond'), ['blah']);
+  shouldBe(regexp10.firstMatch('first\nblah'), ['blah']);
+  shouldBe(regexp10.firstMatch('first\nblah\nthird'), ['blah']);
+  shouldBe(regexp10.firstMatch('first\nblah2\nblah3'), ['blah2']);
+
+  var regexp11 = new RegExp(r".*(?:blah).*$");
+  shouldBeNull(regexp11.firstMatch('test'));
+  shouldBe(regexp11.firstMatch('blah'), ['blah']);
+  shouldBe(regexp11.firstMatch('1blah'), ['1blah']);
+  shouldBe(regexp11.firstMatch('blah1'), ['blah1']);
+  shouldBe(regexp11.firstMatch('blah blah blah'), ['blah blah blah']);
+  shouldBeNull(regexp11.firstMatch('blah\nsecond'));
+  shouldBe(regexp11.firstMatch('first\nblah'), ['blah']);
+  shouldBeNull(regexp11.firstMatch('first\nblah\nthird'));
+  shouldBe(regexp11.firstMatch('first\nblah2\nblah3'), ['blah3']);
+
+  var regexp12 = new RegExp(r".*(?:blah|buzz|bang).*$");
+  shouldBeNull(regexp12.firstMatch('test'));
+  shouldBe(regexp12.firstMatch('blah'), ['blah']);
+  shouldBe(regexp12.firstMatch('1blah'), ['1blah']);
+  shouldBe(regexp12.firstMatch('blah1'), ['blah1']);
+  shouldBe(regexp12.firstMatch('blah blah blah'), ['blah blah blah']);
+  shouldBeNull(regexp12.firstMatch('blah\nsecond'));
+  shouldBe(regexp12.firstMatch('first\nblah'), ['blah']);
+  shouldBeNull(regexp12.firstMatch('first\nblah\nthird'));
+  shouldBe(regexp12.firstMatch('first\nblah2\nblah3'), ['blah3']);
+
+  var regexp13 = new RegExp(r".*\n\d+.*");
+  shouldBe(regexp13.firstMatch('abc\n123'), ['abc\n123']);
+}
diff --git a/tests/corelib/regexp/early-acid3-86_test.dart b/tests/corelib/regexp/early-acid3-86_test.dart
new file mode 100644
index 0000000..11b3b3c
--- /dev/null
+++ b/tests/corelib/regexp/early-acid3-86_test.dart
@@ -0,0 +1,39 @@
+// Copyright (c) 2014, the Dart project authors. All rights reserved.
+// Copyright 2013 the V8 project authors. All rights reserved.
+// Copyright (C) 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1.  Redistributions of source code must retain the above copyright
+//     notice, this list of conditions and the following disclaimer.
+// 2.  Redistributions in binary form must reproduce the above copyright
+//     notice, this list of conditions and the following disclaimer in the
+//     documentation and/or other materials provided with the distribution.
+//
+// THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
+// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+import 'v8_regexp_utils.dart';
+import 'package:expect/expect.dart';
+
+void main() {
+  description(
+  'Test that covers capturing brackets, and was adapted from a part of an early version of Acid3.'
+  );
+
+  // JS regexps aren't like Perl regexps, if their character
+  // classes start with a ] that means they're empty. So this
+  // is a syntax error; if we get here it's a bug.
+  assertThrows(() => new RegExp(r"TA[])]").firstMatch('TA]'));
+  shouldBeNull(new RegExp(r"[]").firstMatch(''));
+  shouldBe(new RegExp(r"(\3)(\1)(a)").firstMatch('cat'), ['a', '', '', 'a']);
+}
diff --git a/tests/corelib/regexp/ecma-regex-examples_test.dart b/tests/corelib/regexp/ecma-regex-examples_test.dart
new file mode 100644
index 0000000..c6cff0f
--- /dev/null
+++ b/tests/corelib/regexp/ecma-regex-examples_test.dart
@@ -0,0 +1,68 @@
+// Copyright (c) 2014, the Dart project authors. All rights reserved.
+// Copyright 2013 the V8 project authors. All rights reserved.
+// Copyright (C) 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1.  Redistributions of source code must retain the above copyright
+//     notice, this list of conditions and the following disclaimer.
+// 2.  Redistributions in binary form must reproduce the above copyright
+//     notice, this list of conditions and the following disclaimer in the
+//     documentation and/or other materials provided with the distribution.
+//
+// THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
+// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+import 'v8_regexp_utils.dart';
+import 'package:expect/expect.dart';
+
+void main() {
+  description(
+  "This page tests the regex examples from the ECMA-262 specification."
+  );
+
+  var regex01 = new RegExp(r"a|ab");
+  shouldBe(regex01.firstMatch("abc"), ["a"]);
+
+  var regex02 = new RegExp(r"((a)|(ab))((c)|(bc))");
+  shouldBe(regex02.firstMatch("abc"), ["abc", "a", "a", null, "bc", null, "bc"]);
+
+  var regex03 = new RegExp(r"a[a-z]{2,4}");
+  shouldBe(regex03.firstMatch("abcdefghi"), ["abcde"]);
+
+  var regex04 = new RegExp(r"a[a-z]{2,4}?");
+  shouldBe(regex04.firstMatch("abcdefghi"), ["abc"]);
+
+  var regex05 = new RegExp(r"(aa|aabaac|ba|b|c)*");
+  shouldBe(regex05.firstMatch("aabaac"), ["aaba", "ba"]);
+
+  var regex06 = new RegExp(r"^(a+)\1*,\1+$");
+  Expect.equals("aaaaaaaaaa,aaaaaaaaaaaaaaa".replaceAllMapped(regex06,(m) => m.group(1)), "aaaaa");
+
+  var regex07 = new RegExp(r"(z)((a+)?(b+)?(c))*");
+  shouldBe(regex07.firstMatch("zaacbbbcac"), ["zaacbbbcac", "z", "ac", "a", null, "c"]);
+
+  var regex08 = new RegExp(r"(a*)*");
+  shouldBe(regex08.firstMatch("b"), ["", null]);
+
+  var regex09 = new RegExp(r"(a*)b\1+");
+  shouldBe(regex09.firstMatch("baaaac"), ["b", ""]);
+
+  var regex10 = new RegExp(r"(?=(a+))");
+  shouldBe(regex10.firstMatch("baaabac"), ["", "aaa"]);
+
+  var regex11 = new RegExp(r"(?=(a+))a*b\1");
+  shouldBe(regex11.firstMatch("baaabac"), ["aba", "a"]);
+
+  var regex12 = new RegExp(r"(.*?)a(?!(a+)b\2c)\2(.*)");
+  shouldBe(regex12.firstMatch("baaabaac"), ["baaabaac", "ba", null, "abaac"]);
+}
diff --git a/tests/corelib/regexp/extended-characters-match_test.dart b/tests/corelib/regexp/extended-characters-match_test.dart
new file mode 100644
index 0000000..3135811
--- /dev/null
+++ b/tests/corelib/regexp/extended-characters-match_test.dart
@@ -0,0 +1,44 @@
+// Copyright (c) 2014, the Dart project authors. All rights reserved.
+// Copyright 2013 the V8 project authors. All rights reserved.
+// Copyright (C) 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1.  Redistributions of source code must retain the above copyright
+//     notice, this list of conditions and the following disclaimer.
+// 2.  Redistributions in binary form must reproduce the above copyright
+//     notice, this list of conditions and the following disclaimer in the
+//     documentation and/or other materials provided with the distribution.
+//
+// THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
+// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+import 'v8_regexp_utils.dart';
+import 'package:expect/expect.dart';
+
+void main() {
+  description(
+  "This test checks regular expressions using extended (> 255) characters and character classes."
+  );
+
+  shouldBeNull((new RegExp("[\u0100-\u0101]")).firstMatch("a"));
+  shouldBeNull((new RegExp("[\u0100]")).firstMatch("a"));
+  shouldBeNull((new RegExp("\u0100")).firstMatch("a"));
+  assertEquals((new RegExp("[\u0061]")).firstMatch("a").group(0), "a");
+  assertEquals((new RegExp("[\u0100-\u0101a]")).firstMatch("a").group(0), "a");
+  assertEquals((new RegExp("[\u0100a]")).firstMatch("a").group(0), "a");
+  assertEquals((new RegExp("\u0061")).firstMatch("a").group(0), "a");
+  assertEquals((new RegExp("[a-\u0100]")).firstMatch("a").group(0), "a");
+  assertEquals((new RegExp("[\u0100]")).firstMatch("\u0100").group(0), "\u0100");
+  assertEquals((new RegExp("[\u0100-\u0101]")).firstMatch("\u0100").group(0), "\u0100");
+  assertEquals((new RegExp("\u0100")).firstMatch("\u0100").group(0), "\u0100");
+}
diff --git a/tests/corelib/regexp/extended-characters-more_test.dart b/tests/corelib/regexp/extended-characters-more_test.dart
new file mode 100644
index 0000000..e726d57
--- /dev/null
+++ b/tests/corelib/regexp/extended-characters-more_test.dart
@@ -0,0 +1,36 @@
+// Copyright (c) 2014, the Dart project authors. All rights reserved.
+// Copyright 2013 the V8 project authors. All rights reserved.
+// Copyright (C) 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1.  Redistributions of source code must retain the above copyright
+//     notice, this list of conditions and the following disclaimer.
+// 2.  Redistributions in binary form must reproduce the above copyright
+//     notice, this list of conditions and the following disclaimer in the
+//     documentation and/or other materials provided with the distribution.
+//
+// THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
+// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+import 'v8_regexp_utils.dart';
+import 'package:expect/expect.dart';
+
+void main() {
+  description(
+  "This test checks a few cases of extended (> 127) characters in repeat regular expressions."
+  );
+
+  assertEquals("foo\u00a0\u00a0\u00a0".replaceFirst(new RegExp(new String.fromCharCode(0x00a0) + "*"), ""), "foo\u00a0\u00a0\u00a0");
+  assertEquals("foo\u00a0\u00a0\u00a0".replaceFirst(new RegExp(r"\u00a0+"), ""), "foo");
+  assertEquals("foo\u00a0\u00a0\u00a0".replaceFirst(new RegExp(r"\u00a0*$"), ""), "foo");
+}
diff --git a/tests/corelib/regexp/find-first-asserted_test.dart b/tests/corelib/regexp/find-first-asserted_test.dart
new file mode 100644
index 0000000..9dbc9f8
--- /dev/null
+++ b/tests/corelib/regexp/find-first-asserted_test.dart
@@ -0,0 +1,35 @@
+// Copyright (c) 2014, the Dart project authors. All rights reserved.
+// Copyright 2013 the V8 project authors. All rights reserved.
+// Copyright (C) 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1.  Redistributions of source code must retain the above copyright
+//     notice, this list of conditions and the following disclaimer.
+// 2.  Redistributions in binary form must reproduce the above copyright
+//     notice, this list of conditions and the following disclaimer in the
+//     documentation and/or other materials provided with the distribution.
+//
+// THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
+// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+import 'v8_regexp_utils.dart';
+import 'package:expect/expect.dart';
+
+void main() {
+  description(
+  'Tests some regular expressions that were doing the wrong thing with the "find first asserted" optimization.'
+  );
+
+  shouldBe(new RegExp(r".*<body>(.*)</body>.*").firstMatch("foo<body>bar</body>baz"), ["foo<body>bar</body>baz", "bar"]);
+  shouldBe(new RegExp(r"\s*<!--([\s\S]*)//\s*-->\s*").firstMatch("<!--// -->"), ["<!--// -->", ""]);
+}
diff --git a/tests/corelib/regexp/global_test.dart b/tests/corelib/regexp/global_test.dart
new file mode 100644
index 0000000..2ad468f
--- /dev/null
+++ b/tests/corelib/regexp/global_test.dart
@@ -0,0 +1,189 @@
+// Copyright (c) 2014, the Dart project authors. All rights reserved.
+// Copyright 2012 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+//       copyright notice, this list of conditions and the following
+//       disclaimer in the documentation and/or other materials provided
+//       with the distribution.
+//     * Neither the name of Google Inc. nor the names of its
+//       contributors may be used to endorse or promote products derived
+//       from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+import 'v8_regexp_utils.dart';
+import 'package:expect/expect.dart';
+
+void main() {
+  var str = "ABX X";
+  str = str.replaceAll(new RegExp(r"(\w)?X"), "c");
+  assertEquals("Ac c", str);
+
+  // Test zero-length matches.
+  str = "Als Gregor Samsa eines Morgens";
+  str = str.replaceAll(new RegExp(r"\b"), "/");
+  assertEquals("/Als/ /Gregor/ /Samsa/ /eines/ /Morgens/", str);
+
+  // Test zero-length matches that have non-zero-length sub-captures.
+  str = "It was a pleasure to burn.";
+  str = str.replaceAllMapped(new RegExp(r"(?=(\w+))\b"), (Match m) => m.group(1).length.toString());
+  assertEquals("2It 3was 1a 8pleasure 2to 4burn.", str);
+
+  // Test multiple captures.
+  str = "Try not. Do, or do not. There is no try.";
+  str = str.replaceAllMapped(new RegExp(r"(not?)|(do)|(try)", caseSensitive: false),
+                    (m) { 
+                      if (m.group(1) != null) return "-";
+                      if (m.group(2) != null) return "+";
+                      if (m.group(3) != null) return "=";
+                    });
+  assertEquals("= -. +, or + -. There is - =.", str);
+
+  // Test multiple alternate captures.
+  str = "FOUR LEGS GOOD, TWO LEGS BAD!";
+  str = str.replaceAllMapped(new RegExp(r"(FOUR|TWO) LEGS (GOOD|BAD)"),
+                    (m) {
+                      if (m.group(1) == "FOUR") assertTrue(m.group(2) == "GOOD");
+                      if (m.group(1) == "TWO") assertTrue(m.group(2) == "BAD");
+                      return m.group(0).length - 10;
+                    });
+  assertEquals("4, 2!", str);
+
+
+  // The same tests with UC16.
+
+  //Test that an optional capture is cleared between two matches.
+  str = "AB\u1234 \u1234";
+  str = str.replaceAll(new RegExp(r"(\w)?\u1234"), "c");
+  assertEquals("Ac c", str);
+
+  // Test zero-length matches.
+  str = "Als \u2623\u2642 eines Morgens";
+  str = str.replaceAll(new RegExp(r"\b"), "/");
+
+  // Test zero-length matches that have non-zero-length sub-captures.
+  str = "It was a pleasure to \u70e7.";
+  str = str.replaceAllMapped(new RegExp(r"(?=(\w+))\b"), (m) => "${m.group(1).length}");
+  assertEquals("2It 3was 1a 8pleasure 2to \u70e7.", str);
+
+  // Test multiple captures.
+  str = "Try not. D\u26aa, or d\u26aa not. There is no try.";
+  str = str.replaceAllMapped(new RegExp(r"(not?)|(d\u26aa)|(try)", caseSensitive: false),
+                    (m) { 
+                      if (m.group(1) != null) return "-";
+                      if (m.group(2) != null) return "+";
+                      if (m.group(3) != null) return "=";
+                    });
+  assertEquals("= -. +, or + -. There is - =.", str);
+
+  // Test multiple alternate captures.
+  str = "FOUR \u817f GOOD, TWO \u817f BAD!";
+  str = str.replaceAllMapped(new RegExp(r"(FOUR|TWO) \u817f (GOOD|BAD)"),
+                    (m) {
+                      if (m.group(1) == "FOUR") assertTrue(m.group(2) == "GOOD");
+                      if (m.group(1) == "TWO") assertTrue(m.group(2) == "BAD");
+                      return m.group(0).length - 7;
+                    });
+  assertEquals("4, 2!", str);
+
+  // Test capture that is a real substring.
+  str = "Beasts of England, beasts of Ireland";
+  str = str.replaceAll(new RegExp(r"(.*)"), '~');
+  assertEquals("~~", str);
+
+  // Test zero-length matches that have non-zero-length sub-captures that do not
+  // start at the match start position.
+  str = "up up up up";
+  str = str.replaceAllMapped(new RegExp(r"\b(?=u(p))"), (m) => "${m.group(1).length}");
+
+  assertEquals("1up 1up 1up 1up", str);
+
+
+  // Create regexp that has a *lot* of captures.
+  var re_string = "(a)";
+  for (var i = 0; i < 500; i++) {
+    re_string = "(" + re_string + ")";
+  }
+  re_string = re_string + "1";
+  // re_string = "(((...((a))...)))1"
+
+  var regexps = new List();
+  var last_match_expectations = new List();
+  var first_capture_expectations = new List();
+
+  // Atomic regexp.
+  regexps.add(new RegExp(r"a1"));
+  last_match_expectations.add("a1");
+  first_capture_expectations.add("");
+  // Small regexp (no capture);
+  regexps.add(new RegExp(r"\w1"));
+  last_match_expectations.add("a1");
+  first_capture_expectations.add("");
+  // Small regexp (one capture).
+  regexps.add(new RegExp(r"(a)1"));
+  last_match_expectations.add("a1");
+  first_capture_expectations.add("a");
+  // Large regexp (a lot of captures).
+  regexps.add(new RegExp(re_string));
+  last_match_expectations.add("a1");
+  first_capture_expectations.add("a");
+
+  dynamic test_replace(result_expectation,
+                        subject,
+                        regexp,
+                        replacement) {
+    for (var i = 0; i < regexps.length; i++) {
+      // Conduct tests.
+      assertEquals(result_expectation, subject.replaceAll(regexps[i], replacement));
+    }
+  }
+
+
+  // Test for different number of matches.
+  for (var m = 0; m < 33; m++) {
+    // Create string that matches m times.
+    var subject = "";
+    var test_1_expectation = "";
+    var test_2_expectation = "";
+    var test_3_expectation = (m == 0) ? null : new List();
+    for (var i = 0; i < m; i++) {
+      subject += "a11";
+      test_1_expectation += "x1";
+      test_2_expectation += "1";
+      test_3_expectation.add("a1");
+    }
+
+    // Test 1a: String.replace with string.
+    test_replace(test_1_expectation, subject, new RegExp(r"a1"), "x");
+
+    // Test 2a: String.replace with empty string.
+    test_replace(test_2_expectation, subject, new RegExp(r"a1"), "");
+  }
+
+
+  // Test String hashing (compiling regular expression includes hashing).
+  var crosscheck = "\x80";
+  for (var i = 0; i < 12; i++) crosscheck += crosscheck;
+    new RegExp(crosscheck);
+
+  var subject = "ascii~only~string~here~";
+  var replacement = "\x80";
+  var result = subject.replaceAll(new RegExp(r"~"), replacement);
+  for (var i = 0; i < 5; i++) result += result;
+    new RegExp(result);
+}
diff --git a/tests/corelib/regexp/indexof_test.dart b/tests/corelib/regexp/indexof_test.dart
new file mode 100644
index 0000000..1082987
--- /dev/null
+++ b/tests/corelib/regexp/indexof_test.dart
@@ -0,0 +1,70 @@
+// Copyright (c) 2014, the Dart project authors. All rights reserved.
+// Copyright 2008 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+//       copyright notice, this list of conditions and the following
+//       disclaimer in the documentation and/or other materials provided
+//       with the distribution.
+//     * Neither the name of Google Inc. nor the names of its
+//       contributors may be used to endorse or promote products derived
+//       from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+import 'v8_regexp_utils.dart';
+import 'package:expect/expect.dart';
+
+void main() {
+  dynamic CheckMatch(re, str, matches) {
+    assertEquals(matches.length > 0, re.hasMatch(str));
+    var result = re.allMatches(str).toList();
+    if (matches.length > 0) {
+      assertEquals(matches.length, result.length);
+      var lastExpected;
+      var lastFrom;
+      var lastLength;
+      for (var idx = 0; idx < matches.length; idx++) {
+        var from = matches[idx][0];
+        var length = matches[idx][1];
+        var expected = str.substring(from, from + length);
+        var name = "$str[$from..${from+length}]";
+        assertEquals(expected, result[idx].group(0), name);
+      }
+    } else {
+      assertTrue(result.isEmpty);
+    }
+  }
+
+  CheckMatch(new RegExp(r"abc"), "xxxabcxxxabcxxx", [[3, 3], [9, 3]]);
+  CheckMatch(new RegExp(r"abc"), "abcabcabc", [[0, 3], [3, 3], [6, 3]]);
+  CheckMatch(new RegExp(r"aba"), "ababababa", [[0, 3], [4, 3]]);
+  CheckMatch(new RegExp(r"foo"), "ofooofoooofofooofo", [[1, 3], [5, 3], [12, 3]]);
+  CheckMatch(new RegExp(r"foobarbaz"), "xx", []);
+  CheckMatch(new RegExp(r"abc"), "abababa", []);
+
+  assertEquals("xxxdefxxxdefxxx", "xxxabcxxxabcxxx".replaceAll(new RegExp(r"abc"), "def"));
+  assertEquals("o-o-oofo-ofo", "ofooofoooofofooofo".replaceAll(new RegExp(r"foo"), "-"));
+  assertEquals("deded", "deded".replaceAll(new RegExp(r"x"), "-"));
+  assertEquals("-a-b-c-d-e-f-", "abcdef".replaceAll(new RegExp(""), "-"));
+
+  CheckMatch(new RegExp(r"a(.)"), "xyzzyabxyzzyacxyzzy", [[5, 2], [12, 2]]);
+
+  CheckMatch(new RegExp(r"a|(?:)"), "aba", [[0, 1], [1, 0], [2, 1], [3, 0]]);
+  CheckMatch(new RegExp(r"a|(?:)"), "baba", [[0, 0], [1, 1], [2, 0], [3, 1], [4, 0]]);
+  CheckMatch(new RegExp(r"a|(?:)"), "bab", [[0, 0], [1, 1], [2, 0], [3, 0]]);
+}
diff --git a/tests/corelib/regexp/invalid-range-in-class_test.dart b/tests/corelib/regexp/invalid-range-in-class_test.dart
new file mode 100644
index 0000000..d4a6aa5
--- /dev/null
+++ b/tests/corelib/regexp/invalid-range-in-class_test.dart
@@ -0,0 +1,56 @@
+// Copyright (c) 2014, the Dart project authors. All rights reserved.
+// Copyright 2013 the V8 project authors. All rights reserved.
+// Copyright (C) 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1.  Redistributions of source code must retain the above copyright
+//     notice, this list of conditions and the following disclaimer.
+// 2.  Redistributions in binary form must reproduce the above copyright
+//     notice, this list of conditions and the following disclaimer in the
+//     documentation and/or other materials provided with the distribution.
+//
+// THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
+// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+import 'v8_regexp_utils.dart';
+import 'package:expect/expect.dart';
+
+void main() {
+  description(
+  "This page tests invalid character ranges in character classes."
+  );
+
+  // These test a basic range / non range.
+  shouldBe(new RegExp(r"[a-c]+").firstMatch("-acbd"), ["acb"]);
+  shouldBe(new RegExp(r"[a\-c]+").firstMatch("-acbd"), ["-ac"]);
+
+  // A reverse-range is invalid.
+  assertThrows(() => new RegExp(r"[c-a]+").firstMatch("-acbd"));
+
+  // A character-class in a range is invalid, according to ECMA-262, but we allow it.
+  shouldBe(new RegExp(r"[\d-x]+").firstMatch("1-3xy"), ["1-3x"]);
+  shouldBe(new RegExp(r"[x-\d]+").firstMatch("1-3xy"), ["1-3x"]);
+  shouldBe(new RegExp(r"[\\d-\d]+").firstMatch("1-3xy"), ["1-3"]);
+
+  // Whilst we break with ECMA-262's definition of CharacterRange, we do comply with
+  // the grammar, and as such in the following regex a-z cannot be matched as a range.
+  shouldBe(new RegExp(r"[\d-a-z]+").firstMatch("az1-3y"), ["az1-3"]);
+
+  // An escaped hypen should not be confused for an invalid range.
+  shouldBe(new RegExp(r"[\d\-x]+").firstMatch("1-3xy"), ["1-3x"]);
+  shouldBe(new RegExp(r"[x\-\d]+").firstMatch("1-3xy"), ["1-3x"]);
+  shouldBe(new RegExp(r"[\d\-\d]+").firstMatch("1-3xy"), ["1-3"]);
+
+  // A hyphen after a character-class is not invalid.
+  shouldBe(new RegExp(r"[\d-]+").firstMatch("1-3xy"), ["1-3"]);
+}
diff --git a/tests/corelib/regexp/lastindex_test.dart b/tests/corelib/regexp/lastindex_test.dart
new file mode 100644
index 0000000..87f9a18
--- /dev/null
+++ b/tests/corelib/regexp/lastindex_test.dart
@@ -0,0 +1,44 @@
+// Copyright (c) 2014, the Dart project authors. All rights reserved.
+// Copyright 2013 the V8 project authors. All rights reserved.
+// Copyright (C) 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1.  Redistributions of source code must retain the above copyright
+//     notice, this list of conditions and the following disclaimer.
+// 2.  Redistributions in binary form must reproduce the above copyright
+//     notice, this list of conditions and the following disclaimer in the
+//     documentation and/or other materials provided with the distribution.
+//
+// THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
+// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+import 'v8_regexp_utils.dart';
+import 'package:expect/expect.dart';
+
+void main() {
+  // 'Test for regression against "https://bugs.webkit.org/show_bug.cgi?id=5602"
+  // REGRESSION: RegExp("[^\\s$]+", "g") returns extra matches'
+
+  var re = new RegExp(r"[^\s$]+");
+  var accumulate = "";
+  var match;
+  for (var match in re.allMatches("  abcdefg"))
+    accumulate += match.group(0) + "; "; 
+  assertEquals(accumulate, "abcdefg; ");
+
+  re = new RegExp(r"\d");
+  accumulate = "";
+  for (var match in re.allMatches("123456789"))
+    accumulate += match.group(0) + "; "; 
+  assertEquals(accumulate, "1; 2; 3; 4; 5; 6; 7; 8; 9; ");
+}
diff --git a/tests/corelib/regexp/look-ahead_test.dart b/tests/corelib/regexp/look-ahead_test.dart
new file mode 100644
index 0000000..ffb67e4
--- /dev/null
+++ b/tests/corelib/regexp/look-ahead_test.dart
@@ -0,0 +1,35 @@
+// Copyright (c) 2014, the Dart project authors. All rights reserved.
+// Copyright 2013 the V8 project authors. All rights reserved.
+// Copyright (C) 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1.  Redistributions of source code must retain the above copyright
+//     notice, this list of conditions and the following disclaimer.
+// 2.  Redistributions in binary form must reproduce the above copyright
+//     notice, this list of conditions and the following disclaimer in the
+//     documentation and/or other materials provided with the distribution.
+//
+// THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
+// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+import 'v8_regexp_utils.dart';
+import 'package:expect/expect.dart';
+
+void main() {
+  description(
+  'Test for regression against <a href="https://bugs.webkit.org/show_bug.cgi?id=41458">Yarr Interpreter is crashing in some cases of look-ahead regex patterns</a>'
+  );
+
+  shouldBe(firstMatch("ab", new RegExp(r"a(?=b|c)")), ["a"]);
+  shouldBe(firstMatch("abd", new RegExp(r"a(?=c|b)|d")), ["a"]);
+}
diff --git a/tests/corelib/regexp/lookahead_test.dart b/tests/corelib/regexp/lookahead_test.dart
new file mode 100644
index 0000000..fce48cd
--- /dev/null
+++ b/tests/corelib/regexp/lookahead_test.dart
@@ -0,0 +1,165 @@
+// Copyright (c) 2014, the Dart project authors. All rights reserved.
+// Copyright 2009 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+//       copyright notice, this list of conditions and the following
+//       disclaimer in the documentation and/or other materials provided
+//       with the distribution.
+//     * Neither the name of Google Inc. nor the names of its
+//       contributors may be used to endorse or promote products derived
+//       from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+import 'v8_regexp_utils.dart';
+import 'package:expect/expect.dart';
+
+void main() {
+  // Tests captures in positive and negative look-ahead in regular expressions.
+
+  dynamic testRE(re, input, expected_result) {
+    if (expected_result) {
+      assertTrue(re.hasMatch(input));
+    } else {
+      assertFalse(re.hasMatch(input));
+    }
+  }
+
+  dynamic execRE(re, input, expected_result) {
+    shouldBe(re.firstMatch(input), expected_result);
+  }
+
+  // Test of simple positive lookahead.
+
+  var re = new RegExp(r"^(?=a)");
+  testRE(re, "a", true);
+  testRE(re, "b", false);
+  execRE(re, "a", [""]);
+
+  re = new RegExp(r"^(?=\woo)f\w");
+  testRE(re, "foo", true);
+  testRE(re, "boo", false);
+  testRE(re, "fao", false);
+  testRE(re, "foa", false);
+  execRE(re, "foo", ["fo"]);
+
+  re = new RegExp(r"(?=\w).(?=\W)");
+  testRE(re, ".a! ", true);
+  testRE(re, ".! ", false);
+  testRE(re, ".ab! ", true);
+  execRE(re, ".ab! ", ["b"]);
+
+  re = new RegExp(r"(?=f(?=[^f]o))..");
+  testRE(re, ", foo!", true);
+  testRE(re, ", fo!", false);
+  testRE(re, ", ffo", false);
+  execRE(re, ", foo!", ["fo"]);
+
+  // Positive lookahead with captures.
+  re = new RegExp("^[^\'\"]*(?=([\'\"])).*\\1(\\w+)\\1");
+  testRE(re, "  'foo' ", true);
+  testRE(re, '  "foo" ', true);
+  testRE(re, " \" 'foo' ", false);
+  testRE(re, " ' \"foo\" ", false);
+  testRE(re, "  'foo\" ", false);
+  testRE(re, "  \"foo' ", false);
+  execRE(re, "  'foo' ", ["  'foo'", "'", "foo"]);
+  execRE(re, '  "foo" ', ['  "foo"', '"', 'foo']);
+
+  // Captures are cleared on backtrack past the look-ahead.
+  re = new RegExp(r"^(?:(?=(.))a|b)\1$");
+  testRE(re, "aa", true);
+  testRE(re, "b", true);
+  testRE(re, "bb", false);
+  testRE(re, "a", false);
+  execRE(re, "aa", ["aa", "a"]);
+  execRE(re, "b", ["b", null]);
+
+  re = new RegExp(r"^(?=(.)(?=(.)\1\2)\2\1)\1\2");
+  testRE(re, "abab", true);
+  testRE(re, "ababxxxxxxxx", true);
+  testRE(re, "aba", false);
+  execRE(re, "abab", ["ab", "a", "b"]);
+
+  re = new RegExp(r"^(?:(?=(.))a|b|c)$");
+  testRE(re, "a", true);
+  testRE(re, "b", true);
+  testRE(re, "c", true);
+  testRE(re, "d", false);
+  execRE(re, "a", ["a", "a"]);
+  execRE(re, "b", ["b", null]);
+  execRE(re, "c", ["c", null]);
+
+  execRE(new RegExp(r"^(?=(b))b"), "b", ["b", "b"]);
+  execRE(new RegExp(r"^(?:(?=(b))|a)b"), "ab", ["ab", null]);
+  execRE(new RegExp(r"^(?:(?=(b)(?:(?=(c))|d))|)bd"), "bd", ["bd", "b", null]);
+
+
+
+  // Test of Negative Look-Ahead.
+
+  re = new RegExp(r"(?!x).");
+  testRE(re, "y", true);
+  testRE(re, "x", false);
+  execRE(re, "y", ["y"]);
+
+  re = new RegExp(r"(?!(\d))|\d");
+  testRE(re, "4", true);
+  execRE(re, "4", ["4", null]);
+  execRE(re, "x", ["", null]);
+
+
+  // Test mixed nested look-ahead with captures.
+
+  re = new RegExp(r"^(?=(x)(?=(y)))");
+  testRE(re, "xy", true);
+  testRE(re, "xz", false);
+  execRE(re, "xy", ["", "x", "y"]);
+
+  re = new RegExp(r"^(?!(x)(?!(y)))");
+  testRE(re, "xy", true);
+  testRE(re, "xz", false);
+  execRE(re, "xy", ["", null, null]);
+
+  re = new RegExp(r"^(?=(x)(?!(y)))");
+  testRE(re, "xz", true);
+  testRE(re, "xy", false);
+  execRE(re, "xz", ["", "x", null]);
+
+  re = new RegExp(r"^(?!(x)(?=(y)))");
+  testRE(re, "xz", true);
+  testRE(re, "xy", false);
+  execRE(re, "xz", ["", null, null]);
+
+  re = new RegExp(r"^(?=(x)(?!(y)(?=(z))))");
+  testRE(re, "xaz", true);
+  testRE(re, "xya", true);
+  testRE(re, "xyz", false);
+  testRE(re, "a", false);
+  execRE(re, "xaz", ["", "x", null, null]);
+  execRE(re, "xya", ["", "x", null, null]);
+
+  re = new RegExp(r"^(?!(x)(?=(y)(?!(z))))");
+  testRE(re, "a", true);
+  testRE(re, "xa", true);
+  testRE(re, "xyz", true);
+  testRE(re, "xya", false);
+  execRE(re, "a", ["", null, null, null]);
+  execRE(re, "xa", ["", null, null, null]);
+  execRE(re, "xyz", ["", null, null, null]);
+}
diff --git a/tests/corelib/regexp/loop-capture_test.dart b/tests/corelib/regexp/loop-capture_test.dart
new file mode 100644
index 0000000..fb8174f
--- /dev/null
+++ b/tests/corelib/regexp/loop-capture_test.dart
@@ -0,0 +1,35 @@
+// Copyright (c) 2014, the Dart project authors. All rights reserved.
+// Copyright 2009 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+//       copyright notice, this list of conditions and the following
+//       disclaimer in the documentation and/or other materials provided
+//       with the distribution.
+//     * Neither the name of Google Inc. nor the names of its
+//       contributors may be used to endorse or promote products derived
+//       from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+import 'v8_regexp_utils.dart';
+import 'package:expect/expect.dart';
+
+void main() {
+  shouldBe(new RegExp(r"(?:(a)|(b)|(c))+").firstMatch("abc"), ["abc",null,null,"c"]);
+  shouldBe(new RegExp(r"(?:(a)|b)*").firstMatch("ab"), ["ab",null]);
+}
diff --git a/tests/corelib/regexp/malformed-escapes_test.dart b/tests/corelib/regexp/malformed-escapes_test.dart
new file mode 100644
index 0000000..b64090c
--- /dev/null
+++ b/tests/corelib/regexp/malformed-escapes_test.dart
@@ -0,0 +1,61 @@
+// Copyright (c) 2014, the Dart project authors. All rights reserved.
+// Copyright 2013 the V8 project authors. All rights reserved.
+// Copyright (C) 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1.  Redistributions of source code must retain the above copyright
+//     notice, this list of conditions and the following disclaimer.
+// 2.  Redistributions in binary form must reproduce the above copyright
+//     notice, this list of conditions and the following disclaimer in the
+//     documentation and/or other materials provided with the distribution.
+//
+// THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
+// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+import 'v8_regexp_utils.dart';
+import 'package:expect/expect.dart';
+
+void main() {
+  description(
+  "This page tests handling of malformed escape sequences."
+  );
+
+  var regexp;
+
+  regexp = new RegExp(r"\ug", multiLine: true);
+  shouldBeTrue(regexp.hasMatch('ug'));
+
+  regexp = new RegExp(r"\xg", multiLine: true);
+  shouldBeTrue(regexp.hasMatch('xg'));
+
+  regexp = new RegExp(r"\c_", multiLine: true);
+  shouldBeTrue(regexp.hasMatch('\\\\c_'));
+
+  regexp = new RegExp(r"[\B]", multiLine: true);
+  shouldBeTrue(regexp.hasMatch('B'));
+
+  regexp = new RegExp(r"[\b]", multiLine: true);
+  shouldBeTrue(regexp.hasMatch('\b'));
+
+  regexp = new RegExp(r"\8", multiLine: true);
+  shouldBeTrue(regexp.hasMatch('\\\8'));
+
+  regexp = new RegExp(r"^[\c]$");
+  shouldBeTrue(regexp.hasMatch('c'));
+
+  regexp = new RegExp(r"^[\c_]$");
+  shouldBeFalse(regexp.hasMatch('c'));
+
+  regexp = new RegExp(r"^[\c]]$");
+  shouldBeTrue(regexp.hasMatch('c]'));
+}
diff --git a/tests/corelib/regexp/many-brackets_test.dart b/tests/corelib/regexp/many-brackets_test.dart
new file mode 100644
index 0000000..d014f2b
--- /dev/null
+++ b/tests/corelib/regexp/many-brackets_test.dart
@@ -0,0 +1,48 @@
+// Copyright (c) 2014, the Dart project authors. All rights reserved.
+// Copyright 2013 the V8 project authors. All rights reserved.
+// Copyright (C) 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1.  Redistributions of source code must retain the above copyright
+//     notice, this list of conditions and the following disclaimer.
+// 2.  Redistributions in binary form must reproduce the above copyright
+//     notice, this list of conditions and the following disclaimer in the
+//     documentation and/or other materials provided with the distribution.
+//
+// THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
+// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+import 'v8_regexp_utils.dart';
+import 'package:expect/expect.dart';
+
+void main() {
+  description(
+  'Test regular expression processing with many capturing brackets (200).'
+  );
+
+  var count = 200;
+
+  var regexp = "";
+  for (var i = 0; i < count; ++i)
+      regexp += "(";
+  regexp += "hello";
+  for (var i = 0; i < count; ++i)
+      regexp += ")";
+
+  var manyHellosArray = [];
+  for (var i = 0; i <= count; ++i)
+      manyHellosArray.add("hello");
+
+  var manyBracketsRegExp = new RegExp(regexp);
+  shouldBe(firstMatch('hello', manyBracketsRegExp), manyHellosArray);
+}
diff --git a/tests/corelib/regexp/multiline_test.dart b/tests/corelib/regexp/multiline_test.dart
new file mode 100644
index 0000000..88222bf
--- /dev/null
+++ b/tests/corelib/regexp/multiline_test.dart
@@ -0,0 +1,118 @@
+// Copyright (c) 2014, the Dart project authors. All rights reserved.
+// Copyright 2008 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+//       copyright notice, this list of conditions and the following
+//       disclaimer in the documentation and/or other materials provided
+//       with the distribution.
+//     * Neither the name of Google Inc. nor the names of its
+//       contributors may be used to endorse or promote products derived
+//       from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+/**
+ * @fileoverview Check that various regexp constructs work as intended.
+ * Particularly those regexps that use ^ and $.
+ */
+
+import 'v8_regexp_utils.dart';
+import 'package:expect/expect.dart';
+
+void main() {
+  assertTrue(new RegExp(r"^bar").hasMatch("bar"));
+  assertTrue(new RegExp(r"^bar").hasMatch("bar\nfoo"));
+  assertFalse(new RegExp(r"^bar").hasMatch("foo\nbar"));
+  assertTrue(new RegExp(r"^bar", multiLine: true).hasMatch("bar"));
+  assertTrue(new RegExp(r"^bar", multiLine: true).hasMatch("bar\nfoo"));
+  assertTrue(new RegExp(r"^bar", multiLine: true).hasMatch("foo\nbar"));
+
+  assertTrue(new RegExp(r"bar$").hasMatch("bar"));
+  assertFalse(new RegExp(r"bar$").hasMatch("bar\nfoo"));
+  assertTrue(new RegExp(r"bar$").hasMatch("foo\nbar"));
+  assertTrue(new RegExp(r"bar$", multiLine: true).hasMatch("bar"));
+  assertTrue(new RegExp(r"bar$", multiLine: true).hasMatch("bar\nfoo"));
+  assertTrue(new RegExp(r"bar$", multiLine: true).hasMatch("foo\nbar"));
+
+  assertFalse(new RegExp(r"^bxr").hasMatch("bar"));
+  assertFalse(new RegExp(r"^bxr").hasMatch("bar\nfoo"));
+  assertFalse(new RegExp(r"^bxr", multiLine: true).hasMatch("bar"));
+  assertFalse(new RegExp(r"^bxr", multiLine: true).hasMatch("bar\nfoo"));
+  assertFalse(new RegExp(r"^bxr", multiLine: true).hasMatch("foo\nbar"));
+
+  assertFalse(new RegExp(r"bxr$").hasMatch("bar"));
+  assertFalse(new RegExp(r"bxr$").hasMatch("foo\nbar"));
+  assertFalse(new RegExp(r"bxr$", multiLine: true).hasMatch("bar"));
+  assertFalse(new RegExp(r"bxr$", multiLine: true).hasMatch("bar\nfoo"));
+  assertFalse(new RegExp(r"bxr$", multiLine: true).hasMatch("foo\nbar"));
+
+
+  assertTrue(new RegExp(r"^.*$").hasMatch(""));
+  assertTrue(new RegExp(r"^.*$").hasMatch("foo"));
+  assertFalse(new RegExp(r"^.*$").hasMatch("\n"));
+  assertTrue(new RegExp(r"^.*$", multiLine: true).hasMatch("\n"));
+
+  assertTrue(new RegExp(r"^[\s]*$").hasMatch(" "));
+  assertTrue(new RegExp(r"^[\s]*$").hasMatch("\n"));
+
+  assertTrue(new RegExp(r"^[^]*$").hasMatch(""));
+  assertTrue(new RegExp(r"^[^]*$").hasMatch("foo"));
+  assertTrue(new RegExp(r"^[^]*$").hasMatch("\n"));
+
+  assertTrue(new RegExp(r"^([()\s]|.)*$").hasMatch("()\n()"));
+  assertTrue(new RegExp(r"^([()\n]|.)*$").hasMatch("()\n()"));
+  assertFalse(new RegExp(r"^([()]|.)*$").hasMatch("()\n()"));
+  assertTrue(new RegExp(r"^([()]|.)*$", multiLine: true).hasMatch("()\n()"));
+  assertTrue(new RegExp(r"^([()]|.)*$", multiLine: true).hasMatch("()\n"));
+  assertTrue(new RegExp(r"^[()]*$", multiLine: true).hasMatch("()\n."));
+
+  assertTrue(new RegExp(r"^[\].]*$").hasMatch("...]..."));
+
+
+  dynamic check_case(lc, uc) {
+    var a = new RegExp("^" + lc + r"$");
+    assertFalse(a.hasMatch(uc));
+    a = new RegExp("^" + lc + r"$", caseSensitive: false);
+    assertTrue(a.hasMatch(uc));
+
+    var A = new RegExp("^" + uc + r"$");
+    assertFalse(A.hasMatch(lc));
+    A = new RegExp("^" + uc + r"$", caseSensitive: false);
+    assertTrue(A.hasMatch(lc));
+
+    a = new RegExp("^[" + lc + r"]$");
+    assertFalse(a.hasMatch(uc));
+    a = new RegExp("^[" + lc + r"]$", caseSensitive: false);
+    assertTrue(a.hasMatch(uc));
+
+    A = new RegExp("^[" + uc + r"]$");
+    assertFalse(A.hasMatch(lc));
+    A = new RegExp("^[" + uc + r"]$", caseSensitive: false);
+    assertTrue(A.hasMatch(lc));
+  }
+
+
+  check_case("a", "A");
+  // Aring
+  check_case(new String.fromCharCode(229), new String.fromCharCode(197));
+  // Russian G
+  check_case(new String.fromCharCode(0x413), new String.fromCharCode(0x433));
+
+
+  assertThrows(() => new RegExp('[z-a]'));
+}
diff --git a/tests/corelib/regexp/negative-special-characters_test.dart b/tests/corelib/regexp/negative-special-characters_test.dart
new file mode 100644
index 0000000..5fda4c9
--- /dev/null
+++ b/tests/corelib/regexp/negative-special-characters_test.dart
@@ -0,0 +1,95 @@
+// Copyright (c) 2014, the Dart project authors. All rights reserved.
+// Copyright 2013 the V8 project authors. All rights reserved.
+// Copyright (C) 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1.  Redistributions of source code must retain the above copyright
+//     notice, this list of conditions and the following disclaimer.
+// 2.  Redistributions in binary form must reproduce the above copyright
+//     notice, this list of conditions and the following disclaimer in the
+//     documentation and/or other materials provided with the distribution.
+//
+// THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
+// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+import 'v8_regexp_utils.dart';
+import 'package:expect/expect.dart';
+
+void main() {
+  description(
+  "This test checks Unicode in negative RegExp character classes."
+  );
+
+  dynamic testPassed(str) { }
+  dynamic testFailed(str) => Expect.fail(str);
+
+  dynamic test(pattern, str, expected_length) {
+    var result = str.replaceAll(new RegExp(pattern, caseSensitive: false, multiLine: true), '');
+
+    if (result.length == expected_length)
+      testPassed('"' + pattern + '", ' + '"' + str + '".');
+    else
+      testFailed('"' + pattern + '", ' + '"' + str + '". Was "' + result + '".');
+  }
+
+
+  test("\\s", " \t\f\v\r\n", 0); // ASCII whitespace.
+  test("\\S", "Проверка", 0); // Cyrillic letters are non-whitespace...
+  test("\\s", "Проверка", 8); // ...and they aren't whitespace.
+  test("[\\s]", "Проверка", 8);
+  test("[\\S]", "Проверка", 0);
+  test("[^\\s]", "Проверка", 0);
+  test("[^\\S]", "Проверка", 8);
+  test("[\\s\\S]*", "\\u2002Проверка\\r\\n\\u00a0", 0);
+  test("\\S\\S", "уф", 0);
+  test("\\S{2}", "уф", 0);
+
+  test("\\w", "Проверка", 8); // Alas, only ASCII characters count as word ones in JS.
+  test("\\W", "Проверка", 0);
+  test("[\\w]", "Проверка", 8);
+  test("[\\W]", "Проверка", 0);
+  test("[^\\w]", "Проверка", 0);
+  test("[^\\W]", "Проверка", 8);
+  test("\\W\\W", "уф", 0);
+  test("\\W{2}", "уф", 0);
+
+  test("\\d", "Проверка", 8); // Digit and non-digit.
+  test("\\D", "Проверка", 0);
+  test("[\\d]", "Проверка", 8);
+  test("[\\D]", "Проверка", 0);
+  test("[^\\d]", "Проверка", 0);
+  test("[^\\D]", "Проверка", 8);
+  test("\\D\\D", "уф", 0);
+  test("\\D{2}", "уф", 0);
+
+  test("[\\S\\d]", "Проверка123", 0);
+  test("[\\d\\S]", "Проверка123", 0);
+  test("[^\\S\\d]", "Проверка123", 11);
+  test("[^\\d\\S]", "Проверка123", 11);
+
+  test("[ \\S]", " Проверка ", 0);
+  test("[\\S ]", " Проверка ", 0);
+  test("[ф \\S]", " Проверка ", 0);
+  test("[\\Sф ]", " Проверка ", 0);
+
+  test("[^р\\S]", " Проверка ", 8);
+  test("[^\\Sр]", " Проверка ", 8);
+  test("[^р\\s]", " Проверка ", 4);
+  test("[^\\sр]", " Проверка ", 4);
+
+  test("[ф \\s\\S]", "Проверка \\r\\n", 0);
+  test("[\\S\\sф ]", "Проверка \\r\\n", 0);
+
+  test("[^z]", "Проверка \\r\\n", 0);
+  test("[^ф]", "Проверка \\r\\n", 0);
+}
diff --git a/tests/corelib/regexp/no-extensions_test.dart b/tests/corelib/regexp/no-extensions_test.dart
new file mode 100644
index 0000000..8d2564b
--- /dev/null
+++ b/tests/corelib/regexp/no-extensions_test.dart
@@ -0,0 +1,69 @@
+// Copyright (c) 2014, the Dart project authors. All rights reserved.
+// Copyright 2013 the V8 project authors. All rights reserved.
+// Copyright (C) 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1.  Redistributions of source code must retain the above copyright
+//     notice, this list of conditions and the following disclaimer.
+// 2.  Redistributions in binary form must reproduce the above copyright
+//     notice, this list of conditions and the following disclaimer in the
+//     documentation and/or other materials provided with the distribution.
+//
+// THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
+// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+import 'v8_regexp_utils.dart';
+import 'package:expect/expect.dart';
+
+void main() {
+  description(
+  'Tests that regular expressions do not have extensions that diverge from the JavaScript specification. '
+  + 'Because WebKit originally used a copy of PCRE, various non-JavaScript regular expression features were historically present. '
+  + 'Also tests various related edge cases.'
+  );
+
+  shouldBeNull(new RegExp(r"\\x{41}").firstMatch("yA1"));
+  assertEquals(new RegExp(r"[\x{41}]").firstMatch("yA1").group(0), "1");
+  assertEquals(new RegExp(r"\x1g").firstMatch("x1g").group(0), "x1g");
+  assertEquals(new RegExp(r"[\x1g]").firstMatch("x").group(0), "x");
+  assertEquals(new RegExp(r"[\x1g]").firstMatch("1").group(0), "1");
+  assertEquals(new RegExp(r"\2147483648").firstMatch(new String.fromCharCode(140) + "7483648").group(0), new String.fromCharCode(140) + "7483648");
+  assertEquals(new RegExp(r"\4294967296").firstMatch("\"94967296").group(0), "\"94967296");
+  assertEquals(new RegExp(r"\8589934592").firstMatch("\8589934592").group(0), "\8589934592");
+  assertEquals("\nAbc\n".replaceAllMapped(new RegExp(r"(\n)[^\n]+$"), (m) => m.group(1)), "\nAbc\n");
+  shouldBeNull(new RegExp(r"x$").firstMatch("x\n"));
+  assertThrows(() => new RegExp(r"x++"));
+  shouldBeNull(new RegExp(r"[]]").firstMatch("]"));
+
+  assertEquals(new RegExp(r"\060").firstMatch("y01").group(0), "0");
+  assertEquals(new RegExp(r"[\060]").firstMatch("y01").group(0), "0");
+  assertEquals(new RegExp(r"\606").firstMatch("y06").group(0), "06");
+  assertEquals(new RegExp(r"[\606]").firstMatch("y06").group(0), "0");
+  assertEquals(new RegExp(r"[\606]").firstMatch("y6").group(0), "6");
+  assertEquals(new RegExp(r"\101").firstMatch("yA1").group(0), "A");
+  assertEquals(new RegExp(r"[\101]").firstMatch("yA1").group(0), "A");
+  assertEquals(new RegExp(r"\1011").firstMatch("yA1").group(0), "A1");
+  assertEquals(new RegExp(r"[\1011]").firstMatch("yA1").group(0), "A");
+  assertEquals(new RegExp(r"[\1011]").firstMatch("y1").group(0), "1");
+  assertEquals(new RegExp(r"\10q").firstMatch("y" + new String.fromCharCode(8) + "q").group(0), new String.fromCharCode(8) + "q");
+  assertEquals(new RegExp(r"[\10q]").firstMatch("y" + new String.fromCharCode(8) + "q").group(0), new String.fromCharCode(8));
+  assertEquals(new RegExp(r"\1q").firstMatch("y" + new String.fromCharCode(1) + "q").group(0), new String.fromCharCode(1) + "q");
+  assertEquals(new RegExp(r"[\1q]").firstMatch("y" + new String.fromCharCode(1) + "q").group(0), new String.fromCharCode(1));
+  assertEquals(new RegExp(r"[\1q]").firstMatch("yq").group(0), "q");
+  assertEquals(new RegExp(r"\8q").firstMatch("\8q").group(0), "\8q");
+  assertEquals(new RegExp(r"[\8q]").firstMatch("y8q").group(0), "8");
+  assertEquals(new RegExp(r"[\8q]").firstMatch("yq").group(0), "q");
+  shouldBe(new RegExp(r"(x)\1q").firstMatch("xxq"), ["xxq", "x"]);
+  shouldBe(new RegExp(r"(x)[\1q]").firstMatch("xxq"), ["xq", "x"]);
+  shouldBe(new RegExp(r"(x)[\1q]").firstMatch("xx" + new String.fromCharCode(1)), ["x" + new String.fromCharCode(1), "x"]);
+}
diff --git a/tests/corelib/regexp/non-bmp_test.dart b/tests/corelib/regexp/non-bmp_test.dart
new file mode 100644
index 0000000..3160f9e
--- /dev/null
+++ b/tests/corelib/regexp/non-bmp_test.dart
@@ -0,0 +1,46 @@
+// Copyright (c) 2014, the Dart project authors. All rights reserved.
+// Copyright 2013 the V8 project authors. All rights reserved.
+// Copyright (C) 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1.  Redistributions of source code must retain the above copyright
+//     notice, this list of conditions and the following disclaimer.
+// 2.  Redistributions in binary form must reproduce the above copyright
+//     notice, this list of conditions and the following disclaimer in the
+//     documentation and/or other materials provided with the distribution.
+//
+// THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
+// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+import 'v8_regexp_utils.dart';
+import 'package:expect/expect.dart';
+
+void main() {
+  description(
+  'Tests that regular expressions treat non-BMP characters as two separate characters. '
+  + 'From a Unicode correctness point of view this is wrong, but it is what other browsers do. '
+  + 'And given that we store strings as UTF-16, it is also more efficient to implement. '
+  + 'Also test some other cases related to UTF-8 and UTF-16.'
+  );
+
+  var surrogatePair = new String.fromCharCode(0xD800) + new String.fromCharCode(0xDC00);
+
+  assertEquals(new RegExp(r".").firstMatch(surrogatePair).group(0).length, 1);
+  assertEquals(new RegExp(r"\D").firstMatch(surrogatePair).group(0).length, 1);
+  assertEquals(new RegExp(r"\S").firstMatch(surrogatePair).group(0).length, 1);
+  assertEquals(new RegExp(r"\W").firstMatch(surrogatePair).group(0).length, 1);
+  assertEquals(new RegExp(r"[^x]").firstMatch(surrogatePair).group(0).length, 1);
+
+  assertEquals(new RegExp(r".{1,2}").firstMatch("!!" + new String.fromCharCode(0xA1)).group(0).length, 2);
+  shouldBeNull(new RegExp(r".").firstMatch(""));
+}
diff --git a/tests/corelib/regexp/non-capturing-backtracking_test.dart b/tests/corelib/regexp/non-capturing-backtracking_test.dart
new file mode 100644
index 0000000..f7796de
--- /dev/null
+++ b/tests/corelib/regexp/non-capturing-backtracking_test.dart
@@ -0,0 +1,35 @@
+// Copyright (c) 2014, the Dart project authors. All rights reserved.
+// Copyright 2013 the V8 project authors. All rights reserved.
+// Copyright (C) 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1.  Redistributions of source code must retain the above copyright
+//     notice, this list of conditions and the following disclaimer.
+// 2.  Redistributions in binary form must reproduce the above copyright
+//     notice, this list of conditions and the following disclaimer in the
+//     documentation and/or other materials provided with the distribution.
+//
+// THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
+// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+import 'v8_regexp_utils.dart';
+import 'package:expect/expect.dart';
+
+void main() {
+  description(
+  "This page tests for proper backtracking with greedy quantifiers and non-capturing parentheses."
+  );
+
+  var re = new RegExp(r"(?:a*)a");
+  shouldBe(re.firstMatch('a'), ['a']);
+}
diff --git a/tests/corelib/regexp/non-capturing-groups_test.dart b/tests/corelib/regexp/non-capturing-groups_test.dart
new file mode 100644
index 0000000..a91cdab
--- /dev/null
+++ b/tests/corelib/regexp/non-capturing-groups_test.dart
@@ -0,0 +1,47 @@
+// Copyright (c) 2014, the Dart project authors. All rights reserved.
+// Copyright 2013 the V8 project authors. All rights reserved.
+// Copyright (C) 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1.  Redistributions of source code must retain the above copyright
+//     notice, this list of conditions and the following disclaimer.
+// 2.  Redistributions in binary form must reproduce the above copyright
+//     notice, this list of conditions and the following disclaimer in the
+//     documentation and/or other materials provided with the distribution.
+//
+// THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
+// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+import 'v8_regexp_utils.dart';
+import 'package:expect/expect.dart';
+
+void main() {
+  description(
+  'Test for behavior of non-capturing groups, as described in <a href="http://blog.stevenlevithan.com/archives/npcg-javascript">' +
+  'a blog post by Steven Levithan</a> and <a href="http://bugs.webkit.org/show_bug.cgi?id=14931">bug 14931</a>.'
+  );
+
+  shouldBeTrue(new RegExp(r"(x)?\1y").hasMatch("y"));
+  shouldBe(new RegExp(r"(x)?\1y").firstMatch("y"), ["y", null]);
+  shouldBe(new RegExp(r"(x)?y").firstMatch("y"), ["y", null]);
+  shouldBe(firstMatch("y", new RegExp(r"(x)?\1y")), ["y", null]);
+  shouldBe(firstMatch("y", new RegExp(r"(x)?y")), ["y", null]);
+  shouldBe(firstMatch("y", new RegExp(r"(x)?\1y")), ["y", null]);
+  Expect.listEquals("y".split(new RegExp(r"(x)?\1y")), ["", ""]);
+  Expect.listEquals("y".split(new RegExp(r"(x)?y")), ["", ""]);
+  assertEquals("y".indexOf(new RegExp(r"(x)?\1y")), 0);
+  assertEquals("y".replaceAll(new RegExp(r"(x)?\1y"), "z"), "z");
+  assertEquals("y".replaceAllMapped(new RegExp(r"(x)?y"), (m) => m.group(1)), "null");
+  assertEquals("y".replaceAllMapped(new RegExp(r"(x)?\1y"), (m) => m.group(1)), "null");
+  assertEquals("y".replaceAllMapped(new RegExp(r"(x)?y"), (m) => m.group(1)), "null");
+}
diff --git a/tests/corelib/regexp/non-character_test.dart b/tests/corelib/regexp/non-character_test.dart
new file mode 100644
index 0000000..bc4a206
--- /dev/null
+++ b/tests/corelib/regexp/non-character_test.dart
@@ -0,0 +1,47 @@
+// Copyright (c) 2014, the Dart project authors. All rights reserved.
+// Copyright 2013 the V8 project authors. All rights reserved.
+// Copyright (C) 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1.  Redistributions of source code must retain the above copyright
+//     notice, this list of conditions and the following disclaimer.
+// 2.  Redistributions in binary form must reproduce the above copyright
+//     notice, this list of conditions and the following disclaimer in the
+//     documentation and/or other materials provided with the distribution.
+//
+// THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
+// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+import 'v8_regexp_utils.dart';
+import 'package:expect/expect.dart';
+
+void main() {
+  description(
+  'Test for regular expressions with non-character values in them, specifically in character classes.'
+  );
+
+  shouldBeNull(firstMatch("F", new RegExp(r"[\uD7FF]")));
+  shouldBeNull(firstMatch("0", new RegExp(r"[\uD800]")));
+  shouldBeNull(firstMatch("F", new RegExp(r"[\uDFFF]")));
+  shouldBeNull(firstMatch("E", new RegExp(r"[\uE000]")));
+  shouldBeNull(firstMatch("y", new RegExp(r"[\uFDBF]")));
+  shouldBeNull(firstMatch("y", new RegExp(r"[\uFDD0]")));
+  shouldBeNull(firstMatch("y", new RegExp(r"[\uFDEF]")));
+  shouldBeNull(firstMatch("y", new RegExp(r"[\uFDF0]")));
+  shouldBeNull(firstMatch("y", new RegExp(r"[\uFEFF]")));
+  shouldBeNull(firstMatch("y", new RegExp(r"[\uFEFF]")));
+  shouldBeNull(firstMatch("y", new RegExp(r"[\uFFFE]")));
+  shouldBeNull(firstMatch("y", new RegExp(r"[\uFFFF]")));
+  shouldBeNull(firstMatch("y", new RegExp(r"[\u10FFFF]")));
+  shouldBeNull(firstMatch("y", new RegExp(r"[\u110000]")));
+}
diff --git a/tests/corelib/regexp/non-greedy-parentheses_test.dart b/tests/corelib/regexp/non-greedy-parentheses_test.dart
new file mode 100644
index 0000000..94494bf
--- /dev/null
+++ b/tests/corelib/regexp/non-greedy-parentheses_test.dart
@@ -0,0 +1,41 @@
+// Copyright (c) 2014, the Dart project authors. All rights reserved.
+// Copyright 2013 the V8 project authors. All rights reserved.
+// Copyright (C) 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1.  Redistributions of source code must retain the above copyright
+//     notice, this list of conditions and the following disclaimer.
+// 2.  Redistributions in binary form must reproduce the above copyright
+//     notice, this list of conditions and the following disclaimer in the
+//     documentation and/or other materials provided with the distribution.
+//
+// THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
+// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+import 'v8_regexp_utils.dart';
+import 'package:expect/expect.dart';
+
+void main() {
+  description(
+'Test for regression against <a href="https://bugs.webkit.org/show_bug.cgi?id=39289">Wrong result in case of non-iterative matching of subpatterns in non-greedy cases in YARR Interpreter</a>'
+  );
+
+  shouldBe(firstMatch("a", new RegExp(r"(a)??")), ["", null]);
+  shouldBe(firstMatch("b", new RegExp(r"(a)??")), ["", null]);
+  shouldBe(firstMatch("ab", new RegExp(r"(a)??b")), ["ab", "a"]);
+  shouldBe(firstMatch("aaab", new RegExp(r"(a+)??b")), ["aaab", "aaa"]);
+  shouldBe(firstMatch("abbc", new RegExp(r"(a)??(b+)??c")), ["abbc", "a", "bb"]);
+  shouldBe(firstMatch("ac", new RegExp(r"(a)??(b)??c")), ["ac", "a", null]);
+  shouldBe(firstMatch("abc", new RegExp(r"(a(b)??)??c")), ["abc", "ab", "b"]);
+  shouldBe(firstMatch("ac", new RegExp(r"(a(b)??)??c")), ["ac", "a", null]);
+}
diff --git a/tests/corelib/regexp/norepeat_test.dart b/tests/corelib/regexp/norepeat_test.dart
new file mode 100644
index 0000000..2f7b9a4
--- /dev/null
+++ b/tests/corelib/regexp/norepeat_test.dart
@@ -0,0 +1,36 @@
+// Copyright (c) 2014, the Dart project authors. All rights reserved.
+// Copyright 2013 the V8 project authors. All rights reserved.
+// Copyright (C) 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1.  Redistributions of source code must retain the above copyright
+//     notice, this list of conditions and the following disclaimer.
+// 2.  Redistributions in binary form must reproduce the above copyright
+//     notice, this list of conditions and the following disclaimer in the
+//     documentation and/or other materials provided with the distribution.
+//
+// THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
+// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+import 'v8_regexp_utils.dart';
+import 'package:expect/expect.dart';
+
+void main() {
+  description(
+  'Test for https://bugs.webkit.org/show_bug.cgi?id=46077'
+  );
+
+  var re = new RegExp(r"^b|^cd");
+  var str = "abcd";
+  shouldBeFalse(re.hasMatch(str));
+}
diff --git a/tests/corelib/regexp/overflow_test.dart b/tests/corelib/regexp/overflow_test.dart
new file mode 100644
index 0000000..67def80
--- /dev/null
+++ b/tests/corelib/regexp/overflow_test.dart
@@ -0,0 +1,43 @@
+// Copyright (c) 2014, the Dart project authors. All rights reserved.
+// Copyright 2013 the V8 project authors. All rights reserved.
+// Copyright (C) 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1.  Redistributions of source code must retain the above copyright
+//     notice, this list of conditions and the following disclaimer.
+// 2.  Redistributions in binary form must reproduce the above copyright
+//     notice, this list of conditions and the following disclaimer in the
+//     documentation and/or other materials provided with the distribution.
+//
+// THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
+// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+import 'v8_regexp_utils.dart';
+import 'package:expect/expect.dart';
+
+void main() {
+  description("This test checks expressions with alternative lengths of appox. 2^31.");
+
+  var regexp1 = new RegExp(r"(?:(?=g))|(?:m).{2147483648,}");
+  shouldBeNull(regexp1.firstMatch(''));
+
+  var regexp2 = new RegExp(r"(?:(?=g)).{2147483648,}");
+  shouldBeNull(regexp2.firstMatch(''));
+
+  var s3 = r"&{6}u4a64YfQP{C}u88c4u5772Qu8693{4294967167}u85f2u7f3fs((uf202){4})u5bc6u1947";
+  var regexp3 = new RegExp(s3);
+  shouldBeNull(regexp3.firstMatch(s3));
+
+  var regexp4 = new RegExp(r"[^a$]{4294967295}");
+  shouldBeNull(regexp4.firstMatch(s3));
+}
diff --git a/tests/corelib/regexp/parentheses_test.dart b/tests/corelib/regexp/parentheses_test.dart
new file mode 100644
index 0000000..4524035
--- /dev/null
+++ b/tests/corelib/regexp/parentheses_test.dart
@@ -0,0 +1,288 @@
+// Copyright (c) 2014, the Dart project authors. All rights reserved.
+// Copyright 2013 the V8 project authors. All rights reserved.
+// Copyright (C) 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1.  Redistributions of source code must retain the above copyright
+//     notice, this list of conditions and the following disclaimer.
+// 2.  Redistributions in binary form must reproduce the above copyright
+//     notice, this list of conditions and the following disclaimer in the
+//     documentation and/or other materials provided with the distribution.
+//
+// THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
+// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+import 'v8_regexp_utils.dart';
+import 'package:expect/expect.dart';
+
+void main() {
+  description("This page tests handling of parentheses subexpressions.");
+
+  var regexp1 = new RegExp(r"(a|A)(b|B)");
+  shouldBe(regexp1.firstMatch('abc'), ['ab','a','b']);
+
+  var regexp2 = new RegExp(r"(a((b)|c|d))e");
+  shouldBe(regexp2.firstMatch('abacadabe'), ['abe','ab','b','b']);
+
+  var regexp3 = new RegExp(r"(a(b|(c)|d))e");
+  shouldBe(regexp3.firstMatch('abacadabe'), ['abe','ab','b',null]);
+
+  var regexp4 = new RegExp(r"(a(b|c|(d)))e");
+  shouldBe(regexp4.firstMatch('abacadabe'), ['abe','ab','b',null]);
+
+  var regexp5 = new RegExp(r"(a((b)|(c)|(d)))e");
+  shouldBe(regexp5.firstMatch('abacadabe'), ['abe','ab','b','b',null,null]);
+
+  var regexp6 = new RegExp(r"(a((b)|(c)|(d)))");
+  shouldBe(regexp6.firstMatch('abcde'), ['ab','ab','b','b',null,null]);
+
+  var regexp7 = new RegExp(r"(a(b)??)??c");
+  shouldBe(regexp7.firstMatch('abc'), ['abc','ab','b']);
+
+  var regexp8 = new RegExp(r"(a|(e|q))(x|y)");
+  shouldBe(regexp8.firstMatch('bcaddxqy') , ['qy','q','q','y']);
+
+  var regexp9 = new RegExp(r"((t|b)?|a)$");
+  shouldBe(regexp9.firstMatch('asdfjejgsdflaksdfjkeljghkjea'), ['a','a',null]);
+
+  var regexp10 = new RegExp(r"(?:h|e?(?:t|b)?|a?(?:t|b)?)(?:$)");
+  shouldBe(regexp10.firstMatch('asdfjejgsdflaksdfjkeljghat'), ['at']);
+
+  var regexp11 = new RegExp(r"([Jj]ava([Ss]cript)?)\sis\s(fun\w*)");
+  shouldBeNull(regexp11.firstMatch('Developing with JavaScript is dangerous, do not try it without assistance'));
+
+  var regexp12 = new RegExp(r"(?:(.+), )?(.+), (..) to (?:(.+), )?(.+), (..)");
+  shouldBe(regexp12.firstMatch('Seattle, WA to Buckley, WA'), ['Seattle, WA to Buckley, WA', null, 'Seattle', 'WA', null, 'Buckley', 'WA']);
+
+  var regexp13 = new RegExp(r"(A)?(A.*)");
+  shouldBe(regexp13.firstMatch('zxcasd;fl\ ^AaaAAaaaf;lrlrzs'), ['AaaAAaaaf;lrlrzs',null,'AaaAAaaaf;lrlrzs']);
+
+  var regexp14 = new RegExp(r"(a)|(b)");
+  shouldBe(regexp14.firstMatch('b'), ['b',null,'b']);
+
+  var regexp15 = new RegExp(r"^(?!(ab)de|x)(abd)(f)");
+  shouldBe(regexp15.firstMatch('abdf'), ['abdf',null,'abd','f']);
+
+  var regexp16 = new RegExp(r"(a|A)(b|B)");
+  shouldBe(regexp16.firstMatch('abc'), ['ab','a','b']);
+
+  var regexp17 = new RegExp(r"(a|d|q|)x", caseSensitive: false);
+  shouldBe(regexp17.firstMatch('bcaDxqy'), ['Dx','D']);
+
+  var regexp18 = new RegExp(r"^.*?(:|$)");
+  shouldBe(regexp18.firstMatch('Hello: World'), ['Hello:',':']);
+
+  var regexp19 = new RegExp(r"(ab|^.{0,2})bar");
+  shouldBe(regexp19.firstMatch('barrel'), ['bar','']);
+
+  var regexp20 = new RegExp(r"(?:(?!foo)...|^.{0,2})bar(.*)");
+  shouldBe(regexp20.firstMatch('barrel'), ['barrel','rel']);
+  shouldBe(regexp20.firstMatch('2barrel'), ['2barrel','rel']);
+
+  var regexp21 = new RegExp(r"([a-g](b|B)|xyz)");
+  shouldBe(regexp21.firstMatch('abc'), ['ab','ab','b']);
+
+  var regexp22 = new RegExp(r"(?:^|;)\s*abc=([^;]*)");
+  shouldBeNull(regexp22.firstMatch('abcdlskfgjdslkfg'));
+
+  var regexp23 = new RegExp("\"[^<\"]*\"|'[^<']*'");
+  shouldBe(regexp23.firstMatch('<html xmlns=\"http://www.w3.org/1999/xhtml\"'),
+        ['\"http://www.w3.org/1999/xhtml\"']);
+
+  var regexp24 = new RegExp(r"^(?:(?=abc)\w{3}:|\d\d)$");
+  shouldBeNull(regexp24.firstMatch('123'));
+
+  var regexp25 = new RegExp(r"^\s*(\*|[\w\-]+)(\b|$)?");
+  shouldBe(regexp25.firstMatch('this is a test'), ['this','this',null]);
+  shouldBeNull(regexp25.firstMatch('!this is a test'));
+
+  var regexp26 = new RegExp(r"a(b)(a*)|aaa");
+  shouldBe(regexp26.firstMatch('aaa'), ['aaa',null,null]);
+
+  var regexp27 = new RegExp(
+      "^" +
+      "(?:" +
+          "([^:/?#]+):" + /* scheme */
+      ")?" +
+      "(?:" +
+          "(//)" + /* authorityRoot */
+          "(" + /* authority */
+              "(?:" +
+                  "(" + /* userInfo */
+                      "([^:@]*)" + /* user */
+                      ":?" +
+                      "([^:@]*)" + /* password */
+                  ")?" +
+                  "@" +
+              ")?" +
+              "([^:/?#]*)" + /* domain */
+              "(?::(\\d*))?" + /* port */
+          ")" +
+      ")?" +
+      "([^?#]*)" + /*path*/
+      "(?:\\?([^#]*))?" + /* queryString */
+      "(?:#(.*))?" /*fragment */
+  );
+  shouldBe(regexp27.firstMatch('file:///Users/Someone/Desktop/HelloWorld/index.html'), ['file:///Users/Someone/Desktop/HelloWorld/index.html','file','//','',null,null,null,'',null,'/Users/Someone/Desktop/HelloWorld/index.html',null,null]);
+
+  var regexp28 = new RegExp(
+      "^" +
+      "(?:" +
+          "([^:/?#]+):" + /* scheme */
+      ")?" +
+      "(?:" +
+          "(//)" + /* authorityRoot */
+          "(" + /* authority */
+              "(" + /* userInfo */
+                  "([^:@]*)" + /* user */
+                  ":?" +
+                  "([^:@]*)" + /* password */
+              ")?" +
+              "@" +
+          ")" +
+      ")?"
+  );
+  shouldBe(regexp28.firstMatch('file:///Users/Someone/Desktop/HelloWorld/index.html'), ['file:','file',null,null,null,null,null]);
+
+  var regexp29 = new RegExp(r'^\s*((\[[^\]]+\])|(u?)("[^"]+"))\s*');
+  shouldBeNull(regexp29.firstMatch('Committer:'));
+
+  var regexp30 = new RegExp(r'^\s*((\[[^\]]+\])|m(u?)("[^"]+"))\s*');
+  shouldBeNull(regexp30.firstMatch('Committer:'));
+
+  var regexp31 = new RegExp(r'^\s*(m(\[[^\]]+\])|m(u?)("[^"]+"))\s*');
+  shouldBeNull(regexp31.firstMatch('Committer:'));
+
+  var regexp32 = new RegExp(r'\s*(m(\[[^\]]+\])|m(u?)("[^"]+"))\s*');
+  shouldBeNull(regexp32.firstMatch('Committer:'));
+
+  var regexp33 = new RegExp('^(?:(?:(a)(xyz|[^>"\'\s]*)?)|(/?>)|.[^\w\s>]*)');
+  shouldBe(regexp33.firstMatch('> <head>'), ['>',null,null,'>']);
+
+  var regexp34 = new RegExp(r"(?:^|\b)btn-\S+");
+  shouldBeNull(regexp34.firstMatch('xyz123'));
+  shouldBe(regexp34.firstMatch('btn-abc'),['btn-abc']);
+  shouldBeNull(regexp34.firstMatch('btn- abc'));
+  shouldBeNull(regexp34.firstMatch('XXbtn-abc'));
+  shouldBe(regexp34.firstMatch('XX btn-abc'),['btn-abc']);
+
+  var regexp35 = new RegExp(r"^((a|b)(x|xxx)|)$");
+  shouldBe(regexp35.firstMatch('ax'), ['ax','ax','a','x']);
+  shouldBeNull(regexp35.firstMatch('axx'));
+  shouldBe(regexp35.firstMatch('axxx'), ['axxx','axxx','a','xxx']);
+  shouldBe(regexp35.firstMatch('bx'), ['bx','bx','b','x']);
+  shouldBeNull(regexp35.firstMatch('bxx'));
+  shouldBe(regexp35.firstMatch('bxxx'), ['bxxx','bxxx','b','xxx']);
+
+  var regexp36 = new RegExp(r"^((\/|\.|\-)(\d\d|\d\d\d\d)|)$");
+  shouldBe(regexp36.firstMatch('/2011'), ['/2011','/2011','/','2011']);
+  shouldBe(regexp36.firstMatch('/11'), ['/11','/11','/','11']);
+  shouldBeNull(regexp36.firstMatch('/123'));
+
+  var regexp37 = new RegExp(r"^([1][0-2]|[0]\d|\d)(\/|\.|\-)([0-2]\d|[3][0-1]|\d)((\/|\.|\-)(\d\d|\d\d\d\d)|)$");
+  shouldBe(regexp37.firstMatch('7/4/1776'), ['7/4/1776','7','/','4','/1776','/','1776']);
+  shouldBe(regexp37.firstMatch('07-04-1776'), ['07-04-1776','07','-','04','-1776','-','1776']);
+
+  var regexp38 = new RegExp(r"^(z|(x|xx)|b|)$");
+  shouldBe(regexp38.firstMatch('xx'), ['xx','xx','xx']);
+  shouldBe(regexp38.firstMatch('b'), ['b','b',null]);
+  shouldBe(regexp38.firstMatch('z'), ['z','z',null]);
+  shouldBe(regexp38.firstMatch(''), ['','',null]);
+
+  var regexp39 = new RegExp(r"(8|((?=P)))?");
+  shouldBe(regexp39.firstMatch(''), ['',null,null]);
+  shouldBe(regexp39.firstMatch('8'), ['8','8',null]);
+  shouldBe(regexp39.firstMatch('zP'), ['',null,null]);
+
+  var regexp40 = new RegExp(r"((8)|((?=P){4}))?()");
+  shouldBe(regexp40.firstMatch(''), ['',null,null,null,'']);
+  shouldBe(regexp40.firstMatch('8'), ['8','8','8',null,'']);
+  shouldBe(regexp40.firstMatch('zPz'), ['',null,null,null,'']);
+  shouldBe(regexp40.firstMatch('zPPz'), ['',null,null,null,'']);
+  shouldBe(regexp40.firstMatch('zPPPz'), ['',null,null,null,'']);
+  shouldBe(regexp40.firstMatch('zPPPPz'), ['',null,null,null,'']);
+
+  var regexp41 = new RegExp(r"(([\w\-]+:\/\/?|www[.])[^\s()<>]+(?:([\w\d]+)|([^\[:punct:\]\s()<>\W]|\/)))");
+  shouldBe(regexp41.firstMatch('Here is a link: http://www.acme.com/our_products/index.html. That is all we want!'),
+      ['http://www.acme.com/our_products/index.html','http://www.acme.com/our_products/index.html','http://','l',null]);
+
+  var regexp42 = new RegExp(r"((?:(4)?))?");
+  shouldBe(regexp42.firstMatch(''), ['',null,null]);
+  shouldBe(regexp42.firstMatch('4'), ['4','4','4']);
+  shouldBe(regexp42.firstMatch('4321'), ['4','4','4']);
+
+  shouldBeTrue(new RegExp(r"(?!(?=r{0}){2,})|((z)?)?", caseSensitive: false).hasMatch(''));
+
+  var regexp43 = new RegExp(r"(?!(?:\1+s))");
+  shouldBe(regexp43.firstMatch('SSS'), ['']);
+
+  var regexp44 = new RegExp(r"(?!(?:\3+(s+?)))");
+  shouldBe(regexp44.firstMatch('SSS'), ['',null]);
+
+  var regexp45 = new RegExp(r"((?!(?:|)v{2,}|))");
+  shouldBeNull(regexp45.firstMatch('vt'));
+
+  var regexp46 = new RegExp(r"(w)(?:5{3}|())|pk");
+  shouldBeNull(regexp46.firstMatch('5'));
+  shouldBe(regexp46.firstMatch('pk'), ['pk',null,null]);
+  shouldBe(regexp46.firstMatch('Xw555'), ['w555','w',null]);
+  shouldBe(regexp46.firstMatch('Xw55pk5'), ['w','w','']);
+
+  var regexp47 = new RegExp(r"(.*?)(?:(?:\?(.*?)?)?)(?:(?:#)?)$");
+  shouldBe(regexp47.firstMatch('/www.acme.com/this/is/a/path/file.txt'),
+        ['/www.acme.com/this/is/a/path/file.txt','/www.acme.com/this/is/a/path/file.txt',null]);
+
+  var regexp48 = new RegExp(r"^(?:(\w+):\/*([\w\.\-\d]+)(?::(\d+)|)(?=(?:\/|$))|)(?:$|\/?(.*?)(?:\?(.*?)?|)(?:#(.*)|)$)");
+  shouldBe(regexp48.firstMatch('http://www.acme.com/this/is/a/path/file.txt'),
+      ['http://www.acme.com/this/is/a/path/file.txt','http','www.acme.com',null,'this/is/a/path/file.txt',null,null]);
+
+  var regexp49 = new RegExp(r"(?:([^:]*?)(?:(?:\?(.*?)?)?)(?:(?:#)?)$)|(?:^(?:(\w+):\/*([\w\.\-\d]+)(?::(\d+)|)(?=(?:\/|$))|)(?:$|\/?(.*?)(?:\?(.*?)?|)(?:#(.*)|)$))");
+  shouldBe(regexp49.firstMatch('http://www.acme.com/this/is/a/path/file.txt'),
+      ['http://www.acme.com/this/is/a/path/file.txt',null,null,'http','www.acme.com',null,'this/is/a/path/file.txt',null,null]);
+
+  var regexp50 = new RegExp(r"((a)b{28,}c|d)x");
+  shouldBeNull(regexp50.firstMatch('((a)b{28,}c|d)x'));
+  shouldBe(regexp50.firstMatch('abbbbbbbbbbbbbbbbbbbbbbbbbbbbcx'), ['abbbbbbbbbbbbbbbbbbbbbbbbbbbbcx', 'abbbbbbbbbbbbbbbbbbbbbbbbbbbbc', 'a']);
+  shouldBe(regexp50.firstMatch('dx'), ['dx', 'd', null]);
+
+  var s = "((.\s{-}).{28,}\P{Yi}?{,30}\|.)\x9e{-,}\P{Any}";
+  var regexp51 = new RegExp(s);
+  shouldBeNull(regexp51.firstMatch('abc'));
+  shouldBe(regexp51.firstMatch(s), [')\x9e{-,}P{Any}',')',null]);
+
+  var regexp52 = new RegExp(r"(Rob)|(Bob)|(Robert)|(Bobby)");
+  shouldBe(regexp52.firstMatch('Hi Bob'), ['Bob',null,'Bob',null,null]);
+
+  // Test cases discovered by fuzzing that crashed the compiler.
+  var regexp53 = new RegExp(r"(?=(?:(?:(gB)|(?!cs|<))((?=(?!v6){0,})))|(?=#)+?)", multiLine: true);
+  shouldBe(regexp53.firstMatch('#'), ['',null,'']);
+  var regexp54 = new RegExp(r"((?:(?:()|(?!))((?=(?!))))|())", multiLine: true);
+  shouldBe(regexp54.firstMatch('#'), ['','',null,null,'']);
+  var regexp55 = new RegExp(r"(?:(?:(?:a?|(?:))((?:)))|a?)", multiLine: true);
+  shouldBe(regexp55.firstMatch('#'), ['','']);
+
+  // Test evaluation order of empty subpattern alternatives.
+  var regexp56 = new RegExp(r"(|a)");
+  shouldBe(regexp56.firstMatch('a'), ['','']);
+  var regexp57 = new RegExp(r"(a|)");
+  shouldBe(regexp57.firstMatch('a'), ['a','a']);
+
+  // Tests that non-greedy repeat quantified parentheses will backtrack through multiple frames of subpattern matches.
+  var regexp58 = new RegExp(r"a|b(?:[^b])*?c");
+  shouldBe(regexp58.firstMatch('badbc'), ['a']);
+  var regexp59 = new RegExp(r"(X(?:.(?!X))*?Y)|(Y(?:.(?!Y))*?Z)");
+  Expect.listEquals(regexp59.allMatches('Y aaa X Match1 Y aaa Y Match2 Z')
+                   .map((m) => m.group(0))
+                   .toList(),
+      ['X Match1 Y','Y Match2 Z']);
+}
diff --git a/tests/corelib/regexp/pcre-test-4_test.dart b/tests/corelib/regexp/pcre-test-4_test.dart
new file mode 100644
index 0000000..fa4c37a
--- /dev/null
+++ b/tests/corelib/regexp/pcre-test-4_test.dart
@@ -0,0 +1,1027 @@
+// Copyright (c) 2014, the Dart project authors. All rights reserved.
+// Copyright 2013 the V8 project authors. All rights reserved.
+// Copyright (C) 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1.  Redistributions of source code must retain the above copyright
+//     notice, this list of conditions and the following disclaimer.
+// 2.  Redistributions in binary form must reproduce the above copyright
+//     notice, this list of conditions and the following disclaimer in the
+//     documentation and/or other materials provided with the distribution.
+//
+// THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
+// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+import 'v8_regexp_utils.dart';
+import 'package:expect/expect.dart';
+
+void main() {
+  description(
+  "A chunk of our port of PCRE's test suite, adapted to be more applicable to JavaScript."
+  );
+
+  var regex0 = new RegExp(r"a.b");
+  var input0 = "acb";
+  var results = ["acb"];
+  shouldBe(regex0.firstMatch(input0), results);
+  var input1 = "a\x7fb";
+  results = ["a\u007fb"];
+  shouldBe(regex0.firstMatch(input1), results);
+  var input2 = "a\u0100b";
+  results = ["a\u0100b"];
+  shouldBe(regex0.firstMatch(input2), results);
+  // Failers
+  var input3 = "a\nb";
+  results = null;
+  shouldBe(regex0.firstMatch(input3), results);
+
+  var regex1 = new RegExp(r"a(.{3})b");
+  input0 = "a\u4000xyb";
+  results = ["a\u4000xyb", "\u4000xy"];
+  shouldBe(regex1.firstMatch(input0), results);
+  input1 = "a\u4000\x7fyb";
+  results = ["a\u4000\u007fyb", "\u4000\u007fy"];
+  shouldBe(regex1.firstMatch(input1), results);
+  input2 = "a\u4000\u0100yb";
+  results = ["a\u4000\u0100yb", "\u4000\u0100y"];
+  shouldBe(regex1.firstMatch(input2), results);
+  // Failers
+  input3 = "a\u4000b";
+  results = null;
+  shouldBe(regex1.firstMatch(input3), results);
+  var input4 = "ac\ncb";
+  results = null;
+  shouldBe(regex1.firstMatch(input4), results);
+
+  var regex2 = new RegExp(r"a(.*?)(.)");
+  input0 = "a\xc0\x88b";
+  results = ["a\xc0", "", "\xc0"];
+  shouldBe(regex2.firstMatch(input0), results);
+
+  var regex3 = new RegExp(r"a(.*?)(.)");
+  input0 = "a\u0100b";
+  results = ["a\u0100", "", "\u0100"];
+  shouldBe(regex3.firstMatch(input0), results);
+
+  var regex4 = new RegExp(r"a(.*)(.)");
+  input0 = "a\xc0\x88b";
+  results = ["a\xc0\x88b", "\xc0\x88", "b"];
+  shouldBe(regex4.firstMatch(input0), results);
+
+  var regex5 = new RegExp(r"a(.*)(.)");
+  input0 = "a\u0100b";
+  results = ["a\u0100b", "\u0100", "b"];
+  shouldBe(regex5.firstMatch(input0), results);
+
+  var regex6 = new RegExp(r"a(.)(.)");
+  input0 = "a\xc0\x92bcd";
+  results = ["a\xc0\x92", "\xc0", "\x92"];
+  shouldBe(regex6.firstMatch(input0), results);
+
+  var regex7 = new RegExp(r"a(.)(.)");
+  input0 = "a\u0240bcd";
+  results = ["a\u0240b", "\u0240", "b"];
+  shouldBe(regex7.firstMatch(input0), results);
+
+  var regex8 = new RegExp(r"a(.?)(.)");
+  input0 = "a\xc0\x92bcd";
+  results = ["a\xc0\x92", "\xc0", "\x92"];
+  shouldBe(regex8.firstMatch(input0), results);
+
+  var regex9 = new RegExp(r"a(.?)(.)");
+  input0 = "a\u0240bcd";
+  results = ["a\u0240b", "\u0240", "b"];
+  shouldBe(regex9.firstMatch(input0), results);
+
+  var regex10 = new RegExp(r"a(.??)(.)");
+  input0 = "a\xc0\x92bcd";
+  results = ["a\xc0", "", "\xc0"];
+  shouldBe(regex10.firstMatch(input0), results);
+
+  var regex11 = new RegExp(r"a(.??)(.)");
+  input0 = "a\u0240bcd";
+  results = ["a\u0240", "", "\u0240"];
+  shouldBe(regex11.firstMatch(input0), results);
+
+  var regex12 = new RegExp(r"a(.{3})b");
+  input0 = "a\u1234xyb";
+  results = ["a\u1234xyb", "\u1234xy"];
+  shouldBe(regex12.firstMatch(input0), results);
+  input1 = "a\u1234\u4321yb";
+  results = ["a\u1234\u4321yb", "\u1234\u4321y"];
+  shouldBe(regex12.firstMatch(input1), results);
+  input2 = "a\u1234\u4321\u3412b";
+  results = ["a\u1234\u4321\u3412b", "\u1234\u4321\u3412"];
+  shouldBe(regex12.firstMatch(input2), results);
+  // Failers
+  input3 = "a\u1234b";
+  results = null;
+  shouldBe(regex12.firstMatch(input3), results);
+  input4 = "ac\ncb";
+  results = null;
+  shouldBe(regex12.firstMatch(input4), results);
+
+  var regex13 = new RegExp(r"a(.{3,})b");
+  input0 = "a\u1234xyb";
+  results = ["a\u1234xyb", "\u1234xy"];
+  shouldBe(regex13.firstMatch(input0), results);
+  input1 = "a\u1234\u4321yb";
+  results = ["a\u1234\u4321yb", "\u1234\u4321y"];
+  shouldBe(regex13.firstMatch(input1), results);
+  input2 = "a\u1234\u4321\u3412b";
+  results = ["a\u1234\u4321\u3412b", "\u1234\u4321\u3412"];
+  shouldBe(regex13.firstMatch(input2), results);
+  input3 = "axxxxbcdefghijb";
+  results = ["axxxxbcdefghijb", "xxxxbcdefghij"];
+  shouldBe(regex13.firstMatch(input3), results);
+  input4 = "a\u1234\u4321\u3412\u3421b";
+  results = ["a\u1234\u4321\u3412\u3421b", "\u1234\u4321\u3412\u3421"];
+  shouldBe(regex13.firstMatch(input4), results);
+  // Failers
+  var input5 = "a\u1234b";
+  results = null;
+  shouldBe(regex13.firstMatch(input5), results);
+
+  var regex14 = new RegExp(r"a(.{3,}?)b");
+  input0 = "a\u1234xyb";
+  results = ["a\u1234xyb", "\u1234xy"];
+  shouldBe(regex14.firstMatch(input0), results);
+  input1 = "a\u1234\u4321yb";
+  results = ["a\u1234\u4321yb", "\u1234\u4321y"];
+  shouldBe(regex14.firstMatch(input1), results);
+  input2 = "a\u1234\u4321\u3412b";
+  results = ["a\u1234\u4321\u3412b", "\u1234\u4321\u3412"];
+  shouldBe(regex14.firstMatch(input2), results);
+  input3 = "axxxxbcdefghijb";
+  results = ["axxxxb", "xxxx"];
+  shouldBe(regex14.firstMatch(input3), results);
+  input4 = "a\u1234\u4321\u3412\u3421b";
+  results = ["a\u1234\u4321\u3412\u3421b", "\u1234\u4321\u3412\u3421"];
+  shouldBe(regex14.firstMatch(input4), results);
+  // Failers
+  input5 = "a\u1234b";
+  results = null;
+  shouldBe(regex14.firstMatch(input5), results);
+
+  var regex15 = new RegExp(r"a(.{3,5})b");
+  input0 = "a\u1234xyb";
+  results = ["a\u1234xyb", "\u1234xy"];
+  shouldBe(regex15.firstMatch(input0), results);
+  input1 = "a\u1234\u4321yb";
+  results = ["a\u1234\u4321yb", "\u1234\u4321y"];
+  shouldBe(regex15.firstMatch(input1), results);
+  input2 = "a\u1234\u4321\u3412b";
+  results = ["a\u1234\u4321\u3412b", "\u1234\u4321\u3412"];
+  shouldBe(regex15.firstMatch(input2), results);
+  input3 = "axxxxbcdefghijb";
+  results = ["axxxxb", "xxxx"];
+  shouldBe(regex15.firstMatch(input3), results);
+  input4 = "a\u1234\u4321\u3412\u3421b";
+  results = ["a\u1234\u4321\u3412\u3421b", "\u1234\u4321\u3412\u3421"];
+  shouldBe(regex15.firstMatch(input4), results);
+  input5 = "axbxxbcdefghijb";
+  results = ["axbxxb", "xbxx"];
+  shouldBe(regex15.firstMatch(input5), results);
+  var input6 = "axxxxxbcdefghijb";
+  results = ["axxxxxb", "xxxxx"];
+  shouldBe(regex15.firstMatch(input6), results);
+  // Failers
+  var input7 = "a\u1234b";
+  results = null;
+  shouldBe(regex15.firstMatch(input7), results);
+  var input8 = "axxxxxxbcdefghijb";
+  results = null;
+  shouldBe(regex15.firstMatch(input8), results);
+
+  var regex16 = new RegExp(r"a(.{3,5}?)b");
+  input0 = "a\u1234xyb";
+  results = ["a\u1234xyb", "\u1234xy"];
+  shouldBe(regex16.firstMatch(input0), results);
+  input1 = "a\u1234\u4321yb";
+  results = ["a\u1234\u4321yb", "\u1234\u4321y"];
+  shouldBe(regex16.firstMatch(input1), results);
+  input2 = "a\u1234\u4321\u3412b";
+  results = ["a\u1234\u4321\u3412b", "\u1234\u4321\u3412"];
+  shouldBe(regex16.firstMatch(input2), results);
+  input3 = "axxxxbcdefghijb";
+  results = ["axxxxb", "xxxx"];
+  shouldBe(regex16.firstMatch(input3), results);
+  input4 = "a\u1234\u4321\u3412\u3421b";
+  results = ["a\u1234\u4321\u3412\u3421b", "\u1234\u4321\u3412\u3421"];
+  shouldBe(regex16.firstMatch(input4), results);
+  input5 = "axbxxbcdefghijb";
+  results = ["axbxxb", "xbxx"];
+  shouldBe(regex16.firstMatch(input5), results);
+  input6 = "axxxxxbcdefghijb";
+  results = ["axxxxxb", "xxxxx"];
+  shouldBe(regex16.firstMatch(input6), results);
+  // Failers
+  input7 = "a\u1234b";
+  results = null;
+  shouldBe(regex16.firstMatch(input7), results);
+  input8 = "axxxxxxbcdefghijb";
+  results = null;
+  shouldBe(regex16.firstMatch(input8), results);
+
+  var regex17 = new RegExp(r"^[a\u00c0]");
+  // Failers
+  input0 = "\u0100";
+  results = null;
+  shouldBe(regex17.firstMatch(input0), results);
+
+  var regex21 = new RegExp(r"(?:\u0100){3}b");
+  input0 = "\u0100\u0100\u0100b";
+  results = ["\u0100\u0100\u0100b"];
+  shouldBe(regex21.firstMatch(input0), results);
+  // Failers
+  input1 = "\u0100\u0100b";
+  results = null;
+  shouldBe(regex21.firstMatch(input1), results);
+
+  var regex22 = new RegExp(r"\u00ab");
+  input0 = "\u00ab";
+  results = ["\u00ab"];
+  shouldBe(regex22.firstMatch(input0), results);
+  input1 = "\xc2\xab";
+  results = ["\u00ab"];
+  shouldBe(regex22.firstMatch(input1), results);
+  // Failers
+  input2 = "\x00{ab}";
+  results = null;
+  shouldBe(regex22.firstMatch(input2), results);
+
+  var regex30 = new RegExp(r"^[^a]{2}");
+  input0 = "\u0100bc";
+  results = ["\u0100b"];
+  shouldBe(regex30.firstMatch(input0), results);
+
+  var regex31 = new RegExp(r"^[^a]{2,}");
+  input0 = "\u0100bcAa";
+  results = ["\u0100bcA"];
+  shouldBe(regex31.firstMatch(input0), results);
+
+  var regex32 = new RegExp(r"^[^a]{2,}?");
+  input0 = "\u0100bca";
+  results = ["\u0100b"];
+  shouldBe(regex32.firstMatch(input0), results);
+
+  var regex33 = new RegExp(r"^[^a]{2}", caseSensitive: false);
+  input0 = "\u0100bc";
+  results = ["\u0100b"];
+  shouldBe(regex33.firstMatch(input0), results);
+
+  var regex34 = new RegExp(r"^[^a]{2,}", caseSensitive: false);
+  input0 = "\u0100bcAa";
+  results = ["\u0100bc"];
+  shouldBe(regex34.firstMatch(input0), results);
+
+  var regex35 = new RegExp(r"^[^a]{2,}?", caseSensitive: false);
+  input0 = "\u0100bca";
+  results = ["\u0100b"];
+  shouldBe(regex35.firstMatch(input0), results);
+
+  var regex36 = new RegExp(r"\u0100{0,0}");
+  input0 = "abcd";
+  results = [""];
+  shouldBe(regex36.firstMatch(input0), results);
+
+  var regex37 = new RegExp(r"\u0100?");
+  input0 = "abcd";
+  results = [""];
+  shouldBe(regex37.firstMatch(input0), results);
+  input1 = "\u0100\u0100";
+  results = ["\u0100"];
+  shouldBe(regex37.firstMatch(input1), results);
+
+  var regex38 = new RegExp(r"\u0100{0,3}");
+  input0 = "\u0100\u0100";
+  results = ["\u0100\u0100"];
+  shouldBe(regex38.firstMatch(input0), results);
+  input1 = "\u0100\u0100\u0100\u0100";
+  results = ["\u0100\u0100\u0100"];
+  shouldBe(regex38.firstMatch(input1), results);
+
+  var regex39 = new RegExp(r"\u0100*");
+  input0 = "abce";
+  results = [""];
+  shouldBe(regex39.firstMatch(input0), results);
+  input1 = "\u0100\u0100\u0100\u0100";
+  results = ["\u0100\u0100\u0100\u0100"];
+  shouldBe(regex39.firstMatch(input1), results);
+
+  var regex40 = new RegExp(r"\u0100{1,1}");
+  input0 = "abcd\u0100\u0100\u0100\u0100";
+  results = ["\u0100"];
+  shouldBe(regex40.firstMatch(input0), results);
+
+  var regex41 = new RegExp(r"\u0100{1,3}");
+  input0 = "abcd\u0100\u0100\u0100\u0100";
+  results = ["\u0100\u0100\u0100"];
+  shouldBe(regex41.firstMatch(input0), results);
+
+  var regex42 = new RegExp(r"\u0100+");
+  input0 = "abcd\u0100\u0100\u0100\u0100";
+  results = ["\u0100\u0100\u0100\u0100"];
+  shouldBe(regex42.firstMatch(input0), results);
+
+  var regex43 = new RegExp(r"\u0100{3}");
+  input0 = "abcd\u0100\u0100\u0100XX";
+  results = ["\u0100\u0100\u0100"];
+  shouldBe(regex43.firstMatch(input0), results);
+
+  var regex44 = new RegExp(r"\u0100{3,5}");
+  input0 = "abcd\u0100\u0100\u0100\u0100\u0100\u0100\u0100XX";
+  results = ["\u0100\u0100\u0100\u0100\u0100"];
+  shouldBe(regex44.firstMatch(input0), results);
+
+  var regex45 = new RegExp(r"\u0100{3,}");
+  input0 = "abcd\u0100\u0100\u0100\u0100\u0100\u0100\u0100XX";
+  results = ["\u0100\u0100\u0100\u0100\u0100\u0100\u0100"];
+  shouldBe(regex45.firstMatch(input0), results);
+
+  var regex47 = new RegExp(r"\D*");
+  input0 = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
+  results = ["aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"];
+  shouldBe(regex47.firstMatch(input0), results);
+
+  var regex48 = new RegExp(r"\D*");
+  input0 = "\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100";
+  results = ["\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100\u0100"];
+  shouldBe(regex48.firstMatch(input0), results);
+
+  var regex49 = new RegExp(r"\D");
+  input0 = "1X2";
+  results = ["X"];
+  shouldBe(regex49.firstMatch(input0), results);
+  input1 = "1\u01002";
+  results = ["\u0100"];
+  shouldBe(regex49.firstMatch(input1), results);
+
+  var regex50 = new RegExp(r">\S");
+  input0 = "> >X Y";
+  results = [">X"];
+  shouldBe(regex50.firstMatch(input0), results);
+  input1 = "> >\u0100 Y";
+  results = [">\u0100"];
+  shouldBe(regex50.firstMatch(input1), results);
+
+  var regex51 = new RegExp(r"\d");
+  input0 = "\u01003";
+  results = ["3"];
+  shouldBe(regex51.firstMatch(input0), results);
+
+  var regex52 = new RegExp(r"\s");
+  input0 = "\u0100 X";
+  results = [" "];
+  shouldBe(regex52.firstMatch(input0), results);
+
+  var regex53 = new RegExp(r"\D+");
+  input0 = "12abcd34";
+  results = ["abcd"];
+  shouldBe(regex53.firstMatch(input0), results);
+  // Failers
+  input1 = "1234";
+  results = null;
+  shouldBe(regex53.firstMatch(input1), results);
+
+  var regex54 = new RegExp(r"\D{2,3}");
+  input0 = "12abcd34";
+  results = ["abc"];
+  shouldBe(regex54.firstMatch(input0), results);
+  input1 = "12ab34";
+  results = ["ab"];
+  shouldBe(regex54.firstMatch(input1), results);
+  // Failers
+  input2 = "1234";
+  results = null;
+  shouldBe(regex54.firstMatch(input2), results);
+  input3 = "12a34";
+  results = null;
+  shouldBe(regex54.firstMatch(input3), results);
+
+  var regex55 = new RegExp(r"\D{2,3}?");
+  input0 = "12abcd34";
+  results = ["ab"];
+  shouldBe(regex55.firstMatch(input0), results);
+  input1 = "12ab34";
+  results = ["ab"];
+  shouldBe(regex55.firstMatch(input1), results);
+  // Failers
+  input2 = "1234";
+  results = null;
+  shouldBe(regex55.firstMatch(input2), results);
+  input3 = "12a34";
+  results = null;
+  shouldBe(regex55.firstMatch(input3), results);
+
+  var regex56 = new RegExp(r"\d+");
+  input0 = "12abcd34";
+  results = ["12"];
+  shouldBe(regex56.firstMatch(input0), results);
+
+  var regex57 = new RegExp(r"\d{2,3}");
+  input0 = "12abcd34";
+  results = ["12"];
+  shouldBe(regex57.firstMatch(input0), results);
+  input1 = "1234abcd";
+  results = ["123"];
+  shouldBe(regex57.firstMatch(input1), results);
+  // Failers
+  input2 = "1.4";
+  results = null;
+  shouldBe(regex57.firstMatch(input2), results);
+
+  var regex58 = new RegExp(r"\d{2,3}?");
+  input0 = "12abcd34";
+  results = ["12"];
+  shouldBe(regex58.firstMatch(input0), results);
+  input1 = "1234abcd";
+  results = ["12"];
+  shouldBe(regex58.firstMatch(input1), results);
+  // Failers
+  input2 = "1.4";
+  results = null;
+  shouldBe(regex58.firstMatch(input2), results);
+
+  var regex59 = new RegExp(r"\S+");
+  input0 = "12abcd34";
+  results = ["12abcd34"];
+  shouldBe(regex59.firstMatch(input0), results);
+  // Failers
+  input1 = "    ";
+  results = null;
+  shouldBe(regex59.firstMatch(input1), results);
+
+  var regex60 = new RegExp(r"\S{2,3}");
+  input0 = "12abcd34";
+  results = ["12a"];
+  shouldBe(regex60.firstMatch(input0), results);
+  input1 = "1234abcd";
+  results = ["123"];
+  shouldBe(regex60.firstMatch(input1), results);
+  // Failers
+  input2 = "    ";
+  results = null;
+  shouldBe(regex60.firstMatch(input2), results);
+
+  var regex61 = new RegExp(r"\S{2,3}?");
+  input0 = "12abcd34";
+  results = ["12"];
+  shouldBe(regex61.firstMatch(input0), results);
+  input1 = "1234abcd";
+  results = ["12"];
+  shouldBe(regex61.firstMatch(input1), results);
+  // Failers
+  input2 = "    ";
+  results = null;
+  shouldBe(regex61.firstMatch(input2), results);
+
+  var regex62 = new RegExp(r">\s+<");
+  input0 = "12>      <34";
+  results = [">      <"];
+  shouldBe(regex62.firstMatch(input0), results);
+
+  var regex63 = new RegExp(r">\s{2,3}<");
+  input0 = "ab>  <cd";
+  results = [">  <"];
+  shouldBe(regex63.firstMatch(input0), results);
+  input1 = "ab>   <ce";
+  results = [">   <"];
+  shouldBe(regex63.firstMatch(input1), results);
+  // Failers
+  input2 = "ab>    <cd";
+  results = null;
+  shouldBe(regex63.firstMatch(input2), results);
+
+  var regex64 = new RegExp(r">\s{2,3}?<");
+  input0 = "ab>  <cd";
+  results = [">  <"];
+  shouldBe(regex64.firstMatch(input0), results);
+  input1 = "ab>   <ce";
+  results = [">   <"];
+  shouldBe(regex64.firstMatch(input1), results);
+  // Failers
+  input2 = "ab>    <cd";
+  results = null;
+  shouldBe(regex64.firstMatch(input2), results);
+
+  var regex65 = new RegExp(r"\w+");
+  input0 = "12      34";
+  results = ["12"];
+  shouldBe(regex65.firstMatch(input0), results);
+  // Failers
+  input1 = "+++=*!";
+  results = null;
+  shouldBe(regex65.firstMatch(input1), results);
+
+  var regex66 = new RegExp(r"\w{2,3}");
+  input0 = "ab  cd";
+  results = ["ab"];
+  shouldBe(regex66.firstMatch(input0), results);
+  input1 = "abcd ce";
+  results = ["abc"];
+  shouldBe(regex66.firstMatch(input1), results);
+  // Failers
+  input2 = "a.b.c";
+  results = null;
+  shouldBe(regex66.firstMatch(input2), results);
+
+  var regex67 = new RegExp(r"\w{2,3}?");
+  input0 = "ab  cd";
+  results = ["ab"];
+  shouldBe(regex67.firstMatch(input0), results);
+  input1 = "abcd ce";
+  results = ["ab"];
+  shouldBe(regex67.firstMatch(input1), results);
+  // Failers
+  input2 = "a.b.c";
+  results = null;
+  shouldBe(regex67.firstMatch(input2), results);
+
+  var regex68 = new RegExp(r"\W+");
+  input0 = "12====34";
+  results = ["===="];
+  shouldBe(regex68.firstMatch(input0), results);
+  // Failers
+  input1 = "abcd";
+  results = null;
+  shouldBe(regex68.firstMatch(input1), results);
+
+  var regex69 = new RegExp(r"\W{2,3}");
+  input0 = "ab====cd";
+  results = ["==="];
+  shouldBe(regex69.firstMatch(input0), results);
+  input1 = "ab==cd";
+  results = ["=="];
+  shouldBe(regex69.firstMatch(input1), results);
+  // Failers
+  input2 = "a.b.c";
+  results = null;
+  shouldBe(regex69.firstMatch(input2), results);
+
+  var regex70 = new RegExp(r"\W{2,3}?");
+  input0 = "ab====cd";
+  results = ["=="];
+  shouldBe(regex70.firstMatch(input0), results);
+  input1 = "ab==cd";
+  results = ["=="];
+  shouldBe(regex70.firstMatch(input1), results);
+  // Failers
+  input2 = "a.b.c";
+  results = null;
+  shouldBe(regex70.firstMatch(input2), results);
+
+  var regex71 = new RegExp(r"[\u0100]");
+  input0 = "\u0100";
+  results = ["\u0100"];
+  shouldBe(regex71.firstMatch(input0), results);
+  input1 = "Z\u0100";
+  results = ["\u0100"];
+  shouldBe(regex71.firstMatch(input1), results);
+  input2 = "\u0100Z";
+  results = ["\u0100"];
+  shouldBe(regex71.firstMatch(input2), results);
+
+  var regex72 = new RegExp(r"[Z\u0100]");
+  input0 = "Z\u0100";
+  results = ["Z"];
+  shouldBe(regex72.firstMatch(input0), results);
+  input1 = "\u0100";
+  results = ["\u0100"];
+  shouldBe(regex72.firstMatch(input1), results);
+  input2 = "\u0100Z";
+  results = ["\u0100"];
+  shouldBe(regex72.firstMatch(input2), results);
+
+  var regex73 = new RegExp(r"[\u0100\u0200]");
+  input0 = "ab\u0100cd";
+  results = ["\u0100"];
+  shouldBe(regex73.firstMatch(input0), results);
+  input1 = "ab\u0200cd";
+  results = ["\u0200"];
+  shouldBe(regex73.firstMatch(input1), results);
+
+  var regex74 = new RegExp(r"[\u0100-\u0200]");
+  input0 = "ab\u0100cd";
+  results = ["\u0100"];
+  shouldBe(regex74.firstMatch(input0), results);
+  input1 = "ab\u0200cd";
+  results = ["\u0200"];
+  shouldBe(regex74.firstMatch(input1), results);
+  input2 = "ab\u0111cd";
+  results = ["\u0111"];
+  shouldBe(regex74.firstMatch(input2), results);
+
+  var regex75 = new RegExp(r"[z-\u0200]");
+  input0 = "ab\u0100cd";
+  results = ["\u0100"];
+  shouldBe(regex75.firstMatch(input0), results);
+  input1 = "ab\u0200cd";
+  results = ["\u0200"];
+  shouldBe(regex75.firstMatch(input1), results);
+  input2 = "ab\u0111cd";
+  results = ["\u0111"];
+  shouldBe(regex75.firstMatch(input2), results);
+  input3 = "abzcd";
+  results = ["z"];
+  shouldBe(regex75.firstMatch(input3), results);
+  input4 = "ab|cd";
+  results = ["|"];
+  shouldBe(regex75.firstMatch(input4), results);
+
+  var regex76 = new RegExp(r"[Q\u0100\u0200]");
+  input0 = "ab\u0100cd";
+  results = ["\u0100"];
+  shouldBe(regex76.firstMatch(input0), results);
+  input1 = "ab\u0200cd";
+  results = ["\u0200"];
+  shouldBe(regex76.firstMatch(input1), results);
+  input2 = "Q?";
+  results = ["Q"];
+  shouldBe(regex76.firstMatch(input2), results);
+
+  var regex77 = new RegExp(r"[Q\u0100-\u0200]");
+  input0 = "ab\u0100cd";
+  results = ["\u0100"];
+  shouldBe(regex77.firstMatch(input0), results);
+  input1 = "ab\u0200cd";
+  results = ["\u0200"];
+  shouldBe(regex77.firstMatch(input1), results);
+  input2 = "ab\u0111cd";
+  results = ["\u0111"];
+  shouldBe(regex77.firstMatch(input2), results);
+  input3 = "Q?";
+  results = ["Q"];
+  shouldBe(regex77.firstMatch(input3), results);
+
+  var regex78 = new RegExp(r"[Qz-\u0200]");
+  input0 = "ab\u0100cd";
+  results = ["\u0100"];
+  shouldBe(regex78.firstMatch(input0), results);
+  input1 = "ab\u0200cd";
+  results = ["\u0200"];
+  shouldBe(regex78.firstMatch(input1), results);
+  input2 = "ab\u0111cd";
+  results = ["\u0111"];
+  shouldBe(regex78.firstMatch(input2), results);
+  input3 = "abzcd";
+  results = ["z"];
+  shouldBe(regex78.firstMatch(input3), results);
+  input4 = "ab|cd";
+  results = ["|"];
+  shouldBe(regex78.firstMatch(input4), results);
+  input5 = "Q?";
+  results = ["Q"];
+  shouldBe(regex78.firstMatch(input5), results);
+
+  var regex79 = new RegExp(r"[\u0100\u0200]{1,3}");
+  input0 = "ab\u0100cd";
+  results = ["\u0100"];
+  shouldBe(regex79.firstMatch(input0), results);
+  input1 = "ab\u0200cd";
+  results = ["\u0200"];
+  shouldBe(regex79.firstMatch(input1), results);
+  input2 = "ab\u0200\u0100\u0200\u0100cd";
+  results = ["\u0200\u0100\u0200"];
+  shouldBe(regex79.firstMatch(input2), results);
+
+  var regex80 = new RegExp(r"[\u0100\u0200]{1,3}?");
+  input0 = "ab\u0100cd";
+  results = ["\u0100"];
+  shouldBe(regex80.firstMatch(input0), results);
+  input1 = "ab\u0200cd";
+  results = ["\u0200"];
+  shouldBe(regex80.firstMatch(input1), results);
+  input2 = "ab\u0200\u0100\u0200\u0100cd";
+  results = ["\u0200"];
+  shouldBe(regex80.firstMatch(input2), results);
+
+  var regex81 = new RegExp(r"[Q\u0100\u0200]{1,3}");
+  input0 = "ab\u0100cd";
+  results = ["\u0100"];
+  shouldBe(regex81.firstMatch(input0), results);
+  input1 = "ab\u0200cd";
+  results = ["\u0200"];
+  shouldBe(regex81.firstMatch(input1), results);
+  input2 = "ab\u0200\u0100\u0200\u0100cd";
+  results = ["\u0200\u0100\u0200"];
+  shouldBe(regex81.firstMatch(input2), results);
+
+  var regex82 = new RegExp(r"[Q\u0100\u0200]{1,3}?");
+  input0 = "ab\u0100cd";
+  results = ["\u0100"];
+  shouldBe(regex82.firstMatch(input0), results);
+  input1 = "ab\u0200cd";
+  results = ["\u0200"];
+  shouldBe(regex82.firstMatch(input1), results);
+  input2 = "ab\u0200\u0100\u0200\u0100cd";
+  results = ["\u0200"];
+  shouldBe(regex82.firstMatch(input2), results);
+
+  var regex86 = new RegExp(r"[^\u0100\u0200]X");
+  input0 = "AX";
+  results = ["AX"];
+  shouldBe(regex86.firstMatch(input0), results);
+  input1 = "\u0150X";
+  results = ["\u0150X"];
+  shouldBe(regex86.firstMatch(input1), results);
+  input2 = "\u0500X";
+  results = ["\u0500X"];
+  shouldBe(regex86.firstMatch(input2), results);
+  // Failers
+  input3 = "\u0100X";
+  results = null;
+  shouldBe(regex86.firstMatch(input3), results);
+  input4 = "\u0200X";
+  results = null;
+  shouldBe(regex86.firstMatch(input4), results);
+
+  var regex87 = new RegExp(r"[^Q\u0100\u0200]X");
+  input0 = "AX";
+  results = ["AX"];
+  shouldBe(regex87.firstMatch(input0), results);
+  input1 = "\u0150X";
+  results = ["\u0150X"];
+  shouldBe(regex87.firstMatch(input1), results);
+  input2 = "\u0500X";
+  results = ["\u0500X"];
+  shouldBe(regex87.firstMatch(input2), results);
+  // Failers
+  input3 = "\u0100X";
+  results = null;
+  shouldBe(regex87.firstMatch(input3), results);
+  input4 = "\u0200X";
+  results = null;
+  shouldBe(regex87.firstMatch(input4), results);
+  input5 = "QX";
+  results = null;
+  shouldBe(regex87.firstMatch(input5), results);
+
+  var regex88 = new RegExp(r"[^\u0100-\u0200]X");
+  input0 = "AX";
+  results = ["AX"];
+  shouldBe(regex88.firstMatch(input0), results);
+  input1 = "\u0500X";
+  results = ["\u0500X"];
+  shouldBe(regex88.firstMatch(input1), results);
+  // Failers
+  input2 = "\u0100X";
+  results = null;
+  shouldBe(regex88.firstMatch(input2), results);
+  input3 = "\u0150X";
+  results = null;
+  shouldBe(regex88.firstMatch(input3), results);
+  input4 = "\u0200X";
+  results = null;
+  shouldBe(regex88.firstMatch(input4), results);
+
+  var regex91 = new RegExp(r"[z-\u0100]", caseSensitive: false);
+  input0 = "z";
+  results = ["z"];
+  shouldBe(regex91.firstMatch(input0), results);
+  input1 = "Z";
+  results = ["Z"];
+  shouldBe(regex91.firstMatch(input1), results);
+  input2 = "\u0100";
+  results = ["\u0100"];
+  shouldBe(regex91.firstMatch(input2), results);
+  // Failers
+  input3 = "\u0102";
+  results = null;
+  shouldBe(regex91.firstMatch(input3), results);
+  input4 = "y";
+  results = null;
+  shouldBe(regex91.firstMatch(input4), results);
+
+  var regex92 = new RegExp(r"[\xFF]");
+  input0 = ">\xff<";
+  results = ["\xff"];
+  shouldBe(regex92.firstMatch(input0), results);
+
+  var regex93 = new RegExp(r"[\xff]");
+  input0 = ">\u00ff<";
+  results = ["\u00ff"];
+  shouldBe(regex93.firstMatch(input0), results);
+
+  var regex94 = new RegExp(r"[^\xFF]");
+  input0 = "XYZ";
+  results = ["X"];
+  shouldBe(regex94.firstMatch(input0), results);
+
+  var regex95 = new RegExp(r"[^\xff]");
+  input0 = "XYZ";
+  results = ["X"];
+  shouldBe(regex95.firstMatch(input0), results);
+  input1 = "\u0123";
+  results = ["\u0123"];
+  shouldBe(regex95.firstMatch(input1), results);
+
+  var regex96 = new RegExp(r"^[ac]*b");
+  input0 = "xb";
+  results = null;
+  shouldBe(regex96.firstMatch(input0), results);
+
+  var regex97 = new RegExp(r"^[ac\u0100]*b");
+  input0 = "xb";
+  results = null;
+  shouldBe(regex97.firstMatch(input0), results);
+
+  var regex98 = new RegExp(r"^[^x]*b", caseSensitive: false);
+  input0 = "xb";
+  results = null;
+  shouldBe(regex98.firstMatch(input0), results);
+
+  var regex99 = new RegExp(r"^[^x]*b");
+  input0 = "xb";
+  results = null;
+  shouldBe(regex99.firstMatch(input0), results);
+
+  var regex100 = new RegExp(r"^\d*b");
+  input0 = "xb";
+  results = null;
+  shouldBe(regex100.firstMatch(input0), results);
+
+  var regex102 = new RegExp(r"^\u0085$", caseSensitive: false);
+  input0 = "\u0085";
+  results = ["\u0085"];
+  shouldBe(regex102.firstMatch(input0), results);
+
+  var regex103 = new RegExp(r"^\xe1\x88\xb4");
+  input0 = "\xe1\x88\xb4";
+  results = ["\xe1\x88\xb4"];
+  shouldBe(regex103.firstMatch(input0), results);
+
+  var regex104 = new RegExp(r"^\xe1\x88\xb4");
+  input0 = "\xe1\x88\xb4";
+  results = ["\xe1\x88\xb4"];
+  shouldBe(regex104.firstMatch(input0), results);
+
+  var regex105 = new RegExp(r"(.{1,5})");
+  input0 = "abcdefg";
+  results = ["abcde", "abcde"];
+  shouldBe(regex105.firstMatch(input0), results);
+  input1 = "ab";
+  results = ["ab", "ab"];
+  shouldBe(regex105.firstMatch(input1), results);
+
+  var regex106 = new RegExp(r"a*\u0100*\w");
+  input0 = "a";
+  results = ["a"];
+  shouldBe(regex106.firstMatch(input0), results);
+
+  var regex107 = new RegExp(r"[\S\s]*");
+  input0 = "abc\n\r\u0442\u0435\u0441\u0442xyz";
+  results = ["abc\u000a\u000d\u0442\u0435\u0441\u0442xyz"];
+  shouldBe(regex107.firstMatch(input0), results);
+
+  var regexGlobal0 = new RegExp(r"[^a]+");
+  input0 = "bcd";
+  results = ["bcd"];
+  shouldBe(firstMatch(input0, regexGlobal0), results);
+  input1 = "\u0100aY\u0256Z";
+  results = ["\u0100", "Y\u0256Z"];
+  Expect.listEquals(regexGlobal0.allMatches(input1)
+                      .map((m) => m.group(0)).toList(),
+                    results);
+
+  var regexGlobal1 = new RegExp(r"\S\S");
+  input0 = "A\u00a3BC";
+  results = ["A\u00a3", "BC"];
+  Expect.listEquals(allStringMatches(input0, regexGlobal1), results);
+
+  var regexGlobal2 = new RegExp(r"\S{2}");
+  input0 = "A\u00a3BC";
+  results = ["A\u00a3", "BC"];
+  Expect.listEquals(allStringMatches(input0, regexGlobal2), results);
+
+  var regexGlobal3 = new RegExp(r"\W\W");
+  input0 = "+\u00a3==";
+  results = ["+\u00a3", "=="];
+  Expect.listEquals(allStringMatches(input0, regexGlobal3), results);
+
+  var regexGlobal4 = new RegExp(r"\W{2}");
+  input0 = "+\u00a3==";
+  results = ["+\u00a3", "=="];
+  Expect.listEquals(allStringMatches(input0, regexGlobal4), results);
+
+  var regexGlobal5 = new RegExp(r"\S");
+  input0 = "\u0442\u0435\u0441\u0442";
+  results = ["\u0442", "\u0435", "\u0441", "\u0442"];
+  Expect.listEquals(allStringMatches(input0, regexGlobal5), results);
+
+  var regexGlobal6 = new RegExp(r"[\S]");
+  input0 = "\u0442\u0435\u0441\u0442";
+  results = ["\u0442", "\u0435", "\u0441", "\u0442"];
+  Expect.listEquals(allStringMatches(input0, regexGlobal6), results);
+
+  var regexGlobal7 = new RegExp(r"\D");
+  input0 = "\u0442\u0435\u0441\u0442";
+  results = ["\u0442", "\u0435", "\u0441", "\u0442"];
+  Expect.listEquals(allStringMatches(input0, regexGlobal7), results);
+
+  var regexGlobal8 = new RegExp(r"[\D]");
+  input0 = "\u0442\u0435\u0441\u0442";
+  results = ["\u0442", "\u0435", "\u0441", "\u0442"];
+  Expect.listEquals(allStringMatches(input0, regexGlobal8), results);
+
+  var regexGlobal9 = new RegExp(r"\W");
+  input0 = "\u2442\u2435\u2441\u2442";
+  results = ["\u2442", "\u2435", "\u2441", "\u2442"];
+  Expect.listEquals(allStringMatches(input0, regexGlobal9), results);
+
+  var regexGlobal10 = new RegExp(r"[\W]");
+  input0 = "\u2442\u2435\u2441\u2442";
+  results = ["\u2442", "\u2435", "\u2441", "\u2442"];
+  Expect.listEquals(allStringMatches(input0, regexGlobal10), results);
+
+  var regexGlobal11 = new RegExp(r"[\u041f\S]");
+  input0 = "\u0442\u0435\u0441\u0442";
+  results = ["\u0442", "\u0435", "\u0441", "\u0442"];
+  Expect.listEquals(allStringMatches(input0, regexGlobal11), results);
+
+  var regexGlobal12 = new RegExp(r".[^\S].");
+  input0 = "abc def\u0442\u0443xyz\npqr";
+  results = ["c d", "z\u000ap"];
+  Expect.listEquals(allStringMatches(input0, regexGlobal12), results);
+
+  var regexGlobal13 = new RegExp(r".[^\S\n].");
+  input0 = "abc def\u0442\u0443xyz\npqr";
+  results = ["c d"];
+  Expect.listEquals(allStringMatches(input0, regexGlobal13), results);
+
+  var regexGlobal14 = new RegExp(r"[\W]");
+  input0 = "+\u2442";
+  results = ["+", "\u2442"];
+  Expect.listEquals(allStringMatches(input0, regexGlobal14), results);
+
+  var regexGlobal15 = new RegExp(r"[^a-zA-Z]");
+  input0 = "+\u2442";
+  results = ["+", "\u2442"];
+  Expect.listEquals(allStringMatches(input0, regexGlobal15), results);
+
+  var regexGlobal16 = new RegExp(r"[^a-zA-Z]");
+  input0 = "A\u0442";
+  results = ["\u0442"];
+  Expect.listEquals(allStringMatches(input0, regexGlobal16), results);
+
+  var regexGlobal17 = new RegExp(r"[\S]");
+  input0 = "A\u0442";
+  results = ["A", "\u0442"];
+  Expect.listEquals(allStringMatches(input0, regexGlobal17), results);
+
+  var regexGlobal19 = new RegExp(r"[\D]");
+  input0 = "A\u0442";
+  results = ["A", "\u0442"];
+  Expect.listEquals(allStringMatches(input0, regexGlobal19), results);
+
+  var regexGlobal21 = new RegExp(r"[^a-z]");
+  input0 = "A\u0422";
+  results = ["A", "\u0422"];
+  Expect.listEquals(allStringMatches(input0, regexGlobal21), results);
+
+  var regexGlobal24 = new RegExp(r"[\S]");
+  input0 = "A\u0442";
+  results = ["A", "\u0442"];
+  Expect.listEquals(allStringMatches(input0, regexGlobal24), results);
+
+  var regexGlobal25 = new RegExp(r"[^A-Z]");
+  input0 = "a\u0442";
+  results = ["a", "\u0442"];
+  Expect.listEquals(allStringMatches(input0, regexGlobal25), results);
+
+  var regexGlobal26 = new RegExp(r"[\W]");
+  input0 = "+\u2442";
+  results = ["+", "\u2442"];
+  Expect.listEquals(allStringMatches(input0, regexGlobal26), results);
+
+  var regexGlobal27 = new RegExp(r"[\D]");
+  input0 = "M\u0442";
+  results = ["M", "\u0442"];
+  Expect.listEquals(allStringMatches(input0, regexGlobal27), results);
+
+  var regexGlobal28 = new RegExp(r"[^a]+", caseSensitive: false);
+  input0 = "bcd";
+  results = ["bcd"];
+  Expect.listEquals(allStringMatches(input0, regexGlobal28), results);
+  input1 = "\u0100aY\u0256Z";
+  results = ["\u0100", "Y\u0256Z"];
+  Expect.listEquals(allStringMatches(input1, regexGlobal28), results);
+
+  var regexGlobal29 = new RegExp(r"(a|)");
+  input0 = "catac";
+  results = ["", "a", "", "a", "", ""];
+  Expect.listEquals(allStringMatches(input0, regexGlobal29), results);
+  input1 = "a\u0256a";
+  results = ["a", "", "a", ""];
+  Expect.listEquals(allStringMatches(input1, regexGlobal29), results);
+}
diff --git a/tests/corelib/regexp/pcre_test.dart b/tests/corelib/regexp/pcre_test.dart
new file mode 100644
index 0000000..a8b6206
--- /dev/null
+++ b/tests/corelib/regexp/pcre_test.dart
@@ -0,0 +1,6599 @@
+// Copyright (c) 2014, the Dart project authors. All rights reserved.
+// Autogenerated from the PCRE test suite Mon Feb  2 15:14:04 CET 2009
+
+// Note that some regexps in the PCRE test suite use features not present
+// in JavaScript.  These don't work in JS, but they fail to work in a
+// predictable way, and the expected results reflect this.
+
+// PCRE comes with the following license
+
+// PCRE LICENCE
+// ------------
+//
+// PCRE is a library of functions to support regular expressions whose syntax
+// and semantics are as close as possible to those of the Perl 5 language.
+//
+// Release 7 of PCRE is distributed under the terms of the "BSD" licence, as
+// specified below. The documentation for PCRE, supplied in the "doc"
+// directory, is distributed under the same terms as the software itself.
+//
+// The basic library functions are written in C and are freestanding. Also
+// included in the distribution is a set of C++ wrapper functions.
+//
+//
+// THE BASIC LIBRARY FUNCTIONS
+// ---------------------------
+//
+// Written by:       Philip Hazel
+// Email local part: ph10
+// Email domain:     cam.ac.uk
+//
+// University of Cambridge Computing Service,
+// Cambridge, England.
+//
+// Copyright (c) 1997-2007 University of Cambridge
+// All rights reserved.
+//
+//
+// THE C++ WRAPPER FUNCTIONS
+// -------------------------
+//
+// Contributed by:   Google Inc.
+//
+// Copyright (c) 2007, Google Inc.
+// All rights reserved.
+//
+//
+// THE "BSD" LICENCE
+// -----------------
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+//     * Redistributions of source code must retain the above copyright notice,
+//       this list of conditions and the following disclaimer.
+//
+//     * Redistributions in binary form must reproduce the above copyright
+//       notice, this list of conditions and the following disclaimer in the
+//       documentation and/or other materials provided with the distribution.
+//
+//     * Neither the name of the University of Cambridge nor the name of Google
+//       Inc. nor the names of their contributors may be used to endorse or
+//       promote products derived from this software without specific prior
+//       written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+// POSSIBILITY OF SUCH DAMAGE.
+//
+// End
+
+import 'v8_regexp_utils.dart';
+import 'package:expect/expect.dart';
+
+void main() {
+  var res = <RegExp>[];
+  res.add(new RegExp(r"(a)b|", caseSensitive: false));
+  res.add(new RegExp(r"abc", caseSensitive: false));
+  res.add(new RegExp(r"^abc", caseSensitive: false));
+  res.add(new RegExp(r"a+bc", caseSensitive: false));
+  res.add(new RegExp(r"a*bc", caseSensitive: false));
+  res.add(new RegExp(r"a{3}bc", caseSensitive: false));
+  res.add(new RegExp(r"(abc|a+z)", caseSensitive: false));
+  res.add(new RegExp(r"^abc$", caseSensitive: false));
+  res.add(new RegExp(r"ab\idef"));
+  res.add(new RegExp(r".*b", caseSensitive: false));
+  res.add(new RegExp(r".*?b", caseSensitive: false));
+  res.add(new RegExp(r"cat|dog|elephant", caseSensitive: false));
+  res.add(new RegExp(r"cat|dog|elephant", caseSensitive: false));
+  res.add(new RegExp(r"cat|dog|elephant", caseSensitive: false));
+  res.add(new RegExp(r"a|[bcd]", caseSensitive: false));
+  res.add(new RegExp(r"(a|[^\dZ])", caseSensitive: false));
+  res.add(new RegExp(r"(a|b)*[\s]", caseSensitive: false));
+  res.add(new RegExp(r"(ab\2)"));
+  res.add(new RegExp(r"(a)(b)(c)\2", caseSensitive: false));
+  res.add(new RegExp(r"(a)bc|(a)(b)\2", caseSensitive: false));
+  res.add(new RegExp(r"abc$", caseSensitive: false));
+  res.add(new RegExp(r"(a)(b)(c)(d)(e)\6"));
+  res.add(new RegExp(r"the quick brown fox", caseSensitive: false));
+  res.add(new RegExp(r"^abc|def", caseSensitive: false));
+  res.add(new RegExp(r".*((abc)$|(def))", caseSensitive: false));
+  res.add(new RegExp(r"abc", caseSensitive: false));
+  res.add(new RegExp(r"^abc|def", caseSensitive: false));
+  res.add(new RegExp(r".*((abc)$|(def))", caseSensitive: false));
+  res.add(new RegExp(r"the quick brown fox", caseSensitive: false));
+  res.add(new RegExp(r"the quick brown fox", caseSensitive: false));
+  res.add(new RegExp(r"abc.def", caseSensitive: false));
+  res.add(new RegExp(r"abc$", caseSensitive: false));
+  res.add(new RegExp(r"(abc)\2", caseSensitive: false));
+  res.add(new RegExp(r"(abc\1)", caseSensitive: false));
+  res.add(new RegExp(r"a[]b"));
+  res.add(new RegExp(r"[^aeiou ]{3,}", caseSensitive: false));
+  res.add(new RegExp(r"<.*>", caseSensitive: false));
+  res.add(new RegExp(r"<.*?>", caseSensitive: false));
+  res.add(new RegExp(r"[abcd]", caseSensitive: false));
+  res.add(new RegExp(r"(^a|^b)", multiLine: true, caseSensitive: false));
+  res.add(new RegExp(r"a$", caseSensitive: false));
+  res.add(new RegExp(r"a$", multiLine: true, caseSensitive: false));
+  res.add(new RegExp(r"\Aabc", multiLine: true, caseSensitive: false));
+  res.add(new RegExp(r"^abc", multiLine: true, caseSensitive: false));
+  res.add(new RegExp(r"(?!alphabet)[ab]", caseSensitive: false));
+  res.add(new RegExp(r"The next three are in testinput2 because they have variable length branches"));
+  res.add(new RegExp(r"This one is here because Perl 5.005_02 doesn't fail it", caseSensitive: false));
+  res.add(new RegExp(r"This one is here because I think Perl 5.005_02 gets the setting of $1 wrong", caseSensitive: false));
+  res.add(new RegExp(r"^(a\1?){4}$", caseSensitive: false));
+  res.add(new RegExp(r"These are syntax tests from Perl 5.005", caseSensitive: false));
+  res.add(new RegExp(r"a[]b"));
+  res.add(new RegExp(r"\1"));
+  res.add(new RegExp(r"\2"));
+  res.add(new RegExp(r"(a)|\2"));
+  res.add(new RegExp(r"a[]b", caseSensitive: false));
+  res.add(new RegExp(r"abc"));
+  res.add(new RegExp(r"abc"));
+  res.add(new RegExp(r"abc", caseSensitive: false));
+  res.add(new RegExp(r"(a)bc(d)", caseSensitive: false));
+  res.add(new RegExp(r"(.{20})", caseSensitive: false));
+  res.add(new RegExp(r"(.{15})", caseSensitive: false));
+  res.add(new RegExp(r"(.{16})", caseSensitive: false));
+  res.add(new RegExp(r"^(a|(bc))de(f)", caseSensitive: false));
+  res.add(new RegExp(r"^abc\00def", caseSensitive: false));
+  res.add(new RegExp(r"word ((?:[a-zA-Z0-9]+ )((?:[a-zA-Z0-9]+ )((?:[a-zA-Z0-9]+ )((?:[a-zA-Z0-9]+\n)((?:[a-zA-Z0-9]+ )((?:[a-zA-Z0-9]+ )((?:[a-zA-Z0-9]+ )((?:[a-zA-Z0-9]+\n)?)?)?)?)?)?)?)?)?otherword", caseSensitive: false));
+  res.add(new RegExp(r".*X", caseSensitive: false));
+  res.add(new RegExp(r".*X", caseSensitive: false));
+  res.add(new RegExp(r"(.*X|^B)", caseSensitive: false));
+  res.add(new RegExp(r"(.*X|^B)", caseSensitive: false));
+  res.add(new RegExp(r"\Biss\B", caseSensitive: false));
+  res.add(new RegExp(r"\Biss\B", caseSensitive: false));
+  res.add(new RegExp(r"iss", caseSensitive: false));
+  res.add(new RegExp(r"\Biss\B", caseSensitive: false));
+  res.add(new RegExp(r"\Biss\B", caseSensitive: false));
+  res.add(new RegExp(r"^iss", caseSensitive: false));
+  res.add(new RegExp(r".*iss", caseSensitive: false));
+  res.add(new RegExp(r".i.", caseSensitive: false));
+  res.add(new RegExp(r"^.is", caseSensitive: false));
+  res.add(new RegExp(r"^ab\n", caseSensitive: false));
+  res.add(new RegExp(r"^ab\n", multiLine: true, caseSensitive: false));
+  res.add(new RegExp(r"abc", caseSensitive: false));
+  res.add(new RegExp(r"abc|bac", caseSensitive: false));
+  res.add(new RegExp(r"(abc|bac)", caseSensitive: false));
+  res.add(new RegExp(r"(abc|(c|dc))", caseSensitive: false));
+  res.add(new RegExp(r"(abc|(d|de)c)", caseSensitive: false));
+  res.add(new RegExp(r"a*", caseSensitive: false));
+  res.add(new RegExp(r"a+", caseSensitive: false));
+  res.add(new RegExp(r"(baa|a+)", caseSensitive: false));
+  res.add(new RegExp(r"a{0,3}", caseSensitive: false));
+  res.add(new RegExp(r"baa{3,}", caseSensitive: false));
+  res.add(new RegExp(r'"([^\\"]+|\.)*"', caseSensitive: false));
+  res.add(new RegExp(r"(abc|ab[cd])", caseSensitive: false));
+  res.add(new RegExp(r"(a|.)", caseSensitive: false));
+  res.add(new RegExp(r"a|ba|\w", caseSensitive: false));
+  res.add(new RegExp(r"abc(?=pqr)", caseSensitive: false));
+  res.add(new RegExp(r"abc(?!pqr)", caseSensitive: false));
+  res.add(new RegExp(r"ab.", caseSensitive: false));
+  res.add(new RegExp(r"ab[xyz]", caseSensitive: false));
+  res.add(new RegExp(r"abc*", caseSensitive: false));
+  res.add(new RegExp(r"ab.c*", caseSensitive: false));
+  res.add(new RegExp(r"a.c*", caseSensitive: false));
+  res.add(new RegExp(r".c*", caseSensitive: false));
+  res.add(new RegExp(r"ac*", caseSensitive: false));
+  res.add(new RegExp(r"(a.c*|b.c*)", caseSensitive: false));
+  res.add(new RegExp(r"a.c*|aba", caseSensitive: false));
+  res.add(new RegExp(r".+a", caseSensitive: false));
+  res.add(new RegExp(r"(?=abcda)a.*", caseSensitive: false));
+  res.add(new RegExp(r"(?=a)a.*", caseSensitive: false));
+  res.add(new RegExp(r"a(b)*", caseSensitive: false));
+  res.add(new RegExp(r"a\d*", caseSensitive: false));
+  res.add(new RegExp(r"ab\d*", caseSensitive: false));
+  res.add(new RegExp(r"a(\d)*", caseSensitive: false));
+  res.add(new RegExp(r"abcde{0,0}", caseSensitive: false));
+  res.add(new RegExp(r"ab\d+", caseSensitive: false));
+  res.add(new RegExp(r"ab\d{0}e", caseSensitive: false));
+  res.add(new RegExp(r"a?b?", caseSensitive: false));
+  res.add(new RegExp(r"|-", caseSensitive: false));
+  res.add(new RegExp(r"a*(b+)(z)(z)", caseSensitive: false));
+  res.add(new RegExp(r"^.?abcd", caseSensitive: false));
+  res.add(new RegExp(r"^[[:alnum:]]"));
+  res.add(new RegExp(r"^[[:^alnum:]]"));
+  res.add(new RegExp(r"^[[:alpha:]]"));
+  res.add(new RegExp(r"^[[:^alpha:]]"));
+  res.add(new RegExp(r"[_[:alpha:]]", caseSensitive: false));
+  res.add(new RegExp(r"^[[:ascii:]]"));
+  res.add(new RegExp(r"^[[:^ascii:]]"));
+  res.add(new RegExp(r"^[[:blank:]]"));
+  res.add(new RegExp(r"^[[:^blank:]]"));
+  res.add(new RegExp(r"[\n\x0b\x0c\x0d[:blank:]]", caseSensitive: false));
+  res.add(new RegExp(r"^[[:cntrl:]]"));
+  res.add(new RegExp(r"^[[:digit:]]"));
+  res.add(new RegExp(r"^[[:graph:]]"));
+  res.add(new RegExp(r"^[[:lower:]]"));
+  res.add(new RegExp(r"^[[:print:]]"));
+  res.add(new RegExp(r"^[[:punct:]]"));
+  res.add(new RegExp(r"^[[:space:]]"));
+  res.add(new RegExp(r"^[[:upper:]]"));
+  res.add(new RegExp(r"^[[:xdigit:]]"));
+  res.add(new RegExp(r"^[[:word:]]"));
+  res.add(new RegExp(r"^[[:^cntrl:]]"));
+  res.add(new RegExp(r"^[12[:^digit:]]"));
+  res.add(new RegExp(r"^[[:^blank:]]"));
+  res.add(new RegExp(r"[01[:alpha:]%]"));
+  res.add(new RegExp(r"[[.ch.]]", caseSensitive: false));
+  res.add(new RegExp(r"[[=ch=]]", caseSensitive: false));
+  res.add(new RegExp(r"[[:rhubarb:]]", caseSensitive: false));
+  res.add(new RegExp(r"[[:upper:]]", caseSensitive: false));
+  res.add(new RegExp(r"[[:lower:]]", caseSensitive: false));
+  res.add(new RegExp(r"This one's here because of the large output vector needed", caseSensitive: false));
+  res.add(new RegExp(r"(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\w+)\s+(\270)", caseSensitive: false));
+  res.add(new RegExp(r"This one's here because Perl does this differently and PCRE can't at present", caseSensitive: false));
+  res.add(new RegExp(r"(main(O)?)+", caseSensitive: false));
+  res.add(new RegExp(r"These are all cases where Perl does it differently (nested captures)", caseSensitive: false));
+  res.add(new RegExp(r"^(a(b)?)+$", caseSensitive: false));
+  res.add(new RegExp(r"^(aa(bb)?)+$", caseSensitive: false));
+  res.add(new RegExp(r"^(aa|aa(bb))+$", caseSensitive: false));
+  res.add(new RegExp(r"^(aa(bb)??)+$", caseSensitive: false));
+  res.add(new RegExp(r"^(?:aa(bb)?)+$", caseSensitive: false));
+  res.add(new RegExp(r"^(aa(b(b))?)+$", caseSensitive: false));
+  res.add(new RegExp(r"^(?:aa(b(b))?)+$", caseSensitive: false));
+  res.add(new RegExp(r"^(?:aa(b(?:b))?)+$", caseSensitive: false));
+  res.add(new RegExp(r"^(?:aa(bb(?:b))?)+$", caseSensitive: false));
+  res.add(new RegExp(r"^(?:aa(b(?:bb))?)+$", caseSensitive: false));
+  res.add(new RegExp(r"^(?:aa(?:b(b))?)+$", caseSensitive: false));
+  res.add(new RegExp(r"^(?:aa(?:b(bb))?)+$", caseSensitive: false));
+  res.add(new RegExp(r"^(aa(b(bb))?)+$", caseSensitive: false));
+  res.add(new RegExp(r"^(aa(bb(bb))?)+$", caseSensitive: false));
+  res.add(new RegExp(r"a", caseSensitive: false));
+  res.add(new RegExp(r"[\s]"));
+  res.add(new RegExp(r"[\S]"));
+  res.add(new RegExp(r"123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890"));
+  res.add(new RegExp(r"\Q123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890"));
+  res.add(new RegExp(r"\Q\E"));
+  res.add(new RegExp(r"\Q\Ex"));
+  res.add(new RegExp(r" \Q\E"));
+  res.add(new RegExp(r"a\Q\E"));
+  res.add(new RegExp(r"a\Q\Eb"));
+  res.add(new RegExp(r"\Q\Eabc"));
+  res.add(new RegExp(r"[.x.]", caseSensitive: false));
+  res.add(new RegExp(r"[=x=]", caseSensitive: false));
+  res.add(new RegExp(r"[:x:]", caseSensitive: false));
+  res.add(new RegExp(r"\l", caseSensitive: false));
+  res.add(new RegExp(r"\L", caseSensitive: false));
+  res.add(new RegExp(r"\N{name}", caseSensitive: false));
+  res.add(new RegExp(r"\u", caseSensitive: false));
+  res.add(new RegExp(r"\U", caseSensitive: false));
+  res.add(new RegExp(r"[[:space:]", caseSensitive: false));
+  res.add(new RegExp(r"[\s]", caseSensitive: false));
+  res.add(new RegExp(r"[[:space:]]", caseSensitive: false));
+  res.add(new RegExp(r"[[:space:]abcde]", caseSensitive: false));
+  res.add(new RegExp(r"(.*)\d+\1", caseSensitive: false));
+  res.add(new RegExp(r"(.*)\d+", caseSensitive: false));
+  res.add(new RegExp(r"(.*)\d+\1", caseSensitive: false));
+  res.add(new RegExp(r"(.*)\d+", caseSensitive: false));
+  res.add(new RegExp(r"(.*(xyz))\d+\2", caseSensitive: false));
+  res.add(new RegExp(r"((.*))\d+\1", caseSensitive: false));
+  res.add(new RegExp(r"a[b]", caseSensitive: false));
+  res.add(new RegExp(r"(?=a).*", caseSensitive: false));
+  res.add(new RegExp(r"(?=abc).xyz", caseSensitive: false));
+  res.add(new RegExp(r"(?=a)(?=b)", caseSensitive: false));
+  res.add(new RegExp(r"(?=.)a", caseSensitive: false));
+  res.add(new RegExp(r"((?=abcda)a)", caseSensitive: false));
+  res.add(new RegExp(r"((?=abcda)ab)", caseSensitive: false));
+  res.add(new RegExp(r"()a", caseSensitive: false));
+  res.add(new RegExp(r"(a)+", caseSensitive: false));
+  res.add(new RegExp(r"(a){2,3}", caseSensitive: false));
+  res.add(new RegExp(r"(a)*", caseSensitive: false));
+  res.add(new RegExp(r"[a]", caseSensitive: false));
+  res.add(new RegExp(r"[ab]", caseSensitive: false));
+  res.add(new RegExp(r"[ab]", caseSensitive: false));
+  res.add(new RegExp(r"[^a]", caseSensitive: false));
+  res.add(new RegExp(r"\d456", caseSensitive: false));
+  res.add(new RegExp(r"\d456", caseSensitive: false));
+  res.add(new RegExp(r"a^b", caseSensitive: false));
+  res.add(new RegExp(r"^a", multiLine: true, caseSensitive: false));
+  res.add(new RegExp(r"c|abc", caseSensitive: false));
+  res.add(new RegExp(r"(.*)a", caseSensitive: false));
+  res.add(new RegExp(r"(.*)a\1", caseSensitive: false));
+  res.add(new RegExp(r"(.*)a(b)\2", caseSensitive: false));
+  res.add(new RegExp(r"((.*)a|(.*)b)z", caseSensitive: false));
+  res.add(new RegExp(r"((.*)a|(.*)b)z\1", caseSensitive: false));
+  res.add(new RegExp(r"((.*)a|(.*)b)z\2", caseSensitive: false));
+  res.add(new RegExp(r"((.*)a|(.*)b)z\3", caseSensitive: false));
+  res.add(new RegExp(r"((.*)a|^(.*)b)z\3", caseSensitive: false));
+  res.add(new RegExp(r"(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)a", caseSensitive: false));
+  res.add(new RegExp(r"(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)a\31", caseSensitive: false));
+  res.add(new RegExp(r"(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)a\32", caseSensitive: false));
+  res.add(new RegExp(r"(a)(bc)", caseSensitive: false));
+  res.add(new RegExp(r"(a+)*zz", caseSensitive: false));
+  res.add(new RegExp(r"((w\/|-|with)*(free|immediate)*.*?shipping\s*[!.-]*)", caseSensitive: false));
+  res.add(new RegExp(r"((w\/|-|with)*(free|immediate)*.*?shipping\s*[!.-]*)", caseSensitive: false));
+  res.add(new RegExp(r"a*.*b", caseSensitive: false));
+  res.add(new RegExp(r"(a|b)*.?c", caseSensitive: false));
+  res.add(new RegExp(r"abcde", caseSensitive: false));
+  res.add(new RegExp(r"a*b", caseSensitive: false));
+  res.add(new RegExp(r"a+b", caseSensitive: false));
+  res.add(new RegExp(r"(abc|def)x", caseSensitive: false));
+  res.add(new RegExp(r"(ab|cd){3,4}", caseSensitive: false));
+  res.add(new RegExp(r"([ab]{,4}c|xy)", caseSensitive: false));
+  res.add(new RegExp(r"([ab]{1,4}c|xy){4,5}?123", caseSensitive: false));
+  res.add(new RegExp(r"\b.*", caseSensitive: false));
+  res.add(new RegExp(r"\b.*", caseSensitive: false));
+  res.add(new RegExp(r"(?!.bcd).*", caseSensitive: false));
+  res.add(new RegExp(r"abcde", caseSensitive: false));
+  res.add(new RegExp(r"0{0,2}ABC", caseSensitive: false));
+  res.add(new RegExp(r"\d{3,}ABC", caseSensitive: false));
+  res.add(new RegExp(r"\d*ABC", caseSensitive: false));
+  res.add(new RegExp(r"[abc]+DE", caseSensitive: false));
+  res.add(new RegExp(r"[abc]?123", caseSensitive: false));
+  res.add(new RegExp(r"^(?:\d){3,5}X", caseSensitive: false));
+  res.add(new RegExp(r"^a", caseSensitive: false));
+  res.add(new RegExp(r"line\nbreak", caseSensitive: false));
+  res.add(new RegExp(r"line\nbreak", caseSensitive: false));
+  res.add(new RegExp(r"line\nbreak", multiLine: true, caseSensitive: false));
+  res.add(new RegExp(r"ab.cd", caseSensitive: false));
+  res.add(new RegExp(r"ab.cd", caseSensitive: false));
+  res.add(new RegExp(r"a(b)c", caseSensitive: false));
+  res.add(new RegExp(r"Inthisnexttest,Jisnotsetattheouterlevel;consequentlyitisn'tsetinthepattern'soptions;consequentlypcre_get_named_substring()producesarandomvalue.", caseSensitive: false));
+  res.add(new RegExp(r"\777", caseSensitive: false));
+  res.add(new RegExp(r"\s*,\s*", caseSensitive: false));
+  res.add(new RegExp(r"^abc", multiLine: true, caseSensitive: false));
+  res.add(new RegExp(r"abc$", multiLine: true, caseSensitive: false));
+  res.add(new RegExp(r"^abc", multiLine: true, caseSensitive: false));
+  res.add(new RegExp(r"^abc", multiLine: true, caseSensitive: false));
+  res.add(new RegExp(r"^abc", multiLine: true, caseSensitive: false));
+  res.add(new RegExp(r"^abc", multiLine: true, caseSensitive: false));
+  res.add(new RegExp(r"abc", caseSensitive: false));
+  res.add(new RegExp(r".*", caseSensitive: false));
+  res.add(new RegExp(r"\w+(.)(.)?def", caseSensitive: false));
+  res.add(new RegExp(r"()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()(.(.))", caseSensitive: false));
+  res.add(new RegExp(r"()[ab]xyz", caseSensitive: false));
+  res.add(new RegExp(r"(|)[ab]xyz", caseSensitive: false));
+  res.add(new RegExp(r"(|c)[ab]xyz", caseSensitive: false));
+  res.add(new RegExp(r"(|c?)[ab]xyz", caseSensitive: false));
+  res.add(new RegExp(r"(d?|c?)[ab]xyz", caseSensitive: false));
+  res.add(new RegExp(r"(d?|c)[ab]xyz", caseSensitive: false));
+  res.add(new RegExp(r"^a*b\d"));
+  res.add(new RegExp(r"^a*?b\d"));
+  res.add(new RegExp(r"^a+A\d"));
+  res.add(new RegExp(r"^a*A\d", caseSensitive: false));
+  res.add(new RegExp(r"(a*|b*)[cd]", caseSensitive: false));
+  res.add(new RegExp(r"(a+|b*)[cd]", caseSensitive: false));
+  res.add(new RegExp(r"(a*|b+)[cd]", caseSensitive: false));
+  res.add(new RegExp(r"(a+|b+)[cd]", caseSensitive: false));
+  res.add(new RegExp(r"(((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((a)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))", caseSensitive: false));
+  res.add(new RegExp(r"a*\d"));
+  res.add(new RegExp(r"a*\D"));
+  res.add(new RegExp(r"0*\d"));
+  res.add(new RegExp(r"0*\D"));
+  res.add(new RegExp(r"a*\s"));
+  res.add(new RegExp(r"a*\S"));
+  res.add(new RegExp(r" *\s"));
+  res.add(new RegExp(r" *\S"));
+  res.add(new RegExp(r"a*\w"));
+  res.add(new RegExp(r"a*\W"));
+  res.add(new RegExp(r"=*\w"));
+  res.add(new RegExp(r"=*\W"));
+  res.add(new RegExp(r"\d*a"));
+  res.add(new RegExp(r"\d*2"));
+  res.add(new RegExp(r"\d*\d"));
+  res.add(new RegExp(r"\d*\D"));
+  res.add(new RegExp(r"\d*\s"));
+  res.add(new RegExp(r"\d*\S"));
+  res.add(new RegExp(r"\d*\w"));
+  res.add(new RegExp(r"\d*\W"));
+  res.add(new RegExp(r"\D*a"));
+  res.add(new RegExp(r"\D*2"));
+  res.add(new RegExp(r"\D*\d"));
+  res.add(new RegExp(r"\D*\D"));
+  res.add(new RegExp(r"\D*\s"));
+  res.add(new RegExp(r"\D*\S"));
+  res.add(new RegExp(r"\D*\w"));
+  res.add(new RegExp(r"\D*\W"));
+  res.add(new RegExp(r"\s*a"));
+  res.add(new RegExp(r"\s*2"));
+  res.add(new RegExp(r"\s*\d"));
+  res.add(new RegExp(r"\s*\D"));
+  res.add(new RegExp(r"\s*\s"));
+  res.add(new RegExp(r"\s*\S"));
+  res.add(new RegExp(r"\s*\w"));
+  res.add(new RegExp(r"\s*\W"));
+  res.add(new RegExp(r"\S*a"));
+  res.add(new RegExp(r"\S*2"));
+  res.add(new RegExp(r"\S*\d"));
+  res.add(new RegExp(r"\S*\D"));
+  res.add(new RegExp(r"\S*\s"));
+  res.add(new RegExp(r"\S*\S"));
+  res.add(new RegExp(r"\S*\w"));
+  res.add(new RegExp(r"\S*\W"));
+  res.add(new RegExp(r"\w*a"));
+  res.add(new RegExp(r"\w*2"));
+  res.add(new RegExp(r"\w*\d"));
+  res.add(new RegExp(r"\w*\D"));
+  res.add(new RegExp(r"\w*\s"));
+  res.add(new RegExp(r"\w*\S"));
+  res.add(new RegExp(r"\w*\w"));
+  res.add(new RegExp(r"\w*\W"));
+  res.add(new RegExp(r"\W*a"));
+  res.add(new RegExp(r"\W*2"));
+  res.add(new RegExp(r"\W*\d"));
+  res.add(new RegExp(r"\W*\D"));
+  res.add(new RegExp(r"\W*\s"));
+  res.add(new RegExp(r"\W*\S"));
+  res.add(new RegExp(r"\W*\w"));
+  res.add(new RegExp(r"\W*\W"));
+  res.add(new RegExp(r"[^a]+a"));
+  res.add(new RegExp(r"[^a]+a", caseSensitive: false));
+  res.add(new RegExp(r"[^a]+A", caseSensitive: false));
+  res.add(new RegExp(r"[^a]+b"));
+  res.add(new RegExp(r"[^a]+\d"));
+  res.add(new RegExp(r"a*[^a]"));
+  res.add(new RegExp(r"^(?:(?:\1|X)(a|b))+"));
+  res.add(new RegExp(r"^[\E\Qa\E-\Qz\E]+"));
+  res.add(new RegExp(r"^[a\Q]bc\E]"));
+  res.add(new RegExp(r"(?=(\w+))\1:", caseSensitive: false));
+  res.add(new RegExp(r"(a|)*\d"));
+  res.add(new RegExp(r"^a.b"));
+  res.add(new RegExp(r"^abc.", multiLine: true));
+  res.add(new RegExp(r"abc.$", multiLine: true));
+  res.add(new RegExp(r"a"));
+  res.add(new RegExp(r"a"));
+  res.add(new RegExp(r"^a\Rb", caseSensitive: false));
+  res.add(new RegExp(r"^a\R*b", caseSensitive: false));
+  res.add(new RegExp(r"^a\R+b", caseSensitive: false));
+  res.add(new RegExp(r"^a\R{1,3}b", caseSensitive: false));
+  res.add(new RegExp(r"^a[\R]b", caseSensitive: false));
+  res.add(new RegExp(r"^(a(b))\1\g1\g{1}\g-1\g{-1}\g{-02}Z"));
+  res.add(new RegExp(r"^(a)\g-2"));
+  res.add(new RegExp(r"^(a)\g"));
+  res.add(new RegExp(r"^(a)\g{0}"));
+  res.add(new RegExp(r"^(a)\g{3"));
+  res.add(new RegExp(r"^(a)\g{4a}"));
+  res.add(new RegExp(r"^a.b"));
+  res.add(new RegExp(r".+foo"));
+  res.add(new RegExp(r".+foo"));
+  res.add(new RegExp(r".+foo"));
+  res.add(new RegExp(r".+foo"));
+  res.add(new RegExp(r"^$", multiLine: true));
+  res.add(new RegExp(r"abc.$", multiLine: true));
+  res.add(new RegExp(r"^X", multiLine: true));
+  res.add(new RegExp(r"(foo)\Kbar"));
+  res.add(new RegExp(r"(foo)(\Kbar|baz)"));
+  res.add(new RegExp(r"(foo\Kbar)baz"));
+  res.add(new RegExp(r"\g{A"));
+  res.add(new RegExp(r"\H\h\V\v"));
+  res.add(new RegExp(r"\H*\h+\V?\v{3,4}"));
+  res.add(new RegExp(r"\H{3,4}"));
+  res.add(new RegExp(r".\h{3,4}."));
+  res.add(new RegExp(r"\h*X\h?\H+Y\H?Z"));
+  res.add(new RegExp(r"\v*X\v?Y\v+Z\V*\x0a\V+\x0b\V{2,3}\x0c"));
+  res.add(new RegExp(r"[\h]"));
+  res.add(new RegExp(r"[\h]+"));
+  res.add(new RegExp(r"[\v]"));
+  res.add(new RegExp(r"[\H]"));
+  res.add(new RegExp(r"[^\h]"));
+  res.add(new RegExp(r"[\V]"));
+  res.add(new RegExp(r"[\x0a\V]"));
+  res.add(new RegExp(r"\H+\hY"));
+  res.add(new RegExp(r"\H+ Y"));
+  res.add(new RegExp(r"\h+A"));
+  res.add(new RegExp(r"\v*B"));
+  res.add(new RegExp(r"\V+\x0a"));
+  res.add(new RegExp(r"A+\h"));
+  res.add(new RegExp(r" *\H"));
+  res.add(new RegExp(r"A*\v"));
+  res.add(new RegExp(r"\x0b*\V"));
+  res.add(new RegExp(r"\d+\h"));
+  res.add(new RegExp(r"\d*\v"));
+  res.add(new RegExp(r"S+\h\S+\v"));
+  res.add(new RegExp(r"\w{3,}\h\w+\v"));
+  res.add(new RegExp(r"\h+\d\h+\w\h+\S\h+\H"));
+  res.add(new RegExp(r"\v+\d\v+\w\v+\S\v+\V"));
+  res.add(new RegExp(r"\H+\h\H+\d"));
+  res.add(new RegExp(r"\V+\v\V+\w"));
+  res.add(new RegExp(r"[\E]AAA"));
+  res.add(new RegExp(r"[\Q\E]AAA"));
+  res.add(new RegExp(r"[^\E]AAA"));
+  res.add(new RegExp(r"[^\Q\E]AAA"));
+  res.add(new RegExp(r"[\E^]AAA"));
+  res.add(new RegExp(r"[\Q\E^]AAA"));
+  res.add(new RegExp(r"\g6666666666"));
+  res.add(new RegExp(r"[\g6666666666]"));
+  res.add(new RegExp(r".+A"));
+  res.add(new RegExp(r"\nA"));
+  res.add(new RegExp(r"[\r\n]A"));
+  res.add(new RegExp(r"(\r|\n)A"));
+  res.add(new RegExp(r"a\Rb", caseSensitive: false));
+  res.add(new RegExp(r"a\Rb", caseSensitive: false));
+  res.add(new RegExp(r"a\R?b", caseSensitive: false));
+  res.add(new RegExp(r"a\R?b", caseSensitive: false));
+  res.add(new RegExp(r"a\R{2,4}b", caseSensitive: false));
+  res.add(new RegExp(r"a\R{2,4}b", caseSensitive: false));
+  res.add(new RegExp(r"\k''"));
+  res.add(new RegExp(r"\k<>"));
+  res.add(new RegExp(r"\k{}"));
+  res.add(new RegExp(r"[[:foo:]]"));
+  res.add(new RegExp(r"[[:1234:]]"));
+  res.add(new RegExp(r"[[:f\oo:]]"));
+  res.add(new RegExp(r"[[: :]]"));
+  res.add(new RegExp(r"[[:...:]]"));
+  res.add(new RegExp(r"[[:l\ower:]]"));
+  res.add(new RegExp(r"[[:abc\:]]"));
+  res.add(new RegExp(r"[abc[:x\]pqr:]]"));
+  res.add(new RegExp(r"[[:a\dz:]]"));
+  res.add(new RegExp(r"^(a|b\g<1>c)"));
+  res.add(new RegExp(r"^(a|b\g'1'c)"));
+  res.add(new RegExp(r"^(a|b\g'-1'c)"));
+  res.add(new RegExp(r"(^(a|b\g<-1>c))"));
+  res.add(new RegExp(r"(^(a|b\g<-1'c))"));
+  res.add(new RegExp(r"(^(a|b\g{-1}))"));
+  res.add(new RegExp(r"(\3)(\1)(a)"));
+  res.add(new RegExp(r"(\3)(\1)(a)"));
+  res.add(new RegExp(r"TA]"));
+  res.add(new RegExp(r"TA]"));
+  res.add(new RegExp(r"a[]b"));
+  res.add(new RegExp(r"a[^]b"));
+  res.add(new RegExp(r"a[]b"));
+  res.add(new RegExp(r"a[]+b"));
+  res.add(new RegExp(r"a[^]b"));
+  res.add(new RegExp(r"a[^]+b"));
+  res.add(new RegExp(r"a(?!)+b"));
+  res.add(new RegExp(r"(abc|pqr|123){0}[xyz]", caseSensitive: false));
+  res.add(new RegExp(r" End of testinput2 "));
+  res.add(new RegExp(r"a.b"));
+  res.add(new RegExp(r"a(.{3})b"));
+  res.add(new RegExp(r"a(.*?)(.)"));
+  res.add(new RegExp(r"a(.*?)(.)"));
+  res.add(new RegExp(r"a(.*)(.)"));
+  res.add(new RegExp(r"a(.*)(.)"));
+  res.add(new RegExp(r"a(.)(.)"));
+  res.add(new RegExp(r"a(.)(.)"));
+  res.add(new RegExp(r"a(.?)(.)"));
+  res.add(new RegExp(r"a(.?)(.)"));
+  res.add(new RegExp(r"a(.??)(.)"));
+  res.add(new RegExp(r"a(.??)(.)"));
+  res.add(new RegExp(r"a(.{3})b"));
+  res.add(new RegExp(r"a(.{3,})b"));
+  res.add(new RegExp(r"a(.{3,}?)b"));
+  res.add(new RegExp(r"a(.{3,5})b"));
+  res.add(new RegExp(r"a(.{3,5}?)b"));
+  res.add(new RegExp(r"X(\C{3})"));
+  res.add(new RegExp(r"X(\C{4})"));
+  res.add(new RegExp(r"X\C*"));
+  res.add(new RegExp(r"X\C*?"));
+  res.add(new RegExp(r"X\C{3,5}"));
+  res.add(new RegExp(r"X\C{3,5}?"));
+  res.add(new RegExp(r"[^a]+"));
+  res.add(new RegExp(r"^[^a]{2}"));
+  res.add(new RegExp(r"^[^a]{2,}"));
+  res.add(new RegExp(r"^[^a]{2,}?"));
+  res.add(new RegExp(r"[^a]+", caseSensitive: false));
+  res.add(new RegExp(r"^[^a]{2}", caseSensitive: false));
+  res.add(new RegExp(r"^[^a]{2,}", caseSensitive: false));
+  res.add(new RegExp(r"^[^a]{2,}?", caseSensitive: false));
+  res.add(new RegExp(r"\D*"));
+  res.add(new RegExp(r"\D*"));
+  res.add(new RegExp(r"\D"));
+  res.add(new RegExp(r">\S"));
+  res.add(new RegExp(r"\d"));
+  res.add(new RegExp(r"\s"));
+  res.add(new RegExp(r"\D+"));
+  res.add(new RegExp(r"\D{2,3}"));
+  res.add(new RegExp(r"\D{2,3}?"));
+  res.add(new RegExp(r"\d+"));
+  res.add(new RegExp(r"\d{2,3}"));
+  res.add(new RegExp(r"\d{2,3}?"));
+  res.add(new RegExp(r"\S+"));
+  res.add(new RegExp(r"\S{2,3}"));
+  res.add(new RegExp(r"\S{2,3}?"));
+  res.add(new RegExp(r">\s+<"));
+  res.add(new RegExp(r">\s{2,3}<"));
+  res.add(new RegExp(r">\s{2,3}?<"));
+  res.add(new RegExp(r"\w+"));
+  res.add(new RegExp(r"\w{2,3}"));
+  res.add(new RegExp(r"\w{2,3}?"));
+  res.add(new RegExp(r"\W+"));
+  res.add(new RegExp(r"\W{2,3}"));
+  res.add(new RegExp(r"\W{2,3}?"));
+  res.add(new RegExp(r"a\Cb"));
+  res.add(new RegExp(r"a\Cb"));
+  res.add(new RegExp(r"[\xFF]"));
+  res.add(new RegExp(r"[\xff]"));
+  res.add(new RegExp(r"[^\xFF]"));
+  res.add(new RegExp(r"[^\xff]"));
+  res.add(new RegExp(r"^[ac]*b"));
+  res.add(new RegExp(r"^[^x]*b", caseSensitive: false));
+  res.add(new RegExp(r"^[^x]*b"));
+  res.add(new RegExp(r"^\d*b"));
+  res.add(new RegExp(r"(|a)"));
+  res.add(new RegExp(r"\S\S"));
+  res.add(new RegExp(r"\S{2}"));
+  res.add(new RegExp(r"\W\W"));
+  res.add(new RegExp(r"\W{2}"));
+  res.add(new RegExp(r"\S"));
+  res.add(new RegExp(r"[\S]"));
+  res.add(new RegExp(r"\D"));
+  res.add(new RegExp(r"[\D]"));
+  res.add(new RegExp(r"\W"));
+  res.add(new RegExp(r"[\W]"));
+  res.add(new RegExp(r"[\S\s]*"));
+  res.add(new RegExp(r".[^\S]."));
+  res.add(new RegExp(r".[^\S\n]."));
+  res.add(new RegExp(r"[[:^alnum:]]"));
+  res.add(new RegExp(r"[[:^alpha:]]"));
+  res.add(new RegExp(r"[[:^ascii:]]"));
+  res.add(new RegExp(r"[[:^blank:]]"));
+  res.add(new RegExp(r"[[:^cntrl:]]"));
+  res.add(new RegExp(r"[[:^digit:]]"));
+  res.add(new RegExp(r"[[:^graph:]]"));
+  res.add(new RegExp(r"[[:^lower:]]"));
+  res.add(new RegExp(r"[[:^print:]]"));
+  res.add(new RegExp(r"[[:^punct:]]"));
+  res.add(new RegExp(r"[[:^space:]]"));
+  res.add(new RegExp(r"[[:^upper:]]"));
+  res.add(new RegExp(r"[[:^word:]]"));
+  res.add(new RegExp(r"[[:^xdigit:]]"));
+  res.add(new RegExp(r"^[^d]*?$"));
+  res.add(new RegExp(r"^[^d]*?$"));
+  res.add(new RegExp(r"^[^d]*?$", caseSensitive: false));
+  res.add(new RegExp(r"^[^d]*?$", caseSensitive: false));
+  res.add(new RegExp(r" End of testinput4 "));
+  res.add(new RegExp(r"\x80"));
+  res.add(new RegExp(r"\xff"));
+  res.add(new RegExp(r".{3,5}X"));
+  res.add(new RegExp(r".{3,5}?"));
+  res.add(new RegExp(r"X(\C)(.*)"));
+  res.add(new RegExp(r"^[ab]"));
+  res.add(new RegExp(r"^[^ab]"));
+  res.add(new RegExp(r"[^ab\xC0-\xF0]"));
+  res.add(new RegExp(r"[\xFF]"));
+  res.add(new RegExp(r"[\xff]"));
+  res.add(new RegExp(r"[^\xFF]"));
+  res.add(new RegExp(r"[^\xff]"));
+  res.add(new RegExp(r"anything"));
+  res.add(new RegExp(r"\W"));
+  res.add(new RegExp(r"\w"));
+  res.add(new RegExp(r"\777", caseSensitive: false));
+  res.add(new RegExp(r"\777", caseSensitive: false));
+  res.add(new RegExp(r"^abc.", multiLine: true));
+  res.add(new RegExp(r"abc.$", multiLine: true));
+  res.add(new RegExp(r"^a\Rb", caseSensitive: false));
+  res.add(new RegExp(r"^a\R*b", caseSensitive: false));
+  res.add(new RegExp(r"^a\R+b", caseSensitive: false));
+  res.add(new RegExp(r"^a\R{1,3}b", caseSensitive: false));
+  res.add(new RegExp(r"\H\h\V\v"));
+  res.add(new RegExp(r"\H*\h+\V?\v{3,4}"));
+  res.add(new RegExp(r"\H\h\V\v"));
+  res.add(new RegExp(r"\H*\h+\V?\v{3,4}"));
+  res.add(new RegExp(r"[\h]"));
+  res.add(new RegExp(r"[\h]{3,}"));
+  res.add(new RegExp(r"[\v]"));
+  res.add(new RegExp(r"[\H]"));
+  res.add(new RegExp(r"[\V]"));
+  res.add(new RegExp(r".*$"));
+  res.add(new RegExp(r"X"));
+  res.add(new RegExp(r"a\Rb", caseSensitive: false));
+  res.add(new RegExp(r"a\Rb", caseSensitive: false));
+  res.add(new RegExp(r"a\R?b", caseSensitive: false));
+  res.add(new RegExp(r"a\R?b", caseSensitive: false));
+  res.add(new RegExp(r".*a.*=.b.*"));
+  res.add(new RegExp(r"a[^]b"));
+  res.add(new RegExp(r"a[^]+b"));
+  res.add(new RegExp(r"X"));
+  res.add(new RegExp(r" End of testinput5 "));
+  res.add(new RegExp(r"^\pC\pL\pM\pN\pP\pS\pZ<"));
+  res.add(new RegExp(r"^\PC"));
+  res.add(new RegExp(r"^\PL"));
+  res.add(new RegExp(r"^\PM"));
+  res.add(new RegExp(r"^\PN"));
+  res.add(new RegExp(r"^\PP"));
+  res.add(new RegExp(r"^\PS"));
+  res.add(new RegExp(r"^\PZ"));
+  res.add(new RegExp(r"^\p{Cc}"));
+  res.add(new RegExp(r"^\p{Cf}"));
+  res.add(new RegExp(r"^\p{Cn}"));
+  res.add(new RegExp(r"^\p{Co}"));
+  res.add(new RegExp(r"^\p{Cs}"));
+  res.add(new RegExp(r"^\p{Ll}"));
+  res.add(new RegExp(r"^\p{Lm}"));
+  res.add(new RegExp(r"^\p{Lo}"));
+  res.add(new RegExp(r"^\p{Lt}"));
+  res.add(new RegExp(r"^\p{Lu}"));
+  res.add(new RegExp(r"^\p{Mc}"));
+  res.add(new RegExp(r"^\p{Me}"));
+  res.add(new RegExp(r"^\p{Mn}"));
+  res.add(new RegExp(r"^\p{Nl}"));
+  res.add(new RegExp(r"^\p{No}"));
+  res.add(new RegExp(r"^\p{Pc}"));
+  res.add(new RegExp(r"^\p{Pd}"));
+  res.add(new RegExp(r"^\p{Pe}"));
+  res.add(new RegExp(r"^\p{Pf}"));
+  res.add(new RegExp(r"^\p{Pi}"));
+  res.add(new RegExp(r"^\p{Po}"));
+  res.add(new RegExp(r"^\p{Ps}"));
+  res.add(new RegExp(r"^\p{Sk}"));
+  res.add(new RegExp(r"^\p{So}"));
+  res.add(new RegExp(r"^\p{Zl}"));
+  res.add(new RegExp(r"^\p{Zp}"));
+  res.add(new RegExp(r"^\p{Zs}"));
+  res.add(new RegExp(r"\p{Nd}{2,}(..)"));
+  res.add(new RegExp(r"\p{Nd}{2,}?(..)"));
+  res.add(new RegExp(r"\p{Nd}*(..)"));
+  res.add(new RegExp(r"\p{Nd}*?(..)"));
+  res.add(new RegExp(r"\p{Nd}{2}(..)"));
+  res.add(new RegExp(r"\p{Nd}{2,3}(..)"));
+  res.add(new RegExp(r"\p{Nd}{2,3}?(..)"));
+  res.add(new RegExp(r"\p{Nd}?(..)"));
+  res.add(new RegExp(r"\p{Nd}??(..)"));
+  res.add(new RegExp(r"\p{Lu}", caseSensitive: false));
+  res.add(new RegExp(r"\p{^Lu}", caseSensitive: false));
+  res.add(new RegExp(r"\P{Lu}", caseSensitive: false));
+  res.add(new RegExp(r"[\p{L}]"));
+  res.add(new RegExp(r"[\p{^L}]"));
+  res.add(new RegExp(r"[\P{L}]"));
+  res.add(new RegExp(r"[\P{^L}]"));
+  res.add(new RegExp(r"[\p{Nd}]"));
+  res.add(new RegExp(r"[\P{Nd}]+"));
+  res.add(new RegExp(r"\D+"));
+  res.add(new RegExp(r"[\D]+"));
+  res.add(new RegExp(r"[\P{Nd}]+"));
+  res.add(new RegExp(r"[\D\P{Nd}]+"));
+  res.add(new RegExp(r"\pL"));
+  res.add(new RegExp(r"\pL", caseSensitive: false));
+  res.add(new RegExp(r"\p{Lu}"));
+  res.add(new RegExp(r"\p{Lu}", caseSensitive: false));
+  res.add(new RegExp(r"\p{Ll}"));
+  res.add(new RegExp(r"\p{Ll}", caseSensitive: false));
+  res.add(new RegExp(r"^\X"));
+  res.add(new RegExp(r"^[\X]"));
+  res.add(new RegExp(r"^(\X*)C"));
+  res.add(new RegExp(r"^(\X*?)C"));
+  res.add(new RegExp(r"^(\X*)(.)"));
+  res.add(new RegExp(r"^(\X*?)(.)"));
+  res.add(new RegExp(r"^\X(.)"));
+  res.add(new RegExp(r"^\X{2,3}(.)"));
+  res.add(new RegExp(r"^\X{2,3}?(.)"));
+  res.add(new RegExp(r"^[\p{Arabic}]"));
+  res.add(new RegExp(r"^[\P{Yi}]"));
+  res.add(new RegExp(r"^\p{Any}X"));
+  res.add(new RegExp(r"^\P{Any}X"));
+  res.add(new RegExp(r"^\p{Any}?X"));
+  res.add(new RegExp(r"^\P{Any}?X"));
+  res.add(new RegExp(r"^\p{Any}*X"));
+  res.add(new RegExp(r"^\P{Any}*X"));
+  res.add(new RegExp(r"^[\p{Any}]X"));
+  res.add(new RegExp(r"^[\P{Any}]X"));
+  res.add(new RegExp(r"^[\p{Any}]?X"));
+  res.add(new RegExp(r"^[\P{Any}]?X"));
+  res.add(new RegExp(r"^[\p{Any}]+X"));
+  res.add(new RegExp(r"^[\P{Any}]+X"));
+  res.add(new RegExp(r"^[\p{Any}]*X"));
+  res.add(new RegExp(r"^[\P{Any}]*X"));
+  res.add(new RegExp(r"^\p{Any}{3,5}?"));
+  res.add(new RegExp(r"^\p{Any}{3,5}"));
+  res.add(new RegExp(r"^\P{Any}{3,5}?"));
+  res.add(new RegExp(r"^\p{L&}X"));
+  res.add(new RegExp(r"^[\p{L&}]X"));
+  res.add(new RegExp(r"^[\p{L&}]+X"));
+  res.add(new RegExp(r"^[\p{L&}]+?X"));
+  res.add(new RegExp(r"^\P{L&}X"));
+  res.add(new RegExp(r"^[\P{L&}]X"));
+  res.add(new RegExp(r"^(\p{Z}[^\p{C}\p{Z}]+)*$"));
+  res.add(new RegExp(r"([\pL]=(abc))*X"));
+  res.add(new RegExp(r"^\p{Balinese}\p{Cuneiform}\p{Nko}\p{Phags_Pa}\p{Phoenician}"));
+  res.add(new RegExp(r"The next two are special cases where the lengths of the different cases of the \nsame character differ. The first went wrong with heap frame storage; the 2nd\nwas broken in all cases."));
+  res.add(new RegExp(r"Check property support in non-UTF-8 mode"));
+  res.add(new RegExp(r"\p{L}{4}"));
+  res.add(new RegExp(r"\X{1,3}\d"));
+  res.add(new RegExp(r"\X?\d"));
+  res.add(new RegExp(r"\P{L}?\d"));
+  res.add(new RegExp(r"[\PPP\x8a]{1,}\x80"));
+  res.add(new RegExp(r"(?:[\PPa*]*){8,}"));
+  res.add(new RegExp(r"[\P{Any}]"));
+  res.add(new RegExp(r"[\P{Any}\E]"));
+  res.add(new RegExp(r"(\P{Yi}{2}\277)?"));
+  res.add(new RegExp(r"[\P{Yi}A]"));
+  res.add(new RegExp(r"[\P{Yi}\P{Yi}\P{Yi}A]"));
+  res.add(new RegExp(r"[^\P{Yi}A]"));
+  res.add(new RegExp(r"[^\P{Yi}\P{Yi}\P{Yi}A]"));
+  res.add(new RegExp(r"(\P{Yi}*\277)*"));
+  res.add(new RegExp(r"(\P{Yi}*?\277)*"));
+  res.add(new RegExp(r"(\P{Yi}?\277)*"));
+  res.add(new RegExp(r"(\P{Yi}??\277)*"));
+  res.add(new RegExp(r"(\P{Yi}{0,3}\277)*"));
+  res.add(new RegExp(r"(\P{Yi}{0,3}?\277)*"));
+  res.add(new RegExp(r"^[\p{Arabic}]"));
+  res.add(new RegExp(r"^\p{Cyrillic}"));
+  res.add(new RegExp(r"^\p{Common}"));
+  res.add(new RegExp(r"^\p{Inherited}"));
+  res.add(new RegExp(r"^\p{Shavian}"));
+  res.add(new RegExp(r"^\p{Deseret}"));
+  res.add(new RegExp(r"^\p{Osmanya}"));
+  res.add(new RegExp(r"\p{Zl}"));
+  res.add(new RegExp(r"\p{Carian}\p{Cham}\p{Kayah_Li}\p{Lepcha}\p{Lycian}\p{Lydian}\p{Ol_Chiki}\p{Rejang}\p{Saurashtra}\p{Sundanese}\p{Vai}"));
+  res.add(new RegExp(r"(A)\1", caseSensitive: false));
+  res.add(new RegExp(r" End of testinput6 "));
+  res.add(new RegExp(r"abc"));
+  res.add(new RegExp(r"ab*c"));
+  res.add(new RegExp(r"ab+c"));
+  res.add(new RegExp(r"a*"));
+  res.add(new RegExp(r"(a|abcd|african)"));
+  res.add(new RegExp(r"^abc"));
+  res.add(new RegExp(r"^abc", multiLine: true));
+  res.add(new RegExp(r"\Aabc"));
+  res.add(new RegExp(r"\Aabc", multiLine: true));
+  res.add(new RegExp(r"\Gabc"));
+  res.add(new RegExp(r"x\dy\Dz"));
+  res.add(new RegExp(r"x\sy\Sz"));
+  res.add(new RegExp(r"x\wy\Wz"));
+  res.add(new RegExp(r"x.y"));
+  res.add(new RegExp(r"x.y"));
+  res.add(new RegExp(r"a\d\z"));
+  res.add(new RegExp(r"a\d\z", multiLine: true));
+  res.add(new RegExp(r"a\d\Z"));
+  res.add(new RegExp(r"a\d\Z", multiLine: true));
+  res.add(new RegExp(r"a\d$"));
+  res.add(new RegExp(r"a\d$", multiLine: true));
+  res.add(new RegExp(r"abc", caseSensitive: false));
+  res.add(new RegExp(r"[^a]"));
+  res.add(new RegExp(r"ab?\w"));
+  res.add(new RegExp(r"x{0,3}yz"));
+  res.add(new RegExp(r"x{3}yz"));
+  res.add(new RegExp(r"x{2,3}yz"));
+  res.add(new RegExp(r"[^a]+"));
+  res.add(new RegExp(r"[^a]*"));
+  res.add(new RegExp(r"[^a]{3,5}"));
+  res.add(new RegExp(r"\d*"));
+  res.add(new RegExp(r"\D*"));
+  res.add(new RegExp(r"\d+"));
+  res.add(new RegExp(r"\D+"));
+  res.add(new RegExp(r"\d?A"));
+  res.add(new RegExp(r"\D?A"));
+  res.add(new RegExp(r"a+"));
+  res.add(new RegExp(r"^.*xyz"));
+  res.add(new RegExp(r"^.+xyz"));
+  res.add(new RegExp(r"^.?xyz"));
+  res.add(new RegExp(r"^\d{2,3}X"));
+  res.add(new RegExp(r"^[abcd]\d"));
+  res.add(new RegExp(r"^[abcd]*\d"));
+  res.add(new RegExp(r"^[abcd]+\d"));
+  res.add(new RegExp(r"^a+X"));
+  res.add(new RegExp(r"^[abcd]?\d"));
+  res.add(new RegExp(r"^[abcd]{2,3}\d"));
+  res.add(new RegExp(r"^(abc)*\d"));
+  res.add(new RegExp(r"^(abc)+\d"));
+  res.add(new RegExp(r"^(abc)?\d"));
+  res.add(new RegExp(r"^(abc){2,3}\d"));
+  res.add(new RegExp(r"^(a*\w|ab)=(a*\w|ab)"));
+  res.add(new RegExp(r"^(?=abc)\w{5}:$"));
+  res.add(new RegExp(r"^(?!abc)\d\d$"));
+  res.add(new RegExp(r"(ab|cd){3,4}"));
+  res.add(new RegExp(r"^abc"));
+  res.add(new RegExp(r"^(a*|xyz)"));
+  res.add(new RegExp(r"xyz$"));
+  res.add(new RegExp(r"xyz$", multiLine: true));
+  res.add(new RegExp(r"\Gabc"));
+  res.add(new RegExp(r"^abcdef"));
+  res.add(new RegExp(r"^a{2,4}\d+z"));
+  res.add(new RegExp(r"^abcdef"));
+  res.add(new RegExp(r"(ab*(cd|ef))+X"));
+  res.add(new RegExp(r"the quick brown fox"));
+  res.add(new RegExp(r"The quick brown fox", caseSensitive: false));
+  res.add(new RegExp(r"abcd\t\n\r\f\a\e\071\x3b\$\\\?caxyz"));
+  res.add(new RegExp(r"a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz"));
+  res.add(new RegExp(r"^(abc){1,2}zz"));
+  res.add(new RegExp(r"^(b+?|a){1,2}?c"));
+  res.add(new RegExp(r"^(b+|a){1,2}c"));
+  res.add(new RegExp(r"^(b*|ba){1,2}?bc"));
+  res.add(new RegExp(r"^(ba|b*){1,2}?bc"));
+  res.add(new RegExp(r"^[ab\]cde]"));
+  res.add(new RegExp(r"^[]cde]"));
+  res.add(new RegExp(r"^[^ab\]cde]"));
+  res.add(new RegExp(r"^[^]cde]"));
+  res.add(new RegExp(r"^[0-9]+$"));
+  res.add(new RegExp(r"^.*nter"));
+  res.add(new RegExp(r"^xxx[0-9]+$"));
+  res.add(new RegExp(r"^.+[0-9][0-9][0-9]$"));
+  res.add(new RegExp(r"^.+?[0-9][0-9][0-9]$"));
+  res.add(new RegExp(r"^([^!]+)!(.+)=apquxz\.ixr\.zzz\.ac\.uk$"));
+  res.add(new RegExp(r":"));
+  res.add(new RegExp(r"([\da-f:]+)$", caseSensitive: false));
+  res.add(new RegExp(r"^.*\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$"));
+  res.add(new RegExp(r"^(\d+)\s+IN\s+SOA\s+(\S+)\s+(\S+)\s*\(\s*$"));
+  res.add(new RegExp(r"^[a-zA-Z\d][a-zA-Z\d\-]*(\.[a-zA-Z\d][a-zA-z\d\-]*)*\.$"));
+  res.add(new RegExp(r"^\*\.[a-z]([a-z\-\d]*[a-z\d]+)?(\.[a-z]([a-z\-\d]*[a-z\d]+)?)*$"));
+  res.add(new RegExp(r"^(?=ab(de))(abd)(e)"));
+  res.add(new RegExp(r"^(?!(ab)de|x)(abd)(f)"));
+  res.add(new RegExp(r"^(?=(ab(cd)))(ab)"));
+  res.add(new RegExp(r"^[\da-f](\.[\da-f])*$", caseSensitive: false));
+  res.add(new RegExp(r'^\".*\"\s*(;.*)?$'));
+  res.add(new RegExp(r"^$"));
+  res.add(new RegExp(r"^ab\sc$"));
+  res.add(new RegExp(r"^a\ b[c]d$"));
+  res.add(new RegExp(r"^(a(b(c)))(d(e(f)))(h(i(j)))(k(l(m)))$"));
+  res.add(new RegExp(r"^(?:a(b(c)))(?:d(e(f)))(?:h(i(j)))(?:k(l(m)))$"));
+  res.add(new RegExp(r"^[\w][\W][\s][\S][\d][\D][\b][\n][\c]][\022]"));
+  res.add(new RegExp(r"^a*\w"));
+  res.add(new RegExp(r"^a*?\w"));
+  res.add(new RegExp(r"^a+\w"));
+  res.add(new RegExp(r"^a+?\w"));
+  res.add(new RegExp(r"^\d{8}\w{2,}"));
+  res.add(new RegExp(r"^[aeiou\d]{4,5}$"));
+  res.add(new RegExp(r"^[aeiou\d]{4,5}?"));
+  res.add(new RegExp(r"^From +([^ ]+) +[a-zA-Z][a-zA-Z][a-zA-Z] +[a-zA-Z][a-zA-Z][a-zA-Z] +[0-9]?[0-9] +[0-9][0-9]:[0-9][0-9]"));
+  res.add(new RegExp(r"^From\s+\S+\s+([a-zA-Z]{3}\s+){2}\d{1,2}\s+\d\d:\d\d"));
+  res.add(new RegExp(r"^12.34"));
+  res.add(new RegExp(r"\w+(?=\t)"));
+  res.add(new RegExp(r"foo(?!bar)(.*)"));
+  res.add(new RegExp(r"(?:(?!foo)...|^.{0,2})bar(.*)"));
+  res.add(new RegExp(r"^(\D*)(?=\d)(?!123)"));
+  res.add(new RegExp(r"^1234"));
+  res.add(new RegExp(r"^1234"));
+  res.add(new RegExp(r"abcd"));
+  res.add(new RegExp(r"^abcd"));
+  res.add(new RegExp(r"(?!^)abc"));
+  res.add(new RegExp(r"(?=^)abc"));
+  res.add(new RegExp(r"^[ab]{1,3}(ab*|b)"));
+  res.add(new RegExp(r"^[ab]{1,3}?(ab*|b)"));
+  res.add(new RegExp(r"^[ab]{1,3}?(ab*?|b)"));
+  res.add(new RegExp(r"^[ab]{1,3}(ab*?|b)"));
+  res.add(new RegExp(r'(?:[\040\t]|\((?:[^\\\x80-\xff\n\015()]|\\[^\x80-\xff]|\((?:[^\\\x80-\xff\n\015()]|\\[^\x80-\xff])*\))*\))*(?:(?:[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff])|"(?:[^\\\x80-\xff\n\015"]|\\[^\x80-\xff])*")(?:(?:[\040\t]|\((?:[^\\\x80-\xff\n\015()]|\\[^\x80-\xff]|\((?:[^\\\x80-\xff\n\015()]|\\[^\x80-\xff])*\))*\))*\.(?:[\040\t]|\((?:[^\\\x80-\xff\n\015()]|\\[^\x80-\xff]|\((?:[^\\\x80-\xff\n\015()]|\\[^\x80-\xff])*\))*\))*(?:[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff])|"(?:[^\\\x80-\xff\n\015"]|\\[^\x80-\xff])*"))*(?:[\040\t]|\((?:[^\\\x80-\xff\n\015()]|\\[^\x80-\xff]|\((?:[^\\\x80-\xff\n\015()]|\\[^\x80-\xff])*\))*\))*@(?:[\040\t]|\((?:[^\\\x80-\xff\n\015()]|\\[^\x80-\xff]|\((?:[^\\\x80-\xff\n\015()]|\\[^\x80-\xff])*\))*\))*(?:[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff])|\[(?:[^\\\x80-\xff\n\015\[\]]|\\[^\x80-\xff])*\])(?:(?:[\040\t]|\((?:[^\\\x80-\xff\n\015()]|\\[^\x80-\xff]|\((?:[^\\\x80-\xff\n\015()]|\\[^\x80-\xff])*\))*\))*\.(?:[\040\t]|\((?:[^\\\x80-\xff\n\015()]|\\[^\x80-\xff]|\((?:[^\\\x80-\xff\n\015()]|\\[^\x80-\xff])*\))*\))*(?:[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff])|\[(?:[^\\\x80-\xff\n\015\[\]]|\\[^\x80-\xff])*\]))*|(?:[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff])|"(?:[^\\\x80-\xff\n\015"]|\\[^\x80-\xff])*")(?:[^()<>@,;:".\\\[\]\x80-\xff\000-\010\012-\037]|\((?:[^\\\x80-\xff\n\015()]|\\[^\x80-\xff]|\((?:[^\\\x80-\xff\n\015()]|\\[^\x80-\xff])*\))*\)|"(?:[^\\\x80-\xff\n\015"]|\\[^\x80-\xff])*")*<(?:[\040\t]|\((?:[^\\\x80-\xff\n\015()]|\\[^\x80-\xff]|\((?:[^\\\x80-\xff\n\015()]|\\[^\x80-\xff])*\))*\))*(?:@(?:[\040\t]|\((?:[^\\\x80-\xff\n\015()]|\\[^\x80-\xff]|\((?:[^\\\x80-\xff\n\015()]|\\[^\x80-\xff])*\))*\))*(?:[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff])|\[(?:[^\\\x80-\xff\n\015\[\]]|\\[^\x80-\xff])*\])(?:(?:[\040\t]|\((?:[^\\\x80-\xff\n\015()]|\\[^\x80-\xff]|\((?:[^\\\x80-\xff\n\015()]|\\[^\x80-\xff])*\))*\))*\.(?:[\040\t]|\((?:[^\\\x80-\xff\n\015()]|\\[^\x80-\xff]|\((?:[^\\\x80-\xff\n\015()]|\\[^\x80-\xff])*\))*\))*(?:[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff])|\[(?:[^\\\x80-\xff\n\015\[\]]|\\[^\x80-\xff])*\]))*(?:(?:[\040\t]|\((?:[^\\\x80-\xff\n\015()]|\\[^\x80-\xff]|\((?:[^\\\x80-\xff\n\015()]|\\[^\x80-\xff])*\))*\))*,(?:[\040\t]|\((?:[^\\\x80-\xff\n\015()]|\\[^\x80-\xff]|\((?:[^\\\x80-\xff\n\015()]|\\[^\x80-\xff])*\))*\))*@(?:[\040\t]|\((?:[^\\\x80-\xff\n\015()]|\\[^\x80-\xff]|\((?:[^\\\x80-\xff\n\015()]|\\[^\x80-\xff])*\))*\))*(?:[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff])|\[(?:[^\\\x80-\xff\n\015\[\]]|\\[^\x80-\xff])*\])(?:(?:[\040\t]|\((?:[^\\\x80-\xff\n\015()]|\\[^\x80-\xff]|\((?:[^\\\x80-\xff\n\015()]|\\[^\x80-\xff])*\))*\))*\.(?:[\040\t]|\((?:[^\\\x80-\xff\n\015()]|\\[^\x80-\xff]|\((?:[^\\\x80-\xff\n\015()]|\\[^\x80-\xff])*\))*\))*(?:[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff])|\[(?:[^\\\x80-\xff\n\015\[\]]|\\[^\x80-\xff])*\]))*)*:(?:[\040\t]|\((?:[^\\\x80-\xff\n\015()]|\\[^\x80-\xff]|\((?:[^\\\x80-\xff\n\015()]|\\[^\x80-\xff])*\))*\))*)?(?:[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff])|"(?:[^\\\x80-\xff\n\015"]|\\[^\x80-\xff])*")(?:(?:[\040\t]|\((?:[^\\\x80-\xff\n\015()]|\\[^\x80-\xff]|\((?:[^\\\x80-\xff\n\015()]|\\[^\x80-\xff])*\))*\))*\.(?:[\040\t]|\((?:[^\\\x80-\xff\n\015()]|\\[^\x80-\xff]|\((?:[^\\\x80-\xff\n\015()]|\\[^\x80-\xff])*\))*\))*(?:[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff])|"(?:[^\\\x80-\xff\n\015"]|\\[^\x80-\xff])*"))*(?:[\040\t]|\((?:[^\\\x80-\xff\n\015()]|\\[^\x80-\xff]|\((?:[^\\\x80-\xff\n\015()]|\\[^\x80-\xff])*\))*\))*@(?:[\040\t]|\((?:[^\\\x80-\xff\n\015()]|\\[^\x80-\xff]|\((?:[^\\\x80-\xff\n\015()]|\\[^\x80-\xff])*\))*\))*(?:[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff])|\[(?:[^\\\x80-\xff\n\015\[\]]|\\[^\x80-\xff])*\])(?:(?:[\040\t]|\((?:[^\\\x80-\xff\n\015()]|\\[^\x80-\xff]|\((?:[^\\\x80-\xff\n\015()]|\\[^\x80-\xff])*\))*\))*\.(?:[\040\t]|\((?:[^\\\x80-\xff\n\015()]|\\[^\x80-\xff]|\((?:[^\\\x80-\xff\n\015()]|\\[^\x80-\xff])*\))*\))*(?:[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff])|\[(?:[^\\\x80-\xff\n\015\[\]]|\\[^\x80-\xff])*\]))*(?:[\040\t]|\((?:[^\\\x80-\xff\n\015()]|\\[^\x80-\xff]|\((?:[^\\\x80-\xff\n\015()]|\\[^\x80-\xff])*\))*\))*>)(?:[\040\t]|\((?:[^\\\x80-\xff\n\015()]|\\[^\x80-\xff]|\((?:[^\\\x80-\xff\n\015()]|\\[^\x80-\xff])*\))*\))*'));
+  res.add(new RegExp(r'[\040\t]*(?:\([^\\\x80-\xff\n\015()]*(?:(?:\\[^\x80-\xff]|\([^\\\x80-\xff\n\015()]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015()]*)*\))[^\\\x80-\xff\n\015()]*)*\)[\040\t]*)*(?:(?:[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff])|"[^\\\x80-\xff\n\015"]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015"]*)*")[\040\t]*(?:\([^\\\x80-\xff\n\015()]*(?:(?:\\[^\x80-\xff]|\([^\\\x80-\xff\n\015()]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015()]*)*\))[^\\\x80-\xff\n\015()]*)*\)[\040\t]*)*(?:\.[\040\t]*(?:\([^\\\x80-\xff\n\015()]*(?:(?:\\[^\x80-\xff]|\([^\\\x80-\xff\n\015()]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015()]*)*\))[^\\\x80-\xff\n\015()]*)*\)[\040\t]*)*(?:[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff])|"[^\\\x80-\xff\n\015"]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015"]*)*")[\040\t]*(?:\([^\\\x80-\xff\n\015()]*(?:(?:\\[^\x80-\xff]|\([^\\\x80-\xff\n\015()]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015()]*)*\))[^\\\x80-\xff\n\015()]*)*\)[\040\t]*)*)*@[\040\t]*(?:\([^\\\x80-\xff\n\015()]*(?:(?:\\[^\x80-\xff]|\([^\\\x80-\xff\n\015()]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015()]*)*\))[^\\\x80-\xff\n\015()]*)*\)[\040\t]*)*(?:[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff])|\[(?:[^\\\x80-\xff\n\015\[\]]|\\[^\x80-\xff])*\])[\040\t]*(?:\([^\\\x80-\xff\n\015()]*(?:(?:\\[^\x80-\xff]|\([^\\\x80-\xff\n\015()]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015()]*)*\))[^\\\x80-\xff\n\015()]*)*\)[\040\t]*)*(?:\.[\040\t]*(?:\([^\\\x80-\xff\n\015()]*(?:(?:\\[^\x80-\xff]|\([^\\\x80-\xff\n\015()]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015()]*)*\))[^\\\x80-\xff\n\015()]*)*\)[\040\t]*)*(?:[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff])|\[(?:[^\\\x80-\xff\n\015\[\]]|\\[^\x80-\xff])*\])[\040\t]*(?:\([^\\\x80-\xff\n\015()]*(?:(?:\\[^\x80-\xff]|\([^\\\x80-\xff\n\015()]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015()]*)*\))[^\\\x80-\xff\n\015()]*)*\)[\040\t]*)*)*|(?:[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff])|"[^\\\x80-\xff\n\015"]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015"]*)*")[^()<>@,;:".\\\[\]\x80-\xff\000-\010\012-\037]*(?:(?:\([^\\\x80-\xff\n\015()]*(?:(?:\\[^\x80-\xff]|\([^\\\x80-\xff\n\015()]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015()]*)*\))[^\\\x80-\xff\n\015()]*)*\)|"[^\\\x80-\xff\n\015"]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015"]*)*")[^()<>@,;:".\\\[\]\x80-\xff\000-\010\012-\037]*)*<[\040\t]*(?:\([^\\\x80-\xff\n\015()]*(?:(?:\\[^\x80-\xff]|\([^\\\x80-\xff\n\015()]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015()]*)*\))[^\\\x80-\xff\n\015()]*)*\)[\040\t]*)*(?:@[\040\t]*(?:\([^\\\x80-\xff\n\015()]*(?:(?:\\[^\x80-\xff]|\([^\\\x80-\xff\n\015()]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015()]*)*\))[^\\\x80-\xff\n\015()]*)*\)[\040\t]*)*(?:[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff])|\[(?:[^\\\x80-\xff\n\015\[\]]|\\[^\x80-\xff])*\])[\040\t]*(?:\([^\\\x80-\xff\n\015()]*(?:(?:\\[^\x80-\xff]|\([^\\\x80-\xff\n\015()]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015()]*)*\))[^\\\x80-\xff\n\015()]*)*\)[\040\t]*)*(?:\.[\040\t]*(?:\([^\\\x80-\xff\n\015()]*(?:(?:\\[^\x80-\xff]|\([^\\\x80-\xff\n\015()]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015()]*)*\))[^\\\x80-\xff\n\015()]*)*\)[\040\t]*)*(?:[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff])|\[(?:[^\\\x80-\xff\n\015\[\]]|\\[^\x80-\xff])*\])[\040\t]*(?:\([^\\\x80-\xff\n\015()]*(?:(?:\\[^\x80-\xff]|\([^\\\x80-\xff\n\015()]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015()]*)*\))[^\\\x80-\xff\n\015()]*)*\)[\040\t]*)*)*(?:,[\040\t]*(?:\([^\\\x80-\xff\n\015()]*(?:(?:\\[^\x80-\xff]|\([^\\\x80-\xff\n\015()]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015()]*)*\))[^\\\x80-\xff\n\015()]*)*\)[\040\t]*)*@[\040\t]*(?:\([^\\\x80-\xff\n\015()]*(?:(?:\\[^\x80-\xff]|\([^\\\x80-\xff\n\015()]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015()]*)*\))[^\\\x80-\xff\n\015()]*)*\)[\040\t]*)*(?:[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff])|\[(?:[^\\\x80-\xff\n\015\[\]]|\\[^\x80-\xff])*\])[\040\t]*(?:\([^\\\x80-\xff\n\015()]*(?:(?:\\[^\x80-\xff]|\([^\\\x80-\xff\n\015()]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015()]*)*\))[^\\\x80-\xff\n\015()]*)*\)[\040\t]*)*(?:\.[\040\t]*(?:\([^\\\x80-\xff\n\015()]*(?:(?:\\[^\x80-\xff]|\([^\\\x80-\xff\n\015()]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015()]*)*\))[^\\\x80-\xff\n\015()]*)*\)[\040\t]*)*(?:[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff])|\[(?:[^\\\x80-\xff\n\015\[\]]|\\[^\x80-\xff])*\])[\040\t]*(?:\([^\\\x80-\xff\n\015()]*(?:(?:\\[^\x80-\xff]|\([^\\\x80-\xff\n\015()]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015()]*)*\))[^\\\x80-\xff\n\015()]*)*\)[\040\t]*)*)*)*:[\040\t]*(?:\([^\\\x80-\xff\n\015()]*(?:(?:\\[^\x80-\xff]|\([^\\\x80-\xff\n\015()]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015()]*)*\))[^\\\x80-\xff\n\015()]*)*\)[\040\t]*)*)?(?:[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff])|"[^\\\x80-\xff\n\015"]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015"]*)*")[\040\t]*(?:\([^\\\x80-\xff\n\015()]*(?:(?:\\[^\x80-\xff]|\([^\\\x80-\xff\n\015()]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015()]*)*\))[^\\\x80-\xff\n\015()]*)*\)[\040\t]*)*(?:\.[\040\t]*(?:\([^\\\x80-\xff\n\015()]*(?:(?:\\[^\x80-\xff]|\([^\\\x80-\xff\n\015()]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015()]*)*\))[^\\\x80-\xff\n\015()]*)*\)[\040\t]*)*(?:[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff])|"[^\\\x80-\xff\n\015"]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015"]*)*")[\040\t]*(?:\([^\\\x80-\xff\n\015()]*(?:(?:\\[^\x80-\xff]|\([^\\\x80-\xff\n\015()]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015()]*)*\))[^\\\x80-\xff\n\015()]*)*\)[\040\t]*)*)*@[\040\t]*(?:\([^\\\x80-\xff\n\015()]*(?:(?:\\[^\x80-\xff]|\([^\\\x80-\xff\n\015()]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015()]*)*\))[^\\\x80-\xff\n\015()]*)*\)[\040\t]*)*(?:[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff])|\[(?:[^\\\x80-\xff\n\015\[\]]|\\[^\x80-\xff])*\])[\040\t]*(?:\([^\\\x80-\xff\n\015()]*(?:(?:\\[^\x80-\xff]|\([^\\\x80-\xff\n\015()]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015()]*)*\))[^\\\x80-\xff\n\015()]*)*\)[\040\t]*)*(?:\.[\040\t]*(?:\([^\\\x80-\xff\n\015()]*(?:(?:\\[^\x80-\xff]|\([^\\\x80-\xff\n\015()]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015()]*)*\))[^\\\x80-\xff\n\015()]*)*\)[\040\t]*)*(?:[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff])|\[(?:[^\\\x80-\xff\n\015\[\]]|\\[^\x80-\xff])*\])[\040\t]*(?:\([^\\\x80-\xff\n\015()]*(?:(?:\\[^\x80-\xff]|\([^\\\x80-\xff\n\015()]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015()]*)*\))[^\\\x80-\xff\n\015()]*)*\)[\040\t]*)*)*>)'));
+  res.add(new RegExp(r"abc\x0def\x00pqr\x000xyz\x0000AB"));
+  res.add(new RegExp(r"^[\000-\037]"));
+  res.add(new RegExp(r"\0*"));
+  res.add(new RegExp(r"A\x0{2,3}Z"));
+  res.add(new RegExp(r"^\s"));
+  res.add(new RegExp(r"^abc"));
+  res.add(new RegExp(r"ab{1,3}bc"));
+  res.add(new RegExp(r"([^.]*)\.([^:]*):[T ]+(.*)"));
+  res.add(new RegExp(r"([^.]*)\.([^:]*):[T ]+(.*)", caseSensitive: false));
+  res.add(new RegExp(r"([^.]*)\.([^:]*):[t ]+(.*)", caseSensitive: false));
+  res.add(new RegExp(r"^[W-c]+$"));
+  res.add(new RegExp(r"^[W-c]+$", caseSensitive: false));
+  res.add(new RegExp(r"^[\x3f-\x5F]+$", caseSensitive: false));
+  res.add(new RegExp(r"^abc$", multiLine: true));
+  res.add(new RegExp(r"^abc$"));
+  res.add(new RegExp(r"\Aabc\Z", multiLine: true));
+  res.add(new RegExp(r"\A(.)*\Z"));
+  res.add(new RegExp(r"\A(.)*\Z", multiLine: true));
+  res.add(new RegExp(r"(?:b)|(?::+)"));
+  res.add(new RegExp(r"[-az]+"));
+  res.add(new RegExp(r"[az-]+"));
+  res.add(new RegExp(r"[a\-z]+"));
+  res.add(new RegExp(r"[a-z]+"));
+  res.add(new RegExp(r"[\d-]+"));
+  res.add(new RegExp(r"[\d-z]+"));
+  res.add(new RegExp(r"\x5c"));
+  res.add(new RegExp(r"\x20Z"));
+  res.add(new RegExp(r"ab{3cd"));
+  res.add(new RegExp(r"ab{3,cd"));
+  res.add(new RegExp(r"ab{3,4a}cd"));
+  res.add(new RegExp(r"{4,5a}bc"));
+  res.add(new RegExp(r"^a.b"));
+  res.add(new RegExp(r"abc$"));
+  res.add(new RegExp(r"(abc)\123"));
+  res.add(new RegExp(r"(abc)\223"));
+  res.add(new RegExp(r"(abc)\323"));
+  res.add(new RegExp(r"(abc)\100"));
+  res.add(new RegExp(r"abc\81"));
+  res.add(new RegExp(r"abc\91"));
+  res.add(new RegExp(r"(a)(b)(c)(d)(e)(f)(g)(h)(i)(j)(k)\12\123"));
+  res.add(new RegExp(r"ab\idef"));
+  res.add(new RegExp(r"a{0}bc"));
+  res.add(new RegExp(r"(a|(bc)){0,0}?xyz"));
+  res.add(new RegExp(r"abc[\10]de"));
+  res.add(new RegExp(r"abc[\1]de"));
+  res.add(new RegExp(r"(abc)[\1]de"));
+  res.add(new RegExp(r"^([^a])([^\b])([^c]*)([^d]{3,4})"));
+  res.add(new RegExp(r"[^a]"));
+  res.add(new RegExp(r"[^a]", caseSensitive: false));
+  res.add(new RegExp(r"[^a]+"));
+  res.add(new RegExp(r"[^a]+", caseSensitive: false));
+  res.add(new RegExp(r"[^a]+"));
+  res.add(new RegExp(r"[^k]$"));
+  res.add(new RegExp(r"[^k]{2,3}$"));
+  res.add(new RegExp(r"^\d{8,}\@.+[^k]$"));
+  res.add(new RegExp(r"[^a]"));
+  res.add(new RegExp(r"[^a]", caseSensitive: false));
+  res.add(new RegExp(r"[^az]"));
+  res.add(new RegExp(r"[^az]", caseSensitive: false));
+  res.add(new RegExp(r"\000\001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037\040\041\042\043\044\045\046\047\050\051\052\053\054\055\056\057\060\061\062\063\064\065\066\067\070\071\072\073\074\075\076\077\100\101\102\103\104\105\106\107\110\111\112\113\114\115\116\117\120\121\122\123\124\125\126\127\130\131\132\133\134\135\136\137\140\141\142\143\144\145\146\147\150\151\152\153\154\155\156\157\160\161\162\163\164\165\166\167\170\171\172\173\174\175\176\177\200\201\202\203\204\205\206\207\210\211\212\213\214\215\216\217\220\221\222\223\224\225\226\227\230\231\232\233\234\235\236\237\240\241\242\243\244\245\246\247\250\251\252\253\254\255\256\257\260\261\262\263\264\265\266\267\270\271\272\273\274\275\276\277\300\301\302\303\304\305\306\307\310\311\312\313\314\315\316\317\320\321\322\323\324\325\326\327\330\331\332\333\334\335\336\337\340\341\342\343\344\345\346\347\350\351\352\353\354\355\356\357\360\361\362\363\364\365\366\367\370\371\372\373\374\375\376\377"));
+  res.add(new RegExp(r"P[^*]TAIRE[^*]{1,6}?LL"));
+  res.add(new RegExp(r"P[^*]TAIRE[^*]{1,}?LL"));
+  res.add(new RegExp(r"(\.\d\d[1-9]?)\d+"));
+  res.add(new RegExp(r"(\.\d\d((?=0)|\d(?=\d)))"));
+  res.add(new RegExp(r"\b(foo)\s+(\w+)", caseSensitive: false));
+  res.add(new RegExp(r"foo(.*)bar"));
+  res.add(new RegExp(r"foo(.*?)bar"));
+  res.add(new RegExp(r"(.*)(\d*)"));
+  res.add(new RegExp(r"(.*)(\d+)"));
+  res.add(new RegExp(r"(.*?)(\d*)"));
+  res.add(new RegExp(r"(.*?)(\d+)"));
+  res.add(new RegExp(r"(.*)(\d+)$"));
+  res.add(new RegExp(r"(.*?)(\d+)$"));
+  res.add(new RegExp(r"(.*)\b(\d+)$"));
+  res.add(new RegExp(r"(.*\D)(\d+)$"));
+  res.add(new RegExp(r"^\D*(?!123)"));
+  res.add(new RegExp(r"^(\D*)(?=\d)(?!123)"));
+  res.add(new RegExp(r"^[W-]46]"));
+  res.add(new RegExp(r"^[W-\]46]"));
+  res.add(new RegExp(r"\d\d\/\d\d\/\d\d\d\d"));
+  res.add(new RegExp(r"word (?:[a-zA-Z0-9]+ ){0,10}otherword"));
+  res.add(new RegExp(r"word (?:[a-zA-Z0-9]+ ){0,300}otherword"));
+  res.add(new RegExp(r"^(a){0,0}"));
+  res.add(new RegExp(r"^(a){0,1}"));
+  res.add(new RegExp(r"^(a){0,2}"));
+  res.add(new RegExp(r"^(a){0,3}"));
+  res.add(new RegExp(r"^(a){0,}"));
+  res.add(new RegExp(r"^(a){1,1}"));
+  res.add(new RegExp(r"^(a){1,2}"));
+  res.add(new RegExp(r"^(a){1,3}"));
+  res.add(new RegExp(r"^(a){1,}"));
+  res.add(new RegExp(r".*\.gif"));
+  res.add(new RegExp(r".{0,}\.gif"));
+  res.add(new RegExp(r".*\.gif", multiLine: true));
+  res.add(new RegExp(r".*\.gif"));
+  res.add(new RegExp(r".*\.gif", multiLine: true));
+  res.add(new RegExp(r".*$"));
+  res.add(new RegExp(r".*$", multiLine: true));
+  res.add(new RegExp(r".*$"));
+  res.add(new RegExp(r".*$", multiLine: true));
+  res.add(new RegExp(r".*$"));
+  res.add(new RegExp(r".*$", multiLine: true));
+  res.add(new RegExp(r".*$"));
+  res.add(new RegExp(r".*$", multiLine: true));
+  res.add(new RegExp(r"(.*X|^B)"));
+  res.add(new RegExp(r"(.*X|^B)", multiLine: true));
+  res.add(new RegExp(r"(.*X|^B)"));
+  res.add(new RegExp(r"(.*X|^B)", multiLine: true));
+  res.add(new RegExp(r"^.*B"));
+  res.add(new RegExp(r"^[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]"));
+  res.add(new RegExp(r"^\d\d\d\d\d\d\d\d\d\d\d\d"));
+  res.add(new RegExp(r"^[\d][\d][\d][\d][\d][\d][\d][\d][\d][\d][\d][\d]"));
+  res.add(new RegExp(r"^[abc]{12}"));
+  res.add(new RegExp(r"^[a-c]{12}"));
+  res.add(new RegExp(r"^(a|b|c){12}"));
+  res.add(new RegExp(r"^[abcdefghijklmnopqrstuvwxy0123456789]"));
+  res.add(new RegExp(r"abcde{0,0}"));
+  res.add(new RegExp(r"ab[cd]{0,0}e"));
+  res.add(new RegExp(r"ab(c){0,0}d"));
+  res.add(new RegExp(r"a(b*)"));
+  res.add(new RegExp(r"ab\d{0}e"));
+  res.add(new RegExp(r'"([^\\"]+|\\.)*"'));
+  res.add(new RegExp(r".*?"));
+  res.add(new RegExp(r"\b"));
+  res.add(new RegExp(r"\b"));
+  res.add(new RegExp(r"<tr([\w\W\s\d][^<>]{0,})><TD([\w\W\s\d][^<>]{0,})>([\d]{0,}\.)(.*)((<BR>([\w\W\s\d][^<>]{0,})|[\s]{0,}))<\/a><\/TD><TD([\w\W\s\d][^<>]{0,})>([\w\W\s\d][^<>]{0,})<\/TD><TD([\w\W\s\d][^<>]{0,})>([\w\W\s\d][^<>]{0,})<\/TD><\/TR>", caseSensitive: false));
+  res.add(new RegExp(r"a[^a]b"));
+  res.add(new RegExp(r"a.b"));
+  res.add(new RegExp(r"a[^a]b"));
+  res.add(new RegExp(r"a.b"));
+  res.add(new RegExp(r"^(b+?|a){1,2}?c"));
+  res.add(new RegExp(r"^(b+|a){1,2}?c"));
+  res.add(new RegExp(r"(?!\A)x", multiLine: true));
+  res.add(new RegExp(r"\x0{ab}"));
+  res.add(new RegExp(r"(A|B)*?CD"));
+  res.add(new RegExp(r"(A|B)*CD"));
+  res.add(new RegExp(r"\Aabc\z", multiLine: true));
+  res.add(new RegExp(r"(\d+)(\w)"));
+  res.add(new RegExp(r"(a+|b+|c+)*c"));
+  res.add(new RegExp(r"(abc|)+"));
+  res.add(new RegExp(r"([a]*)*"));
+  res.add(new RegExp(r"([ab]*)*"));
+  res.add(new RegExp(r"([^a]*)*"));
+  res.add(new RegExp(r"([^ab]*)*"));
+  res.add(new RegExp(r"([a]*?)*"));
+  res.add(new RegExp(r"([ab]*?)*"));
+  res.add(new RegExp(r"([^a]*?)*"));
+  res.add(new RegExp(r"([^ab]*?)*"));
+  res.add(new RegExp(r"The following tests are taken from the Perl 5.005 test suite; some of them"));
+  res.add(new RegExp(r"are compatible with 5.004, but I'd rather not have to sort them out."));
+  res.add(new RegExp(r"abc"));
+  res.add(new RegExp(r"ab*c"));
+  res.add(new RegExp(r"ab*bc"));
+  res.add(new RegExp(r".{1}"));
+  res.add(new RegExp(r".{3,4}"));
+  res.add(new RegExp(r"ab{0,}bc"));
+  res.add(new RegExp(r"ab+bc"));
+  res.add(new RegExp(r"ab{1,}bc"));
+  res.add(new RegExp(r"ab+bc"));
+  res.add(new RegExp(r"ab{1,}bc"));
+  res.add(new RegExp(r"ab{1,3}bc"));
+  res.add(new RegExp(r"ab{3,4}bc"));
+  res.add(new RegExp(r"ab{4,5}bc"));
+  res.add(new RegExp(r"ab?bc"));
+  res.add(new RegExp(r"ab{0,1}bc"));
+  res.add(new RegExp(r"ab?bc"));
+  res.add(new RegExp(r"ab?c"));
+  res.add(new RegExp(r"ab{0,1}c"));
+  res.add(new RegExp(r"^abc$"));
+  res.add(new RegExp(r"^abc"));
+  res.add(new RegExp(r"^abc$"));
+  res.add(new RegExp(r"abc$"));
+  res.add(new RegExp(r"^"));
+  res.add(new RegExp(r"$"));
+  res.add(new RegExp(r"a.c"));
+  res.add(new RegExp(r"a.*c"));
+  res.add(new RegExp(r"a[bc]d"));
+  res.add(new RegExp(r"a[b-d]e"));
+  res.add(new RegExp(r"a[b-d]"));
+  res.add(new RegExp(r"a[-b]"));
+  res.add(new RegExp(r"a[b-]"));
+  res.add(new RegExp(r"a]"));
+  res.add(new RegExp(r"a[]]b"));
+  res.add(new RegExp(r"a[^bc]d"));
+  res.add(new RegExp(r"a[^-b]c"));
+  res.add(new RegExp(r"a[^]b]c"));
+  res.add(new RegExp(r"\ba\b"));
+  res.add(new RegExp(r"\by\b"));
+  res.add(new RegExp(r"\Ba\B"));
+  res.add(new RegExp(r"\By\b"));
+  res.add(new RegExp(r"\by\B"));
+  res.add(new RegExp(r"\By\B"));
+  res.add(new RegExp(r"\w"));
+  res.add(new RegExp(r"\W"));
+  res.add(new RegExp(r"a\sb"));
+  res.add(new RegExp(r"a\Sb"));
+  res.add(new RegExp(r"\d"));
+  res.add(new RegExp(r"\D"));
+  res.add(new RegExp(r"[\w]"));
+  res.add(new RegExp(r"[\W]"));
+  res.add(new RegExp(r"a[\s]b"));
+  res.add(new RegExp(r"a[\S]b"));
+  res.add(new RegExp(r"[\d]"));
+  res.add(new RegExp(r"[\D]"));
+  res.add(new RegExp(r"ab|cd"));
+  res.add(new RegExp(r"()ef"));
+  res.add(new RegExp(r"$b"));
+  res.add(new RegExp(r"a\(b"));
+  res.add(new RegExp(r"a\\b"));
+  res.add(new RegExp(r"((a))"));
+  res.add(new RegExp(r"(a)b(c)"));
+  res.add(new RegExp(r"a+b+c"));
+  res.add(new RegExp(r"a{1,}b{1,}c"));
+  res.add(new RegExp(r"a.+?c"));
+  res.add(new RegExp(r"(a+|b)*"));
+  res.add(new RegExp(r"(a+|b){0,}"));
+  res.add(new RegExp(r"(a+|b)+"));
+  res.add(new RegExp(r"(a+|b){1,}"));
+  res.add(new RegExp(r"(a+|b)?"));
+  res.add(new RegExp(r"(a+|b){0,1}"));
+  res.add(new RegExp(r"[^ab]*"));
+  res.add(new RegExp(r"abc"));
+  res.add(new RegExp(r"a*"));
+  res.add(new RegExp(r"([abc])*d"));
+  res.add(new RegExp(r"([abc])*bcd"));
+  res.add(new RegExp(r"a|b|c|d|e"));
+  res.add(new RegExp(r"(a|b|c|d|e)f"));
+  res.add(new RegExp(r"abcd*efg"));
+  res.add(new RegExp(r"ab*"));
+  res.add(new RegExp(r"(ab|cd)e"));
+  res.add(new RegExp(r"[abhgefdc]ij"));
+  res.add(new RegExp(r"^(ab|cd)e"));
+  res.add(new RegExp(r"(abc|)ef"));
+  res.add(new RegExp(r"(a|b)c*d"));
+  res.add(new RegExp(r"(ab|ab*)bc"));
+  res.add(new RegExp(r"a([bc]*)c*"));
+  res.add(new RegExp(r"a([bc]*)(c*d)"));
+  res.add(new RegExp(r"a([bc]+)(c*d)"));
+  res.add(new RegExp(r"a([bc]*)(c+d)"));
+  res.add(new RegExp(r"a[bcd]*dcdcde"));
+  res.add(new RegExp(r"a[bcd]+dcdcde"));
+  res.add(new RegExp(r"(ab|a)b*c"));
+  res.add(new RegExp(r"((a)(b)c)(d)"));
+  res.add(new RegExp(r"[a-zA-Z_][a-zA-Z0-9_]*"));
+  res.add(new RegExp(r"^a(bc+|b[eh])g|.h$"));
+  res.add(new RegExp(r"(bc+d$|ef*g.|h?i(j|k))"));
+  res.add(new RegExp(r"((((((((((a))))))))))"));
+  res.add(new RegExp(r"(((((((((a)))))))))"));
+  res.add(new RegExp(r"multiple words of text"));
+  res.add(new RegExp(r"multiple words"));
+  res.add(new RegExp(r"(.*)c(.*)"));
+  res.add(new RegExp(r"\((.*), (.*)\)"));
+  res.add(new RegExp(r"[k]"));
+  res.add(new RegExp(r"abcd"));
+  res.add(new RegExp(r"a(bc)d"));
+  res.add(new RegExp(r"a[-]?c"));
+  res.add(new RegExp(r"abc", caseSensitive: false));
+  res.add(new RegExp(r"ab*c", caseSensitive: false));
+  res.add(new RegExp(r"ab*bc", caseSensitive: false));
+  res.add(new RegExp(r"ab*?bc", caseSensitive: false));
+  res.add(new RegExp(r"ab{0,}?bc", caseSensitive: false));
+  res.add(new RegExp(r"ab+?bc", caseSensitive: false));
+  res.add(new RegExp(r"ab+bc", caseSensitive: false));
+  res.add(new RegExp(r"ab{1,}bc", caseSensitive: false));
+  res.add(new RegExp(r"ab+bc", caseSensitive: false));
+  res.add(new RegExp(r"ab{1,}?bc", caseSensitive: false));
+  res.add(new RegExp(r"ab{1,3}?bc", caseSensitive: false));
+  res.add(new RegExp(r"ab{3,4}?bc", caseSensitive: false));
+  res.add(new RegExp(r"ab{4,5}?bc", caseSensitive: false));
+  res.add(new RegExp(r"ab??bc", caseSensitive: false));
+  res.add(new RegExp(r"ab{0,1}?bc", caseSensitive: false));
+  res.add(new RegExp(r"ab??bc", caseSensitive: false));
+  res.add(new RegExp(r"ab??c", caseSensitive: false));
+  res.add(new RegExp(r"ab{0,1}?c", caseSensitive: false));
+  res.add(new RegExp(r"^abc$", caseSensitive: false));
+  res.add(new RegExp(r"^abc", caseSensitive: false));
+  res.add(new RegExp(r"^abc$", caseSensitive: false));
+  res.add(new RegExp(r"abc$", caseSensitive: false));
+  res.add(new RegExp(r"^", caseSensitive: false));
+  res.add(new RegExp(r"$", caseSensitive: false));
+  res.add(new RegExp(r"a.c", caseSensitive: false));
+  res.add(new RegExp(r"a.*?c", caseSensitive: false));
+  res.add(new RegExp(r"a.*c", caseSensitive: false));
+  res.add(new RegExp(r"a[bc]d", caseSensitive: false));
+  res.add(new RegExp(r"a[b-d]e", caseSensitive: false));
+  res.add(new RegExp(r"a[b-d]", caseSensitive: false));
+  res.add(new RegExp(r"a[-b]", caseSensitive: false));
+  res.add(new RegExp(r"a[b-]", caseSensitive: false));
+  res.add(new RegExp(r"a]", caseSensitive: false));
+  res.add(new RegExp(r"a[]]b", caseSensitive: false));
+  res.add(new RegExp(r"a[^bc]d", caseSensitive: false));
+  res.add(new RegExp(r"a[^-b]c", caseSensitive: false));
+  res.add(new RegExp(r"a[^]b]c", caseSensitive: false));
+  res.add(new RegExp(r"ab|cd", caseSensitive: false));
+  res.add(new RegExp(r"()ef", caseSensitive: false));
+  res.add(new RegExp(r"$b", caseSensitive: false));
+  res.add(new RegExp(r"a\(b", caseSensitive: false));
+  res.add(new RegExp(r"a\\b", caseSensitive: false));
+  res.add(new RegExp(r"((a))", caseSensitive: false));
+  res.add(new RegExp(r"(a)b(c)", caseSensitive: false));
+  res.add(new RegExp(r"a+b+c", caseSensitive: false));
+  res.add(new RegExp(r"a{1,}b{1,}c", caseSensitive: false));
+  res.add(new RegExp(r"a.+?c", caseSensitive: false));
+  res.add(new RegExp(r"a.*?c", caseSensitive: false));
+  res.add(new RegExp(r"a.{0,5}?c", caseSensitive: false));
+  res.add(new RegExp(r"(a+|b)*", caseSensitive: false));
+  res.add(new RegExp(r"(a+|b){0,}", caseSensitive: false));
+  res.add(new RegExp(r"(a+|b)+", caseSensitive: false));
+  res.add(new RegExp(r"(a+|b){1,}", caseSensitive: false));
+  res.add(new RegExp(r"(a+|b)?", caseSensitive: false));
+  res.add(new RegExp(r"(a+|b){0,1}", caseSensitive: false));
+  res.add(new RegExp(r"(a+|b){0,1}?", caseSensitive: false));
+  res.add(new RegExp(r"[^ab]*", caseSensitive: false));
+  res.add(new RegExp(r"abc", caseSensitive: false));
+  res.add(new RegExp(r"a*", caseSensitive: false));
+  res.add(new RegExp(r"([abc])*d", caseSensitive: false));
+  res.add(new RegExp(r"([abc])*bcd", caseSensitive: false));
+  res.add(new RegExp(r"a|b|c|d|e", caseSensitive: false));
+  res.add(new RegExp(r"(a|b|c|d|e)f", caseSensitive: false));
+  res.add(new RegExp(r"abcd*efg", caseSensitive: false));
+  res.add(new RegExp(r"ab*", caseSensitive: false));
+  res.add(new RegExp(r"(ab|cd)e", caseSensitive: false));
+  res.add(new RegExp(r"[abhgefdc]ij", caseSensitive: false));
+  res.add(new RegExp(r"^(ab|cd)e", caseSensitive: false));
+  res.add(new RegExp(r"(abc|)ef", caseSensitive: false));
+  res.add(new RegExp(r"(a|b)c*d", caseSensitive: false));
+  res.add(new RegExp(r"(ab|ab*)bc", caseSensitive: false));
+  res.add(new RegExp(r"a([bc]*)c*", caseSensitive: false));
+  res.add(new RegExp(r"a([bc]*)(c*d)", caseSensitive: false));
+  res.add(new RegExp(r"a([bc]+)(c*d)", caseSensitive: false));
+  res.add(new RegExp(r"a([bc]*)(c+d)", caseSensitive: false));
+  res.add(new RegExp(r"a[bcd]*dcdcde", caseSensitive: false));
+  res.add(new RegExp(r"a[bcd]+dcdcde", caseSensitive: false));
+  res.add(new RegExp(r"(ab|a)b*c", caseSensitive: false));
+  res.add(new RegExp(r"((a)(b)c)(d)", caseSensitive: false));
+  res.add(new RegExp(r"[a-zA-Z_][a-zA-Z0-9_]*", caseSensitive: false));
+  res.add(new RegExp(r"^a(bc+|b[eh])g|.h$", caseSensitive: false));
+  res.add(new RegExp(r"(bc+d$|ef*g.|h?i(j|k))", caseSensitive: false));
+  res.add(new RegExp(r"((((((((((a))))))))))", caseSensitive: false));
+  res.add(new RegExp(r"(((((((((a)))))))))", caseSensitive: false));
+  res.add(new RegExp(r"(?:(?:(?:(?:(?:(?:(?:(?:(?:(a))))))))))", caseSensitive: false));
+  res.add(new RegExp(r"(?:(?:(?:(?:(?:(?:(?:(?:(?:(a|b|c))))))))))", caseSensitive: false));
+  res.add(new RegExp(r"multiple words of text", caseSensitive: false));
+  res.add(new RegExp(r"multiple words", caseSensitive: false));
+  res.add(new RegExp(r"(.*)c(.*)", caseSensitive: false));
+  res.add(new RegExp(r"\((.*), (.*)\)", caseSensitive: false));
+  res.add(new RegExp(r"[k]", caseSensitive: false));
+  res.add(new RegExp(r"abcd", caseSensitive: false));
+  res.add(new RegExp(r"a(bc)d", caseSensitive: false));
+  res.add(new RegExp(r"a[-]?c", caseSensitive: false));
+  res.add(new RegExp(r"a(?!b)."));
+  res.add(new RegExp(r"a(?=d)."));
+  res.add(new RegExp(r"a(?=c|d)."));
+  res.add(new RegExp(r"a(?:b|c|d)(.)"));
+  res.add(new RegExp(r"a(?:b|c|d)*(.)"));
+  res.add(new RegExp(r"a(?:b|c|d)+?(.)"));
+  res.add(new RegExp(r"a(?:b|c|d)+(.)"));
+  res.add(new RegExp(r"a(?:b|c|d){2}(.)"));
+  res.add(new RegExp(r"a(?:b|c|d){4,5}(.)"));
+  res.add(new RegExp(r"a(?:b|c|d){4,5}?(.)"));
+  res.add(new RegExp(r"((foo)|(bar))*"));
+  res.add(new RegExp(r"a(?:b|c|d){6,7}(.)"));
+  res.add(new RegExp(r"a(?:b|c|d){6,7}?(.)"));
+  res.add(new RegExp(r"a(?:b|c|d){5,6}(.)"));
+  res.add(new RegExp(r"a(?:b|c|d){5,6}?(.)"));
+  res.add(new RegExp(r"a(?:b|c|d){5,7}(.)"));
+  res.add(new RegExp(r"a(?:b|c|d){5,7}?(.)"));
+  res.add(new RegExp(r"a(?:b|(c|e){1,2}?|d)+?(.)"));
+  res.add(new RegExp(r"^(.+)?B"));
+  res.add(new RegExp(r"^([^a-z])|(\^)$"));
+  res.add(new RegExp(r"^[<>]&"));
+  res.add(new RegExp(r"(?:(f)(o)(o)|(b)(a)(r))*"));
+  res.add(new RegExp(r"(?:..)*a"));
+  res.add(new RegExp(r"(?:..)*?a"));
+  res.add(new RegExp(r"^(){3,5}"));
+  res.add(new RegExp(r"^(a+)*ax"));
+  res.add(new RegExp(r"^((a|b)+)*ax"));
+  res.add(new RegExp(r"^((a|bc)+)*ax"));
+  res.add(new RegExp(r"(a|x)*ab"));
+  res.add(new RegExp(r"(a)*ab"));
+  res.add(new RegExp(r"(?:c|d)(?:)(?:a(?:)(?:b)(?:b(?:))(?:b(?:)(?:b)))"));
+  res.add(new RegExp(r"(?:c|d)(?:)(?:aaaaaaaa(?:)(?:bbbbbbbb)(?:bbbbbbbb(?:))(?:bbbbbbbb(?:)(?:bbbbbbbb)))"));
+  res.add(new RegExp(r"foo\w*\d{4}baz"));
+  res.add(new RegExp(r"x(~~)*(?:(?:F)?)?"));
+  res.add(new RegExp(r"^a{3}c"));
+  res.add(new RegExp(r"^a{3}c"));
+  res.add(new RegExp(r"^(?:a?b?)*$"));
+  res.add(new RegExp(r"^b"));
+  res.add(new RegExp(r"()^b"));
+  res.add(new RegExp(r"(\w+:)+"));
+  res.add(new RegExp(r"([\w:]+::)?(\w+)$"));
+  res.add(new RegExp(r"^[^bcd]*(c+)"));
+  res.add(new RegExp(r"(a*)b+"));
+  res.add(new RegExp(r"([\w:]+::)?(\w+)$"));
+  res.add(new RegExp(r"^[^bcd]*(c+)"));
+  res.add(new RegExp(r"(>a+)ab"));
+  res.add(new RegExp(r"([[:]+)"));
+  res.add(new RegExp(r"([[=]+)"));
+  res.add(new RegExp(r"([[.]+)"));
+  res.add(new RegExp(r"a\Z"));
+  res.add(new RegExp(r"b\Z"));
+  res.add(new RegExp(r"b\z"));
+  res.add(new RegExp(r"b\Z"));
+  res.add(new RegExp(r"b\z"));
+  res.add(new RegExp(r"((Z)+|A)*"));
+  res.add(new RegExp(r"(Z()|A)*"));
+  res.add(new RegExp(r"(Z(())|A)*"));
+  res.add(new RegExp(r"a*"));
+  res.add(new RegExp(r"^[\d-a]"));
+  res.add(new RegExp(r"[[:space:]]+"));
+  res.add(new RegExp(r"[[:blank:]]+"));
+  res.add(new RegExp(r"[\s]+"));
+  res.add(new RegExp(r"\s+"));
+  res.add(new RegExp(r"ab"));
+  res.add(new RegExp(r"(?!\A)x", multiLine: true));
+  res.add(new RegExp(r"(?!^)x", multiLine: true));
+  res.add(new RegExp(r"abc\Qabc\Eabc"));
+  res.add(new RegExp(r"abc\Qabc\Eabc"));
+  res.add(new RegExp(r"abc\Qliteral\E"));
+  res.add(new RegExp(r"abc\Qliteral"));
+  res.add(new RegExp(r"abc\Qliteral\E"));
+  res.add(new RegExp(r"abc\Qliteral\E"));
+  res.add(new RegExp(r"\Qabc\$xyz\E"));
+  res.add(new RegExp(r"\Qabc\E\$\Qxyz\E"));
+  res.add(new RegExp(r"\Gabc"));
+  res.add(new RegExp(r"\Gabc."));
+  res.add(new RegExp(r"abc."));
+  res.add(new RegExp(r"[z\Qa-d]\E]"));
+  res.add(new RegExp(r"[\z\C]"));
+  res.add(new RegExp(r"\M"));
+  res.add(new RegExp(r"(a+)*b"));
+  res.add(new RegExp(r"line\nbreak"));
+  res.add(new RegExp(r"line\nbreak"));
+  res.add(new RegExp(r"line\nbreak", multiLine: true));
+  res.add(new RegExp(r"1234"));
+  res.add(new RegExp(r"1234"));
+  res.add(new RegExp(r"^", multiLine: true));
+  res.add(new RegExp(r"Content-Type\x3A[^\r\n]{6,}"));
+  res.add(new RegExp(r"Content-Type\x3A[^\r\n]{6,}z"));
+  res.add(new RegExp(r"Content-Type\x3A[^a]{6,}"));
+  res.add(new RegExp(r"Content-Type\x3A[^a]{6,}z"));
+  res.add(new RegExp(r"^abc", multiLine: true));
+  res.add(new RegExp(r"abc$", multiLine: true));
+  res.add(new RegExp(r"^abc", multiLine: true));
+  res.add(new RegExp(r"^abc", multiLine: true));
+  res.add(new RegExp(r"^abc", multiLine: true));
+  res.add(new RegExp(r".*"));
+  res.add(new RegExp(r"\w+(.)(.)?def"));
+  res.add(new RegExp(r"^\w+=.*(\\\n.*)*"));
+  res.add(new RegExp(r"^(a()*)*"));
+  res.add(new RegExp(r"^(?:a(?:(?:))*)*"));
+  res.add(new RegExp(r"^(a()+)+"));
+  res.add(new RegExp(r"^(?:a(?:(?:))+)+"));
+  res.add(new RegExp(r"(a|)*\d"));
+  res.add(new RegExp(r"(?:a|)*\d"));
+  res.add(new RegExp(r"^a.b"));
+  res.add(new RegExp(r"^abc.", multiLine: true));
+  res.add(new RegExp(r"abc.$", multiLine: true));
+  res.add(new RegExp(r"^a\Rb", caseSensitive: false));
+  res.add(new RegExp(r"^a\R*b", caseSensitive: false));
+  res.add(new RegExp(r"^a\R+b", caseSensitive: false));
+  res.add(new RegExp(r"^a\R{1,3}b", caseSensitive: false));
+  res.add(new RegExp(r"^a[\R]b", caseSensitive: false));
+  res.add(new RegExp(r".+foo"));
+  res.add(new RegExp(r".+foo"));
+  res.add(new RegExp(r".+foo"));
+  res.add(new RegExp(r".+foo"));
+  res.add(new RegExp(r"^$", multiLine: true));
+  res.add(new RegExp(r"^X", multiLine: true));
+  res.add(new RegExp(r"\H\h\V\v"));
+  res.add(new RegExp(r"\H*\h+\V?\v{3,4}"));
+  res.add(new RegExp(r"\H{3,4}"));
+  res.add(new RegExp(r".\h{3,4}."));
+  res.add(new RegExp(r"\h*X\h?\H+Y\H?Z"));
+  res.add(new RegExp(r"\v*X\v?Y\v+Z\V*\x0a\V+\x0b\V{2,3}\x0c"));
+  res.add(new RegExp(r".+A"));
+  res.add(new RegExp(r"\nA"));
+  res.add(new RegExp(r"[\r\n]A"));
+  res.add(new RegExp(r"(\r|\n)A"));
+  res.add(new RegExp(r"a\Rb", caseSensitive: false));
+  res.add(new RegExp(r"a\Rb", caseSensitive: false));
+  res.add(new RegExp(r"a\R?b", caseSensitive: false));
+  res.add(new RegExp(r"a\R?b", caseSensitive: false));
+  res.add(new RegExp(r"a\R{2,4}b", caseSensitive: false));
+  res.add(new RegExp(r"a\R{2,4}b", caseSensitive: false));
+  res.add(new RegExp(r"a(?!)|\wbc"));
+  res.add(new RegExp(r"a[]b"));
+  res.add(new RegExp(r"a[]+b"));
+  res.add(new RegExp(r"a[^]b"));
+  res.add(new RegExp(r"a[^]+b"));
+  res.add(new RegExp(r" End of testinput7 "));
+  res.add(new RegExp(r"\bX"));
+  res.add(new RegExp(r"\BX"));
+  res.add(new RegExp(r"X\b"));
+  res.add(new RegExp(r"X\B"));
+  res.add(new RegExp(r"[^a]"));
+  res.add(new RegExp(r"abc"));
+  res.add(new RegExp(r"a.b"));
+  res.add(new RegExp(r"a(.{3})b"));
+  res.add(new RegExp(r"a(.*?)(.)"));
+  res.add(new RegExp(r"a(.*?)(.)"));
+  res.add(new RegExp(r"a(.*)(.)"));
+  res.add(new RegExp(r"a(.*)(.)"));
+  res.add(new RegExp(r"a(.)(.)"));
+  res.add(new RegExp(r"a(.)(.)"));
+  res.add(new RegExp(r"a(.?)(.)"));
+  res.add(new RegExp(r"a(.?)(.)"));
+  res.add(new RegExp(r"a(.??)(.)"));
+  res.add(new RegExp(r"a(.??)(.)"));
+  res.add(new RegExp(r"a(.{3})b"));
+  res.add(new RegExp(r"a(.{3,})b"));
+  res.add(new RegExp(r"a(.{3,}?)b"));
+  res.add(new RegExp(r"a(.{3,5})b"));
+  res.add(new RegExp(r"a(.{3,5}?)b"));
+  res.add(new RegExp(r"[^a]+"));
+  res.add(new RegExp(r"^[^a]{2}"));
+  res.add(new RegExp(r"^[^a]{2,}"));
+  res.add(new RegExp(r"^[^a]{2,}?"));
+  res.add(new RegExp(r"[^a]+", caseSensitive: false));
+  res.add(new RegExp(r"^[^a]{2}", caseSensitive: false));
+  res.add(new RegExp(r"^[^a]{2,}", caseSensitive: false));
+  res.add(new RegExp(r"^[^a]{2,}?", caseSensitive: false));
+  res.add(new RegExp(r"\D*"));
+  res.add(new RegExp(r"\D*"));
+  res.add(new RegExp(r"\D"));
+  res.add(new RegExp(r">\S"));
+  res.add(new RegExp(r"\d"));
+  res.add(new RegExp(r"\s"));
+  res.add(new RegExp(r"\D+"));
+  res.add(new RegExp(r"\D{2,3}"));
+  res.add(new RegExp(r"\D{2,3}?"));
+  res.add(new RegExp(r"\d+"));
+  res.add(new RegExp(r"\d{2,3}"));
+  res.add(new RegExp(r"\d{2,3}?"));
+  res.add(new RegExp(r"\S+"));
+  res.add(new RegExp(r"\S{2,3}"));
+  res.add(new RegExp(r"\S{2,3}?"));
+  res.add(new RegExp(r">\s+<"));
+  res.add(new RegExp(r">\s{2,3}<"));
+  res.add(new RegExp(r">\s{2,3}?<"));
+  res.add(new RegExp(r"\w+"));
+  res.add(new RegExp(r"\w{2,3}"));
+  res.add(new RegExp(r"\w{2,3}?"));
+  res.add(new RegExp(r"\W+"));
+  res.add(new RegExp(r"\W{2,3}"));
+  res.add(new RegExp(r"\W{2,3}?"));
+  res.add(new RegExp(r"[\xFF]"));
+  res.add(new RegExp(r"[\xff]"));
+  res.add(new RegExp(r"[^\xFF]"));
+  res.add(new RegExp(r"[^\xff]"));
+  res.add(new RegExp(r"^[ac]*b"));
+  res.add(new RegExp(r"^[^x]*b", caseSensitive: false));
+  res.add(new RegExp(r"^[^x]*b"));
+  res.add(new RegExp(r"^\d*b"));
+  res.add(new RegExp(r"(|a)"));
+  res.add(new RegExp(r"^abc.", multiLine: true));
+  res.add(new RegExp(r"abc.$", multiLine: true));
+  res.add(new RegExp(r"^a\Rb", caseSensitive: false));
+  res.add(new RegExp(r"^a\R*b", caseSensitive: false));
+  res.add(new RegExp(r"^a\R+b", caseSensitive: false));
+  res.add(new RegExp(r"^a\R{1,3}b", caseSensitive: false));
+  res.add(new RegExp(r"\h+\V?\v{3,4}"));
+  res.add(new RegExp(r"\V?\v{3,4}"));
+  res.add(new RegExp(r"\h+\V?\v{3,4}"));
+  res.add(new RegExp(r"\V?\v{3,4}"));
+  res.add(new RegExp(r"\H\h\V\v"));
+  res.add(new RegExp(r"\H*\h+\V?\v{3,4}"));
+  res.add(new RegExp(r"\H\h\V\v"));
+  res.add(new RegExp(r"\H*\h+\V?\v{3,4}"));
+  res.add(new RegExp(r"a\Rb", caseSensitive: false));
+  res.add(new RegExp(r"a\Rb", caseSensitive: false));
+  res.add(new RegExp(r"a\R?b", caseSensitive: false));
+  res.add(new RegExp(r"a\R?b", caseSensitive: false));
+  res.add(new RegExp(r"X"));
+  res.add(new RegExp(r" End of testinput 8 "));
+  res.add(new RegExp(r"\pL\P{Nd}"));
+  res.add(new RegExp(r"\X."));
+  res.add(new RegExp(r"\X\X"));
+  res.add(new RegExp(r"^\pL+"));
+  res.add(new RegExp(r"^\PL+"));
+  res.add(new RegExp(r"^\X+"));
+  res.add(new RegExp(r"\X?abc"));
+  res.add(new RegExp(r"^\X?abc"));
+  res.add(new RegExp(r"\X*abc"));
+  res.add(new RegExp(r"^\X*abc"));
+  res.add(new RegExp(r"^\pL?=."));
+  res.add(new RegExp(r"^\pL*=."));
+  res.add(new RegExp(r"^\X{2,3}X"));
+  res.add(new RegExp(r"^\pC\pL\pM\pN\pP\pS\pZ<"));
+  res.add(new RegExp(r"^\PC"));
+  res.add(new RegExp(r"^\PL"));
+  res.add(new RegExp(r"^\PM"));
+  res.add(new RegExp(r"^\PN"));
+  res.add(new RegExp(r"^\PP"));
+  res.add(new RegExp(r"^\PS"));
+  res.add(new RegExp(r"^\PZ"));
+  res.add(new RegExp(r"^\p{Cc}"));
+  res.add(new RegExp(r"^\p{Cf}"));
+  res.add(new RegExp(r"^\p{Cn}"));
+  res.add(new RegExp(r"^\p{Co}"));
+  res.add(new RegExp(r"^\p{Cs}"));
+  res.add(new RegExp(r"^\p{Ll}"));
+  res.add(new RegExp(r"^\p{Lm}"));
+  res.add(new RegExp(r"^\p{Lo}"));
+  res.add(new RegExp(r"^\p{Lt}"));
+  res.add(new RegExp(r"^\p{Lu}"));
+  res.add(new RegExp(r"^\p{Mc}"));
+  res.add(new RegExp(r"^\p{Me}"));
+  res.add(new RegExp(r"^\p{Mn}"));
+  res.add(new RegExp(r"^\p{Nl}"));
+  res.add(new RegExp(r"^\p{No}"));
+  res.add(new RegExp(r"^\p{Pc}"));
+  res.add(new RegExp(r"^\p{Pd}"));
+  res.add(new RegExp(r"^\p{Pe}"));
+  res.add(new RegExp(r"^\p{Pf}"));
+  res.add(new RegExp(r"^\p{Pi}"));
+  res.add(new RegExp(r"^\p{Po}"));
+  res.add(new RegExp(r"^\p{Ps}"));
+  res.add(new RegExp(r"^\p{Sk}"));
+  res.add(new RegExp(r"^\p{So}"));
+  res.add(new RegExp(r"^\p{Zl}"));
+  res.add(new RegExp(r"^\p{Zp}"));
+  res.add(new RegExp(r"^\p{Zs}"));
+  res.add(new RegExp(r"\p{Nd}{2,}(..)"));
+  res.add(new RegExp(r"\p{Nd}{2,}?(..)"));
+  res.add(new RegExp(r"\p{Nd}*(..)"));
+  res.add(new RegExp(r"\p{Nd}*?(..)"));
+  res.add(new RegExp(r"\p{Nd}{2}(..)"));
+  res.add(new RegExp(r"\p{Nd}{2,3}(..)"));
+  res.add(new RegExp(r"\p{Nd}{2,3}?(..)"));
+  res.add(new RegExp(r"\p{Nd}?(..)"));
+  res.add(new RegExp(r"\p{Nd}??(..)"));
+  res.add(new RegExp(r"\p{Lu}", caseSensitive: false));
+  res.add(new RegExp(r"\p{^Lu}", caseSensitive: false));
+  res.add(new RegExp(r"\P{Lu}", caseSensitive: false));
+  res.add(new RegExp(r"[\p{Nd}]"));
+  res.add(new RegExp(r"[\P{Nd}]+"));
+  res.add(new RegExp(r"\D+"));
+  res.add(new RegExp(r"[\D]+"));
+  res.add(new RegExp(r"[\P{Nd}]+"));
+  res.add(new RegExp(r"[\D\P{Nd}]+"));
+  res.add(new RegExp(r"\pL"));
+  res.add(new RegExp(r"\pL", caseSensitive: false));
+  res.add(new RegExp(r"\p{Lu}"));
+  res.add(new RegExp(r"\p{Lu}", caseSensitive: false));
+  res.add(new RegExp(r"\p{Ll}"));
+  res.add(new RegExp(r"\p{Ll}", caseSensitive: false));
+  res.add(new RegExp(r"^\X"));
+  res.add(new RegExp(r"^[\X]"));
+  res.add(new RegExp(r"^(\X*)C"));
+  res.add(new RegExp(r"^(\X*?)C"));
+  res.add(new RegExp(r"^(\X*)(.)"));
+  res.add(new RegExp(r"^(\X*?)(.)"));
+  res.add(new RegExp(r"^\X(.)"));
+  res.add(new RegExp(r"^\X{2,3}(.)"));
+  res.add(new RegExp(r"^\X{2,3}?(.)"));
+  res.add(new RegExp(r"^\pN{2,3}X"));
+  res.add(new RegExp(r"^[\p{Arabic}]"));
+  res.add(new RegExp(r"^[\P{Yi}]"));
+  res.add(new RegExp(r"^\p{Any}X"));
+  res.add(new RegExp(r"^\P{Any}X"));
+  res.add(new RegExp(r"^\p{Any}?X"));
+  res.add(new RegExp(r"^\P{Any}?X"));
+  res.add(new RegExp(r"^\p{Any}*X"));
+  res.add(new RegExp(r"^\P{Any}*X"));
+  res.add(new RegExp(r"^[\p{Any}]X"));
+  res.add(new RegExp(r"^[\P{Any}]X"));
+  res.add(new RegExp(r"^[\p{Any}]?X"));
+  res.add(new RegExp(r"^[\P{Any}]?X"));
+  res.add(new RegExp(r"^[\p{Any}]+X"));
+  res.add(new RegExp(r"^[\P{Any}]+X"));
+  res.add(new RegExp(r"^[\p{Any}]*X"));
+  res.add(new RegExp(r"^[\P{Any}]*X"));
+  res.add(new RegExp(r"^\p{Any}{3,5}?"));
+  res.add(new RegExp(r"^\p{Any}{3,5}"));
+  res.add(new RegExp(r"^\P{Any}{3,5}?"));
+  res.add(new RegExp(r"^\p{L&}X"));
+  res.add(new RegExp(r"^[\p{L&}]X"));
+  res.add(new RegExp(r"^[\p{L&}]+X"));
+  res.add(new RegExp(r"^[\p{L&}]+?X"));
+  res.add(new RegExp(r"^\P{L&}X"));
+  res.add(new RegExp(r"^[\P{L&}]X"));
+  res.add(new RegExp(r"Check property support in non-UTF-8 mode"));
+  res.add(new RegExp(r"\p{L}{4}"));
+  res.add(new RegExp(r"\p{Carian}\p{Cham}\p{Kayah_Li}\p{Lepcha}\p{Lycian}\p{Lydian}\p{Ol_Chiki}\p{Rejang}\p{Saurashtra}\p{Sundanese}\p{Vai}"));
+  res.add(new RegExp(r" End "));
+  res.add(new RegExp(r"^[[:alnum:]]", multiLine: true));
+  res.add(new RegExp(r"a", multiLine: true, caseSensitive: false));
+  res.add(new RegExp(r"abcde", multiLine: true));
+  res.add(new RegExp(r"\x80", multiLine: true));
+  res.add(new RegExp(r"\xff", multiLine: true));
+  res.add(new RegExp(r"[\p{L}]", multiLine: true));
+  res.add(new RegExp(r"[\p{^L}]", multiLine: true));
+  res.add(new RegExp(r"[\P{L}]", multiLine: true));
+  res.add(new RegExp(r"[\P{^L}]", multiLine: true));
+  res.add(new RegExp(r"[\p{Nd}]", multiLine: true));
+  res.add(new RegExp(r"[a]", multiLine: true));
+  res.add(new RegExp(r"[a]", multiLine: true));
+  res.add(new RegExp(r"[\xaa]", multiLine: true));
+  res.add(new RegExp(r"[\xaa]", multiLine: true));
+  res.add(new RegExp(r"[^a]", multiLine: true));
+  res.add(new RegExp(r"[^a]", multiLine: true));
+  res.add(new RegExp(r"[^\xaa]", multiLine: true));
+  res.add(new RegExp(r"[^\xaa]", multiLine: true));
+  res.add(new RegExp(r" End of testinput10 "));
+  assertToStringEquals("abc", res[1].firstMatch("abc"), 0);
+  assertToStringEquals("abc", res[1].firstMatch("defabc"), 1);
+  assertToStringEquals("abc", res[1].firstMatch("Aabc"), 2);
+  assertNull(res[1].firstMatch("*** Failers"), 3);
+  assertToStringEquals("abc", res[1].firstMatch("Adefabc"), 4);
+  assertToStringEquals("ABC", res[1].firstMatch("ABC"), 5);
+  assertToStringEquals("abc", res[2].firstMatch("abc"), 6);
+  assertNull(res[2].firstMatch("Aabc"), 7);
+  assertNull(res[2].firstMatch("*** Failers"), 8);
+  assertNull(res[2].firstMatch("defabc"), 9);
+  assertNull(res[2].firstMatch("Adefabc"), 10);
+  assertToStringEquals("abc", res[7].firstMatch("abc"), 11);
+  assertNull(res[7].firstMatch("*** Failers"), 12);
+  assertNull(res[7].firstMatch("def\nabc"), 13);
+  assertThrows(() => new RegExp(r"x{5,4}"));
+  assertThrows(() => new RegExp(r"[abcd"));
+  assertThrows(() => new RegExp(r"[z-a]"));
+  assertThrows(() => new RegExp(r"^*"));
+  assertThrows(() => new RegExp(r"(abc"));
+  assertThrows(() => new RegExp(r"(?# abc"));
+  assertToStringEquals("cat", res[11].firstMatch("this sentence eventually mentions a cat"), 20);
+  assertToStringEquals("elephant", res[11].firstMatch("this sentences rambles on and on for a while and then reaches elephant"), 21);
+  assertToStringEquals("cat", res[12].firstMatch("this sentence eventually mentions a cat"), 22);
+  assertToStringEquals("elephant", res[12].firstMatch("this sentences rambles on and on for a while and then reaches elephant"), 23);
+  assertToStringEquals("CAT", res[13].firstMatch("this sentence eventually mentions a CAT cat"), 24);
+  assertToStringEquals("elephant", res[13].firstMatch("this sentences rambles on and on for a while to elephant ElePhant"), 25);
+  assertThrows(() => new RegExp(r"{4,5}abc"));
+  assertToStringEquals("abcb,a,b,c", res[18].firstMatch("abcb"), 27);
+  assertToStringEquals("abcb,a,b,c", res[18].firstMatch("O0abcb"), 28);
+  assertToStringEquals("abcb,a,b,c", res[18].firstMatch("O3abcb"), 29);
+  assertToStringEquals("abcb,a,b,c", res[18].firstMatch("O6abcb"), 30);
+  assertToStringEquals("abcb,a,b,c", res[18].firstMatch("O9abcb"), 31);
+  assertToStringEquals("abcb,a,b,c", res[18].firstMatch("O12abcb"), 32);
+  assertToStringEquals("abc,a,,", res[19].firstMatch("abc"), 33);
+  assertToStringEquals("abc,a,,", res[19].firstMatch("O0abc"), 34);
+  assertToStringEquals("abc,a,,", res[19].firstMatch("O3abc"), 35);
+  assertToStringEquals("abc,a,,", res[19].firstMatch("O6abc"), 36);
+  assertToStringEquals("aba,,a,b", res[19].firstMatch("aba"), 37);
+  assertToStringEquals("aba,,a,b", res[19].firstMatch("O0aba"), 38);
+  assertToStringEquals("aba,,a,b", res[19].firstMatch("O3aba"), 39);
+  assertToStringEquals("aba,,a,b", res[19].firstMatch("O6aba"), 40);
+  assertToStringEquals("aba,,a,b", res[19].firstMatch("O9aba"), 41);
+  assertToStringEquals("aba,,a,b", res[19].firstMatch("O12aba"), 42);
+  assertToStringEquals("abc", res[20].firstMatch("abc"), 43);
+  assertNull(res[20].firstMatch("*** Failers"), 44);
+  assertNull(res[20].firstMatch("abc\n"), 45);
+  assertNull(res[20].firstMatch("abc\ndef"), 46);
+  assertToStringEquals("the quick brown fox", res[22].firstMatch("the quick brown fox"), 47);
+  assertToStringEquals("the quick brown fox", res[22].firstMatch("this is a line with the quick brown fox"), 48);
+  assertToStringEquals("abc", res[23].firstMatch("abcdef"), 49);
+  assertToStringEquals("abc", res[23].firstMatch("abcdefB"), 50);
+  assertToStringEquals("defabc,abc,abc,", res[24].firstMatch("defabc"), 51);
+  assertToStringEquals("Zdefabc,abc,abc,", res[24].firstMatch("Zdefabc"), 52);
+  assertToStringEquals("abc", res[25].firstMatch("abc"), 53);
+  assertNull(res[25].firstMatch("*** Failers"), 54);
+  assertToStringEquals("abc", res[26].firstMatch("abcdef"), 55);
+  assertToStringEquals("abc", res[26].firstMatch("abcdefB"), 56);
+  assertToStringEquals("defabc,abc,abc,", res[27].firstMatch("defabc"), 57);
+  assertToStringEquals("Zdefabc,abc,abc,", res[27].firstMatch("Zdefabc"), 58);
+  assertToStringEquals("the quick brown fox", res[28].firstMatch("the quick brown fox"), 59);
+  assertNull(res[28].firstMatch("*** Failers"), 60);
+  assertToStringEquals("The Quick Brown Fox", res[28].firstMatch("The Quick Brown Fox"), 61);
+  assertToStringEquals("the quick brown fox", res[29].firstMatch("the quick brown fox"), 62);
+  assertToStringEquals("The Quick Brown Fox", res[29].firstMatch("The Quick Brown Fox"), 63);
+  assertNull(res[30].firstMatch("*** Failers"), 64);
+  assertNull(res[30].firstMatch("abc\ndef"), 65);
+  assertToStringEquals("abc", res[31].firstMatch("abc"), 66);
+  assertNull(res[31].firstMatch("abc\n"), 67);
+  assertToStringEquals("abc,abc", res[33].firstMatch("abc"), 68);
+  assertThrows(() => new RegExp(r")"));
+  assertToStringEquals("-pr", res[35].firstMatch("co-processors, and for"), 70);
+  assertToStringEquals("<def>ghi<klm>", res[36].firstMatch("abc<def>ghi<klm>nop"), 71);
+  assertToStringEquals("<def>", res[37].firstMatch("abc<def>ghi<klm>nop"), 72);
+  assertToStringEquals("<def>", res[37].firstMatch("abc<def>ghi<klm>nop"), 73);
+  assertNull(res[37].firstMatch("abc========def"), 74);
+  assertNull(res[37].firstMatch("foo"), 75);
+  assertNull(res[37].firstMatch("catfoo"), 76);
+  assertNull(res[37].firstMatch("*** Failers"), 77);
+  assertNull(res[37].firstMatch("the barfoo"), 78);
+  assertNull(res[37].firstMatch("and cattlefoo"), 79);
+  assertToStringEquals("a", res[40].firstMatch("a"), 80);
+  assertNull(res[40].firstMatch("a\n"), 81);
+  assertNull(res[40].firstMatch("*** Failers"), 82);
+  assertToStringEquals("a", res[40].firstMatch("Za"), 83);
+  assertNull(res[40].firstMatch("Za\n"), 84);
+  assertToStringEquals("a", res[41].firstMatch("a"), 85);
+  assertToStringEquals("a", res[41].firstMatch("a\n"), 86);
+  assertToStringEquals("a", res[41].firstMatch("Za\n"), 87);
+  assertNull(res[41].firstMatch("*** Failers"), 88);
+  assertToStringEquals("a", res[41].firstMatch("Za"), 89);
+  assertToStringEquals("b", res[44].firstMatch("foo\nbarbar"), 90);
+  assertToStringEquals("a", res[44].firstMatch("***Failers"), 91);
+  assertToStringEquals("b", res[44].firstMatch("rhubarb"), 92);
+  assertToStringEquals("b", res[44].firstMatch("barbell"), 93);
+  assertToStringEquals("a", res[44].firstMatch("abc\nbarton"), 94);
+  assertToStringEquals("b", res[44].firstMatch("foo\nbarbar"), 95);
+  assertToStringEquals("a", res[44].firstMatch("***Failers"), 96);
+  assertToStringEquals("b", res[44].firstMatch("rhubarb"), 97);
+  assertToStringEquals("b", res[44].firstMatch("barbell"), 98);
+  assertToStringEquals("a", res[44].firstMatch("abc\nbarton"), 99);
+  assertToStringEquals("a", res[44].firstMatch("abc"), 100);
+  assertToStringEquals("a", res[44].firstMatch("def\nabc"), 101);
+  assertToStringEquals("a", res[44].firstMatch("*** Failers"), 102);
+  assertToStringEquals("a", res[44].firstMatch("defabc"), 103);
+  assertNull(res[45].firstMatch("the bullock-cart"), 104);
+  assertNull(res[45].firstMatch("a donkey-cart race"), 105);
+  assertNull(res[45].firstMatch("*** Failers"), 106);
+  assertNull(res[45].firstMatch("cart"), 107);
+  assertNull(res[45].firstMatch("horse-and-cart"), 108);
+  assertNull(res[45].firstMatch("alphabetabcd"), 109);
+  assertNull(res[45].firstMatch("endingxyz"), 110);
+  assertNull(res[45].firstMatch("abxyZZ"), 111);
+  assertNull(res[45].firstMatch("abXyZZ"), 112);
+  assertNull(res[45].firstMatch("ZZZ"), 113);
+  assertNull(res[45].firstMatch("zZZ"), 114);
+  assertNull(res[45].firstMatch("bZZ"), 115);
+  assertNull(res[45].firstMatch("BZZ"), 116);
+  assertNull(res[45].firstMatch("*** Failers"), 117);
+  assertNull(res[45].firstMatch("ZZ"), 118);
+  assertNull(res[45].firstMatch("abXYZZ"), 119);
+  assertNull(res[45].firstMatch("zzz"), 120);
+  assertNull(res[45].firstMatch("bzz"), 121);
+  assertNull(res[45].firstMatch("bar"), 122);
+  assertNull(res[45].firstMatch("foobbar"), 123);
+  assertNull(res[45].firstMatch("*** Failers"), 124);
+  assertNull(res[45].firstMatch("fooabar"), 125);
+  assertNull(res[46].firstMatch("*** Failers"), 126);
+  assertNull(res[46].firstMatch("a"), 127);
+  assertNull(res[48].firstMatch("aaaaaa"), 128);
+  assertThrows(() => new RegExp(r"a[b-a]"), 129);
+  assertThrows(() => new RegExp(r"a["), 130);
+  assertThrows(() => new RegExp(r"*a"), 131);
+  assertThrows(() => new RegExp(r"abc)"), 132);
+  assertThrows(() => new RegExp(r"(abc"), 133);
+  assertThrows(() => new RegExp(r"a**"), 134);
+  assertThrows(() => new RegExp(r")("), 135);
+  assertThrows(() => new RegExp(r"a[b-a]"), 136);
+  assertThrows(() => new RegExp(r"a["), 137);
+  assertThrows(() => new RegExp(r"*a"), 138);
+  assertThrows(() => new RegExp(r"abc)"), 139);
+  assertThrows(() => new RegExp(r"(abc"), 140);
+  assertThrows(() => new RegExp(r"a**"), 141);
+  assertThrows(() => new RegExp(r")("), 142);
+  assertThrows(() => new RegExp(r":(?:"), 143);
+  assertThrows(() => new RegExp(r"a(?{)b"), 144);
+  assertThrows(() => new RegExp(r"a(?{{})b"), 145);
+  assertThrows(() => new RegExp(r"a(?{}})b"), 146);
+  assertThrows(() => new RegExp(r'a(?{\"{\"})b'), 147);
+  assertThrows(() => new RegExp(r'a(?{\"{\"}})b'), 148);
+  assertThrows(() => new RegExp(r"[a[:xyz:"), 149);
+  assertThrows(() => new RegExp(r"a{37,17}"), 150);
+  assertToStringEquals("abcd,a,d", res[58].firstMatch("abcd"), 151);
+  assertToStringEquals("abcd,a,d", res[58].firstMatch("abcdC2"), 152);
+  assertToStringEquals("abcd,a,d", res[58].firstMatch("abcdC5"), 153);
+  assertToStringEquals("abcdefghijklmnopqrst,abcdefghijklmnopqrst", res[59].firstMatch("abcdefghijklmnopqrstuvwxyz"), 154);
+  assertToStringEquals("abcdefghijklmnopqrst,abcdefghijklmnopqrst", res[59].firstMatch("abcdefghijklmnopqrstuvwxyzC1"), 155);
+  assertToStringEquals("abcdefghijklmnopqrst,abcdefghijklmnopqrst", res[59].firstMatch("abcdefghijklmnopqrstuvwxyzG1"), 156);
+  assertToStringEquals("abcdefghijklmno,abcdefghijklmno", res[60].firstMatch("abcdefghijklmnopqrstuvwxyz"), 157);
+  assertToStringEquals("abcdefghijklmno,abcdefghijklmno", res[60].firstMatch("abcdefghijklmnopqrstuvwxyzC1G1"), 158);
+  assertToStringEquals("abcdefghijklmnop,abcdefghijklmnop", res[61].firstMatch("abcdefghijklmnopqrstuvwxyz"), 159);
+  assertToStringEquals("abcdefghijklmnop,abcdefghijklmnop", res[61].firstMatch("abcdefghijklmnopqrstuvwxyzC1G1L"), 160);
+  assertToStringEquals("adef,a,,f", res[62].firstMatch("adefG1G2G3G4L"), 161);
+  assertToStringEquals("bcdef,bc,bc,f", res[62].firstMatch("bcdefG1G2G3G4L"), 162);
+  assertToStringEquals("adef,a,,f", res[62].firstMatch("adefghijkC0"), 163);
+  assertToStringEquals("abc\x00def", res[63].firstMatch("abc\x00defLC0"), 164);
+  assertToStringEquals("iss", res[69].firstMatch("Mississippi"), 165);
+  assertToStringEquals("iss", res[70].firstMatch("Mississippi"), 166);
+  assertToStringEquals("iss", res[71].firstMatch("Mississippi"), 167);
+  assertToStringEquals("iss", res[72].firstMatch("Mississippi"), 168);
+  assertToStringEquals("iss", res[73].firstMatch("Mississippi"), 169);
+  assertNull(res[73].firstMatch("*** Failers"), 170);
+  assertToStringEquals("iss", res[73].firstMatch("MississippiA"), 171);
+  assertToStringEquals("iss", res[73].firstMatch("Mississippi"), 172);
+  assertToStringEquals("iss", res[74].firstMatch("ississippi"), 174);
+  assertToStringEquals("abciss", res[75].firstMatch("abciss\nxyzisspqr"), 175);
+  assertToStringEquals("Mis", res[76].firstMatch("Mississippi"), 176);
+  assertToStringEquals("Mis", res[77].firstMatch("Mississippi"), 180);
+  assertToStringEquals("ab\n", res[78].firstMatch("ab\nab\ncd"), 181);
+  assertToStringEquals("ab\n", res[79].firstMatch("ab\nab\ncd"), 182);
+  assertToStringEquals("a", res[115].firstMatch("a"), 183);
+  assertToStringEquals("b", res[115].firstMatch("b"), 184);
+  assertToStringEquals("ab", res[115].firstMatch("ab"), 185);
+  assertToStringEquals("", res[115].firstMatch("\\"), 186);
+  assertToStringEquals("", res[115].firstMatch("*** Failers"), 187);
+  assertToStringEquals("", res[115].firstMatch("N"), 188);
+  assertToStringEquals("", res[116].firstMatch("abcd"), 189);
+  assertToStringEquals("", res[116].firstMatch("-abc"), 190);
+  assertToStringEquals("", res[116].firstMatch("Nab-c"), 191);
+  assertToStringEquals("", res[116].firstMatch("*** Failers"), 192);
+  assertToStringEquals("", res[116].firstMatch("Nabc"), 193);
+  assertToStringEquals("aaaabbbbzz,bbbb,z,z", res[117].firstMatch("aaaabbbbzzzz"), 194);
+  assertToStringEquals("aaaabbbbzz,bbbb,z,z", res[117].firstMatch("aaaabbbbzzzzO0"), 195);
+  assertToStringEquals("aaaabbbbzz,bbbb,z,z", res[117].firstMatch("aaaabbbbzzzzO1"), 196);
+  assertToStringEquals("aaaabbbbzz,bbbb,z,z", res[117].firstMatch("aaaabbbbzzzzO2"), 197);
+  assertToStringEquals("aaaabbbbzz,bbbb,z,z", res[117].firstMatch("aaaabbbbzzzzO3"), 198);
+  assertToStringEquals("aaaabbbbzz,bbbb,z,z", res[117].firstMatch("aaaabbbbzzzzO4"), 199);
+  assertToStringEquals("aaaabbbbzz,bbbb,z,z", res[117].firstMatch("aaaabbbbzzzzO5"), 200);
+  assertToStringEquals("(abcd", res[118].firstMatch("(abcd)"), 201);
+  assertToStringEquals("(abcd", res[118].firstMatch("(abcd)xyz"), 202);
+  assertNull(res[118].firstMatch("xyz(abcd)"), 203);
+  assertNull(res[118].firstMatch("(ab(xy)cd)pqr"), 204);
+  assertNull(res[118].firstMatch("(ab(xycd)pqr"), 205);
+  assertNull(res[118].firstMatch("() abc ()"), 206);
+  assertNull(res[118].firstMatch("12(abcde(fsh)xyz(foo(bar))lmno)89"), 207);
+  assertNull(res[118].firstMatch("*** Failers"), 208);
+  assertToStringEquals("abcd", res[118].firstMatch("abcd"), 209);
+  assertToStringEquals("abcd", res[118].firstMatch("abcd)"), 210);
+  assertToStringEquals("(abcd", res[118].firstMatch("(abcd"), 211);
+  assertNull(res[118].firstMatch("(ab(xy)cd)pqr"), 212);
+  assertNull(res[118].firstMatch("1(abcd)(x(y)z)pqr"), 213);
+  assertToStringEquals("(abcd", res[118].firstMatch("(abcd)"), 214);
+  assertNull(res[118].firstMatch("(ab(xy)cd)"), 215);
+  assertNull(res[118].firstMatch("(a(b(c)d)e)"), 216);
+  assertNull(res[118].firstMatch("((ab))"), 217);
+  assertNull(res[118].firstMatch("*** Failers"), 218);
+  assertNull(res[118].firstMatch("()"), 219);
+  assertNull(res[118].firstMatch("()"), 220);
+  assertNull(res[118].firstMatch("12(abcde(fsh)xyz(foo(bar))lmno)89"), 221);
+  assertNull(res[118].firstMatch("(ab(xy)cd)"), 222);
+  assertNull(res[118].firstMatch("(ab(xy)cd)"), 223);
+  assertNull(res[118].firstMatch("(ab(xy)cd)"), 224);
+  assertNull(res[118].firstMatch("(123ab(xy)cd)"), 225);
+  assertNull(res[118].firstMatch("(ab(xy)cd)"), 226);
+  assertNull(res[118].firstMatch("(123ab(xy)cd)"), 227);
+  assertNull(res[118].firstMatch("(ab(xy)cd)"), 228);
+  assertToStringEquals("(abcd", res[118].firstMatch("(abcd(xyz<p>qrs)123)"), 229);
+  assertNull(res[118].firstMatch("(ab(cd)ef)"), 230);
+  assertNull(res[118].firstMatch("(ab(cd(ef)gh)ij)"), 231);
+  assertNull(res[146].firstMatch("A"), 232);
+  assertNull(res[146].firstMatch("a"), 233);
+  assertNull(res[147].firstMatch("A"), 234);
+  assertNull(res[147].firstMatch("a"), 235);
+  assertNull(res[147].firstMatch("ab"), 236);
+  assertNull(res[147].firstMatch("aB"), 237);
+  assertNull(res[147].firstMatch("*** Failers"), 238);
+  assertNull(res[147].firstMatch("Ab"), 239);
+  assertNull(res[147].firstMatch("AB"), 240);
+  assertThrows(() => new RegExp(r"[\200-\110]"), 241);
+  // TODO(jgruber): Reintegrate stack-overflow2_test.dart once it passes.
+  assertToStringEquals("mainmain,main,", res[151].firstMatch("mainmain"), 243);
+  assertToStringEquals("mainOmain,main,", res[151].firstMatch("mainOmain"), 244);
+  assertToStringEquals("aba,a,", res[153].firstMatch("aba"), 245);
+  assertToStringEquals("aabbaa,aa,", res[154].firstMatch("aabbaa"), 246);
+  assertToStringEquals("aabbaa,aa,", res[155].firstMatch("aabbaa"), 247);
+  assertToStringEquals("aabbaa,aa,", res[156].firstMatch("aabbaa"), 248);
+  assertToStringEquals("aabbaa,", res[157].firstMatch("aabbaa"), 249);
+  assertToStringEquals("aabbaa,aa,,", res[158].firstMatch("aabbaa"), 250);
+  assertToStringEquals("aabbaa,,", res[159].firstMatch("aabbaa"), 251);
+  assertToStringEquals("aabbaa,", res[160].firstMatch("aabbaa"), 252);
+  assertToStringEquals("aabbbaa,", res[161].firstMatch("aabbbaa"), 253);
+  assertToStringEquals("aabbbaa,", res[162].firstMatch("aabbbaa"), 254);
+  assertToStringEquals("aabbaa,", res[163].firstMatch("aabbaa"), 255);
+  assertToStringEquals("aabbbaa,", res[164].firstMatch("aabbbaa"), 256);
+  assertToStringEquals("aabbbaa,aa,,", res[165].firstMatch("aabbbaa"), 257);
+  assertToStringEquals("aabbbbaa,aa,,", res[166].firstMatch("aabbbbaa"), 258);
+  // Dart does not have RegExp literals and thus no translatation of the below.
+  // assertThrows("var re = //;", 259);
+  assertToStringEquals("a", res[169].firstMatch("ab"), 260);
+  assertToStringEquals("a", res[169].firstMatch("aB"), 261);
+  assertToStringEquals("*", res[169].firstMatch("*** Failers"), 262);
+  assertToStringEquals("A", res[169].firstMatch("AB"), 263);
+  assertToStringEquals("a", res[169].firstMatch("ab"), 264);
+  assertToStringEquals("a", res[169].firstMatch("aB"), 265);
+  assertToStringEquals("*", res[169].firstMatch("*** Failers"), 266);
+  assertToStringEquals("A", res[169].firstMatch("AB"), 267);
+  assertNull(res[172].firstMatch("\\"), 268);
+  assertNull(res[177].firstMatch("*** Failers"), 269);
+  assertNull(res[177].firstMatch("xxxxx"), 270);
+  assertNull(res[177].firstMatch("now is the time for all good men to come to the aid of the party"), 271);
+  assertNull(res[177].firstMatch("*** Failers"), 272);
+  assertNull(res[177].firstMatch("this is not a line with only words and spaces!"), 273);
+  assertNull(res[177].firstMatch("12345a"), 274);
+  assertNull(res[177].firstMatch("*** Failers"), 275);
+  assertNull(res[177].firstMatch("12345+"), 276);
+  assertNull(res[177].firstMatch("aaab"), 277);
+  assertNull(res[177].firstMatch("aaab"), 278);
+  assertNull(res[177].firstMatch("aaab"), 279);
+  assertNull(res[177].firstMatch("((abc(ade)ufh()()x"), 280);
+  assertNull(res[177].firstMatch("(abc)"), 281);
+  assertNull(res[177].firstMatch("(abc(def)xyz)"), 282);
+  assertNull(res[177].firstMatch("*** Failers"), 283);
+  assertNull(res[177].firstMatch("((()aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"), 284);
+  assertNull(res[177].firstMatch("xaaaab"), 285);
+  assertNull(res[177].firstMatch("xaaaab"), 286);
+  assertThrows(() => new RegExp(r"["), 287);
+  assertThrows(() => new RegExp(r"[a-"), 288);
+  assertNull(res[189].firstMatch("<>"), 289);
+  assertNull(res[189].firstMatch("<abcd>"), 290);
+  assertNull(res[189].firstMatch("<abc <123> hij>"), 291);
+  assertNull(res[189].firstMatch("<abc <def> hij>"), 292);
+  assertNull(res[189].firstMatch("<abc<>def>"), 293);
+  assertNull(res[189].firstMatch("<abc<>"), 294);
+  assertNull(res[189].firstMatch("*** Failers"), 295);
+  assertNull(res[189].firstMatch("<abc"), 296);
+  assertToStringEquals("bc123bc,bc,bc", res[195].firstMatch("abc123bc"), 297);
+  assertToStringEquals("abc", res[215].firstMatch("abcdef"), 298);
+  assertToStringEquals("abc", res[215].firstMatch("1234abcdef"), 299);
+  assertNull(res[215].firstMatch("*** Failers"), 300);
+  assertToStringEquals("abc", res[215].firstMatch("abcxyz"), 301);
+  assertToStringEquals("abc", res[215].firstMatch("abcxyzf"), 302);
+  assertToStringEquals("abc", res[215].firstMatch("123abcdef"), 303);
+  assertToStringEquals("abc", res[215].firstMatch("1234abcdef"), 304);
+  assertNull(res[215].firstMatch("*** Failers"), 305);
+  assertToStringEquals("abc", res[215].firstMatch("abcdef"), 306);
+  assertNull(res[215].firstMatch("*** Failers"), 307);
+  assertToStringEquals("abc", res[215].firstMatch("\x83x0abcdef"), 308);
+  assertToStringEquals("abc", res[215].firstMatch("123abcdef"), 309);
+  assertToStringEquals("abc", res[215].firstMatch("123abcdefC+"), 310);
+  assertToStringEquals("abc", res[215].firstMatch("123abcdefC-"), 311);
+  assertNull(res[215].firstMatch("*** Failers"), 312);
+  assertToStringEquals("abc", res[215].firstMatch("123abcdefC!1"), 313);
+  assertToStringEquals("abc", res[215].firstMatch("abcabcabc"), 314);
+  assertToStringEquals("abc", res[215].firstMatch("abcabcC!1!3"), 315);
+  assertNull(res[215].firstMatch("*** Failers"), 316);
+  assertToStringEquals("abc", res[215].firstMatch("abcabcabcC!1!3"), 317);
+  assertToStringEquals("C", res[215].firstMatch("123C+"), 318);
+  assertToStringEquals("C", res[215].firstMatch("123456C+"), 319);
+  assertToStringEquals("C", res[215].firstMatch("123456789C+"), 320);
+  assertToStringEquals("abc", res[215].firstMatch("xyzabcC+"), 321);
+  assertToStringEquals("abc", res[215].firstMatch("XxyzabcC+"), 322);
+  assertToStringEquals("abc", res[215].firstMatch("abcdefC+"), 323);
+  assertToStringEquals("abc", res[215].firstMatch("abcxyzC+"), 324);
+  assertToStringEquals("c", res[215].firstMatch("abbbbbcccC*1"), 325);
+  assertToStringEquals("c", res[215].firstMatch("abbbbbcccC*1"), 326);
+  assertNull(res[215].firstMatch("xab"), 327);
+  assertToStringEquals("c", res[215].firstMatch("xbc"), 328);
+  assertNull(res[215].firstMatch("xde"), 329);
+  assertNull(res[215].firstMatch("xxab"), 330);
+  assertNull(res[215].firstMatch("xxxab"), 331);
+  assertNull(res[215].firstMatch("*** Failers"), 332);
+  assertNull(res[215].firstMatch("xyab"), 333);
+  assertToStringEquals("abc", res[215].firstMatch("abc"), 334);
+  assertToStringEquals("c", res[215].firstMatch("a(b)c"), 335);
+  assertToStringEquals("c", res[215].firstMatch("a(b(c))d"), 336);
+  assertNull(res[215].firstMatch("*** Failers)"), 337);
+  assertToStringEquals("c", res[215].firstMatch("a(b(c)d"), 338);
+  assertNull(res[215].firstMatch("1221"), 339);
+  assertToStringEquals("c", res[215].firstMatch("Satan, oscillate my metallic sonatas!"), 340);
+  assertToStringEquals("c", res[215].firstMatch("A man, a plan, a canal: Panama!"), 341);
+  assertNull(res[215].firstMatch("Able was I ere I saw Elba."), 342);
+  assertNull(res[215].firstMatch("*** Failers"), 343);
+  assertToStringEquals("c", res[215].firstMatch("The quick brown fox"), 344);
+  assertNull(res[215].firstMatch("12"), 345);
+  assertNull(res[215].firstMatch("(((2+2)*-3)-7)"), 346);
+  assertNull(res[215].firstMatch("-12"), 347);
+  assertNull(res[215].firstMatch("*** Failers"), 348);
+  assertNull(res[215].firstMatch("((2+2)*-3)-7)"), 349);
+  assertNull(res[215].firstMatch("xyz"), 350);
+  assertNull(res[215].firstMatch("xxyzxyzz"), 351);
+  assertNull(res[215].firstMatch("*** Failers"), 352);
+  assertNull(res[215].firstMatch("xxyzz"), 353);
+  assertNull(res[215].firstMatch("xxyzxyzxyzz"), 354);
+  assertNull(res[215].firstMatch("<>"), 355);
+  assertToStringEquals("abc", res[215].firstMatch("<abcd>"), 356);
+  assertToStringEquals("abc", res[215].firstMatch("<abc <123> hij>"), 357);
+  assertToStringEquals("abc", res[215].firstMatch("<abc <def> hij>"), 358);
+  assertToStringEquals("abc", res[215].firstMatch("<abc<>def>"), 359);
+  assertToStringEquals("abc", res[215].firstMatch("<abc<>"), 360);
+  assertNull(res[215].firstMatch("*** Failers"), 361);
+  assertToStringEquals("abc", res[215].firstMatch("<abc"), 362);
+  assertToStringEquals("abc", res[215].firstMatch("abcdefabc"), 363);
+  assertNull(res[215].firstMatch("a=a"), 364);
+  assertNull(res[215].firstMatch("a=b"), 365);
+  assertToStringEquals("c", res[215].firstMatch("a=bc"), 366);
+  assertNull(res[215].firstMatch("a=a"), 367);
+  assertNull(res[215].firstMatch("a=b"), 368);
+  assertToStringEquals("c", res[215].firstMatch("a=bc"), 369);
+  assertNull(res[215].firstMatch("abde"), 370);
+  assertToStringEquals("c", res[215].firstMatch("acde"), 371);
+  assertNull(res[215].firstMatch("1221"), 372);
+  assertToStringEquals("c", res[215].firstMatch("Satan, oscillate my metallic sonatas!"), 373);
+  assertToStringEquals("c", res[215].firstMatch("A man, a plan, a canal: Panama!"), 374);
+  assertNull(res[215].firstMatch("Able was I ere I saw Elba."), 375);
+  assertNull(res[215].firstMatch("*** Failers"), 376);
+  assertToStringEquals("c", res[215].firstMatch("The quick brown fox"), 377);
+  assertNull(res[228].firstMatch("abcdefgh"), 378);
+  assertNull(res[228].firstMatch("abcdefghC1Gtwo"), 379);
+  assertNull(res[228].firstMatch("abcdefghConeCtwo"), 380);
+  assertNull(res[228].firstMatch("abcdefghCthree"), 381);
+  assertToStringEquals("zz,", res[228].firstMatch("zzaaCZ"), 382);
+  assertToStringEquals("zz,", res[228].firstMatch("zzaaCA"), 383);
+  assertNull(res[228].firstMatch("[10,20,30,5,5,4,4,2,43,23,4234]"), 384);
+  assertNull(res[228].firstMatch("*** Failers"), 385);
+  assertNull(res[228].firstMatch("[]"), 386);
+  assertNull(res[228].firstMatch("[10,20,30,5,5,4,4,2,43,23,4234]"), 387);
+  assertNull(res[228].firstMatch("[]"), 388);
+  assertToStringEquals(" Baby Bjorn Active Carrier - With free SHIPPING!!, Baby Bjorn Active Carrier - With free SHIPPING!!,,", res[229].firstMatch(" Baby Bjorn Active Carrier - With free SHIPPING!!"), 389);
+  assertToStringEquals(" Baby Bjorn Active Carrier - With free SHIPPING!!, Baby Bjorn Active Carrier - With free SHIPPING!!,,", res[230].firstMatch(" Baby Bjorn Active Carrier - With free SHIPPING!!"), 390);
+  assertNull(res[238].firstMatch("Note: that { does NOT introduce a quantifier"), 391);
+  assertToStringEquals("aacaacaacaacaac123,aac", res[239].firstMatch("aacaacaacaacaac123"), 392);
+  assertNull(res[243].firstMatch("abP"), 393);
+  assertNull(res[243].firstMatch("abcP"), 394);
+  assertNull(res[243].firstMatch("abcdP"), 395);
+  assertToStringEquals("abcde", res[243].firstMatch("abcdeP"), 396);
+  assertNull(res[243].firstMatch("the quick brown abcP"), 397);
+  assertNull(res[243].firstMatch("** FailersP"), 398);
+  assertNull(res[243].firstMatch("the quick brown abxyz foxP"), 399);
+  assertNull(res[243].firstMatch("13/05/04P"), 400);
+  assertNull(res[243].firstMatch("13/5/2004P"), 401);
+  assertNull(res[243].firstMatch("02/05/09P"), 402);
+  assertNull(res[243].firstMatch("1P"), 403);
+  assertNull(res[243].firstMatch("1/2P"), 404);
+  assertNull(res[243].firstMatch("1/2/0P"), 405);
+  assertNull(res[243].firstMatch("1/2/04P"), 406);
+  assertNull(res[243].firstMatch("0P"), 407);
+  assertNull(res[243].firstMatch("02/P"), 408);
+  assertNull(res[243].firstMatch("02/0P"), 409);
+  assertNull(res[243].firstMatch("02/1P"), 410);
+  assertNull(res[243].firstMatch("** FailersP"), 411);
+  assertNull(res[243].firstMatch("P"), 412);
+  assertNull(res[243].firstMatch("123P"), 413);
+  assertNull(res[243].firstMatch("33/4/04P"), 414);
+  assertNull(res[243].firstMatch("3/13/04P"), 415);
+  assertNull(res[243].firstMatch("0/1/2003P"), 416);
+  assertNull(res[243].firstMatch("0/P"), 417);
+  assertNull(res[243].firstMatch("02/0/P"), 418);
+  assertNull(res[243].firstMatch("02/13P"), 419);
+  assertToStringEquals("123", res[248].firstMatch("123P"), 420);
+  assertNull(res[248].firstMatch("aP"), 421);
+  assertNull(res[248].firstMatch("bP"), 422);
+  assertNull(res[248].firstMatch("cP"), 423);
+  assertNull(res[248].firstMatch("c12P"), 424);
+  assertToStringEquals("c123", res[248].firstMatch("c123P"), 425);
+  assertNull(res[249].firstMatch("1P"), 426);
+  assertNull(res[249].firstMatch("123P"), 427);
+  assertToStringEquals("123X", res[249].firstMatch("123X"), 428);
+  assertNull(res[249].firstMatch("1234P"), 429);
+  assertToStringEquals("1234X", res[249].firstMatch("1234X"), 430);
+  assertNull(res[249].firstMatch("12345P"), 431);
+  assertToStringEquals("12345X", res[249].firstMatch("12345X"), 432);
+  assertNull(res[249].firstMatch("*** Failers"), 433);
+  assertNull(res[249].firstMatch("1X"), 434);
+  assertNull(res[249].firstMatch("123456P"), 435);
+  assertNull(res[249].firstMatch("abc"), 436);
+  assertNull(res[249].firstMatch("** Failers"), 437);
+  assertNull(res[249].firstMatch("bca"), 438);
+  assertNull(res[249].firstMatch("abc"), 439);
+  assertNull(res[249].firstMatch("** Failers"), 440);
+  assertNull(res[249].firstMatch("bca"), 441);
+  assertNull(res[249].firstMatch("abc"), 442);
+  assertNull(res[249].firstMatch("** Failers"), 443);
+  assertNull(res[249].firstMatch("def"), 444);
+  assertNull(res[249].firstMatch("abc"), 445);
+  assertNull(res[249].firstMatch("** Failers"), 446);
+  assertNull(res[249].firstMatch("def"), 447);
+  assertNull(res[249].firstMatch("<!DOCTYPE seite SYSTEM \"http://www.lco.lineas.de/xmlCms.dtd\">\n<seite>\n<dokumenteninformation>\n<seitentitel>Partner der LCO</seitentitel>\n<sprache>de</sprache>\n<seitenbeschreibung>Partner der LINEAS Consulting\nGmbH</seitenbeschreibung>\n<schluesselworte>LINEAS Consulting GmbH Hamburg\nPartnerfirmen</schluesselworte>\n<revisit>30 days</revisit>\n<robots>index,follow</robots>\n<menueinformation>\n<aktiv>ja</aktiv>\n<menueposition>3</menueposition>\n<menuetext>Partner</menuetext>\n</menueinformation>\n<lastedited>\n<autor>LCO</autor>\n<firma>LINEAS Consulting</firma>\n<datum>15.10.2003</datum>\n</lastedited>\n</dokumenteninformation>\n<inhalt>\n\n<absatzueberschrift>Die Partnerfirmen der LINEAS Consulting\nGmbH</absatzueberschrift>\n\n<absatz><link ziel=\"http://www.ca.com/\" zielfenster=\"_blank\">\n<bild name=\"logo_ca.gif\" rahmen=\"no\"/></link> <link\nziel=\"http://www.ey.com/\" zielfenster=\"_blank\"><bild\nname=\"logo_euy.gif\" rahmen=\"no\"/></link>\n</absatz>\n\n<absatz><link ziel=\"http://www.cisco.de/\" zielfenster=\"_blank\">\n<bild name=\"logo_cisco.gif\" rahmen=\"ja\"/></link></absatz>\n\n<absatz><link ziel=\"http://www.atelion.de/\"\nzielfenster=\"_blank\"><bild\nname=\"logo_atelion.gif\" rahmen=\"no\"/></link>\n</absatz>\n\n<absatz><link ziel=\"http://www.line-information.de/\"\nzielfenster=\"_blank\">\n<bild name=\"logo_line_information.gif\" rahmen=\"no\"/></link>\n</absatz>\n\n<absatz><bild name=\"logo_aw.gif\" rahmen=\"no\"/></absatz>\n\n<absatz><link ziel=\"http://www.incognis.de/\"\nzielfenster=\"_blank\"><bild\nname=\"logo_incognis.gif\" rahmen=\"no\"/></link></absatz>\n\n<absatz><link ziel=\"http://www.addcraft.com/\"\nzielfenster=\"_blank\"><bild\nname=\"logo_addcraft.gif\" rahmen=\"no\"/></link></absatz>\n\n<absatz><link ziel=\"http://www.comendo.com/\"\nzielfenster=\"_blank\"><bild\nname=\"logo_comendo.gif\" rahmen=\"no\"/></link></absatz>\n\n</inhalt>\n</seite>"), 448);
+  assertToStringEquals("line\nbreak", res[251].firstMatch("this is a line\nbreak"), 449);
+  assertToStringEquals("line\nbreak", res[251].firstMatch("line one\nthis is a line\nbreak in the second line"), 450);
+  assertToStringEquals("line\nbreak", res[252].firstMatch("this is a line\nbreak"), 451);
+  assertNull(res[252].firstMatch("** Failers"), 452);
+  assertToStringEquals("line\nbreak", res[252].firstMatch("line one\nthis is a line\nbreak in the second line"), 453);
+  assertToStringEquals("line\nbreak", res[253].firstMatch("this is a line\nbreak"), 454);
+  assertNull(res[253].firstMatch("** Failers"), 455);
+  assertToStringEquals("line\nbreak", res[253].firstMatch("line one\nthis is a line\nbreak in the second line"), 456);
+  assertToStringEquals("ab-cd", res[254].firstMatch("ab-cd"), 457);
+  assertToStringEquals("ab=cd", res[254].firstMatch("ab=cd"), 458);
+  assertNull(res[254].firstMatch("** Failers"), 459);
+  assertNull(res[254].firstMatch("ab\ncd"), 460);
+  assertToStringEquals("ab-cd", res[255].firstMatch("ab-cd"), 461);
+  assertToStringEquals("ab=cd", res[255].firstMatch("ab=cd"), 462);
+  assertNull(res[255].firstMatch("ab\ncd"), 463);
+  assertNull(res[255].firstMatch("AbCd"), 464);
+  assertNull(res[255].firstMatch("** Failers"), 465);
+  assertNull(res[255].firstMatch("abcd"), 466);
+  // We are compatible with JSC, and don't throw an exception in this case.
+  // assertThrows("var re = /(){2,4294967295}/;", 467);
+  assertNull(res[255].firstMatch("abcdefghijklAkB"), 468);
+  assertNull(res[255].firstMatch("abcdefghijklAkB"), 469);
+  assertNull(res[255].firstMatch("abcdefghijklAkB"), 470);
+  assertNull(res[255].firstMatch("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"), 471);
+  assertNull(res[255].firstMatch("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"), 472);
+  assertNull(res[255].firstMatch("(this(and)that"), 473);
+  assertNull(res[255].firstMatch("(this(and)that)"), 474);
+  assertNull(res[255].firstMatch("(this(and)that)stuff"), 475);
+  assertNull(res[255].firstMatch("(this(and)that"), 476);
+  assertNull(res[255].firstMatch("(this(and)that)"), 477);
+  assertNull(res[255].firstMatch("(this(and)that"), 478);
+  assertNull(res[255].firstMatch("(this(and)that)"), 479);
+  assertNull(res[255].firstMatch("(this(and)that"), 480);
+  assertNull(res[255].firstMatch("(this(and)that)"), 481);
+  assertNull(res[255].firstMatch("((this))"), 482);
+  assertNull(res[255].firstMatch("(this(and)that"), 483);
+  assertNull(res[255].firstMatch("(this(and)that)"), 484);
+  assertNull(res[255].firstMatch("(this)"), 485);
+  assertNull(res[255].firstMatch("((this))"), 486);
+  assertToStringEquals("abc,b", res[256].firstMatch("abc"), 487);
+  assertToStringEquals("abc,b", res[256].firstMatch("abc"), 488);
+  assertNull(res[256].firstMatch("a1bCA"), 489);
+  assertNull(res[256].firstMatch("a2bCA"), 490);
+  assertNull(res[257].firstMatch("a bc dCACBCC"), 491);
+  assertNull(res[257].firstMatch("aabc"), 492);
+  assertNull(res[257].firstMatch("bc"), 493);
+  assertNull(res[257].firstMatch("** Failers"), 494);
+  assertNull(res[257].firstMatch("abc"), 495);
+  assertNull(res[257].firstMatch("bXaX"), 496);
+  assertNull(res[257].firstMatch("bbXaaX"), 497);
+  assertNull(res[257].firstMatch("(b)\\Xa\\X"), 498);
+  assertNull(res[257].firstMatch("bXXaYYaY"), 499);
+  assertNull(res[257].firstMatch("bXYaXXaX"), 500);
+  assertNull(res[257].firstMatch("bXXaYYaY"), 501);
+  assertToStringEquals("\x0b,\x0b", res[259].firstMatch("\x0b,\x0b"), 502);
+  assertToStringEquals("\x0c,\x0d", res[259].firstMatch("\x0c,\x0d"), 503);
+  assertToStringEquals("abc", res[260].firstMatch("xyz\nabc"), 504);
+  assertToStringEquals("abc", res[260].firstMatch("xyz\nabc<lf>"), 505);
+  assertToStringEquals("abc", res[260].firstMatch("xyz\x0d\nabc<lf>"), 506);
+  assertToStringEquals("abc", res[260].firstMatch("xyz\x0dabc<cr>"), 507);
+  assertToStringEquals("abc", res[260].firstMatch("xyz\x0d\nabc<crlf>"), 508);
+  assertNull(res[260].firstMatch("** Failers"), 509);
+  assertToStringEquals("abc", res[260].firstMatch("xyz\nabc<cr>"), 510);
+  assertToStringEquals("abc", res[260].firstMatch("xyz\x0d\nabc<cr>"), 511);
+  assertToStringEquals("abc", res[260].firstMatch("xyz\nabc<crlf>"), 512);
+  assertToStringEquals("abc", res[260].firstMatch("xyz\x0dabc<crlf>"), 513);
+  assertToStringEquals("abc", res[260].firstMatch("xyz\x0dabc<lf>"), 514);
+  assertToStringEquals("abc", res[261].firstMatch("xyzabc"), 515);
+  assertToStringEquals("abc", res[261].firstMatch("xyzabc\n"), 516);
+  assertToStringEquals("abc", res[261].firstMatch("xyzabc\npqr"), 517);
+  assertToStringEquals("abc", res[261].firstMatch("xyzabc\x0d<cr>"), 518);
+  assertToStringEquals("abc", res[261].firstMatch("xyzabc\x0dpqr<cr>"), 519);
+  assertToStringEquals("abc", res[261].firstMatch("xyzabc\x0d\n<crlf>"), 520);
+  assertToStringEquals("abc", res[261].firstMatch("xyzabc\x0d\npqr<crlf>"), 521);
+  assertNull(res[261].firstMatch("** Failers"), 522);
+  assertToStringEquals("abc", res[261].firstMatch("xyzabc\x0d"), 523);
+  assertToStringEquals("abc", res[261].firstMatch("xyzabc\x0dpqr"), 524);
+  assertToStringEquals("abc", res[261].firstMatch("xyzabc\x0d\n"), 525);
+  assertToStringEquals("abc", res[261].firstMatch("xyzabc\x0d\npqr"), 526);
+  assertToStringEquals("abc", res[262].firstMatch("xyz\x0dabcdef"), 527);
+  assertToStringEquals("abc", res[262].firstMatch("xyz\nabcdef<lf>"), 528);
+  assertNull(res[262].firstMatch("** Failers"), 529);
+  assertToStringEquals("abc", res[262].firstMatch("xyz\nabcdef"), 530);
+  assertToStringEquals("abc", res[263].firstMatch("xyz\nabcdef"), 531);
+  assertToStringEquals("abc", res[263].firstMatch("xyz\x0dabcdef<cr>"), 532);
+  assertNull(res[263].firstMatch("** Failers"), 533);
+  assertToStringEquals("abc", res[263].firstMatch("xyz\x0dabcdef"), 534);
+  assertToStringEquals("abc", res[264].firstMatch("xyz\x0d\nabcdef"), 535);
+  assertToStringEquals("abc", res[264].firstMatch("xyz\x0dabcdef<cr>"), 536);
+  assertNull(res[264].firstMatch("** Failers"), 537);
+  assertToStringEquals("abc", res[264].firstMatch("xyz\x0dabcdef"), 538);
+  assertToStringEquals("abc", res[266].firstMatch("xyz\x0dabc<bad>"), 539);
+  assertToStringEquals("abc", res[266].firstMatch("abc"), 540);
+  assertToStringEquals("abc", res[267].firstMatch("abc\ndef"), 541);
+  assertToStringEquals("abc", res[267].firstMatch("abc\x0ddef"), 542);
+  assertToStringEquals("abc", res[267].firstMatch("abc\x0d\ndef"), 543);
+  assertToStringEquals("<cr>abc", res[267].firstMatch("<cr>abc\ndef"), 544);
+  assertToStringEquals("<cr>abc", res[267].firstMatch("<cr>abc\x0ddef"), 545);
+  assertToStringEquals("<cr>abc", res[267].firstMatch("<cr>abc\x0d\ndef"), 546);
+  assertToStringEquals("<crlf>abc", res[267].firstMatch("<crlf>abc\ndef"), 547);
+  assertToStringEquals("<crlf>abc", res[267].firstMatch("<crlf>abc\x0ddef"), 548);
+  assertToStringEquals("<crlf>abc", res[267].firstMatch("<crlf>abc\x0d\ndef"), 549);
+  assertNull(res[268].firstMatch("abc\ndef"), 550);
+  assertNull(res[268].firstMatch("abc\x0ddef"), 551);
+  assertNull(res[268].firstMatch("abc\x0d\ndef"), 552);
+  assertToStringEquals("XY,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,XY,Y", res[269].firstMatch("XYO400"), 553);
+  assertToStringEquals("aaaA5", res[278].firstMatch("aaaA5"), 554);
+  assertNull(res[278].firstMatch("** Failers"), 555);
+  assertNull(res[278].firstMatch("aaaa5"), 556);
+  assertToStringEquals("aaaA5", res[279].firstMatch("aaaA5"), 557);
+  assertToStringEquals("aaaa5", res[279].firstMatch("aaaa5"), 558);
+  assertToStringEquals("x", res[350].firstMatch("xyCabcCxyz"), 559);
+  assertToStringEquals("x", res[350].firstMatch("xyCabcCxyz"), 560);
+  assertToStringEquals("b", res[350].firstMatch("bXaX"), 561);
+  assertToStringEquals("b", res[350].firstMatch("bXbX"), 562);
+  assertToStringEquals("*", res[350].firstMatch("** Failers"), 563);
+  assertToStringEquals("aX", res[350].firstMatch("aXaX"), 564);
+  assertToStringEquals("aX", res[350].firstMatch("aXbX"), 565);
+  assertToStringEquals("x", res[350].firstMatch("xx"), 566);
+  assertToStringEquals("x", res[350].firstMatch("xy"), 567);
+  assertToStringEquals("y", res[350].firstMatch("yy"), 568);
+  assertToStringEquals("y", res[350].firstMatch("yx"), 569);
+  assertToStringEquals("x", res[350].firstMatch("xx"), 570);
+  assertToStringEquals("x", res[350].firstMatch("xy"), 571);
+  assertToStringEquals("y", res[350].firstMatch("yy"), 572);
+  assertToStringEquals("y", res[350].firstMatch("yx"), 573);
+  assertToStringEquals("b", res[350].firstMatch("bxay"), 574);
+  assertToStringEquals("b", res[350].firstMatch("bxby"), 575);
+  assertToStringEquals("*", res[350].firstMatch("** Failers"), 576);
+  assertToStringEquals("ax", res[350].firstMatch("axby"), 577);
+  assertToStringEquals("X", res[350].firstMatch("XxXxxx"), 578);
+  assertToStringEquals("X", res[350].firstMatch("XxXyyx"), 579);
+  assertToStringEquals("X", res[350].firstMatch("XxXyxx"), 580);
+  assertToStringEquals("*", res[350].firstMatch("** Failers"), 581);
+  assertToStringEquals("x", res[350].firstMatch("x"), 582);
+  assertToStringEquals("ab", res[350].firstMatch("abcabc"), 583);
+  assertToStringEquals("Xaaa,a", res[351].firstMatch("Xaaa"), 584);
+  assertToStringEquals("Xaba,a", res[351].firstMatch("Xaba"), 585);
+  assertThrows(() => new RegExp(r"^[a-\\Q\\E]"), 586);
+  assertNull(res[353].firstMatch("(xy)x"), 587);
+  assertNull(res[353].firstMatch("1221"), 588);
+  assertNull(res[353].firstMatch("Satan, oscillate my metallic sonatas!"), 589);
+  assertNull(res[353].firstMatch("A man, a plan, a canal: Panama!"), 590);
+  assertNull(res[353].firstMatch("Able was I ere I saw Elba."), 591);
+  assertNull(res[353].firstMatch("*** Failers"), 592);
+  assertNull(res[353].firstMatch("The quick brown fox"), 593);
+  assertToStringEquals("abcd:,abcd", res[354].firstMatch("abcd:"), 594);
+  assertToStringEquals("abcd:,abcd", res[354].firstMatch("abcd:"), 595);
+  assertToStringEquals("a:,a", res[354].firstMatch("a:aaxyz"), 596);
+  assertToStringEquals("ab:,ab", res[354].firstMatch("ab:ababxyz"), 597);
+  assertNull(res[354].firstMatch("** Failers"), 598);
+  assertToStringEquals("a:,a", res[354].firstMatch("a:axyz"), 599);
+  assertToStringEquals("ab:,ab", res[354].firstMatch("ab:abxyz"), 600);
+  assertNull(res[354].firstMatch("abd"), 601);
+  assertNull(res[354].firstMatch("ce"), 602);
+  assertNull(res[354].firstMatch("abcabc1Xabc2XabcXabcabc"), 603);
+  assertNull(res[354].firstMatch("abcabc1Xabc2XabcXabcabc"), 604);
+  assertNull(res[354].firstMatch("abcabc1Xabc2XabcXabcabc"), 605);
+  assertNull(res[354].firstMatch("abcd"), 606);
+  assertNull(res[354].firstMatch("metcalfe 33"), 607);
+  assertNull(res[356].firstMatch("a\x0db"), 608);
+  assertNull(res[356].firstMatch("a\nb<cr>"), 609);
+  assertToStringEquals("a\x85b", res[356].firstMatch("a\x85b<anycrlf> "), 610);
+  assertNull(res[356].firstMatch("** Failers"), 611);
+  assertNull(res[356].firstMatch("a\nb"), 612);
+  assertNull(res[356].firstMatch("a\nb<any>"), 613);
+  assertNull(res[356].firstMatch("a\x0db<cr>"), 614);
+  assertNull(res[356].firstMatch("a\x0db<any>"), 615);
+  assertToStringEquals("a\x85b", res[356].firstMatch("a\x85b<any> "), 616);
+  assertNull(res[356].firstMatch("a\x0db<anycrlf>"), 617);
+  assertToStringEquals("abc1", res[357].firstMatch("abc1 \nabc2 \x0babc3xx \x0cabc4 \x0dabc5xx \x0d\nabc6 \x85abc7 JUNK"), 618);
+  assertToStringEquals("abc1", res[358].firstMatch("abc1\n abc2\x0b abc3\x0c abc4\x0d abc5\x0d\n abc6\x85 abc7 abc9"), 619);
+  assertNull(res[361].firstMatch("a\nb"), 620);
+  assertNull(res[361].firstMatch("a\x0db"), 621);
+  assertNull(res[361].firstMatch("a\x0d\nb"), 622);
+  assertNull(res[361].firstMatch("a\x0bb"), 623);
+  assertNull(res[361].firstMatch("a\x0cb"), 624);
+  assertNull(res[361].firstMatch("a\x85b"), 625);
+  assertNull(res[361].firstMatch("** Failers"), 626);
+  assertNull(res[361].firstMatch("a\n\x0db"), 627);
+  assertToStringEquals("ab", res[362].firstMatch("ab"), 628);
+  assertNull(res[362].firstMatch("a\nb"), 629);
+  assertNull(res[362].firstMatch("a\x0db"), 630);
+  assertNull(res[362].firstMatch("a\x0d\nb"), 631);
+  assertNull(res[362].firstMatch("a\x0bb"), 632);
+  assertNull(res[362].firstMatch("a\x0cb"), 633);
+  assertNull(res[362].firstMatch("a\x85b"), 634);
+  assertNull(res[362].firstMatch("a\n\x0db"), 635);
+  assertNull(res[362].firstMatch("a\n\x0d\x85\x0cb"), 636);
+  assertNull(res[363].firstMatch("a\nb"), 637);
+  assertNull(res[363].firstMatch("a\x0db"), 638);
+  assertNull(res[363].firstMatch("a\x0d\nb"), 639);
+  assertNull(res[363].firstMatch("a\x0bb"), 640);
+  assertNull(res[363].firstMatch("a\x0cb"), 641);
+  assertNull(res[363].firstMatch("a\x85b"), 642);
+  assertNull(res[363].firstMatch("a\n\x0db"), 643);
+  assertNull(res[363].firstMatch("a\n\x0d\x85\x0cb"), 644);
+  assertNull(res[363].firstMatch("** Failers"), 645);
+  assertNull(res[363].firstMatch("ab"), 646);
+  assertNull(res[364].firstMatch("a\nb"), 647);
+  assertNull(res[364].firstMatch("a\n\x0db"), 648);
+  assertNull(res[364].firstMatch("a\n\x0d\x85b"), 649);
+  assertNull(res[364].firstMatch("a\x0d\n\x0d\nb"), 650);
+  assertNull(res[364].firstMatch("a\x0d\n\x0d\n\x0d\nb"), 651);
+  assertNull(res[364].firstMatch("a\n\x0d\n\x0db"), 652);
+  assertNull(res[364].firstMatch("a\n\n\x0d\nb"), 653);
+  assertNull(res[364].firstMatch("** Failers"), 654);
+  assertNull(res[364].firstMatch("a\n\n\n\x0db"), 655);
+  assertNull(res[364].firstMatch("a\x0d"), 656);
+  assertToStringEquals("aRb", res[365].firstMatch("aRb"), 657);
+  assertNull(res[365].firstMatch("** Failers"), 658);
+  assertNull(res[365].firstMatch("a\nb"), 659);
+  assertNull(res[365].firstMatch("abcPXP123"), 660);
+  assertNull(res[365].firstMatch("abcPXP123"), 661);
+  assertNull(res[365].firstMatch("1.2.3.4"), 662);
+  assertNull(res[365].firstMatch("131.111.10.206"), 663);
+  assertNull(res[365].firstMatch("10.0.0.0"), 664);
+  assertNull(res[365].firstMatch("** Failers"), 665);
+  assertNull(res[365].firstMatch("10.6"), 666);
+  assertNull(res[365].firstMatch("455.3.4.5"), 667);
+  assertNull(res[365].firstMatch("1.2.3.4"), 668);
+  assertNull(res[365].firstMatch("131.111.10.206"), 669);
+  assertNull(res[365].firstMatch("10.0.0.0"), 670);
+  assertNull(res[365].firstMatch("** Failers"), 671);
+  assertNull(res[365].firstMatch("10.6"), 672);
+  assertNull(res[365].firstMatch("455.3.4.5"), 673);
+  assertNull(res[365].firstMatch("123axbaxbaxbx456"), 674);
+  assertNull(res[365].firstMatch("123axbaxbaxb456"), 675);
+  assertNull(res[365].firstMatch("123axbaxbaxbx456"), 676);
+  assertNull(res[365].firstMatch("123axbaxbaxbx456"), 677);
+  assertNull(res[365].firstMatch("123axbaxbaxbx456"), 678);
+  assertNull(res[366].firstMatch("ababababbbabZXXXX"), 679);
+  assertNull(res[372].firstMatch("a\x0db"), 680);
+  assertNull(res[372].firstMatch("*** Failers"), 681);
+  assertNull(res[372].firstMatch("a\nb"), 682);
+  assertToStringEquals("afoo", res[373].firstMatch("afoo"), 683);
+  assertNull(res[373].firstMatch("** Failers"), 684);
+  assertNull(res[373].firstMatch("\x0d\nfoo"), 685);
+  assertNull(res[373].firstMatch("\nfoo"), 686);
+  assertToStringEquals("afoo", res[374].firstMatch("afoo"), 687);
+  assertNull(res[374].firstMatch("\nfoo"), 688);
+  assertNull(res[374].firstMatch("** Failers"), 689);
+  assertNull(res[374].firstMatch("\x0d\nfoo"), 690);
+  assertToStringEquals("afoo", res[375].firstMatch("afoo"), 691);
+  assertNull(res[375].firstMatch("** Failers"), 692);
+  assertNull(res[375].firstMatch("\nfoo"), 693);
+  assertNull(res[375].firstMatch("\x0d\nfoo"), 694);
+  assertToStringEquals("afoo", res[376].firstMatch("afoo"), 695);
+  assertNull(res[376].firstMatch("\x0d\nfoo"), 696);
+  assertNull(res[376].firstMatch("\nfoo"), 697);
+  assertToStringEquals("", res[377].firstMatch("abc\x0d\x0dxyz"), 698);
+  assertToStringEquals("", res[377].firstMatch("abc\n\x0dxyz  "), 699);
+  assertNull(res[377].firstMatch("** Failers "), 700);
+  assertToStringEquals("", res[377].firstMatch("abc\x0d\nxyz"), 701);
+  assertToStringEquals("", res[377].firstMatch("abc\x0d\n\x0d\n"), 702);
+  assertToStringEquals("", res[377].firstMatch("abc\x0d\n\x0d\n"), 703);
+  assertToStringEquals("", res[377].firstMatch("abc\x0d\n\x0d\n"), 704);
+  assertToStringEquals("abc1", res[378].firstMatch("abc1\n abc2\x0b abc3\x0c abc4\x0d abc5\x0d\n abc6\x85 abc9"), 705);
+  assertToStringEquals("X", res[379].firstMatch("XABC"), 706);
+  assertNull(res[379].firstMatch("** Failers "), 707);
+  assertToStringEquals("X", res[379].firstMatch("XABCB"), 708);
+  assertThrows(() => new RegExp(r"(ab|c)(?-1)"), 709);
+  assertNull(res[379].firstMatch("abc"), 710);
+  assertNull(res[379].firstMatch("xyabcabc"), 711);
+  assertNull(res[379].firstMatch("** Failers"), 712);
+  assertNull(res[379].firstMatch("xyabc  "), 713);
+  assertThrows(() => new RegExp(r"x(?-0)y"), 714);
+  assertThrows(() => new RegExp(r"x(?-1)y"), 715);
+  assertNull(res[379].firstMatch("abcX"), 716);
+  assertNull(res[379].firstMatch("Y"), 717);
+  assertNull(res[379].firstMatch("** Failers"), 718);
+  assertNull(res[379].firstMatch("abcY   "), 719);
+  assertNull(res[379].firstMatch("YabcXabc"), 720);
+  assertNull(res[379].firstMatch("YabcXabcXabc"), 721);
+  assertNull(res[379].firstMatch("** Failers"), 722);
+  assertToStringEquals("X", res[379].firstMatch("XabcXabc  "), 723);
+  assertNull(res[379].firstMatch("Y!"), 724);
+  assertNull(res[380].firstMatch("foobar"), 725);
+  assertNull(res[381].firstMatch("foobar"), 726);
+  assertToStringEquals("foobaz,foo,baz", res[381].firstMatch("foobaz "), 727);
+  assertNull(res[382].firstMatch("foobarbaz"), 728);
+  assertNull(res[382].firstMatch("tom-tom"), 729);
+  assertNull(res[382].firstMatch("bon-bon "), 730);
+  assertNull(res[382].firstMatch("** Failers"), 731);
+  assertNull(res[382].firstMatch("tom-bon  "), 732);
+  assertNull(res[382].firstMatch("tom-tom"), 733);
+  assertNull(res[382].firstMatch("bon-bon "), 734);
+  assertThrows(() => new RegExp(r"(?|(abc)|(xyz))"), 735);
+  assertThrows(() => new RegExp(r"(x)(?|(abc)|(xyz))(x)"), 736);
+  assertNull(res[383].firstMatch("xabcx"), 737);
+  assertNull(res[383].firstMatch("xxyzx "), 738);
+  assertThrows(() => new RegExp(r"(x)(?|(abc)(pqr)|(xyz))(x)"), 739);
+  assertNull(res[383].firstMatch("xabcpqrx"), 740);
+  assertNull(res[383].firstMatch("xxyzx "), 741);
+  assertThrows(() => new RegExp(r"(?|(abc)|(xyz))\1"), 742);
+  assertNull(res[383].firstMatch("abcabc"), 743);
+  assertNull(res[383].firstMatch("xyzxyz "), 744);
+  assertNull(res[383].firstMatch("** Failers"), 745);
+  assertNull(res[383].firstMatch("abcxyz"), 746);
+  assertNull(res[383].firstMatch("xyzabc   "), 747);
+  assertNull(res[383].firstMatch("abcabc"), 748);
+  assertNull(res[383].firstMatch("xyzabc "), 749);
+  assertNull(res[383].firstMatch("** Failers "), 750);
+  assertNull(res[383].firstMatch("xyzxyz "), 751);
+  assertNull(res[384].firstMatch("X X\n"), 752);
+  assertNull(res[384].firstMatch("X\x09X\x0b"), 753);
+  assertNull(res[384].firstMatch("** Failers"), 754);
+  assertNull(res[384].firstMatch("\xa0 X\n   "), 755);
+  assertNull(res[385].firstMatch("\x09 \xa0X\n\x0b\x0c\x0d\n"), 756);
+  assertNull(res[385].firstMatch("\x09 \xa0\n\x0b\x0c\x0d\n"), 757);
+  assertNull(res[385].firstMatch("\x09 \xa0\n\x0b\x0c"), 758);
+  assertNull(res[385].firstMatch("** Failers "), 759);
+  assertNull(res[385].firstMatch("\x09 \xa0\n\x0b"), 760);
+  assertNull(res[385].firstMatch(" "), 761);
+  assertNull(res[386].firstMatch("XY  ABCDE"), 762);
+  assertNull(res[386].firstMatch("XY  PQR ST "), 763);
+  assertNull(res[387].firstMatch("XY  AB    PQRS"), 764);
+  assertNull(res[388].firstMatch(">XNNNYZ"), 765);
+  assertNull(res[388].firstMatch(">  X NYQZ"), 766);
+  assertNull(res[388].firstMatch("** Failers"), 767);
+  assertNull(res[388].firstMatch(">XYZ   "), 768);
+  assertNull(res[388].firstMatch(">  X NY Z"), 769);
+  assertNull(res[389].firstMatch(">XY\nZ\nA\x0bNN\x0c"), 770);
+  assertNull(res[389].firstMatch(">\n\x0dX\nY\n\x0bZZZ\nAAA\x0bNNN\x0c"), 771);
+  assertNull(res[390].firstMatch(">\x09<"), 772);
+  assertNull(res[391].firstMatch(">\x09 \xa0<"), 773);
+  assertNull(res[396].firstMatch("** Failers"), 774);
+  assertNull(res[396].firstMatch("XXXX"), 775);
+  assertNull(res[397].firstMatch("XXXX Y "), 776);
+  assertNull(res[419].firstMatch("aaaaaa"), 777);
+  assertNull(res[419].firstMatch("aaabccc"), 778);
+  assertNull(res[419].firstMatch("aaabccc"), 779);
+  assertNull(res[419].firstMatch("aaabccc"), 780);
+  assertNull(res[419].firstMatch("aaabcccaaabccc"), 781);
+  assertNull(res[419].firstMatch("aaaxxxxxx"), 782);
+  assertNull(res[419].firstMatch("aaa++++++ "), 783);
+  assertNull(res[419].firstMatch("bbbxxxxx"), 784);
+  assertNull(res[419].firstMatch("bbb+++++ "), 785);
+  assertNull(res[419].firstMatch("cccxxxx"), 786);
+  assertNull(res[419].firstMatch("ccc++++ "), 787);
+  assertNull(res[419].firstMatch("dddddddd   "), 788);
+  assertNull(res[419].firstMatch("aaaxxxxxx"), 789);
+  assertNull(res[419].firstMatch("aaa++++++ "), 790);
+  assertNull(res[419].firstMatch("bbbxxxxx"), 791);
+  assertNull(res[419].firstMatch("bbb+++++ "), 792);
+  assertNull(res[419].firstMatch("cccxxxx"), 793);
+  assertNull(res[419].firstMatch("ccc++++ "), 794);
+  assertNull(res[419].firstMatch("dddddddd   "), 795);
+  assertNull(res[419].firstMatch("aaabccc"), 796);
+  assertNull(res[419].firstMatch("ABX"), 797);
+  assertNull(res[419].firstMatch("AADE"), 798);
+  assertNull(res[419].firstMatch("ACDE"), 799);
+  assertNull(res[419].firstMatch("** Failers"), 800);
+  assertNull(res[419].firstMatch("AD "), 801);
+  assertNull(res[419].firstMatch("    "), 802);
+  assertNull(res[419].firstMatch("aaaaaa"), 803);
+  assertNull(res[419].firstMatch("aaabccc"), 804);
+  assertNull(res[419].firstMatch("aaabccc"), 805);
+  assertNull(res[419].firstMatch("aaabccc"), 806);
+  assertNull(res[419].firstMatch("aaabcccaaabccc"), 807);
+  assertNull(res[419].firstMatch("aaabccc"), 808);
+  assertNull(res[422].firstMatch("\x0d\nA"), 809);
+  assertToStringEquals("\nA", res[423].firstMatch("\x0d\nA "), 810);
+  assertToStringEquals("\nA", res[424].firstMatch("\x0d\nA "), 811);
+  assertToStringEquals("\nA,\n", res[425].firstMatch("\x0d\nA "), 812);
+  assertNull(res[425].firstMatch("a\nb"), 813);
+  assertNull(res[425].firstMatch("** Failers"), 814);
+  assertNull(res[425].firstMatch("a\x0db  "), 815);
+  assertNull(res[425].firstMatch("a\nb"), 816);
+  assertNull(res[425].firstMatch("** Failers"), 817);
+  assertNull(res[425].firstMatch("a\x0db  "), 818);
+  assertNull(res[425].firstMatch("a\x0db"), 819);
+  assertNull(res[425].firstMatch("** Failers"), 820);
+  assertNull(res[425].firstMatch("a\nb  "), 821);
+  assertNull(res[425].firstMatch("a\x0db"), 822);
+  assertNull(res[425].firstMatch("a\nb  "), 823);
+  assertNull(res[425].firstMatch("** Failers"), 824);
+  assertNull(res[425].firstMatch("a\x0d\nb  "), 825);
+  assertNull(res[425].firstMatch("** Failers"), 826);
+  assertNull(res[425].firstMatch("a\x0db"), 827);
+  assertNull(res[425].firstMatch("a\nb  "), 828);
+  assertNull(res[425].firstMatch("a\x0d\nb  "), 829);
+  assertNull(res[425].firstMatch("** Failers"), 830);
+  assertNull(res[425].firstMatch("a\x0db"), 831);
+  assertNull(res[425].firstMatch("a\nb  "), 832);
+  assertNull(res[425].firstMatch("a\x0d\nb  "), 833);
+  assertNull(res[425].firstMatch("a\x85b "), 834);
+  assertNull(res[426].firstMatch("a\x0db"), 835);
+  assertNull(res[426].firstMatch("a\nb"), 836);
+  assertNull(res[426].firstMatch("a\x0d\nb"), 837);
+  assertNull(res[426].firstMatch("** Failers"), 838);
+  assertNull(res[426].firstMatch("a\x85b"), 839);
+  assertNull(res[426].firstMatch("a\x0bb     "), 840);
+  assertNull(res[427].firstMatch("a\x0db"), 841);
+  assertNull(res[427].firstMatch("a\nb"), 842);
+  assertNull(res[427].firstMatch("a\x0d\nb"), 843);
+  assertNull(res[427].firstMatch("a\x85b"), 844);
+  assertNull(res[427].firstMatch("a\x0bb     "), 845);
+  assertNull(res[427].firstMatch("** Failers "), 846);
+  assertNull(res[427].firstMatch("a\x85b<bsr_anycrlf>"), 847);
+  assertNull(res[427].firstMatch("a\x0bb<bsr_anycrlf>"), 848);
+  assertNull(res[428].firstMatch("a\x0db"), 849);
+  assertNull(res[428].firstMatch("a\nb"), 850);
+  assertNull(res[428].firstMatch("a\x0d\nb"), 851);
+  assertNull(res[428].firstMatch("** Failers"), 852);
+  assertNull(res[428].firstMatch("a\x85b"), 853);
+  assertNull(res[428].firstMatch("a\x0bb     "), 854);
+  assertNull(res[429].firstMatch("a\x0db"), 855);
+  assertNull(res[429].firstMatch("a\nb"), 856);
+  assertNull(res[429].firstMatch("a\x0d\nb"), 857);
+  assertNull(res[429].firstMatch("a\x85b"), 858);
+  assertNull(res[429].firstMatch("a\x0bb     "), 859);
+  assertNull(res[429].firstMatch("** Failers "), 860);
+  assertNull(res[429].firstMatch("a\x85b<bsr_anycrlf>"), 861);
+  assertNull(res[429].firstMatch("a\x0bb<bsr_anycrlf>"), 862);
+  assertNull(res[430].firstMatch("a\x0d\n\nb"), 863);
+  assertNull(res[430].firstMatch("a\n\x0d\x0db"), 864);
+  assertNull(res[430].firstMatch("a\x0d\n\x0d\n\x0d\n\x0d\nb"), 865);
+  assertNull(res[430].firstMatch("** Failers"), 866);
+  assertNull(res[430].firstMatch("a\x8585b"), 867);
+  assertNull(res[430].firstMatch("a\x0b\x00bb     "), 868);
+  assertNull(res[431].firstMatch("a\x0d\x0db"), 869);
+  assertNull(res[431].firstMatch("a\n\n\nb"), 870);
+  assertNull(res[431].firstMatch("a\x0d\n\n\x0d\x0db"), 871);
+  assertNull(res[431].firstMatch("a\x8585b"), 872);
+  assertNull(res[431].firstMatch("a\x0b\x00bb     "), 873);
+  assertNull(res[431].firstMatch("** Failers "), 874);
+  assertNull(res[431].firstMatch("a\x0d\x0d\x0d\x0d\x0db "), 875);
+  assertNull(res[431].firstMatch("a\x8585b<bsr_anycrlf>"), 876);
+  assertNull(res[431].firstMatch("a\x0b\x00bb<bsr_anycrlf>"), 877);
+  assertNull(res[431].firstMatch("a\nb"), 878);
+  assertNull(res[431].firstMatch("a\x0db "), 879);
+  assertNull(res[431].firstMatch("a\x85b"), 880);
+  assertNull(res[431].firstMatch("a\nb"), 881);
+  assertNull(res[431].firstMatch("a\x0db "), 882);
+  assertNull(res[431].firstMatch("a\x85b"), 883);
+  assertThrows(() => new RegExp(r"(?-+a)"), 884);
+  assertNull(res[443].firstMatch("aaaa"), 885);
+  assertNull(res[443].firstMatch("bacxxx"), 886);
+  assertNull(res[443].firstMatch("bbaccxxx "), 887);
+  assertNull(res[443].firstMatch("bbbacccxx"), 888);
+  assertNull(res[443].firstMatch("aaaa"), 889);
+  assertNull(res[443].firstMatch("bacxxx"), 890);
+  assertNull(res[443].firstMatch("bbaccxxx "), 891);
+  assertNull(res[443].firstMatch("bbbacccxx"), 892);
+  assertToStringEquals("a,a", res[444].firstMatch("aaaa"), 893);
+  assertNull(res[444].firstMatch("bacxxx"), 894);
+  assertNull(res[444].firstMatch("bbaccxxx "), 895);
+  assertNull(res[444].firstMatch("bbbacccxx"), 896);
+  assertToStringEquals("a,a", res[445].firstMatch("aaaa"), 897);
+  assertNull(res[445].firstMatch("bacxxx"), 898);
+  assertNull(res[445].firstMatch("bbaccxxx "), 899);
+  assertNull(res[445].firstMatch("bbbacccxx"), 900);
+  assertToStringEquals("a,a", res[446].firstMatch("aaaa"), 901);
+  assertNull(res[446].firstMatch("bacxxx"), 902);
+  assertNull(res[446].firstMatch("bbaccxxx "), 903);
+  assertNull(res[446].firstMatch("bbbacccxx"), 904);
+  assertToStringEquals("a,a,a", res[447].firstMatch("aaaa"), 905);
+  assertNull(res[447].firstMatch("bacxxx"), 906);
+  assertNull(res[447].firstMatch("bbaccxxx "), 907);
+  assertNull(res[447].firstMatch("bbbacccxx"), 908);
+  assertNull(res[449].firstMatch("bacxxx"), 909);
+  assertNull(res[449].firstMatch("XaaX"), 910);
+  assertNull(res[449].firstMatch("XAAX "), 911);
+  assertNull(res[449].firstMatch("XaaX"), 912);
+  assertNull(res[449].firstMatch("** Failers "), 913);
+  assertNull(res[449].firstMatch("XAAX "), 914);
+  assertNull(res[449].firstMatch("XaaX"), 915);
+  assertNull(res[449].firstMatch("XAAX "), 916);
+  assertNull(res[449].firstMatch("xzxx"), 917);
+  assertNull(res[449].firstMatch("yzyy "), 918);
+  assertNull(res[449].firstMatch("** Failers"), 919);
+  assertNull(res[449].firstMatch("xxz  "), 920);
+  assertToStringEquals("a,,,a", res[450].firstMatch("cat"), 921);
+  assertToStringEquals("a,,,a", res[451].firstMatch("cat"), 922);
+  assertToStringEquals("TA]", res[452].firstMatch("The ACTA] comes "), 923);
+  assertToStringEquals("TA]", res[453].firstMatch("The ACTA] comes "), 924);
+  assertNull(res[453].firstMatch("abcbabc"), 925);
+  assertNull(res[453].firstMatch("abcbabc"), 926);
+  assertNull(res[453].firstMatch("abcbabc"), 927);
+  assertNull(res[453].firstMatch("** Failers "), 928);
+  assertNull(res[453].firstMatch("abcXabc"), 929);
+  assertNull(res[453].firstMatch("abcXabc"), 930);
+  assertNull(res[453].firstMatch("** Failers "), 931);
+  assertNull(res[453].firstMatch("abcbabc"), 932);
+  assertNull(res[453].firstMatch("xyzbabcxyz"), 933);
+  assertNull(res[456].firstMatch("** Failers"), 934);
+  assertNull(res[456].firstMatch("ab"), 935);
+  assertNull(res[457].firstMatch("** Failers"), 936);
+  assertNull(res[457].firstMatch("ab "), 937);
+  assertNull(res[457].firstMatch("** Failers"), 938);
+  assertNull(res[457].firstMatch("ab "), 939);
+  assertToStringEquals("aXb", res[458].firstMatch("aXb"), 940);
+  assertToStringEquals("a\nb", res[458].firstMatch("a\nb "), 941);
+  assertNull(res[458].firstMatch("** Failers"), 942);
+  assertNull(res[458].firstMatch("ab  "), 943);
+  assertToStringEquals("aXb", res[459].firstMatch("aXb"), 944);
+  assertToStringEquals("a\nX\nXb", res[459].firstMatch("a\nX\nXb "), 945);
+  assertNull(res[459].firstMatch("** Failers"), 946);
+  assertNull(res[459].firstMatch("ab  "), 947);
+  assertToStringEquals("acb", res[463].firstMatch("acb"), 948);
+  assertToStringEquals("ab", res[463].firstMatch("ab"), 949);
+  assertNull(res[463].firstMatch("ax{100}b "), 950);
+  assertNull(res[463].firstMatch("*** Failers"), 951);
+  assertNull(res[463].firstMatch("a\nb  "), 952);
+  assertNull(res[464].firstMatch("ax{4000}xyb "), 953);
+  assertNull(res[464].firstMatch("ax{4000}yb "), 954);
+  assertNull(res[464].firstMatch("ax{4000}x{100}yb "), 955);
+  assertNull(res[464].firstMatch("*** Failers"), 956);
+  assertNull(res[464].firstMatch("ax{4000}b "), 957);
+  assertNull(res[464].firstMatch("ac\ncb "), 958);
+  assertToStringEquals("a\xc0,,\xc0", res[465].firstMatch("a\xc0\x88b"), 959);
+  assertToStringEquals("ax,,x", res[466].firstMatch("ax{100}b"), 960);
+  assertToStringEquals("a\xc0\x88b,\xc0\x88,b", res[467].firstMatch("a\xc0\x88b"), 961);
+  assertToStringEquals("ax{100}b,x{100},b", res[468].firstMatch("ax{100}b"), 962);
+  assertToStringEquals("a\xc0\x92,\xc0,\x92", res[469].firstMatch("a\xc0\x92bcd"), 963);
+  assertToStringEquals("ax{,x,{", res[470].firstMatch("ax{240}bcd"), 964);
+  assertToStringEquals("a\xc0\x92,\xc0,\x92", res[471].firstMatch("a\xc0\x92bcd"), 965);
+  assertToStringEquals("ax{,x,{", res[472].firstMatch("ax{240}bcd"), 966);
+  assertToStringEquals("a\xc0,,\xc0", res[473].firstMatch("a\xc0\x92bcd"), 967);
+  assertToStringEquals("ax,,x", res[474].firstMatch("ax{240}bcd"), 968);
+  assertNull(res[475].firstMatch("ax{1234}xyb "), 969);
+  assertNull(res[475].firstMatch("ax{1234}x{4321}yb "), 970);
+  assertNull(res[475].firstMatch("ax{1234}x{4321}x{3412}b "), 971);
+  assertNull(res[475].firstMatch("*** Failers"), 972);
+  assertNull(res[475].firstMatch("ax{1234}b "), 973);
+  assertNull(res[475].firstMatch("ac\ncb "), 974);
+  assertToStringEquals("ax{1234}xyb,x{1234}xy", res[476].firstMatch("ax{1234}xyb "), 975);
+  assertToStringEquals("ax{1234}x{4321}yb,x{1234}x{4321}y", res[476].firstMatch("ax{1234}x{4321}yb "), 976);
+  assertToStringEquals("ax{1234}x{4321}x{3412}b,x{1234}x{4321}x{3412}", res[476].firstMatch("ax{1234}x{4321}x{3412}b "), 977);
+  assertToStringEquals("axxxxbcdefghijb,xxxxbcdefghij", res[476].firstMatch("axxxxbcdefghijb "), 978);
+  assertToStringEquals("ax{1234}x{4321}x{3412}x{3421}b,x{1234}x{4321}x{3412}x{3421}", res[476].firstMatch("ax{1234}x{4321}x{3412}x{3421}b "), 979);
+  assertNull(res[476].firstMatch("*** Failers"), 980);
+  assertToStringEquals("ax{1234}b,x{1234}", res[476].firstMatch("ax{1234}b "), 981);
+  assertToStringEquals("ax{1234}xyb,x{1234}xy", res[477].firstMatch("ax{1234}xyb "), 982);
+  assertToStringEquals("ax{1234}x{4321}yb,x{1234}x{4321}y", res[477].firstMatch("ax{1234}x{4321}yb "), 983);
+  assertToStringEquals("ax{1234}x{4321}x{3412}b,x{1234}x{4321}x{3412}", res[477].firstMatch("ax{1234}x{4321}x{3412}b "), 984);
+  assertToStringEquals("axxxxb,xxxx", res[477].firstMatch("axxxxbcdefghijb "), 985);
+  assertToStringEquals("ax{1234}x{4321}x{3412}x{3421}b,x{1234}x{4321}x{3412}x{3421}", res[477].firstMatch("ax{1234}x{4321}x{3412}x{3421}b "), 986);
+  assertNull(res[477].firstMatch("*** Failers"), 987);
+  assertToStringEquals("ax{1234}b,x{1234}", res[477].firstMatch("ax{1234}b "), 988);
+  assertNull(res[478].firstMatch("ax{1234}xyb "), 989);
+  assertNull(res[478].firstMatch("ax{1234}x{4321}yb "), 990);
+  assertNull(res[478].firstMatch("ax{1234}x{4321}x{3412}b "), 991);
+  assertToStringEquals("axxxxb,xxxx", res[478].firstMatch("axxxxbcdefghijb "), 992);
+  assertNull(res[478].firstMatch("ax{1234}x{4321}x{3412}x{3421}b "), 993);
+  assertToStringEquals("axbxxb,xbxx", res[478].firstMatch("axbxxbcdefghijb "), 994);
+  assertToStringEquals("axxxxxb,xxxxx", res[478].firstMatch("axxxxxbcdefghijb "), 995);
+  assertNull(res[478].firstMatch("*** Failers"), 996);
+  assertNull(res[478].firstMatch("ax{1234}b "), 997);
+  assertNull(res[478].firstMatch("axxxxxxbcdefghijb "), 998);
+  assertNull(res[479].firstMatch("ax{1234}xyb "), 999);
+  assertNull(res[479].firstMatch("ax{1234}x{4321}yb "), 1000);
+  assertNull(res[479].firstMatch("ax{1234}x{4321}x{3412}b "), 1001);
+  assertToStringEquals("axxxxb,xxxx", res[479].firstMatch("axxxxbcdefghijb "), 1002);
+  assertNull(res[479].firstMatch("ax{1234}x{4321}x{3412}x{3421}b "), 1003);
+  assertToStringEquals("axbxxb,xbxx", res[479].firstMatch("axbxxbcdefghijb "), 1004);
+  assertToStringEquals("axxxxxb,xxxxx", res[479].firstMatch("axxxxxbcdefghijb "), 1005);
+  assertNull(res[479].firstMatch("*** Failers"), 1006);
+  assertNull(res[479].firstMatch("ax{1234}b "), 1007);
+  assertNull(res[479].firstMatch("axxxxxxbcdefghijb "), 1008);
+  assertNull(res[479].firstMatch("*** Failers"), 1009);
+  assertNull(res[479].firstMatch("x{100}"), 1010);
+  assertNull(res[479].firstMatch("aXbcd"), 1011);
+  assertNull(res[479].firstMatch("ax{100}bcd"), 1012);
+  assertNull(res[479].firstMatch("ax{100000}bcd"), 1013);
+  assertNull(res[479].firstMatch("x{100}x{100}x{100}b"), 1014);
+  assertNull(res[479].firstMatch("*** Failers "), 1015);
+  assertNull(res[479].firstMatch("x{100}x{100}b"), 1016);
+  assertNull(res[479].firstMatch("x{ab} "), 1017);
+  assertNull(res[479].firstMatch("\xc2\xab"), 1018);
+  assertNull(res[479].firstMatch("*** Failers "), 1019);
+  assertNull(res[479].firstMatch("\x00{ab}"), 1020);
+  assertNull(res[479].firstMatch("WXYZ"), 1021);
+  assertNull(res[479].firstMatch("x{256}XYZ "), 1022);
+  assertNull(res[479].firstMatch("*** Failers"), 1023);
+  assertNull(res[479].firstMatch("XYZ "), 1024);
+  assertNull(res[480].firstMatch("Xx{1234}"), 1025);
+  assertNull(res[481].firstMatch("Xx{1234}YZ"), 1026);
+  assertToStringEquals("X", res[482].firstMatch("XYZabcdce"), 1027);
+  assertToStringEquals("X", res[483].firstMatch("XYZabcde"), 1028);
+  assertNull(res[484].firstMatch("Xabcdefg   "), 1029);
+  assertNull(res[484].firstMatch("Xx{1234} "), 1030);
+  assertNull(res[484].firstMatch("Xx{1234}YZ"), 1031);
+  assertNull(res[484].firstMatch("Xx{1234}x{512}  "), 1032);
+  assertNull(res[484].firstMatch("Xx{1234}x{512}YZ"), 1033);
+  assertNull(res[485].firstMatch("Xabcdefg   "), 1034);
+  assertNull(res[485].firstMatch("Xx{1234} "), 1035);
+  assertNull(res[485].firstMatch("Xx{1234}YZ"), 1036);
+  assertNull(res[485].firstMatch("Xx{1234}x{512}  "), 1037);
+  assertToStringEquals("bcd", res[486].firstMatch("bcd"), 1038);
+  assertToStringEquals("x{", res[487].firstMatch("x{100}bc"), 1040);
+  assertToStringEquals("x{100}bcA", res[488].firstMatch("x{100}bcAa"), 1041);
+  assertToStringEquals("x{", res[489].firstMatch("x{100}bca"), 1042);
+  assertToStringEquals("bcd", res[490].firstMatch("bcd"), 1043);
+  assertToStringEquals("x{", res[491].firstMatch("x{100}bc"), 1045);
+  assertToStringEquals("x{100}bc", res[492].firstMatch("x{100}bcAa"), 1046);
+  assertToStringEquals("x{", res[493].firstMatch("x{100}bca"), 1047);
+  assertNull(res[493].firstMatch("abcd"), 1048);
+  assertNull(res[493].firstMatch("abcd"), 1049);
+  assertToStringEquals("x{", res[493].firstMatch("x{100}x{100} "), 1050);
+  assertToStringEquals("x{", res[493].firstMatch("x{100}x{100} "), 1051);
+  assertToStringEquals("x{", res[493].firstMatch("x{100}x{100}x{100}x{100} "), 1052);
+  assertNull(res[493].firstMatch("abce"), 1053);
+  assertToStringEquals("x{", res[493].firstMatch("x{100}x{100}x{100}x{100} "), 1054);
+  assertNull(res[493].firstMatch("abcdx{100}x{100}x{100}x{100} "), 1055);
+  assertNull(res[493].firstMatch("abcdx{100}x{100}x{100}x{100} "), 1056);
+  assertNull(res[493].firstMatch("abcdx{100}x{100}x{100}x{100} "), 1057);
+  assertNull(res[493].firstMatch("abcdx{100}x{100}x{100}XX"), 1058);
+  assertNull(res[493].firstMatch("abcdx{100}x{100}x{100}x{100}x{100}x{100}x{100}XX"), 1059);
+  assertNull(res[493].firstMatch("abcdx{100}x{100}x{100}x{100}x{100}x{100}x{100}XX"), 1060);
+  assertToStringEquals("Xy", res[493].firstMatch("Xyyyax{100}x{100}bXzzz"), 1061);
+  assertToStringEquals("X", res[496].firstMatch("1X2"), 1062);
+  assertToStringEquals("x", res[496].firstMatch("1x{100}2 "), 1063);
+  assertToStringEquals(">X", res[497].firstMatch("> >X Y"), 1064);
+  assertToStringEquals(">x", res[497].firstMatch("> >x{100} Y"), 1065);
+  assertToStringEquals("1", res[498].firstMatch("x{100}3"), 1066);
+  assertToStringEquals(" ", res[499].firstMatch("x{100} X"), 1067);
+  assertToStringEquals("abcd", res[500].firstMatch("12abcd34"), 1068);
+  assertToStringEquals("*** Failers", res[500].firstMatch("*** Failers"), 1069);
+  assertToStringEquals("  ", res[500].firstMatch("1234  "), 1070);
+  assertToStringEquals("abc", res[501].firstMatch("12abcd34"), 1071);
+  assertToStringEquals("ab", res[501].firstMatch("12ab34"), 1072);
+  assertToStringEquals("***", res[501].firstMatch("*** Failers  "), 1073);
+  assertNull(res[501].firstMatch("1234"), 1074);
+  assertToStringEquals("  ", res[501].firstMatch("12a34  "), 1075);
+  assertToStringEquals("ab", res[502].firstMatch("12abcd34"), 1076);
+  assertToStringEquals("ab", res[502].firstMatch("12ab34"), 1077);
+  assertToStringEquals("**", res[502].firstMatch("*** Failers  "), 1078);
+  assertNull(res[502].firstMatch("1234"), 1079);
+  assertToStringEquals("  ", res[502].firstMatch("12a34  "), 1080);
+  assertToStringEquals("12", res[503].firstMatch("12abcd34"), 1081);
+  assertNull(res[503].firstMatch("*** Failers"), 1082);
+  assertToStringEquals("12", res[504].firstMatch("12abcd34"), 1083);
+  assertToStringEquals("123", res[504].firstMatch("1234abcd"), 1084);
+  assertNull(res[504].firstMatch("*** Failers  "), 1085);
+  assertNull(res[504].firstMatch("1.4 "), 1086);
+  assertToStringEquals("12", res[505].firstMatch("12abcd34"), 1087);
+  assertToStringEquals("12", res[505].firstMatch("1234abcd"), 1088);
+  assertNull(res[505].firstMatch("*** Failers  "), 1089);
+  assertNull(res[505].firstMatch("1.4 "), 1090);
+  assertToStringEquals("12abcd34", res[506].firstMatch("12abcd34"), 1091);
+  assertToStringEquals("***", res[506].firstMatch("*** Failers"), 1092);
+  assertNull(res[506].firstMatch("     "), 1093);
+  assertToStringEquals("12a", res[507].firstMatch("12abcd34"), 1094);
+  assertToStringEquals("123", res[507].firstMatch("1234abcd"), 1095);
+  assertToStringEquals("***", res[507].firstMatch("*** Failers"), 1096);
+  assertNull(res[507].firstMatch("       "), 1097);
+  assertToStringEquals("12", res[508].firstMatch("12abcd34"), 1098);
+  assertToStringEquals("12", res[508].firstMatch("1234abcd"), 1099);
+  assertToStringEquals("**", res[508].firstMatch("*** Failers"), 1100);
+  assertNull(res[508].firstMatch("       "), 1101);
+  assertToStringEquals(">      <", res[509].firstMatch("12>      <34"), 1102);
+  assertNull(res[509].firstMatch("*** Failers"), 1103);
+  assertToStringEquals(">  <", res[510].firstMatch("ab>  <cd"), 1104);
+  assertToStringEquals(">   <", res[510].firstMatch("ab>   <ce"), 1105);
+  assertNull(res[510].firstMatch("*** Failers"), 1106);
+  assertNull(res[510].firstMatch("ab>    <cd "), 1107);
+  assertToStringEquals(">  <", res[511].firstMatch("ab>  <cd"), 1108);
+  assertToStringEquals(">   <", res[511].firstMatch("ab>   <ce"), 1109);
+  assertNull(res[511].firstMatch("*** Failers"), 1110);
+  assertNull(res[511].firstMatch("ab>    <cd "), 1111);
+  assertToStringEquals("12", res[512].firstMatch("12      34"), 1112);
+  assertToStringEquals("Failers", res[512].firstMatch("*** Failers"), 1113);
+  assertNull(res[512].firstMatch("+++=*! "), 1114);
+  assertToStringEquals("ab", res[513].firstMatch("ab  cd"), 1115);
+  assertToStringEquals("abc", res[513].firstMatch("abcd ce"), 1116);
+  assertToStringEquals("Fai", res[513].firstMatch("*** Failers"), 1117);
+  assertNull(res[513].firstMatch("a.b.c"), 1118);
+  assertToStringEquals("ab", res[514].firstMatch("ab  cd"), 1119);
+  assertToStringEquals("ab", res[514].firstMatch("abcd ce"), 1120);
+  assertToStringEquals("Fa", res[514].firstMatch("*** Failers"), 1121);
+  assertNull(res[514].firstMatch("a.b.c"), 1122);
+  assertToStringEquals("====", res[515].firstMatch("12====34"), 1123);
+  assertToStringEquals("*** ", res[515].firstMatch("*** Failers"), 1124);
+  assertToStringEquals(" ", res[515].firstMatch("abcd "), 1125);
+  assertToStringEquals("===", res[516].firstMatch("ab====cd"), 1126);
+  assertToStringEquals("==", res[516].firstMatch("ab==cd"), 1127);
+  assertToStringEquals("***", res[516].firstMatch("*** Failers"), 1128);
+  assertNull(res[516].firstMatch("a.b.c"), 1129);
+  assertToStringEquals("==", res[517].firstMatch("ab====cd"), 1130);
+  assertToStringEquals("==", res[517].firstMatch("ab==cd"), 1131);
+  assertToStringEquals("**", res[517].firstMatch("*** Failers"), 1132);
+  assertNull(res[517].firstMatch("a.b.c"), 1133);
+  assertNull(res[517].firstMatch("x{100}"), 1134);
+  assertNull(res[517].firstMatch("Zx{100}"), 1135);
+  assertNull(res[517].firstMatch("x{100}Z"), 1136);
+  assertToStringEquals("**", res[517].firstMatch("*** Failers "), 1137);
+  assertNull(res[517].firstMatch("Zx{100}"), 1138);
+  assertNull(res[517].firstMatch("x{100}"), 1139);
+  assertNull(res[517].firstMatch("x{100}Z"), 1140);
+  assertToStringEquals("**", res[517].firstMatch("*** Failers "), 1141);
+  assertNull(res[517].firstMatch("abcx{200}X"), 1142);
+  assertNull(res[517].firstMatch("abcx{100}X "), 1143);
+  assertToStringEquals("**", res[517].firstMatch("*** Failers"), 1144);
+  assertToStringEquals("  ", res[517].firstMatch("X  "), 1145);
+  assertNull(res[517].firstMatch("abcx{200}X"), 1146);
+  assertNull(res[517].firstMatch("abcx{100}X "), 1147);
+  assertNull(res[517].firstMatch("abQX "), 1148);
+  assertToStringEquals("**", res[517].firstMatch("*** Failers"), 1149);
+  assertToStringEquals("  ", res[517].firstMatch("X  "), 1150);
+  assertNull(res[517].firstMatch("abcx{100}x{200}x{100}X"), 1151);
+  assertToStringEquals("**", res[517].firstMatch("*** Failers"), 1152);
+  assertNull(res[517].firstMatch("abcx{200}X"), 1153);
+  assertToStringEquals("  ", res[517].firstMatch("X  "), 1154);
+  assertNull(res[517].firstMatch("AX"), 1155);
+  assertNull(res[517].firstMatch("x{150}X"), 1156);
+  assertNull(res[517].firstMatch("x{500}X "), 1157);
+  assertToStringEquals("**", res[517].firstMatch("*** Failers"), 1158);
+  assertNull(res[517].firstMatch("x{100}X"), 1159);
+  assertToStringEquals("  ", res[517].firstMatch("x{200}X   "), 1160);
+  assertNull(res[517].firstMatch("AX"), 1161);
+  assertNull(res[517].firstMatch("x{150}X"), 1162);
+  assertNull(res[517].firstMatch("x{500}X "), 1163);
+  assertToStringEquals("**", res[517].firstMatch("*** Failers"), 1164);
+  assertNull(res[517].firstMatch("x{100}X"), 1165);
+  assertToStringEquals("  ", res[517].firstMatch("x{200}X   "), 1166);
+  assertNull(res[517].firstMatch("QX "), 1167);
+  assertNull(res[517].firstMatch("AX"), 1168);
+  assertNull(res[517].firstMatch("x{500}X "), 1169);
+  assertToStringEquals("**", res[517].firstMatch("*** Failers"), 1170);
+  assertNull(res[517].firstMatch("x{100}X"), 1171);
+  assertNull(res[517].firstMatch("x{150}X"), 1172);
+  assertToStringEquals("  ", res[517].firstMatch("x{200}X   "), 1173);
+  assertNull(res[518].firstMatch("aXb"), 1174);
+  assertNull(res[518].firstMatch("a\nb"), 1175);
+  assertNull(res[519].firstMatch("aXb"), 1176);
+  assertNull(res[519].firstMatch("a\nb"), 1177);
+  assertNull(res[519].firstMatch("*** Failers "), 1178);
+  assertNull(res[519].firstMatch("ax{100}b "), 1179);
+  assertNull(res[519].firstMatch("z"), 1180);
+  assertNull(res[519].firstMatch("Z "), 1181);
+  assertNull(res[519].firstMatch("x{100}"), 1182);
+  assertNull(res[519].firstMatch("*** Failers"), 1183);
+  assertNull(res[519].firstMatch("x{102}"), 1184);
+  assertNull(res[519].firstMatch("y    "), 1185);
+  assertToStringEquals("\xff", res[520].firstMatch(">\xff<"), 1186);
+  assertNull(res[521].firstMatch(">x{ff}<"), 1187);
+  assertToStringEquals("X", res[522].firstMatch("XYZ"), 1188);
+  assertToStringEquals("X", res[523].firstMatch("XYZ"), 1189);
+  assertToStringEquals("x", res[523].firstMatch("x{123} "), 1190);
+  assertToStringEquals(",", res[528].firstMatch("catac"), 1191);
+  assertToStringEquals(",", res[528].firstMatch("ax{256}a "), 1192);
+  assertToStringEquals(",", res[528].firstMatch("x{85}"), 1193);
+  assertToStringEquals(",", res[528].firstMatch("\u1234 "), 1194);
+  assertToStringEquals(",", res[528].firstMatch("\u1234 "), 1195);
+  assertToStringEquals(",", res[528].firstMatch("abcdefg"), 1196);
+  assertToStringEquals(",", res[528].firstMatch("ab"), 1197);
+  assertToStringEquals(",", res[528].firstMatch("a "), 1198);
+  assertToStringEquals("Ax", res[529].firstMatch("Ax{a3}BC"), 1199);
+  assertToStringEquals("Ax", res[530].firstMatch("Ax{a3}BC"), 1200);
+  assertToStringEquals("}=", res[531].firstMatch("+x{a3}== "), 1201);
+  assertToStringEquals("}=", res[532].firstMatch("+x{a3}== "), 1202);
+  assertToStringEquals("x", res[533].firstMatch("x{442}x{435}x{441}x{442}"), 1203);
+  assertToStringEquals("x", res[534].firstMatch("x{442}x{435}x{441}x{442}"), 1204);
+  assertToStringEquals("x", res[535].firstMatch("x{442}x{435}x{441}x{442}"), 1205);
+  assertToStringEquals("x", res[536].firstMatch("x{442}x{435}x{441}x{442}"), 1206);
+  assertToStringEquals("{", res[537].firstMatch("x{2442}x{2435}x{2441}x{2442}"), 1207);
+  assertToStringEquals("{", res[538].firstMatch("x{2442}x{2435}x{2441}x{2442}"), 1208);
+  assertToStringEquals("abc\n\x0dx{442}x{435}x{441}x{442}xyz ", res[539].firstMatch("abc\n\x0dx{442}x{435}x{441}x{442}xyz "), 1209);
+  assertToStringEquals("x{442}x{435}x{441}x{442}", res[539].firstMatch("x{442}x{435}x{441}x{442}"), 1210);
+  assertToStringEquals("c d", res[540].firstMatch("abc defx{442}x{443}xyz\npqr"), 1211);
+  assertToStringEquals("c d", res[541].firstMatch("abc defx{442}x{443}xyz\npqr"), 1212);
+  assertNull(res[542].firstMatch("+x{2442}"), 1213);
+  assertNull(res[543].firstMatch("+x{2442}"), 1214);
+  assertNull(res[544].firstMatch("Ax{442}"), 1215);
+  assertNull(res[545].firstMatch("Ax{442}"), 1216);
+  assertNull(res[546].firstMatch("Ax{442}"), 1217);
+  assertNull(res[547].firstMatch("Ax{442}"), 1218);
+  assertNull(res[548].firstMatch("\x19x{e01ff}"), 1219);
+  assertNull(res[549].firstMatch("Ax{422}"), 1220);
+  assertNull(res[550].firstMatch("x{19}x{e01ff}"), 1221);
+  assertNull(res[551].firstMatch("Ax{442}"), 1222);
+  assertNull(res[552].firstMatch("Ax{442}"), 1223);
+  assertNull(res[553].firstMatch("ax{442}"), 1224);
+  assertNull(res[554].firstMatch("+x{2442}"), 1225);
+  assertNull(res[555].firstMatch("Mx{442}"), 1226);
+  assertToStringEquals("abc", res[556].firstMatch("abc"), 1227);
+  assertToStringEquals("abc", res[557].firstMatch("abc"), 1228);
+  assertToStringEquals("abc", res[558].firstMatch("abc"), 1229);
+  assertToStringEquals("abc", res[559].firstMatch("abc"), 1230);
+  assertNull(res[560].firstMatch("x{100}ax{1234}bcd"), 1231);
+  assertNull(res[562].firstMatch("x{0041}x{2262}x{0391}x{002e}"), 1232);
+  assertNull(res[562].firstMatch("x{D55c}x{ad6d}x{C5B4} "), 1233);
+  assertNull(res[562].firstMatch("x{65e5}x{672c}x{8a9e}"), 1234);
+  assertToStringEquals("{861}X", res[563].firstMatch("x{212ab}x{212ab}x{212ab}x{861}X"), 1235);
+  assertToStringEquals("x{2", res[564].firstMatch("x{212ab}x{212ab}x{212ab}x{861}"), 1236);
+  assertToStringEquals("x{c", res[564].firstMatch("x{c0}b"), 1237);
+  assertToStringEquals("ax{", res[564].firstMatch("ax{c0}aaaa/ "), 1238);
+  assertToStringEquals("ax{", res[564].firstMatch("ax{c0}aaaa/ "), 1239);
+  assertToStringEquals("ax{", res[564].firstMatch("ax{c0}ax{c0}aaa/ "), 1240);
+  assertToStringEquals("ax{", res[564].firstMatch("ax{c0}aaaa/ "), 1241);
+  assertToStringEquals("ax{", res[564].firstMatch("ax{c0}ax{c0}aaa/ "), 1242);
+  assertToStringEquals("ax{", res[564].firstMatch("ax{c0}aaaa/ "), 1243);
+  assertToStringEquals("ax{", res[564].firstMatch("ax{c0}ax{c0}aaa/ "), 1244);
+  assertToStringEquals("Sho", res[564].firstMatch("Should produce an error diagnostic"), 1245);
+  assertNull(res[565].firstMatch("Xx{1234}"), 1246);
+  assertNull(res[565].firstMatch("X\nabc "), 1247);
+  assertToStringEquals("b", res[566].firstMatch("bar"), 1248);
+  assertNull(res[566].firstMatch("*** Failers"), 1249);
+  assertNull(res[566].firstMatch("c"), 1250);
+  assertNull(res[566].firstMatch("x{ff}"), 1251);
+  assertNull(res[566].firstMatch("x{100}  "), 1252);
+  assertToStringEquals("c", res[567].firstMatch("c"), 1253);
+  assertToStringEquals("x", res[567].firstMatch("x{ff}"), 1254);
+  assertToStringEquals("x", res[567].firstMatch("x{100}  "), 1255);
+  assertToStringEquals("*", res[567].firstMatch("*** Failers "), 1256);
+  assertNull(res[567].firstMatch("aaa"), 1257);
+  assertToStringEquals("x", res[568].firstMatch("x{f1}"), 1258);
+  assertToStringEquals("x", res[568].firstMatch("x{bf}"), 1259);
+  assertToStringEquals("x", res[568].firstMatch("x{100}"), 1260);
+  assertToStringEquals("x", res[568].firstMatch("x{1000}   "), 1261);
+  assertToStringEquals("*", res[568].firstMatch("*** Failers"), 1262);
+  assertToStringEquals("x", res[568].firstMatch("x{c0} "), 1263);
+  assertToStringEquals("x", res[568].firstMatch("x{f0} "), 1264);
+  assertToStringEquals("1", res[568].firstMatch("1234"), 1265);
+  assertToStringEquals("\"", res[568].firstMatch("\"1234\" "), 1266);
+  assertToStringEquals("x", res[568].firstMatch("x{100}1234"), 1267);
+  assertToStringEquals("\"", res[568].firstMatch("\"x{100}1234\"  "), 1268);
+  assertToStringEquals("x", res[568].firstMatch("x{100}x{100}12ab "), 1269);
+  assertToStringEquals("x", res[568].firstMatch("x{100}x{100}\"12\" "), 1270);
+  assertToStringEquals("*", res[568].firstMatch("*** Failers "), 1271);
+  assertToStringEquals("x", res[568].firstMatch("x{100}x{100}abcd"), 1272);
+  assertToStringEquals("A", res[568].firstMatch("A"), 1273);
+  assertToStringEquals("x", res[568].firstMatch("x{100}"), 1274);
+  assertToStringEquals("Z", res[568].firstMatch("Zx{100}"), 1275);
+  assertToStringEquals("x", res[568].firstMatch("x{100}Z"), 1276);
+  assertToStringEquals("*", res[568].firstMatch("*** Failers "), 1277);
+  assertToStringEquals("Z", res[568].firstMatch("Zx{100}"), 1278);
+  assertToStringEquals("x", res[568].firstMatch("x{100}"), 1279);
+  assertToStringEquals("x", res[568].firstMatch("x{100}Z"), 1280);
+  assertToStringEquals("*", res[568].firstMatch("*** Failers "), 1281);
+  assertToStringEquals("x", res[568].firstMatch("x{100}"), 1282);
+  assertToStringEquals("x", res[568].firstMatch("x{104}"), 1283);
+  assertToStringEquals("*", res[568].firstMatch("*** Failers"), 1284);
+  assertToStringEquals("x", res[568].firstMatch("x{105}"), 1285);
+  assertToStringEquals("x", res[568].firstMatch("x{ff}    "), 1286);
+  assertToStringEquals("x", res[568].firstMatch("x{100}"), 1287);
+  assertToStringEquals("\u0100", res[568].firstMatch("\u0100 "), 1288);
+  assertToStringEquals("\xff", res[569].firstMatch(">\xff<"), 1289);
+  assertNull(res[570].firstMatch(">x{ff}<"), 1290);
+  assertToStringEquals("\xd6", res[572].firstMatch("\xd6 # Matches without Study"), 1291);
+  assertToStringEquals("x", res[572].firstMatch("x{d6}"), 1292);
+  assertToStringEquals("\xd6", res[572].firstMatch("\xd6 <-- Same with Study"), 1293);
+  assertToStringEquals("x", res[572].firstMatch("x{d6}"), 1294);
+  assertToStringEquals("\xd6", res[572].firstMatch("\xd6 # Matches without Study"), 1295);
+  assertToStringEquals("x", res[572].firstMatch("x{d6} "), 1296);
+  assertToStringEquals("\xd6", res[572].firstMatch("\xd6 <-- Same with Study"), 1297);
+  assertToStringEquals("x", res[572].firstMatch("x{d6} "), 1298);
+  assertToStringEquals("\ufffd", res[572].firstMatch("\ufffd]"), 1299);
+  assertToStringEquals("\ufffd", res[572].firstMatch("\ufffd"), 1300);
+  assertToStringEquals("\ufffd", res[572].firstMatch("\ufffd\ufffd\ufffd"), 1301);
+  assertToStringEquals("\ufffd", res[572].firstMatch("\ufffd\ufffd\ufffd?"), 1302);
+  assertNull(res[573].firstMatch("\xc0\x80"), 1303);
+  assertNull(res[573].firstMatch("\xc1\x8f "), 1304);
+  assertNull(res[573].firstMatch("\xe0\x9f\x80"), 1305);
+  assertNull(res[573].firstMatch("\xf0\x8f\x80\x80 "), 1306);
+  assertNull(res[573].firstMatch("\xf8\x87\x80\x80\x80  "), 1307);
+  assertNull(res[573].firstMatch("\xfc\x83\x80\x80\x80\x80"), 1308);
+  assertNull(res[573].firstMatch("\xfe\x80\x80\x80\x80\x80  "), 1309);
+  assertNull(res[573].firstMatch("\xff\x80\x80\x80\x80\x80  "), 1310);
+  assertNull(res[573].firstMatch("\xc3\x8f"), 1311);
+  assertNull(res[573].firstMatch("\xe0\xaf\x80"), 1312);
+  assertNull(res[573].firstMatch("\xe1\x80\x80"), 1313);
+  assertNull(res[573].firstMatch("\xf0\x9f\x80\x80 "), 1314);
+  assertNull(res[573].firstMatch("\xf1\x8f\x80\x80 "), 1315);
+  assertNull(res[573].firstMatch("\xf8\x88\x80\x80\x80  "), 1316);
+  assertNull(res[573].firstMatch("\xf9\x87\x80\x80\x80  "), 1317);
+  assertNull(res[573].firstMatch("\xfc\x84\x80\x80\x80\x80"), 1318);
+  assertNull(res[573].firstMatch("\xfd\x83\x80\x80\x80\x80"), 1319);
+  assertNull(res[573].firstMatch("?\xf8\x88\x80\x80\x80  "), 1320);
+  assertNull(res[573].firstMatch("?\xf9\x87\x80\x80\x80  "), 1321);
+  assertNull(res[573].firstMatch("?\xfc\x84\x80\x80\x80\x80"), 1322);
+  assertNull(res[573].firstMatch("?\xfd\x83\x80\x80\x80\x80"), 1323);
+  assertToStringEquals(".", res[574].firstMatch("A.B"), 1324);
+  assertToStringEquals("{", res[574].firstMatch("Ax{100}B "), 1325);
+  assertToStringEquals("x", res[575].firstMatch("x{100}X   "), 1326);
+  assertToStringEquals("a", res[575].firstMatch("ax{1234}b"), 1327);
+  assertNull(res[577].firstMatch("AxxB     "), 1328);
+  assertToStringEquals("abc1", res[578].firstMatch("abc1 \nabc2 \x0babc3xx \x0cabc4 \x0dabc5xx \x0d\nabc6 x{0085}abc7 x{2028}abc8 x{2029}abc9 JUNK"), 1329);
+  assertToStringEquals("abc1", res[579].firstMatch("abc1\n abc2\x0b abc3\x0c abc4\x0d abc5\x0d\n abc6x{0085} abc7x{2028} abc8x{2029} abc9"), 1330);
+  assertNull(res[580].firstMatch("a\nb"), 1331);
+  assertNull(res[580].firstMatch("a\x0db"), 1332);
+  assertNull(res[580].firstMatch("a\x0d\nb"), 1333);
+  assertNull(res[580].firstMatch("a\x0bb"), 1334);
+  assertNull(res[580].firstMatch("a\x0cb"), 1335);
+  assertNull(res[580].firstMatch("ax{85}b   "), 1336);
+  assertNull(res[580].firstMatch("ax{2028}b "), 1337);
+  assertNull(res[580].firstMatch("ax{2029}b "), 1338);
+  assertNull(res[580].firstMatch("** Failers"), 1339);
+  assertNull(res[580].firstMatch("a\n\x0db    "), 1340);
+  assertToStringEquals("ab", res[581].firstMatch("ab"), 1341);
+  assertNull(res[581].firstMatch("a\nb"), 1342);
+  assertNull(res[581].firstMatch("a\x0db"), 1343);
+  assertNull(res[581].firstMatch("a\x0d\nb"), 1344);
+  assertNull(res[581].firstMatch("a\x0bb"), 1345);
+  assertNull(res[581].firstMatch("a\x0cx{2028}x{2029}b"), 1346);
+  assertNull(res[581].firstMatch("ax{85}b   "), 1347);
+  assertNull(res[581].firstMatch("a\n\x0db    "), 1348);
+  assertNull(res[581].firstMatch("a\n\x0dx{85}\x0cb "), 1349);
+  assertNull(res[582].firstMatch("a\nb"), 1350);
+  assertNull(res[582].firstMatch("a\x0db"), 1351);
+  assertNull(res[582].firstMatch("a\x0d\nb"), 1352);
+  assertNull(res[582].firstMatch("a\x0bb"), 1353);
+  assertNull(res[582].firstMatch("a\x0cx{2028}x{2029}b"), 1354);
+  assertNull(res[582].firstMatch("ax{85}b   "), 1355);
+  assertNull(res[582].firstMatch("a\n\x0db    "), 1356);
+  assertNull(res[582].firstMatch("a\n\x0dx{85}\x0cb "), 1357);
+  assertNull(res[582].firstMatch("** Failers"), 1358);
+  assertNull(res[582].firstMatch("ab  "), 1359);
+  assertNull(res[583].firstMatch("a\nb"), 1360);
+  assertNull(res[583].firstMatch("a\n\x0db"), 1361);
+  assertNull(res[583].firstMatch("a\n\x0dx{85}b"), 1362);
+  assertNull(res[583].firstMatch("a\x0d\n\x0d\nb "), 1363);
+  assertNull(res[583].firstMatch("a\x0d\n\x0d\n\x0d\nb "), 1364);
+  assertNull(res[583].firstMatch("a\n\x0d\n\x0db"), 1365);
+  assertNull(res[583].firstMatch("a\n\n\x0d\nb "), 1366);
+  assertNull(res[583].firstMatch("** Failers"), 1367);
+  assertNull(res[583].firstMatch("a\n\n\n\x0db"), 1368);
+  assertNull(res[583].firstMatch("a\x0d"), 1369);
+  assertNull(res[584].firstMatch("X X\n"), 1370);
+  assertNull(res[584].firstMatch("X\x09X\x0b"), 1371);
+  assertNull(res[584].firstMatch("** Failers"), 1372);
+  assertNull(res[584].firstMatch("x{a0} X\n   "), 1373);
+  assertNull(res[585].firstMatch("\x09 x{a0}X\n\x0b\x0c\x0d\n"), 1374);
+  assertNull(res[585].firstMatch("\x09 x{a0}\n\x0b\x0c\x0d\n"), 1375);
+  assertNull(res[585].firstMatch("\x09 x{a0}\n\x0b\x0c"), 1376);
+  assertNull(res[585].firstMatch("** Failers "), 1377);
+  assertNull(res[585].firstMatch("\x09 x{a0}\n\x0b"), 1378);
+  assertNull(res[585].firstMatch(" "), 1379);
+  assertNull(res[586].firstMatch("x{3001}x{3000}x{2030}x{2028}"), 1380);
+  assertNull(res[586].firstMatch("Xx{180e}Xx{85}"), 1381);
+  assertNull(res[586].firstMatch("** Failers"), 1382);
+  assertNull(res[586].firstMatch("x{2009} X\n   "), 1383);
+  assertNull(res[587].firstMatch("x{1680}x{180e}x{2007}Xx{2028}x{2029}\x0c\x0d\n"), 1384);
+  assertNull(res[587].firstMatch("\x09x{205f}x{a0}\nx{2029}\x0cx{2028}\n"), 1385);
+  assertNull(res[587].firstMatch("\x09 x{202f}\n\x0b\x0c"), 1386);
+  assertNull(res[587].firstMatch("** Failers "), 1387);
+  assertNull(res[587].firstMatch("\x09x{200a}x{a0}x{2028}\x0b"), 1388);
+  assertNull(res[587].firstMatch(" "), 1389);
+  assertNull(res[588].firstMatch(">x{1680}"), 1390);
+  assertNull(res[589].firstMatch(">x{1680}x{180e}x{2000}x{2003}x{200a}x{202f}x{205f}x{3000}<"), 1391);
+  assertToStringEquals("x{1ec5} ", res[593].firstMatch("x{1ec5} "), 1392);
+  assertNull(res[594].firstMatch("x{0}x{d7ff}x{e000}x{10ffff}"), 1393);
+  assertNull(res[594].firstMatch("x{d800}"), 1394);
+  assertNull(res[594].firstMatch("x{d800}?"), 1395);
+  assertNull(res[594].firstMatch("x{da00}"), 1396);
+  assertNull(res[594].firstMatch("x{da00}?"), 1397);
+  assertNull(res[594].firstMatch("x{dfff}"), 1398);
+  assertNull(res[594].firstMatch("x{dfff}?"), 1399);
+  assertNull(res[594].firstMatch("x{110000}    "), 1400);
+  assertNull(res[594].firstMatch("x{110000}?    "), 1401);
+  assertNull(res[594].firstMatch("x{2000000} "), 1402);
+  assertNull(res[594].firstMatch("x{2000000}? "), 1403);
+  assertNull(res[594].firstMatch("x{7fffffff} "), 1404);
+  assertNull(res[594].firstMatch("x{7fffffff}? "), 1405);
+  assertNull(res[595].firstMatch("a\x0db"), 1406);
+  assertNull(res[595].firstMatch("a\nb"), 1407);
+  assertNull(res[595].firstMatch("a\x0d\nb"), 1408);
+  assertNull(res[595].firstMatch("** Failers"), 1409);
+  assertNull(res[595].firstMatch("ax{85}b"), 1410);
+  assertNull(res[595].firstMatch("a\x0bb     "), 1411);
+  assertNull(res[596].firstMatch("a\x0db"), 1412);
+  assertNull(res[596].firstMatch("a\nb"), 1413);
+  assertNull(res[596].firstMatch("a\x0d\nb"), 1414);
+  assertNull(res[596].firstMatch("ax{85}b"), 1415);
+  assertNull(res[596].firstMatch("a\x0bb     "), 1416);
+  assertNull(res[596].firstMatch("** Failers "), 1417);
+  assertNull(res[596].firstMatch("ax{85}b<bsr_anycrlf>"), 1418);
+  assertNull(res[596].firstMatch("a\x0bb<bsr_anycrlf>"), 1419);
+  assertNull(res[597].firstMatch("a\x0db"), 1420);
+  assertNull(res[597].firstMatch("a\nb"), 1421);
+  assertNull(res[597].firstMatch("a\x0d\nb"), 1422);
+  assertNull(res[597].firstMatch("** Failers"), 1423);
+  assertNull(res[597].firstMatch("ax{85}b"), 1424);
+  assertNull(res[597].firstMatch("a\x0bb     "), 1425);
+  assertNull(res[598].firstMatch("a\x0db"), 1426);
+  assertNull(res[598].firstMatch("a\nb"), 1427);
+  assertNull(res[598].firstMatch("a\x0d\nb"), 1428);
+  assertNull(res[598].firstMatch("ax{85}b"), 1429);
+  assertNull(res[598].firstMatch("a\x0bb     "), 1430);
+  assertNull(res[598].firstMatch("** Failers "), 1431);
+  assertNull(res[598].firstMatch("ax{85}b<bsr_anycrlf>"), 1432);
+  assertNull(res[598].firstMatch("a\x0bb<bsr_anycrlf>"), 1433);
+  assertToStringEquals("QQQx{2029}ABCaXYZ=!bPQR", res[599].firstMatch("QQQx{2029}ABCaXYZ=!bPQR"), 1434);
+  assertNull(res[599].firstMatch("** Failers"), 1435);
+  assertNull(res[599].firstMatch("ax{2029}b"), 1436);
+  assertNull(res[599].firstMatch("a\xe2\x80\xa9b "), 1437);
+  assertNull(res[600].firstMatch("ax{1234}b"), 1438);
+  assertToStringEquals("a\nb", res[600].firstMatch("a\nb "), 1439);
+  assertNull(res[600].firstMatch("** Failers"), 1440);
+  assertNull(res[600].firstMatch("ab  "), 1441);
+  assertToStringEquals("aXb", res[601].firstMatch("aXb"), 1442);
+  assertToStringEquals("a\nX\nXx{1234}b", res[601].firstMatch("a\nX\nXx{1234}b "), 1443);
+  assertNull(res[601].firstMatch("** Failers"), 1444);
+  assertNull(res[601].firstMatch("ab  "), 1445);
+  assertNull(res[601].firstMatch("x{de}x{de}"), 1446);
+  assertNull(res[601].firstMatch("x{123} "), 1447);
+  assertToStringEquals("X", res[602].firstMatch("Ax{1ec5}ABCXYZ"), 1448);
+  assertNull(res[604].firstMatch("x{c0}x{30f}x{660}x{66c}x{f01}x{1680}<"), 1449);
+  assertNull(res[604].firstMatch("\npx{300}9!\$ < "), 1450);
+  assertNull(res[604].firstMatch("** Failers "), 1451);
+  assertNull(res[604].firstMatch("apx{300}9!\$ < "), 1452);
+  assertNull(res[605].firstMatch("X"), 1453);
+  assertNull(res[605].firstMatch("** Failers "), 1454);
+  assertNull(res[605].firstMatch(""), 1455);
+  assertNull(res[606].firstMatch("9"), 1456);
+  assertNull(res[606].firstMatch("** Failers "), 1457);
+  assertNull(res[606].firstMatch("x{c0}"), 1458);
+  assertNull(res[607].firstMatch("X"), 1459);
+  assertNull(res[607].firstMatch("** Failers "), 1460);
+  assertNull(res[607].firstMatch("x{30f}"), 1461);
+  assertNull(res[608].firstMatch("X"), 1462);
+  assertNull(res[608].firstMatch("** Failers "), 1463);
+  assertNull(res[608].firstMatch("x{660}"), 1464);
+  assertNull(res[609].firstMatch("X"), 1465);
+  assertNull(res[609].firstMatch("** Failers "), 1466);
+  assertNull(res[609].firstMatch("x{66c}"), 1467);
+  assertNull(res[610].firstMatch("X"), 1468);
+  assertNull(res[610].firstMatch("** Failers "), 1469);
+  assertNull(res[610].firstMatch("x{f01}"), 1470);
+  assertNull(res[611].firstMatch("X"), 1471);
+  assertNull(res[611].firstMatch("** Failers "), 1472);
+  assertNull(res[611].firstMatch("x{1680}"), 1473);
+  assertNull(res[612].firstMatch("x{017}"), 1474);
+  assertNull(res[612].firstMatch("x{09f} "), 1475);
+  assertNull(res[612].firstMatch("** Failers"), 1476);
+  assertNull(res[612].firstMatch("x{0600} "), 1477);
+  assertNull(res[613].firstMatch("x{601}"), 1478);
+  assertNull(res[613].firstMatch("** Failers"), 1479);
+  assertNull(res[613].firstMatch("x{09f} "), 1480);
+  assertNull(res[614].firstMatch("x{e0000}"), 1481);
+  assertNull(res[614].firstMatch("** Failers"), 1482);
+  assertNull(res[614].firstMatch("x{09f} "), 1483);
+  assertNull(res[615].firstMatch("x{f8ff}"), 1484);
+  assertNull(res[615].firstMatch("** Failers"), 1485);
+  assertNull(res[615].firstMatch("x{09f} "), 1486);
+  assertNull(res[616].firstMatch("?x{dfff}"), 1487);
+  assertNull(res[616].firstMatch("** Failers"), 1488);
+  assertNull(res[616].firstMatch("x{09f} "), 1489);
+  assertNull(res[617].firstMatch("a"), 1490);
+  assertNull(res[617].firstMatch("** Failers "), 1491);
+  assertNull(res[617].firstMatch("Z"), 1492);
+  assertNull(res[617].firstMatch("x{e000}  "), 1493);
+  assertNull(res[618].firstMatch("x{2b0}"), 1494);
+  assertNull(res[618].firstMatch("** Failers"), 1495);
+  assertNull(res[618].firstMatch("a "), 1496);
+  assertNull(res[619].firstMatch("x{1bb}"), 1497);
+  assertNull(res[619].firstMatch("x{3400}"), 1498);
+  assertNull(res[619].firstMatch("x{3401}"), 1499);
+  assertNull(res[619].firstMatch("x{4d00}"), 1500);
+  assertNull(res[619].firstMatch("x{4db4}"), 1501);
+  assertNull(res[619].firstMatch("x{4db5}     "), 1502);
+  assertNull(res[619].firstMatch("** Failers"), 1503);
+  assertNull(res[619].firstMatch("a "), 1504);
+  assertNull(res[619].firstMatch("x{2b0}"), 1505);
+  assertNull(res[619].firstMatch("x{4db6} "), 1506);
+  assertNull(res[620].firstMatch("x{1c5}"), 1507);
+  assertNull(res[620].firstMatch("** Failers"), 1508);
+  assertNull(res[620].firstMatch("a "), 1509);
+  assertNull(res[620].firstMatch("x{2b0}"), 1510);
+  assertNull(res[621].firstMatch("A"), 1511);
+  assertNull(res[621].firstMatch("** Failers"), 1512);
+  assertNull(res[621].firstMatch("x{2b0}"), 1513);
+  assertNull(res[622].firstMatch("x{903}"), 1514);
+  assertNull(res[622].firstMatch("** Failers"), 1515);
+  assertNull(res[622].firstMatch("X"), 1516);
+  assertNull(res[622].firstMatch("x{300}"), 1517);
+  assertNull(res[622].firstMatch("   "), 1518);
+  assertNull(res[623].firstMatch("x{488}"), 1519);
+  assertNull(res[623].firstMatch("** Failers"), 1520);
+  assertNull(res[623].firstMatch("X"), 1521);
+  assertNull(res[623].firstMatch("x{903}"), 1522);
+  assertNull(res[623].firstMatch("x{300}"), 1523);
+  assertNull(res[624].firstMatch("x{300}"), 1524);
+  assertNull(res[624].firstMatch("** Failers"), 1525);
+  assertNull(res[624].firstMatch("X"), 1526);
+  assertNull(res[624].firstMatch("x{903}"), 1527);
+  assertNull(res[624].firstMatch("0123456789x{660}x{661}x{662}x{663}x{664}x{665}x{666}x{667}x{668}x{669}x{66a}"), 1528);
+  assertNull(res[624].firstMatch("x{6f0}x{6f1}x{6f2}x{6f3}x{6f4}x{6f5}x{6f6}x{6f7}x{6f8}x{6f9}x{6fa}"), 1529);
+  assertNull(res[624].firstMatch("x{966}x{967}x{968}x{969}x{96a}x{96b}x{96c}x{96d}x{96e}x{96f}x{970}"), 1530);
+  assertNull(res[624].firstMatch("** Failers"), 1531);
+  assertNull(res[624].firstMatch("X"), 1532);
+  assertNull(res[625].firstMatch("x{16ee}"), 1533);
+  assertNull(res[625].firstMatch("** Failers"), 1534);
+  assertNull(res[625].firstMatch("X"), 1535);
+  assertNull(res[625].firstMatch("x{966}"), 1536);
+  assertNull(res[626].firstMatch("x{b2}"), 1537);
+  assertNull(res[626].firstMatch("x{b3}"), 1538);
+  assertNull(res[626].firstMatch("** Failers"), 1539);
+  assertNull(res[626].firstMatch("X"), 1540);
+  assertNull(res[626].firstMatch("x{16ee}"), 1541);
+  assertNull(res[627].firstMatch("_"), 1542);
+  assertNull(res[627].firstMatch("x{203f}"), 1543);
+  assertNull(res[627].firstMatch("** Failers"), 1544);
+  assertNull(res[627].firstMatch("X"), 1545);
+  assertNull(res[627].firstMatch("-"), 1546);
+  assertNull(res[627].firstMatch("x{58a}"), 1547);
+  assertNull(res[628].firstMatch("-"), 1548);
+  assertNull(res[628].firstMatch("x{58a}"), 1549);
+  assertNull(res[628].firstMatch("** Failers"), 1550);
+  assertNull(res[628].firstMatch("X"), 1551);
+  assertNull(res[628].firstMatch("x{203f}"), 1552);
+  assertNull(res[629].firstMatch(")"), 1553);
+  assertNull(res[629].firstMatch("]"), 1554);
+  assertNull(res[629].firstMatch("}"), 1555);
+  assertNull(res[629].firstMatch("x{f3b}"), 1556);
+  assertNull(res[629].firstMatch("** Failers"), 1557);
+  assertNull(res[629].firstMatch("X"), 1558);
+  assertNull(res[629].firstMatch("x{203f}"), 1559);
+  assertNull(res[629].firstMatch("("), 1560);
+  assertNull(res[629].firstMatch("["), 1561);
+  assertNull(res[629].firstMatch("{"), 1562);
+  assertNull(res[629].firstMatch("x{f3c}"), 1563);
+  assertNull(res[630].firstMatch("x{bb}"), 1564);
+  assertNull(res[630].firstMatch("x{2019}"), 1565);
+  assertNull(res[630].firstMatch("** Failers"), 1566);
+  assertNull(res[630].firstMatch("X"), 1567);
+  assertNull(res[630].firstMatch("x{203f}"), 1568);
+  assertNull(res[631].firstMatch("x{ab}"), 1569);
+  assertNull(res[631].firstMatch("x{2018}"), 1570);
+  assertNull(res[631].firstMatch("** Failers"), 1571);
+  assertNull(res[631].firstMatch("X"), 1572);
+  assertNull(res[631].firstMatch("x{203f}"), 1573);
+  assertNull(res[632].firstMatch("!"), 1574);
+  assertNull(res[632].firstMatch("x{37e}"), 1575);
+  assertNull(res[632].firstMatch("** Failers"), 1576);
+  assertNull(res[632].firstMatch("X"), 1577);
+  assertNull(res[632].firstMatch("x{203f}"), 1578);
+  assertNull(res[633].firstMatch("("), 1579);
+  assertNull(res[633].firstMatch("["), 1580);
+  assertNull(res[633].firstMatch("{"), 1581);
+  assertNull(res[633].firstMatch("x{f3c}"), 1582);
+  assertNull(res[633].firstMatch("** Failers"), 1583);
+  assertNull(res[633].firstMatch("X"), 1584);
+  assertNull(res[633].firstMatch(")"), 1585);
+  assertNull(res[633].firstMatch("]"), 1586);
+  assertNull(res[633].firstMatch("}"), 1587);
+  assertNull(res[633].firstMatch("x{f3b}"), 1588);
+  assertNull(res[633].firstMatch("\$x{a2}x{a3}x{a4}x{a5}x{a6}"), 1589);
+  assertNull(res[633].firstMatch("x{9f2}"), 1590);
+  assertNull(res[633].firstMatch("** Failers"), 1591);
+  assertNull(res[633].firstMatch("X"), 1592);
+  assertNull(res[633].firstMatch("x{2c2}"), 1593);
+  assertNull(res[634].firstMatch("x{2c2}"), 1594);
+  assertNull(res[634].firstMatch("** Failers"), 1595);
+  assertNull(res[634].firstMatch("X"), 1596);
+  assertNull(res[634].firstMatch("x{9f2}"), 1597);
+  assertNull(res[634].firstMatch("+<|~x{ac}x{2044}"), 1598);
+  assertNull(res[634].firstMatch("** Failers"), 1599);
+  assertNull(res[634].firstMatch("X"), 1600);
+  assertNull(res[634].firstMatch("x{9f2}"), 1601);
+  assertNull(res[635].firstMatch("x{a6}"), 1602);
+  assertNull(res[635].firstMatch("x{482} "), 1603);
+  assertNull(res[635].firstMatch("** Failers"), 1604);
+  assertNull(res[635].firstMatch("X"), 1605);
+  assertNull(res[635].firstMatch("x{9f2}"), 1606);
+  assertNull(res[636].firstMatch("x{2028}"), 1607);
+  assertNull(res[636].firstMatch("** Failers"), 1608);
+  assertNull(res[636].firstMatch("X"), 1609);
+  assertNull(res[636].firstMatch("x{2029}"), 1610);
+  assertNull(res[637].firstMatch("x{2029}"), 1611);
+  assertNull(res[637].firstMatch("** Failers"), 1612);
+  assertNull(res[637].firstMatch("X"), 1613);
+  assertNull(res[637].firstMatch("x{2028}"), 1614);
+  assertNull(res[638].firstMatch("\\ \\"), 1615);
+  assertNull(res[638].firstMatch("x{a0}"), 1616);
+  assertNull(res[638].firstMatch("x{1680}"), 1617);
+  assertNull(res[638].firstMatch("x{180e}"), 1618);
+  assertNull(res[638].firstMatch("x{2000}"), 1619);
+  assertNull(res[638].firstMatch("x{2001}     "), 1620);
+  assertNull(res[638].firstMatch("** Failers"), 1621);
+  assertNull(res[638].firstMatch("x{2028}"), 1622);
+  assertNull(res[638].firstMatch("x{200d} "), 1623);
+  assertNull(res[638].firstMatch("  x{660}x{661}x{662}ABC"), 1624);
+  assertNull(res[638].firstMatch("  x{660}x{661}x{662}ABC"), 1625);
+  assertNull(res[639].firstMatch("  x{660}x{661}x{662}ABC"), 1626);
+  assertNull(res[640].firstMatch("  x{660}x{661}x{662}ABC"), 1627);
+  assertNull(res[641].firstMatch("  x{660}x{661}x{662}ABC"), 1628);
+  assertNull(res[642].firstMatch("  x{660}x{661}x{662}ABC"), 1629);
+  assertNull(res[643].firstMatch("  x{660}x{661}x{662}ABC"), 1630);
+  assertNull(res[644].firstMatch("  x{660}x{661}x{662}ABC"), 1631);
+  assertNull(res[645].firstMatch("  x{660}x{661}x{662}ABC"), 1632);
+  assertNull(res[646].firstMatch("  x{660}x{661}x{662}ABC"), 1633);
+  assertNull(res[647].firstMatch("  x{660}x{661}x{662}ABC"), 1634);
+  assertNull(res[647].firstMatch("  x{660}x{661}x{662}ABC"), 1635);
+  assertNull(res[647].firstMatch("  x{660}x{661}x{662}ABC"), 1636);
+  assertNull(res[647].firstMatch("  ** Failers"), 1637);
+  assertNull(res[647].firstMatch("  x{660}x{661}x{662}ABC"), 1638);
+  assertNull(res[648].firstMatch("A"), 1639);
+  assertNull(res[648].firstMatch("ax{10a0}B "), 1640);
+  assertNull(res[648].firstMatch("** Failers "), 1641);
+  assertNull(res[648].firstMatch("a"), 1642);
+  assertNull(res[648].firstMatch("x{1d00}  "), 1643);
+  assertNull(res[649].firstMatch("1234"), 1644);
+  assertNull(res[649].firstMatch("** Failers"), 1645);
+  assertNull(res[649].firstMatch("ABC "), 1646);
+  assertNull(res[650].firstMatch("1234"), 1647);
+  assertNull(res[650].firstMatch("** Failers"), 1648);
+  assertNull(res[650].firstMatch("ABC "), 1649);
+  assertNull(res[650].firstMatch("A2XYZ"), 1650);
+  assertNull(res[650].firstMatch("123A5XYZPQR"), 1651);
+  assertNull(res[650].firstMatch("ABAx{660}XYZpqr"), 1652);
+  assertNull(res[650].firstMatch("** Failers"), 1653);
+  assertNull(res[650].firstMatch("AXYZ"), 1654);
+  assertNull(res[650].firstMatch("XYZ     "), 1655);
+  assertNull(res[650].firstMatch("1XYZ"), 1656);
+  assertNull(res[650].firstMatch("AB=XYZ.. "), 1657);
+  assertNull(res[650].firstMatch("XYZ "), 1658);
+  assertNull(res[650].firstMatch("** Failers"), 1659);
+  assertNull(res[650].firstMatch("WXYZ "), 1660);
+  assertNull(res[655].firstMatch("1234"), 1661);
+  assertNull(res[655].firstMatch("1234"), 1662);
+  assertNull(res[655].firstMatch("12-34"), 1663);
+  assertToStringEquals("{", res[655].firstMatch("12+x{661}-34  "), 1664);
+  assertNull(res[655].firstMatch("** Failers"), 1665);
+  assertToStringEquals("d", res[655].firstMatch("abcd  "), 1666);
+  assertToStringEquals("d", res[656].firstMatch("abcd"), 1667);
+  assertNull(res[656].firstMatch("** Failers"), 1668);
+  assertNull(res[656].firstMatch("1234"), 1669);
+  assertNull(res[657].firstMatch("11111111111111111111111111111111111111111111111111111111111111111111111"), 1670);
+  assertToStringEquals("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", res[657].firstMatch("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"), 1671);
+  assertToStringEquals(" ", res[657].firstMatch(" "), 1672);
+  assertNull(res[657].firstMatch("11111111111111111111111111111111111111111111111111111111111111111111111"), 1673);
+  assertToStringEquals("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", res[657].firstMatch("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"), 1674);
+  assertNull(res[658].firstMatch("11111111111111111111111111111111111111111111111111111111111111111111111"), 1675);
+  assertToStringEquals("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", res[658].firstMatch("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"), 1676);
+  assertNull(res[659].firstMatch("11111111111111111111111111111111111111111111111111111111111111111111111"), 1677);
+  assertNull(res[659].firstMatch("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"), 1678);
+  assertNull(res[660].firstMatch("11111111111111111111111111111111111111111111111111111111111111111111111"), 1679);
+  assertToStringEquals("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", res[660].firstMatch("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"), 1680);
+  assertNull(res[661].firstMatch("a"), 1681);
+  assertNull(res[661].firstMatch("A "), 1682);
+  assertNull(res[662].firstMatch("a"), 1683);
+  assertNull(res[662].firstMatch("A "), 1684);
+  assertNull(res[663].firstMatch("A"), 1685);
+  assertNull(res[663].firstMatch("aZ"), 1686);
+  assertNull(res[663].firstMatch("** Failers"), 1687);
+  assertNull(res[663].firstMatch("abc   "), 1688);
+  assertNull(res[664].firstMatch("A"), 1689);
+  assertNull(res[664].firstMatch("aZ"), 1690);
+  assertNull(res[664].firstMatch("** Failers"), 1691);
+  assertNull(res[664].firstMatch("abc   "), 1692);
+  assertNull(res[665].firstMatch("a"), 1693);
+  assertNull(res[665].firstMatch("Az"), 1694);
+  assertNull(res[665].firstMatch("** Failers"), 1695);
+  assertNull(res[665].firstMatch("ABC   "), 1696);
+  assertNull(res[666].firstMatch("a"), 1697);
+  assertNull(res[666].firstMatch("Az"), 1698);
+  assertNull(res[666].firstMatch("** Failers"), 1699);
+  assertNull(res[666].firstMatch("ABC   "), 1700);
+  assertNull(res[666].firstMatch("x{c0}"), 1701);
+  assertNull(res[666].firstMatch("x{e0} "), 1702);
+  assertNull(res[666].firstMatch("x{c0}"), 1703);
+  assertNull(res[666].firstMatch("x{e0} "), 1704);
+  assertNull(res[666].firstMatch("Ax{391}x{10427}x{ff3a}x{1fb0}"), 1705);
+  assertNull(res[666].firstMatch("** Failers"), 1706);
+  assertNull(res[666].firstMatch("ax{391}x{10427}x{ff3a}x{1fb0}   "), 1707);
+  assertNull(res[666].firstMatch("Ax{3b1}x{10427}x{ff3a}x{1fb0}"), 1708);
+  assertNull(res[666].firstMatch("Ax{391}x{1044F}x{ff3a}x{1fb0}"), 1709);
+  assertNull(res[666].firstMatch("Ax{391}x{10427}x{ff5a}x{1fb0}"), 1710);
+  assertNull(res[666].firstMatch("Ax{391}x{10427}x{ff3a}x{1fb8}"), 1711);
+  assertNull(res[666].firstMatch("Ax{391}x{10427}x{ff3a}x{1fb0}"), 1712);
+  assertNull(res[666].firstMatch("ax{391}x{10427}x{ff3a}x{1fb0}   "), 1713);
+  assertNull(res[666].firstMatch("Ax{3b1}x{10427}x{ff3a}x{1fb0}"), 1714);
+  assertNull(res[666].firstMatch("Ax{391}x{1044F}x{ff3a}x{1fb0}"), 1715);
+  assertNull(res[666].firstMatch("Ax{391}x{10427}x{ff5a}x{1fb0}"), 1716);
+  assertNull(res[666].firstMatch("Ax{391}x{10427}x{ff3a}x{1fb8}"), 1717);
+  assertNull(res[666].firstMatch("x{391}x{3b1}x{3b1}x{3b1}x{391}"), 1718);
+  assertNull(res[666].firstMatch("x{391}x{3b1}x{3b1}x{3b1}x{391}X"), 1719);
+  assertNull(res[666].firstMatch("x{391}x{3b1}x{3b1}x{3b1}x{391}X"), 1720);
+  assertNull(res[666].firstMatch("x{391}"), 1721);
+  assertNull(res[666].firstMatch("x{ff3a}"), 1722);
+  assertNull(res[666].firstMatch("x{3b1}"), 1723);
+  assertNull(res[666].firstMatch("x{ff5a}   "), 1724);
+  assertNull(res[666].firstMatch("x{c0}"), 1725);
+  assertNull(res[666].firstMatch("x{e0} "), 1726);
+  assertNull(res[666].firstMatch("x{104}"), 1727);
+  assertNull(res[666].firstMatch("x{105}"), 1728);
+  assertNull(res[666].firstMatch("x{109}  "), 1729);
+  assertNull(res[666].firstMatch("** Failers"), 1730);
+  assertNull(res[666].firstMatch("x{100}"), 1731);
+  assertNull(res[666].firstMatch("x{10a} "), 1732);
+  assertNull(res[666].firstMatch("Z"), 1733);
+  assertNull(res[666].firstMatch("z"), 1734);
+  assertNull(res[666].firstMatch("x{39c}"), 1735);
+  assertNull(res[666].firstMatch("x{178}"), 1736);
+  assertNull(res[666].firstMatch("|"), 1737);
+  assertNull(res[666].firstMatch("x{80}"), 1738);
+  assertNull(res[666].firstMatch("x{ff}"), 1739);
+  assertNull(res[666].firstMatch("x{100}"), 1740);
+  assertNull(res[666].firstMatch("x{101} "), 1741);
+  assertNull(res[666].firstMatch("** Failers"), 1742);
+  assertNull(res[666].firstMatch("x{102}"), 1743);
+  assertNull(res[666].firstMatch("Y"), 1744);
+  assertNull(res[666].firstMatch("y           "), 1745);
+  assertNull(res[667].firstMatch("A"), 1746);
+  assertNull(res[667].firstMatch("Ax{300}BC "), 1747);
+  assertNull(res[667].firstMatch("Ax{300}x{301}x{302}BC "), 1748);
+  assertNull(res[667].firstMatch("*** Failers"), 1749);
+  assertNull(res[667].firstMatch("x{300}  "), 1750);
+  assertToStringEquals("X", res[668].firstMatch("X123"), 1751);
+  assertNull(res[668].firstMatch("*** Failers"), 1752);
+  assertNull(res[668].firstMatch("AXYZ"), 1753);
+  assertNull(res[669].firstMatch("Ax{300}x{301}x{302}BCAx{300}x{301} "), 1754);
+  assertNull(res[669].firstMatch("Ax{300}x{301}x{302}BCAx{300}x{301}C "), 1755);
+  assertNull(res[670].firstMatch("Ax{300}x{301}x{302}BCAx{300}x{301} "), 1756);
+  assertNull(res[670].firstMatch("Ax{300}x{301}x{302}BCAx{300}x{301}C "), 1757);
+  assertToStringEquals("A,,A", res[671].firstMatch("Ax{300}x{301}x{302}BCAx{300}x{301} "), 1758);
+  assertToStringEquals("A,,A", res[671].firstMatch("Ax{300}x{301}x{302}BCAx{300}x{301}C "), 1759);
+  assertToStringEquals("A,,A", res[672].firstMatch("Ax{300}x{301}x{302}BCAx{300}x{301} "), 1760);
+  assertToStringEquals("A,,A", res[672].firstMatch("Ax{300}x{301}x{302}BCAx{300}x{301}C "), 1761);
+  assertNull(res[673].firstMatch("*** Failers"), 1762);
+  assertNull(res[673].firstMatch("Ax{300}x{301}x{302}"), 1763);
+  assertNull(res[674].firstMatch("Ax{300}x{301}Bx{300}X"), 1764);
+  assertNull(res[674].firstMatch("Ax{300}x{301}Bx{300}Cx{300}x{301}"), 1765);
+  assertNull(res[674].firstMatch("Ax{300}x{301}Bx{300}Cx{300}x{301}X"), 1766);
+  assertNull(res[674].firstMatch("Ax{300}x{301}Bx{300}Cx{300}x{301}DAx{300}X"), 1767);
+  assertNull(res[675].firstMatch("Ax{300}x{301}Bx{300}X"), 1768);
+  assertNull(res[675].firstMatch("Ax{300}x{301}Bx{300}Cx{300}x{301}"), 1769);
+  assertNull(res[675].firstMatch("Ax{300}x{301}Bx{300}Cx{300}x{301}X"), 1770);
+  assertNull(res[675].firstMatch("Ax{300}x{301}Bx{300}Cx{300}x{301}DAx{300}X"), 1771);
+  assertNull(res[675].firstMatch("x{2e81}x{3007}x{2f804}x{31a0}"), 1772);
+  assertNull(res[675].firstMatch("** Failers"), 1773);
+  assertNull(res[675].firstMatch("x{2e7f}  "), 1774);
+  assertNull(res[675].firstMatch("x{3105}"), 1775);
+  assertNull(res[675].firstMatch("** Failers"), 1776);
+  assertNull(res[675].firstMatch("x{30ff}  "), 1777);
+  assertNull(res[676].firstMatch("x{06e9}"), 1778);
+  assertNull(res[676].firstMatch("x{060b}"), 1779);
+  assertNull(res[676].firstMatch("** Failers"), 1780);
+  assertNull(res[676].firstMatch("Xx{06e9}   "), 1781);
+  assertNull(res[677].firstMatch("x{2f800}"), 1782);
+  assertNull(res[677].firstMatch("** Failers"), 1783);
+  assertNull(res[677].firstMatch("x{a014}"), 1784);
+  assertNull(res[677].firstMatch("x{a4c6}   "), 1785);
+  assertNull(res[678].firstMatch("AXYZ"), 1786);
+  assertNull(res[678].firstMatch("x{1234}XYZ "), 1787);
+  assertNull(res[678].firstMatch("** Failers"), 1788);
+  assertNull(res[678].firstMatch("X  "), 1789);
+  assertNull(res[679].firstMatch("** Failers"), 1790);
+  assertNull(res[679].firstMatch("AX"), 1791);
+  assertNull(res[680].firstMatch("XYZ"), 1792);
+  assertNull(res[680].firstMatch("AXYZ"), 1793);
+  assertNull(res[680].firstMatch("x{1234}XYZ "), 1794);
+  assertNull(res[680].firstMatch("** Failers"), 1795);
+  assertNull(res[680].firstMatch("ABXYZ   "), 1796);
+  assertNull(res[681].firstMatch("XYZ"), 1797);
+  assertNull(res[681].firstMatch("** Failers"), 1798);
+  assertNull(res[681].firstMatch("AXYZ"), 1799);
+  assertNull(res[681].firstMatch("x{1234}XYZ "), 1800);
+  assertNull(res[681].firstMatch("ABXYZ   "), 1801);
+  assertNull(res[681].firstMatch("AXYZ"), 1802);
+  assertNull(res[681].firstMatch("x{1234}XYZ"), 1803);
+  assertNull(res[681].firstMatch("Ax{1234}XYZ"), 1804);
+  assertNull(res[681].firstMatch("** Failers"), 1805);
+  assertNull(res[681].firstMatch("XYZ"), 1806);
+  assertNull(res[681].firstMatch("** Failers"), 1807);
+  assertNull(res[681].firstMatch("AXYZ"), 1808);
+  assertNull(res[681].firstMatch("x{1234}XYZ"), 1809);
+  assertNull(res[681].firstMatch("Ax{1234}XYZ"), 1810);
+  assertNull(res[681].firstMatch("XYZ"), 1811);
+  assertNull(res[682].firstMatch("XYZ"), 1812);
+  assertNull(res[682].firstMatch("AXYZ"), 1813);
+  assertNull(res[682].firstMatch("x{1234}XYZ"), 1814);
+  assertNull(res[682].firstMatch("Ax{1234}XYZ"), 1815);
+  assertNull(res[682].firstMatch("** Failers"), 1816);
+  assertNull(res[683].firstMatch("XYZ"), 1817);
+  assertNull(res[683].firstMatch("** Failers"), 1818);
+  assertNull(res[683].firstMatch("AXYZ"), 1819);
+  assertNull(res[683].firstMatch("x{1234}XYZ"), 1820);
+  assertNull(res[683].firstMatch("Ax{1234}XYZ"), 1821);
+  assertToStringEquals("AX", res[684].firstMatch("AXYZ"), 1822);
+  assertNull(res[684].firstMatch("x{1234}XYZ "), 1823);
+  assertNull(res[684].firstMatch("** Failers"), 1824);
+  assertNull(res[684].firstMatch("X  "), 1825);
+  assertNull(res[685].firstMatch("** Failers"), 1826);
+  assertToStringEquals("AX", res[685].firstMatch("AX"), 1827);
+  assertToStringEquals("X", res[686].firstMatch("XYZ"), 1828);
+  assertToStringEquals("AX", res[686].firstMatch("AXYZ"), 1829);
+  assertNull(res[686].firstMatch("x{1234}XYZ "), 1830);
+  assertNull(res[686].firstMatch("** Failers"), 1831);
+  assertNull(res[686].firstMatch("ABXYZ   "), 1832);
+  assertToStringEquals("X", res[687].firstMatch("XYZ"), 1833);
+  assertNull(res[687].firstMatch("** Failers"), 1834);
+  assertToStringEquals("AX", res[687].firstMatch("AXYZ"), 1835);
+  assertNull(res[687].firstMatch("x{1234}XYZ "), 1836);
+  assertNull(res[687].firstMatch("ABXYZ   "), 1837);
+  assertToStringEquals("AX", res[688].firstMatch("AXYZ"), 1838);
+  assertNull(res[688].firstMatch("x{1234}XYZ"), 1839);
+  assertNull(res[688].firstMatch("Ax{1234}XYZ"), 1840);
+  assertNull(res[688].firstMatch("** Failers"), 1841);
+  assertNull(res[688].firstMatch("XYZ"), 1842);
+  assertNull(res[689].firstMatch("** Failers"), 1843);
+  assertToStringEquals("AX", res[689].firstMatch("AXYZ"), 1844);
+  assertNull(res[689].firstMatch("x{1234}XYZ"), 1845);
+  assertNull(res[689].firstMatch("Ax{1234}XYZ"), 1846);
+  assertNull(res[689].firstMatch("XYZ"), 1847);
+  assertToStringEquals("X", res[690].firstMatch("XYZ"), 1848);
+  assertToStringEquals("AX", res[690].firstMatch("AXYZ"), 1849);
+  assertNull(res[690].firstMatch("x{1234}XYZ"), 1850);
+  assertNull(res[690].firstMatch("Ax{1234}XYZ"), 1851);
+  assertNull(res[690].firstMatch("** Failers"), 1852);
+  assertToStringEquals("X", res[691].firstMatch("XYZ"), 1853);
+  assertNull(res[691].firstMatch("** Failers"), 1854);
+  assertToStringEquals("AX", res[691].firstMatch("AXYZ"), 1855);
+  assertNull(res[691].firstMatch("x{1234}XYZ"), 1856);
+  assertNull(res[691].firstMatch("Ax{1234}XYZ"), 1857);
+  assertNull(res[692].firstMatch("abcdefgh"), 1858);
+  assertNull(res[692].firstMatch("x{1234}\n\x0dx{3456}xyz "), 1859);
+  assertNull(res[693].firstMatch("abcdefgh"), 1860);
+  assertNull(res[693].firstMatch("x{1234}\n\x0dx{3456}xyz "), 1861);
+  assertNull(res[694].firstMatch("** Failers"), 1862);
+  assertNull(res[694].firstMatch("abcdefgh"), 1863);
+  assertNull(res[694].firstMatch("x{1234}\n\x0dx{3456}xyz "), 1864);
+  assertNull(res[695].firstMatch(" AXY"), 1865);
+  assertNull(res[695].firstMatch(" aXY"), 1866);
+  assertNull(res[695].firstMatch(" x{1c5}XY"), 1867);
+  assertNull(res[695].firstMatch(" ** Failers"), 1868);
+  assertNull(res[695].firstMatch(" x{1bb}XY"), 1869);
+  assertNull(res[695].firstMatch(" x{2b0}XY"), 1870);
+  assertNull(res[695].firstMatch(" !XY      "), 1871);
+  assertNull(res[696].firstMatch(" AXY"), 1872);
+  assertNull(res[696].firstMatch(" aXY"), 1873);
+  assertNull(res[696].firstMatch(" x{1c5}XY"), 1874);
+  assertNull(res[696].firstMatch(" ** Failers"), 1875);
+  assertNull(res[696].firstMatch(" x{1bb}XY"), 1876);
+  assertNull(res[696].firstMatch(" x{2b0}XY"), 1877);
+  assertNull(res[696].firstMatch(" !XY      "), 1878);
+  assertNull(res[696].firstMatch(" AXY"), 1879);
+  assertNull(res[696].firstMatch(" aXY"), 1880);
+  assertNull(res[696].firstMatch(" AbcdeXyz "), 1881);
+  assertNull(res[696].firstMatch(" x{1c5}AbXY"), 1882);
+  assertNull(res[696].firstMatch(" abcDEXypqreXlmn "), 1883);
+  assertNull(res[696].firstMatch(" ** Failers"), 1884);
+  assertNull(res[696].firstMatch(" x{1bb}XY"), 1885);
+  assertNull(res[696].firstMatch(" x{2b0}XY"), 1886);
+  assertNull(res[696].firstMatch(" !XY      "), 1887);
+  assertNull(res[697].firstMatch(" AXY"), 1888);
+  assertNull(res[697].firstMatch(" aXY"), 1889);
+  assertNull(res[697].firstMatch(" AbcdeXyz "), 1890);
+  assertNull(res[697].firstMatch(" x{1c5}AbXY"), 1891);
+  assertNull(res[697].firstMatch(" abcDEXypqreXlmn "), 1892);
+  assertNull(res[697].firstMatch(" ** Failers"), 1893);
+  assertNull(res[697].firstMatch(" x{1bb}XY"), 1894);
+  assertNull(res[697].firstMatch(" x{2b0}XY"), 1895);
+  assertNull(res[697].firstMatch(" !XY      "), 1896);
+  assertNull(res[697].firstMatch(" AXY"), 1897);
+  assertNull(res[697].firstMatch(" aXY"), 1898);
+  assertNull(res[697].firstMatch(" AbcdeXyz "), 1899);
+  assertNull(res[697].firstMatch(" x{1c5}AbXY"), 1900);
+  assertNull(res[697].firstMatch(" abcDEXypqreXlmn "), 1901);
+  assertNull(res[697].firstMatch(" ** Failers"), 1902);
+  assertNull(res[697].firstMatch(" x{1bb}XY"), 1903);
+  assertNull(res[697].firstMatch(" x{2b0}XY"), 1904);
+  assertNull(res[697].firstMatch(" !XY      "), 1905);
+  assertNull(res[698].firstMatch(" AXY"), 1906);
+  assertNull(res[698].firstMatch(" aXY"), 1907);
+  assertNull(res[698].firstMatch(" AbcdeXyz "), 1908);
+  assertNull(res[698].firstMatch(" x{1c5}AbXY"), 1909);
+  assertNull(res[698].firstMatch(" abcDEXypqreXlmn "), 1910);
+  assertNull(res[698].firstMatch(" ** Failers"), 1911);
+  assertNull(res[698].firstMatch(" x{1bb}XY"), 1912);
+  assertNull(res[698].firstMatch(" x{2b0}XY"), 1913);
+  assertNull(res[698].firstMatch(" !XY      "), 1914);
+  assertNull(res[699].firstMatch(" !XY"), 1915);
+  assertNull(res[699].firstMatch(" x{1bb}XY"), 1916);
+  assertNull(res[699].firstMatch(" x{2b0}XY"), 1917);
+  assertNull(res[699].firstMatch(" ** Failers"), 1918);
+  assertNull(res[699].firstMatch(" x{1c5}XY"), 1919);
+  assertNull(res[699].firstMatch(" AXY      "), 1920);
+  assertNull(res[700].firstMatch(" !XY"), 1921);
+  assertNull(res[700].firstMatch(" x{1bb}XY"), 1922);
+  assertNull(res[700].firstMatch(" x{2b0}XY"), 1923);
+  assertNull(res[700].firstMatch(" ** Failers"), 1924);
+  assertNull(res[700].firstMatch(" x{1c5}XY"), 1925);
+  assertNull(res[700].firstMatch(" AXY      "), 1926);
+  assertNull(res[701].firstMatch("\xa0!"), 1927);
+  assertNull(res[701].firstMatch("AabcabcYZ    "), 1928);
+  assertToStringEquals("L=abcX,L=abc,abc", res[702].firstMatch("L=abcX"), 1929);
+  assertNull(res[702].firstMatch("x{c0}"), 1930);
+  assertNull(res[702].firstMatch("x{e0} "), 1931);
+  assertNull(res[702].firstMatch("x{c0}"), 1932);
+  assertNull(res[702].firstMatch("x{e0} "), 1933);
+  assertNull(res[703].firstMatch("x{1b00}x{12000}x{7c0}x{a840}x{10900}"), 1934);
+  assertNull(res[706].firstMatch("123abcdefg"), 1935);
+  assertNull(res[706].firstMatch("123abc\xc4\xc5zz"), 1936);
+  assertNull(res[710].firstMatch("A\x80"), 1937);
+  assertNull(res[725].firstMatch("x{60e} "), 1938);
+  assertNull(res[725].firstMatch("x{656} "), 1939);
+  assertNull(res[725].firstMatch("x{657} "), 1940);
+  assertNull(res[725].firstMatch("x{658} "), 1941);
+  assertNull(res[725].firstMatch("x{659} "), 1942);
+  assertNull(res[725].firstMatch("x{65a} "), 1943);
+  assertNull(res[725].firstMatch("x{65b} "), 1944);
+  assertNull(res[725].firstMatch("x{65c} "), 1945);
+  assertNull(res[725].firstMatch("x{65d} "), 1946);
+  assertNull(res[725].firstMatch("x{65e} "), 1947);
+  assertNull(res[725].firstMatch("x{66a} "), 1948);
+  assertNull(res[725].firstMatch("x{6e9} "), 1949);
+  assertNull(res[725].firstMatch("x{6ef}"), 1950);
+  assertNull(res[725].firstMatch("x{6fa}  "), 1951);
+  assertNull(res[725].firstMatch("** Failers"), 1952);
+  assertNull(res[725].firstMatch("x{600}"), 1953);
+  assertNull(res[725].firstMatch("x{650}"), 1954);
+  assertNull(res[725].firstMatch("x{651}  "), 1955);
+  assertNull(res[725].firstMatch("x{652}  "), 1956);
+  assertNull(res[725].firstMatch("x{653}  "), 1957);
+  assertNull(res[725].firstMatch("x{654} "), 1958);
+  assertNull(res[725].firstMatch("x{655} "), 1959);
+  assertNull(res[725].firstMatch("x{65f}  "), 1960);
+  assertNull(res[726].firstMatch("x{1d2b} "), 1961);
+  assertNull(res[727].firstMatch("x{589}"), 1962);
+  assertNull(res[727].firstMatch("x{60c}"), 1963);
+  assertNull(res[727].firstMatch("x{61f}  "), 1964);
+  assertNull(res[727].firstMatch("x{964}"), 1965);
+  assertNull(res[727].firstMatch("x{965}  "), 1966);
+  assertNull(res[727].firstMatch("x{970}  "), 1967);
+  assertNull(res[728].firstMatch("x{64b}"), 1968);
+  assertNull(res[728].firstMatch("x{654}"), 1969);
+  assertNull(res[728].firstMatch("x{655}"), 1970);
+  assertNull(res[728].firstMatch("x{200c} "), 1971);
+  assertNull(res[728].firstMatch("** Failers"), 1972);
+  assertNull(res[728].firstMatch("x{64a}"), 1973);
+  assertNull(res[728].firstMatch("x{656}     "), 1974);
+  assertNull(res[729].firstMatch("x{10450}"), 1975);
+  assertNull(res[729].firstMatch("x{1047f}"), 1976);
+  assertNull(res[730].firstMatch("x{10400}"), 1977);
+  assertNull(res[730].firstMatch("x{1044f}"), 1978);
+  assertNull(res[731].firstMatch("x{10480}"), 1979);
+  assertNull(res[731].firstMatch("x{1049d}"), 1980);
+  assertNull(res[731].firstMatch("x{104a0}"), 1981);
+  assertNull(res[731].firstMatch("x{104a9}"), 1982);
+  assertNull(res[731].firstMatch("** Failers"), 1983);
+  assertNull(res[731].firstMatch("x{1049e}"), 1984);
+  assertNull(res[731].firstMatch("x{1049f}"), 1985);
+  assertNull(res[731].firstMatch("x{104aa}           "), 1986);
+  assertNull(res[731].firstMatch("\xe2\x80\xa8\xe2\x80\xa8"), 1987);
+  assertNull(res[731].firstMatch("x{2028}x{2028}x{2028}"), 1988);
+  assertNull(res[732].firstMatch("x{c0}x{e0}x{116}x{117}"), 1989);
+  assertNull(res[732].firstMatch("x{c0}x{e0}x{116}x{117}"), 1990);
+  assertNull(res[733].firstMatch("x{102A4}x{AA52}x{A91D}x{1C46}x{10283}x{1092E}x{1C6B}x{A93B}x{A8BF}x{1BA0}x{A50A}===="), 1991);
+  assertNull(res[733].firstMatch("x{a77d}x{1d79}"), 1992);
+  assertNull(res[733].firstMatch("x{1d79}x{a77d} "), 1993);
+  assertNull(res[733].firstMatch("x{a77d}x{1d79}"), 1994);
+  assertNull(res[733].firstMatch("** Failers "), 1995);
+  assertNull(res[733].firstMatch("x{1d79}x{a77d} "), 1996);
+  assertToStringEquals("AA,A", res[734].firstMatch("AA"), 1997);
+  assertToStringEquals("Aa,A", res[734].firstMatch("Aa"), 1998);
+  assertToStringEquals("aa,a", res[734].firstMatch("aa"), 1999);
+  assertToStringEquals("aA,a", res[734].firstMatch("aA"), 2000);
+  assertNull(res[734].firstMatch("x{de}x{de}"), 2001);
+  assertNull(res[734].firstMatch("x{de}x{fe}"), 2002);
+  assertNull(res[734].firstMatch("x{fe}x{fe}"), 2003);
+  assertNull(res[734].firstMatch("x{fe}x{de}"), 2004);
+  assertNull(res[734].firstMatch("x{10a}x{10a}"), 2005);
+  assertNull(res[734].firstMatch("x{10a}x{10b}"), 2006);
+  assertNull(res[734].firstMatch("x{10b}x{10b}"), 2007);
+  assertNull(res[734].firstMatch("x{10b}x{10a}"), 2008);
+  assertToStringEquals("abc", res[736].firstMatch("abc"), 2009);
+  assertToStringEquals("abc", res[737].firstMatch("abc"), 2010);
+  assertToStringEquals("abbbbc", res[737].firstMatch("abbbbc"), 2011);
+  assertToStringEquals("ac", res[737].firstMatch("ac"), 2012);
+  assertToStringEquals("abc", res[738].firstMatch("abc"), 2013);
+  assertToStringEquals("abbbbbbc", res[738].firstMatch("abbbbbbc"), 2014);
+  assertNull(res[738].firstMatch("*** Failers "), 2015);
+  assertNull(res[738].firstMatch("ac"), 2016);
+  assertNull(res[738].firstMatch("ab"), 2017);
+  assertToStringEquals("a", res[739].firstMatch("a"), 2018);
+  assertToStringEquals("aaaaaaaaaaaaaaaaa", res[739].firstMatch("aaaaaaaaaaaaaaaaa"), 2019);
+  assertToStringEquals("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", res[739].firstMatch("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa "), 2020);
+  assertToStringEquals("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", res[739].firstMatch("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaF "), 2021);
+  assertToStringEquals("a,a", res[740].firstMatch("a"), 2022);
+  assertToStringEquals("a,a", res[740].firstMatch("abcd"), 2023);
+  assertToStringEquals("a,a", res[740].firstMatch("african"), 2024);
+  assertToStringEquals("abc", res[741].firstMatch("abcdef"), 2025);
+  assertNull(res[741].firstMatch("*** Failers"), 2026);
+  assertNull(res[741].firstMatch("xyzabc"), 2027);
+  assertNull(res[741].firstMatch("xyz\nabc    "), 2028);
+  assertToStringEquals("abc", res[742].firstMatch("abcdef"), 2029);
+  assertToStringEquals("abc", res[742].firstMatch("xyz\nabc    "), 2030);
+  assertNull(res[742].firstMatch("*** Failers"), 2031);
+  assertNull(res[742].firstMatch("xyzabc"), 2032);
+  assertNull(res[743].firstMatch("abcdef"), 2033);
+  assertNull(res[743].firstMatch("*** Failers"), 2034);
+  assertNull(res[743].firstMatch("xyzabc"), 2035);
+  assertNull(res[743].firstMatch("xyz\nabc    "), 2036);
+  assertNull(res[744].firstMatch("abcdef"), 2037);
+  assertNull(res[744].firstMatch("*** Failers"), 2038);
+  assertNull(res[744].firstMatch("xyzabc"), 2039);
+  assertNull(res[744].firstMatch("xyz\nabc    "), 2040);
+  assertNull(res[745].firstMatch("abcdef"), 2041);
+  assertNull(res[745].firstMatch("xyzabc>3"), 2042);
+  assertNull(res[745].firstMatch("*** Failers"), 2043);
+  assertNull(res[745].firstMatch("xyzabc    "), 2044);
+  assertNull(res[745].firstMatch("xyzabc>2 "), 2045);
+  assertToStringEquals("x9yzz", res[746].firstMatch("x9yzz"), 2046);
+  assertToStringEquals("x0y+z", res[746].firstMatch("x0y+z"), 2047);
+  assertNull(res[746].firstMatch("*** Failers"), 2048);
+  assertNull(res[746].firstMatch("xyz"), 2049);
+  assertNull(res[746].firstMatch("xxy0z     "), 2050);
+  assertToStringEquals("x yzz", res[747].firstMatch("x yzz"), 2051);
+  assertToStringEquals("x y+z", res[747].firstMatch("x y+z"), 2052);
+  assertNull(res[747].firstMatch("*** Failers"), 2053);
+  assertNull(res[747].firstMatch("xyz"), 2054);
+  assertNull(res[747].firstMatch("xxyyz"), 2055);
+  assertToStringEquals("xxy+z", res[748].firstMatch("xxy+z"), 2056);
+  assertNull(res[748].firstMatch("*** Failers"), 2057);
+  assertNull(res[748].firstMatch("xxy0z"), 2058);
+  assertNull(res[748].firstMatch("x+y+z         "), 2059);
+  assertToStringEquals("x+y", res[749].firstMatch("x+y"), 2060);
+  assertToStringEquals("x-y", res[749].firstMatch("x-y"), 2061);
+  assertNull(res[749].firstMatch("*** Failers"), 2062);
+  assertNull(res[749].firstMatch("x\ny"), 2063);
+  assertToStringEquals("x+y", res[750].firstMatch("x+y"), 2064);
+  assertToStringEquals("x-y", res[750].firstMatch("x-y"), 2065);
+  assertNull(res[750].firstMatch("x\ny"), 2066);
+  assertNull(res[750].firstMatch("a+bc+dp+q"), 2067);
+  assertNull(res[750].firstMatch("a+bc\ndp+q"), 2068);
+  assertNull(res[750].firstMatch("x\nyp+q "), 2069);
+  assertNull(res[750].firstMatch("*** Failers "), 2070);
+  assertNull(res[750].firstMatch("a\nbc\ndp+q"), 2071);
+  assertNull(res[750].firstMatch("a+bc\ndp\nq"), 2072);
+  assertNull(res[750].firstMatch("x\nyp\nq "), 2073);
+  assertNull(res[751].firstMatch("ba0"), 2074);
+  assertNull(res[751].firstMatch("*** Failers"), 2075);
+  assertNull(res[751].firstMatch("ba0\n"), 2076);
+  assertNull(res[751].firstMatch("ba0\ncd   "), 2077);
+  assertNull(res[752].firstMatch("ba0"), 2078);
+  assertNull(res[752].firstMatch("*** Failers"), 2079);
+  assertNull(res[752].firstMatch("ba0\n"), 2080);
+  assertNull(res[752].firstMatch("ba0\ncd   "), 2081);
+  assertNull(res[753].firstMatch("ba0"), 2082);
+  assertNull(res[753].firstMatch("ba0\n"), 2083);
+  assertNull(res[753].firstMatch("*** Failers"), 2084);
+  assertNull(res[753].firstMatch("ba0\ncd   "), 2085);
+  assertNull(res[754].firstMatch("ba0"), 2086);
+  assertNull(res[754].firstMatch("ba0\n"), 2087);
+  assertNull(res[754].firstMatch("*** Failers"), 2088);
+  assertNull(res[754].firstMatch("ba0\ncd   "), 2089);
+  assertToStringEquals("a0", res[755].firstMatch("ba0"), 2090);
+  assertNull(res[755].firstMatch("ba0\n"), 2091);
+  assertNull(res[755].firstMatch("*** Failers"), 2092);
+  assertNull(res[755].firstMatch("ba0\ncd   "), 2093);
+  assertToStringEquals("a0", res[756].firstMatch("ba0"), 2094);
+  assertToStringEquals("a0", res[756].firstMatch("ba0\n"), 2095);
+  assertToStringEquals("a0", res[756].firstMatch("ba0\ncd   "), 2096);
+  assertNull(res[756].firstMatch("*** Failers"), 2097);
+  assertToStringEquals("abc", res[757].firstMatch("abc"), 2098);
+  assertToStringEquals("aBc", res[757].firstMatch("aBc"), 2099);
+  assertToStringEquals("ABC", res[757].firstMatch("ABC"), 2100);
+  assertToStringEquals("b", res[758].firstMatch("abcd"), 2101);
+  assertToStringEquals("abz", res[759].firstMatch("abz"), 2102);
+  assertToStringEquals("abb", res[759].firstMatch("abbz"), 2103);
+  assertToStringEquals("az", res[759].firstMatch("azz  "), 2104);
+  assertToStringEquals("yz", res[760].firstMatch("ayzq"), 2105);
+  assertToStringEquals("xyz", res[760].firstMatch("axyzq"), 2106);
+  assertToStringEquals("xxyz", res[760].firstMatch("axxyz"), 2107);
+  assertToStringEquals("xxxyz", res[760].firstMatch("axxxyzq"), 2108);
+  assertToStringEquals("xxxyz", res[760].firstMatch("axxxxyzq"), 2109);
+  assertNull(res[760].firstMatch("*** Failers"), 2110);
+  assertNull(res[760].firstMatch("ax"), 2111);
+  assertNull(res[760].firstMatch("axx     "), 2112);
+  assertNull(res[760].firstMatch("  "), 2113);
+  assertToStringEquals("xxxyz", res[761].firstMatch("axxxyzq"), 2114);
+  assertToStringEquals("xxxyz", res[761].firstMatch("axxxxyzq"), 2115);
+  assertNull(res[761].firstMatch("*** Failers"), 2116);
+  assertNull(res[761].firstMatch("ax"), 2117);
+  assertNull(res[761].firstMatch("axx     "), 2118);
+  assertNull(res[761].firstMatch("ayzq"), 2119);
+  assertNull(res[761].firstMatch("axyzq"), 2120);
+  assertNull(res[761].firstMatch("axxyz"), 2121);
+  assertNull(res[761].firstMatch("  "), 2122);
+  assertToStringEquals("xxyz", res[762].firstMatch("axxyz"), 2123);
+  assertToStringEquals("xxxyz", res[762].firstMatch("axxxyzq"), 2124);
+  assertToStringEquals("xxxyz", res[762].firstMatch("axxxxyzq"), 2125);
+  assertNull(res[762].firstMatch("*** Failers"), 2126);
+  assertNull(res[762].firstMatch("ax"), 2127);
+  assertNull(res[762].firstMatch("axx     "), 2128);
+  assertNull(res[762].firstMatch("ayzq"), 2129);
+  assertNull(res[762].firstMatch("axyzq"), 2130);
+  assertNull(res[762].firstMatch("  "), 2131);
+  assertToStringEquals("b", res[763].firstMatch("bac"), 2132);
+  assertToStringEquals("bcdef", res[763].firstMatch("bcdefax"), 2133);
+  assertToStringEquals("*** F", res[763].firstMatch("*** Failers"), 2134);
+  assertToStringEquals("   ", res[763].firstMatch("aaaaa   "), 2135);
+  assertToStringEquals("b", res[764].firstMatch("bac"), 2136);
+  assertToStringEquals("bcdef", res[764].firstMatch("bcdefax"), 2137);
+  assertToStringEquals("*** F", res[764].firstMatch("*** Failers"), 2138);
+  assertToStringEquals("", res[764].firstMatch("aaaaa   "), 2139);
+  assertToStringEquals("xyz", res[765].firstMatch("xyz"), 2140);
+  assertToStringEquals("wxyz", res[765].firstMatch("awxyza"), 2141);
+  assertToStringEquals("bcdef", res[765].firstMatch("abcdefa"), 2142);
+  assertToStringEquals("bcdef", res[765].firstMatch("abcdefghijk"), 2143);
+  assertToStringEquals("*** F", res[765].firstMatch("*** Failers"), 2144);
+  assertNull(res[765].firstMatch("axya"), 2145);
+  assertNull(res[765].firstMatch("axa"), 2146);
+  assertToStringEquals("     ", res[765].firstMatch("aaaaa         "), 2147);
+  assertToStringEquals("1234", res[766].firstMatch("1234b567"), 2148);
+  assertToStringEquals("", res[766].firstMatch("xyz"), 2149);
+  assertToStringEquals("a", res[767].firstMatch("a1234b567"), 2150);
+  assertToStringEquals("xyz", res[767].firstMatch("xyz"), 2151);
+  assertToStringEquals(" ", res[767].firstMatch(" "), 2152);
+  assertToStringEquals("1234", res[768].firstMatch("ab1234c56"), 2153);
+  assertNull(res[768].firstMatch("*** Failers"), 2154);
+  assertNull(res[768].firstMatch("xyz"), 2155);
+  assertToStringEquals("ab", res[769].firstMatch("ab123c56"), 2156);
+  assertToStringEquals("*** Failers", res[769].firstMatch("*** Failers"), 2157);
+  assertNull(res[769].firstMatch("789"), 2158);
+  assertToStringEquals("5A", res[770].firstMatch("045ABC"), 2159);
+  assertToStringEquals("A", res[770].firstMatch("ABC"), 2160);
+  assertNull(res[770].firstMatch("*** Failers"), 2161);
+  assertNull(res[770].firstMatch("XYZ"), 2162);
+  assertToStringEquals("A", res[771].firstMatch("ABC"), 2163);
+  assertToStringEquals("BA", res[771].firstMatch("BAC"), 2164);
+  assertToStringEquals("A", res[771].firstMatch("9ABC             "), 2165);
+  assertNull(res[771].firstMatch("*** Failers"), 2166);
+  assertToStringEquals("aaaa", res[772].firstMatch("aaaa"), 2167);
+  assertToStringEquals("xyz", res[773].firstMatch("xyz"), 2168);
+  assertToStringEquals("ggggggggxyz", res[773].firstMatch("ggggggggxyz"), 2169);
+  assertToStringEquals("abcdxyz", res[774].firstMatch("abcdxyz"), 2170);
+  assertToStringEquals("axyz", res[774].firstMatch("axyz"), 2171);
+  assertNull(res[774].firstMatch("*** Failers"), 2172);
+  assertNull(res[774].firstMatch("xyz"), 2173);
+  assertToStringEquals("xyz", res[775].firstMatch("xyz"), 2174);
+  assertToStringEquals("cxyz", res[775].firstMatch("cxyz       "), 2175);
+  assertToStringEquals("12X", res[776].firstMatch("12X"), 2176);
+  assertToStringEquals("123X", res[776].firstMatch("123X"), 2177);
+  assertNull(res[776].firstMatch("*** Failers"), 2178);
+  assertNull(res[776].firstMatch("X"), 2179);
+  assertNull(res[776].firstMatch("1X"), 2180);
+  assertNull(res[776].firstMatch("1234X     "), 2181);
+  assertToStringEquals("a4", res[777].firstMatch("a45"), 2182);
+  assertToStringEquals("b9", res[777].firstMatch("b93"), 2183);
+  assertToStringEquals("c9", res[777].firstMatch("c99z"), 2184);
+  assertToStringEquals("d0", res[777].firstMatch("d04"), 2185);
+  assertNull(res[777].firstMatch("*** Failers"), 2186);
+  assertNull(res[777].firstMatch("e45"), 2187);
+  assertNull(res[777].firstMatch("abcd      "), 2188);
+  assertNull(res[777].firstMatch("abcd1234"), 2189);
+  assertNull(res[777].firstMatch("1234  "), 2190);
+  assertToStringEquals("a4", res[778].firstMatch("a45"), 2191);
+  assertToStringEquals("b9", res[778].firstMatch("b93"), 2192);
+  assertToStringEquals("c9", res[778].firstMatch("c99z"), 2193);
+  assertToStringEquals("d0", res[778].firstMatch("d04"), 2194);
+  assertToStringEquals("abcd1", res[778].firstMatch("abcd1234"), 2195);
+  assertToStringEquals("1", res[778].firstMatch("1234  "), 2196);
+  assertNull(res[778].firstMatch("*** Failers"), 2197);
+  assertNull(res[778].firstMatch("e45"), 2198);
+  assertNull(res[778].firstMatch("abcd      "), 2199);
+  assertToStringEquals("a4", res[779].firstMatch("a45"), 2200);
+  assertToStringEquals("b9", res[779].firstMatch("b93"), 2201);
+  assertToStringEquals("c9", res[779].firstMatch("c99z"), 2202);
+  assertToStringEquals("d0", res[779].firstMatch("d04"), 2203);
+  assertToStringEquals("abcd1", res[779].firstMatch("abcd1234"), 2204);
+  assertNull(res[779].firstMatch("*** Failers"), 2205);
+  assertNull(res[779].firstMatch("1234  "), 2206);
+  assertNull(res[779].firstMatch("e45"), 2207);
+  assertNull(res[779].firstMatch("abcd      "), 2208);
+  assertToStringEquals("aX", res[780].firstMatch("aX"), 2209);
+  assertToStringEquals("aaX", res[780].firstMatch("aaX "), 2210);
+  assertToStringEquals("a4", res[781].firstMatch("a45"), 2211);
+  assertToStringEquals("b9", res[781].firstMatch("b93"), 2212);
+  assertToStringEquals("c9", res[781].firstMatch("c99z"), 2213);
+  assertToStringEquals("d0", res[781].firstMatch("d04"), 2214);
+  assertToStringEquals("1", res[781].firstMatch("1234  "), 2215);
+  assertNull(res[781].firstMatch("*** Failers"), 2216);
+  assertNull(res[781].firstMatch("abcd1234"), 2217);
+  assertNull(res[781].firstMatch("e45"), 2218);
+  assertToStringEquals("ab4", res[782].firstMatch("ab45"), 2219);
+  assertToStringEquals("bcd9", res[782].firstMatch("bcd93"), 2220);
+  assertNull(res[782].firstMatch("*** Failers"), 2221);
+  assertNull(res[782].firstMatch("1234 "), 2222);
+  assertNull(res[782].firstMatch("a36 "), 2223);
+  assertNull(res[782].firstMatch("abcd1234"), 2224);
+  assertNull(res[782].firstMatch("ee45"), 2225);
+  assertToStringEquals("abc4,abc", res[783].firstMatch("abc45"), 2226);
+  assertToStringEquals("abcabcabc4,abc", res[783].firstMatch("abcabcabc45"), 2227);
+  assertToStringEquals("4,", res[783].firstMatch("42xyz "), 2228);
+  assertNull(res[783].firstMatch("*** Failers"), 2229);
+  assertToStringEquals("abc4,abc", res[784].firstMatch("abc45"), 2230);
+  assertToStringEquals("abcabcabc4,abc", res[784].firstMatch("abcabcabc45"), 2231);
+  assertNull(res[784].firstMatch("*** Failers"), 2232);
+  assertNull(res[784].firstMatch("42xyz "), 2233);
+  assertToStringEquals("abc4,abc", res[785].firstMatch("abc45"), 2234);
+  assertToStringEquals("4,", res[785].firstMatch("42xyz "), 2235);
+  assertNull(res[785].firstMatch("*** Failers"), 2236);
+  assertNull(res[785].firstMatch("abcabcabc45"), 2237);
+  assertToStringEquals("abcabc4,abc", res[786].firstMatch("abcabc45"), 2238);
+  assertToStringEquals("abcabcabc4,abc", res[786].firstMatch("abcabcabc45"), 2239);
+  assertNull(res[786].firstMatch("*** Failers"), 2240);
+  assertNull(res[786].firstMatch("abcabcabcabc45"), 2241);
+  assertNull(res[786].firstMatch("abc45"), 2242);
+  assertNull(res[786].firstMatch("42xyz "), 2243);
+  assertNull(res[786].firstMatch("1abc2abc3456"), 2244);
+  assertNull(res[786].firstMatch("1abc2xyz3456 "), 2245);
+  assertToStringEquals("ab=ab,ab,ab", res[787].firstMatch("ab=ab"), 2246);
+  assertToStringEquals("ab=ab,ab,ab", res[787].firstMatch("ab=ab"), 2247);
+  assertNull(res[787].firstMatch("abc"), 2248);
+  assertNull(res[787].firstMatch("a(b)c"), 2249);
+  assertNull(res[787].firstMatch("a(b(c))d  "), 2250);
+  assertNull(res[787].firstMatch("*** Failers)"), 2251);
+  assertNull(res[787].firstMatch("a(b(c)d  "), 2252);
+  assertNull(res[787].firstMatch(">abc>123<xyz<"), 2253);
+  assertNull(res[787].firstMatch(">abc>1(2)3<xyz<"), 2254);
+  assertNull(res[787].firstMatch(">abc>(1(2)3)<xyz<"), 2255);
+  assertNull(res[787].firstMatch("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa9876"), 2256);
+  assertNull(res[787].firstMatch("*** Failers "), 2257);
+  assertNull(res[787].firstMatch("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"), 2258);
+  assertNull(res[787].firstMatch("<>"), 2259);
+  assertNull(res[787].firstMatch("<abcd>"), 2260);
+  assertNull(res[787].firstMatch("<abc <123> hij>"), 2261);
+  assertNull(res[787].firstMatch("<abc <def> hij>"), 2262);
+  assertNull(res[787].firstMatch("<abc<>def> "), 2263);
+  assertNull(res[787].firstMatch("<abc<>      "), 2264);
+  assertNull(res[787].firstMatch("*** Failers"), 2265);
+  assertNull(res[787].firstMatch("<abc"), 2266);
+  assertNull(res[787].firstMatch("abc:                          "), 2267);
+  assertNull(res[787].firstMatch("12                             "), 2268);
+  assertNull(res[787].firstMatch("*** Failers                     "), 2269);
+  assertNull(res[787].firstMatch("123                       "), 2270);
+  assertNull(res[787].firstMatch("xyz                        "), 2271);
+  assertNull(res[787].firstMatch("                            "), 2272);
+  assertNull(res[787].firstMatch("abc:                        "), 2273);
+  assertNull(res[787].firstMatch("12         "), 2274);
+  assertNull(res[787].firstMatch("*** Failers"), 2275);
+  assertNull(res[787].firstMatch("123"), 2276);
+  assertNull(res[787].firstMatch("xyz    "), 2277);
+  assertNull(res[788].firstMatch("abcde:                          "), 2278);
+  assertNull(res[788].firstMatch("*** Failers                     "), 2279);
+  assertNull(res[788].firstMatch("abc.. "), 2280);
+  assertNull(res[788].firstMatch("123                       "), 2281);
+  assertNull(res[788].firstMatch("vwxyz                        "), 2282);
+  assertNull(res[788].firstMatch("                            "), 2283);
+  assertNull(res[789].firstMatch("12         "), 2284);
+  assertNull(res[789].firstMatch("*** Failers"), 2285);
+  assertNull(res[789].firstMatch("abcde:"), 2286);
+  assertNull(res[789].firstMatch("abc..  "), 2287);
+  assertNull(res[789].firstMatch("123"), 2288);
+  assertNull(res[789].firstMatch("vwxyz    "), 2289);
+  assertNull(res[789].firstMatch("abc12345"), 2290);
+  assertNull(res[789].firstMatch("wxy123z"), 2291);
+  assertNull(res[789].firstMatch("*** Failers"), 2292);
+  assertNull(res[789].firstMatch("123abc"), 2293);
+  assertNull(res[789].firstMatch("123abc"), 2294);
+  assertNull(res[789].firstMatch("mno123456 "), 2295);
+  assertNull(res[789].firstMatch("*** Failers"), 2296);
+  assertNull(res[789].firstMatch("abc12345"), 2297);
+  assertNull(res[789].firstMatch("wxy123z"), 2298);
+  assertNull(res[789].firstMatch("abcxyz"), 2299);
+  assertNull(res[789].firstMatch("123abcxyz999 "), 2300);
+  assertToStringEquals("abc", res[791].firstMatch("abcdef"), 2301);
+  assertNull(res[791].firstMatch("*** Failers"), 2302);
+  assertToStringEquals("abc", res[791].firstMatch("abcdefB  "), 2303);
+  assertToStringEquals(",", res[792].firstMatch("bcd"), 2304);
+  assertToStringEquals("aaa,aaa", res[792].firstMatch("aaabcd"), 2305);
+  assertToStringEquals(",", res[792].firstMatch("xyz"), 2306);
+  assertToStringEquals(",", res[792].firstMatch("xyzN  "), 2307);
+  assertToStringEquals(",", res[792].firstMatch("*** Failers"), 2308);
+  assertToStringEquals(",", res[792].firstMatch("bcdN   "), 2309);
+  assertToStringEquals("xyz", res[793].firstMatch("xyz"), 2310);
+  assertNull(res[793].firstMatch("xyz\n"), 2311);
+  assertNull(res[793].firstMatch("*** Failers"), 2312);
+  assertNull(res[793].firstMatch("xyzZ"), 2313);
+  assertNull(res[793].firstMatch("xyz\nZ    "), 2314);
+  assertToStringEquals("xyz", res[794].firstMatch("xyz"), 2315);
+  assertToStringEquals("xyz", res[794].firstMatch("xyz\n "), 2316);
+  assertToStringEquals("xyz", res[794].firstMatch("abcxyz\npqr "), 2317);
+  assertToStringEquals("xyz", res[794].firstMatch("abcxyz\npqrZ "), 2318);
+  assertToStringEquals("xyz", res[794].firstMatch("xyz\nZ    "), 2319);
+  assertNull(res[794].firstMatch("*** Failers"), 2320);
+  assertNull(res[794].firstMatch("xyzZ"), 2321);
+  assertNull(res[795].firstMatch("abcdef"), 2322);
+  assertNull(res[795].firstMatch("defabcxyz>3 "), 2323);
+  assertNull(res[795].firstMatch("*** Failers "), 2324);
+  assertNull(res[795].firstMatch("defabcxyz"), 2325);
+  assertNull(res[796].firstMatch("abP"), 2326);
+  assertNull(res[796].firstMatch("abcdeP"), 2327);
+  assertToStringEquals("abcdef", res[796].firstMatch("abcdefP"), 2328);
+  assertNull(res[796].firstMatch("*** Failers"), 2329);
+  assertNull(res[796].firstMatch("abxP    "), 2330);
+  assertNull(res[797].firstMatch("aP"), 2331);
+  assertNull(res[797].firstMatch("aaP"), 2332);
+  assertNull(res[797].firstMatch("aa2P "), 2333);
+  assertNull(res[797].firstMatch("aaaP"), 2334);
+  assertNull(res[797].firstMatch("aaa23P "), 2335);
+  assertNull(res[797].firstMatch("aaaa12345P"), 2336);
+  assertToStringEquals("aa0z", res[797].firstMatch("aa0zP"), 2337);
+  assertToStringEquals("aaaa4444444444444z", res[797].firstMatch("aaaa4444444444444zP "), 2338);
+  assertNull(res[797].firstMatch("*** Failers"), 2339);
+  assertNull(res[797].firstMatch("azP "), 2340);
+  assertNull(res[797].firstMatch("aaaaaP "), 2341);
+  assertNull(res[797].firstMatch("a56P "), 2342);
+  assertNull(res[799].firstMatch("adfadadaklhlkalkajhlkjahdfasdfasdfladsfjkjPZ"), 2343);
+  assertNull(res[799].firstMatch("lkjhlkjhlkjhlkjhabbbbbbcdaefabbbbbbbefaPBZ"), 2344);
+  assertNull(res[799].firstMatch("cdabbbbbbbbPRBZ"), 2345);
+  assertNull(res[799].firstMatch("efabbbbbbbbbbbbbbbbPRBZ"), 2346);
+  assertNull(res[799].firstMatch("bbbbbbbbbbbbcdXyasdfadfPRBZ    "), 2347);
+  assertNull(res[799].firstMatch("abc"), 2348);
+  assertNull(res[799].firstMatch("** Failers"), 2349);
+  assertNull(res[799].firstMatch("def  "), 2350);
+  assertToStringEquals("the quick brown fox", res[800].firstMatch("the quick brown fox"), 2351);
+  assertNull(res[800].firstMatch("The quick brown FOX"), 2352);
+  assertToStringEquals("the quick brown fox", res[800].firstMatch("What do you know about the quick brown fox?"), 2353);
+  assertNull(res[800].firstMatch("What do you know about THE QUICK BROWN FOX?"), 2354);
+  assertToStringEquals("the quick brown fox", res[801].firstMatch("the quick brown fox"), 2355);
+  assertToStringEquals("The quick brown FOX", res[801].firstMatch("The quick brown FOX"), 2356);
+  assertToStringEquals("the quick brown fox", res[801].firstMatch("What do you know about the quick brown fox?"), 2357);
+  assertToStringEquals("THE QUICK BROWN FOX", res[801].firstMatch("What do you know about THE QUICK BROWN FOX?"), 2358);
+  assertToStringEquals("abcd\x09\n\x0d\x0cae9;\$\\?caxyz", res[802].firstMatch("abcd\x09\n\x0d\x0cae9;\$\\?caxyz"), 2359);
+  assertToStringEquals("abxyzpqrrrabbxyyyypqAzz", res[803].firstMatch("abxyzpqrrrabbxyyyypqAzz"), 2360);
+  assertToStringEquals("abxyzpqrrrabbxyyyypqAzz", res[803].firstMatch("abxyzpqrrrabbxyyyypqAzz"), 2361);
+  assertToStringEquals("aabxyzpqrrrabbxyyyypqAzz", res[803].firstMatch("aabxyzpqrrrabbxyyyypqAzz"), 2362);
+  assertToStringEquals("aaabxyzpqrrrabbxyyyypqAzz", res[803].firstMatch("aaabxyzpqrrrabbxyyyypqAzz"), 2363);
+  assertToStringEquals("aaaabxyzpqrrrabbxyyyypqAzz", res[803].firstMatch("aaaabxyzpqrrrabbxyyyypqAzz"), 2364);
+  assertToStringEquals("abcxyzpqrrrabbxyyyypqAzz", res[803].firstMatch("abcxyzpqrrrabbxyyyypqAzz"), 2365);
+  assertToStringEquals("aabcxyzpqrrrabbxyyyypqAzz", res[803].firstMatch("aabcxyzpqrrrabbxyyyypqAzz"), 2366);
+  assertToStringEquals("aaabcxyzpqrrrabbxyyyypAzz", res[803].firstMatch("aaabcxyzpqrrrabbxyyyypAzz"), 2367);
+  assertToStringEquals("aaabcxyzpqrrrabbxyyyypqAzz", res[803].firstMatch("aaabcxyzpqrrrabbxyyyypqAzz"), 2368);
+  assertToStringEquals("aaabcxyzpqrrrabbxyyyypqqAzz", res[803].firstMatch("aaabcxyzpqrrrabbxyyyypqqAzz"), 2369);
+  assertToStringEquals("aaabcxyzpqrrrabbxyyyypqqqAzz", res[803].firstMatch("aaabcxyzpqrrrabbxyyyypqqqAzz"), 2370);
+  assertToStringEquals("aaabcxyzpqrrrabbxyyyypqqqqAzz", res[803].firstMatch("aaabcxyzpqrrrabbxyyyypqqqqAzz"), 2371);
+  assertToStringEquals("aaabcxyzpqrrrabbxyyyypqqqqqAzz", res[803].firstMatch("aaabcxyzpqrrrabbxyyyypqqqqqAzz"), 2372);
+  assertToStringEquals("aaabcxyzpqrrrabbxyyyypqqqqqqAzz", res[803].firstMatch("aaabcxyzpqrrrabbxyyyypqqqqqqAzz"), 2373);
+  assertToStringEquals("aaaabcxyzpqrrrabbxyyyypqAzz", res[803].firstMatch("aaaabcxyzpqrrrabbxyyyypqAzz"), 2374);
+  assertToStringEquals("abxyzzpqrrrabbxyyyypqAzz", res[803].firstMatch("abxyzzpqrrrabbxyyyypqAzz"), 2375);
+  assertToStringEquals("aabxyzzzpqrrrabbxyyyypqAzz", res[803].firstMatch("aabxyzzzpqrrrabbxyyyypqAzz"), 2376);
+  assertToStringEquals("aaabxyzzzzpqrrrabbxyyyypqAzz", res[803].firstMatch("aaabxyzzzzpqrrrabbxyyyypqAzz"), 2377);
+  assertToStringEquals("aaaabxyzzzzpqrrrabbxyyyypqAzz", res[803].firstMatch("aaaabxyzzzzpqrrrabbxyyyypqAzz"), 2378);
+  assertToStringEquals("abcxyzzpqrrrabbxyyyypqAzz", res[803].firstMatch("abcxyzzpqrrrabbxyyyypqAzz"), 2379);
+  assertToStringEquals("aabcxyzzzpqrrrabbxyyyypqAzz", res[803].firstMatch("aabcxyzzzpqrrrabbxyyyypqAzz"), 2380);
+  assertToStringEquals("aaabcxyzzzzpqrrrabbxyyyypqAzz", res[803].firstMatch("aaabcxyzzzzpqrrrabbxyyyypqAzz"), 2381);
+  assertToStringEquals("aaaabcxyzzzzpqrrrabbxyyyypqAzz", res[803].firstMatch("aaaabcxyzzzzpqrrrabbxyyyypqAzz"), 2382);
+  assertToStringEquals("aaaabcxyzzzzpqrrrabbbxyyyypqAzz", res[803].firstMatch("aaaabcxyzzzzpqrrrabbbxyyyypqAzz"), 2383);
+  assertToStringEquals("aaaabcxyzzzzpqrrrabbbxyyyyypqAzz", res[803].firstMatch("aaaabcxyzzzzpqrrrabbbxyyyyypqAzz"), 2384);
+  assertToStringEquals("aaabcxyzpqrrrabbxyyyypABzz", res[803].firstMatch("aaabcxyzpqrrrabbxyyyypABzz"), 2385);
+  assertToStringEquals("aaabcxyzpqrrrabbxyyyypABBzz", res[803].firstMatch("aaabcxyzpqrrrabbxyyyypABBzz"), 2386);
+  assertToStringEquals("aaabxyzpqrrrabbxyyyypqAzz", res[803].firstMatch(">>>aaabxyzpqrrrabbxyyyypqAzz"), 2387);
+  assertToStringEquals("aaaabxyzpqrrrabbxyyyypqAzz", res[803].firstMatch(">aaaabxyzpqrrrabbxyyyypqAzz"), 2388);
+  assertToStringEquals("abcxyzpqrrrabbxyyyypqAzz", res[803].firstMatch(">>>>abcxyzpqrrrabbxyyyypqAzz"), 2389);
+  assertNull(res[803].firstMatch("*** Failers"), 2390);
+  assertNull(res[803].firstMatch("abxyzpqrrabbxyyyypqAzz"), 2391);
+  assertNull(res[803].firstMatch("abxyzpqrrrrabbxyyyypqAzz"), 2392);
+  assertNull(res[803].firstMatch("abxyzpqrrrabxyyyypqAzz"), 2393);
+  assertNull(res[803].firstMatch("aaaabcxyzzzzpqrrrabbbxyyyyyypqAzz"), 2394);
+  assertNull(res[803].firstMatch("aaaabcxyzzzzpqrrrabbbxyyypqAzz"), 2395);
+  assertNull(res[803].firstMatch("aaabcxyzpqrrrabbxyyyypqqqqqqqAzz"), 2396);
+  assertToStringEquals("abczz,abc", res[804].firstMatch("abczz"), 2397);
+  assertToStringEquals("abcabczz,abc", res[804].firstMatch("abcabczz"), 2398);
+  assertNull(res[804].firstMatch("*** Failers"), 2399);
+  assertNull(res[804].firstMatch("zz"), 2400);
+  assertNull(res[804].firstMatch("abcabcabczz"), 2401);
+  assertNull(res[804].firstMatch(">>abczz"), 2402);
+  assertToStringEquals("bc,b", res[805].firstMatch("bc"), 2403);
+  assertToStringEquals("bbc,b", res[805].firstMatch("bbc"), 2404);
+  assertToStringEquals("bbbc,bb", res[805].firstMatch("bbbc"), 2405);
+  assertToStringEquals("bac,a", res[805].firstMatch("bac"), 2406);
+  assertToStringEquals("bbac,a", res[805].firstMatch("bbac"), 2407);
+  assertToStringEquals("aac,a", res[805].firstMatch("aac"), 2408);
+  assertToStringEquals("abbbbbbbbbbbc,bbbbbbbbbbb", res[805].firstMatch("abbbbbbbbbbbc"), 2409);
+  assertToStringEquals("bbbbbbbbbbbac,a", res[805].firstMatch("bbbbbbbbbbbac"), 2410);
+  assertNull(res[805].firstMatch("*** Failers"), 2411);
+  assertNull(res[805].firstMatch("aaac"), 2412);
+  assertNull(res[805].firstMatch("abbbbbbbbbbbac"), 2413);
+  assertToStringEquals("bc,b", res[806].firstMatch("bc"), 2414);
+  assertToStringEquals("bbc,bb", res[806].firstMatch("bbc"), 2415);
+  assertToStringEquals("bbbc,bbb", res[806].firstMatch("bbbc"), 2416);
+  assertToStringEquals("bac,a", res[806].firstMatch("bac"), 2417);
+  assertToStringEquals("bbac,a", res[806].firstMatch("bbac"), 2418);
+  assertToStringEquals("aac,a", res[806].firstMatch("aac"), 2419);
+  assertToStringEquals("abbbbbbbbbbbc,bbbbbbbbbbb", res[806].firstMatch("abbbbbbbbbbbc"), 2420);
+  assertToStringEquals("bbbbbbbbbbbac,a", res[806].firstMatch("bbbbbbbbbbbac"), 2421);
+  assertNull(res[806].firstMatch("*** Failers"), 2422);
+  assertNull(res[806].firstMatch("aaac"), 2423);
+  assertNull(res[806].firstMatch("abbbbbbbbbbbac"), 2424);
+  assertToStringEquals("bbc,bb", res[806].firstMatch("bbc"), 2425);
+  assertToStringEquals("babc,ba", res[807].firstMatch("babc"), 2426);
+  assertToStringEquals("bbabc,ba", res[807].firstMatch("bbabc"), 2427);
+  assertToStringEquals("bababc,ba", res[807].firstMatch("bababc"), 2428);
+  assertNull(res[807].firstMatch("*** Failers"), 2429);
+  assertNull(res[807].firstMatch("bababbc"), 2430);
+  assertNull(res[807].firstMatch("babababc"), 2431);
+  assertToStringEquals("babc,ba", res[808].firstMatch("babc"), 2432);
+  assertToStringEquals("bbabc,ba", res[808].firstMatch("bbabc"), 2433);
+  assertToStringEquals("bababc,ba", res[808].firstMatch("bababc"), 2434);
+  assertNull(res[808].firstMatch("*** Failers"), 2435);
+  assertNull(res[808].firstMatch("bababbc"), 2436);
+  assertNull(res[808].firstMatch("babababc"), 2437);
+  assertThrows(() => new RegExp(r"^\\ca\\cA\\c[\\c{\\c:"), 2438);
+  assertNull(res[808].firstMatch("\x01\x01e;z"), 2439);
+  assertToStringEquals("a", res[809].firstMatch("athing"), 2440);
+  assertToStringEquals("b", res[809].firstMatch("bthing"), 2441);
+  assertToStringEquals("]", res[809].firstMatch("]thing"), 2442);
+  assertToStringEquals("c", res[809].firstMatch("cthing"), 2443);
+  assertToStringEquals("d", res[809].firstMatch("dthing"), 2444);
+  assertToStringEquals("e", res[809].firstMatch("ething"), 2445);
+  assertNull(res[809].firstMatch("*** Failers"), 2446);
+  assertNull(res[809].firstMatch("fthing"), 2447);
+  assertNull(res[809].firstMatch("[thing"), 2448);
+  assertNull(res[809].firstMatch("\\thing"), 2449);
+  assertNull(res[810].firstMatch("]thing"), 2450);
+  assertNull(res[810].firstMatch("cthing"), 2451);
+  assertNull(res[810].firstMatch("dthing"), 2452);
+  assertNull(res[810].firstMatch("ething"), 2453);
+  assertNull(res[810].firstMatch("*** Failers"), 2454);
+  assertNull(res[810].firstMatch("athing"), 2455);
+  assertNull(res[810].firstMatch("fthing"), 2456);
+  assertToStringEquals("f", res[811].firstMatch("fthing"), 2457);
+  assertToStringEquals("[", res[811].firstMatch("[thing"), 2458);
+  assertToStringEquals("\\", res[811].firstMatch("\\thing"), 2459);
+  assertToStringEquals("*", res[811].firstMatch("*** Failers"), 2460);
+  assertNull(res[811].firstMatch("athing"), 2461);
+  assertNull(res[811].firstMatch("bthing"), 2462);
+  assertNull(res[811].firstMatch("]thing"), 2463);
+  assertNull(res[811].firstMatch("cthing"), 2464);
+  assertNull(res[811].firstMatch("dthing"), 2465);
+  assertNull(res[811].firstMatch("ething"), 2466);
+  assertNull(res[812].firstMatch("athing"), 2467);
+  assertNull(res[812].firstMatch("fthing"), 2468);
+  assertNull(res[812].firstMatch("*** Failers"), 2469);
+  assertNull(res[812].firstMatch("]thing"), 2470);
+  assertNull(res[812].firstMatch("cthing"), 2471);
+  assertNull(res[812].firstMatch("dthing"), 2472);
+  assertNull(res[812].firstMatch("ething"), 2473);
+  assertNull(res[812].firstMatch("\ufffd"), 2474);
+  assertNull(res[812].firstMatch("\ufffd"), 2475);
+  assertToStringEquals("0", res[813].firstMatch("0"), 2476);
+  assertToStringEquals("1", res[813].firstMatch("1"), 2477);
+  assertToStringEquals("2", res[813].firstMatch("2"), 2478);
+  assertToStringEquals("3", res[813].firstMatch("3"), 2479);
+  assertToStringEquals("4", res[813].firstMatch("4"), 2480);
+  assertToStringEquals("5", res[813].firstMatch("5"), 2481);
+  assertToStringEquals("6", res[813].firstMatch("6"), 2482);
+  assertToStringEquals("7", res[813].firstMatch("7"), 2483);
+  assertToStringEquals("8", res[813].firstMatch("8"), 2484);
+  assertToStringEquals("9", res[813].firstMatch("9"), 2485);
+  assertToStringEquals("10", res[813].firstMatch("10"), 2486);
+  assertToStringEquals("100", res[813].firstMatch("100"), 2487);
+  assertNull(res[813].firstMatch("*** Failers"), 2488);
+  assertNull(res[813].firstMatch("abc"), 2489);
+  assertToStringEquals("enter", res[814].firstMatch("enter"), 2490);
+  assertToStringEquals("inter", res[814].firstMatch("inter"), 2491);
+  assertToStringEquals("uponter", res[814].firstMatch("uponter"), 2492);
+  assertToStringEquals("xxx0", res[815].firstMatch("xxx0"), 2493);
+  assertToStringEquals("xxx1234", res[815].firstMatch("xxx1234"), 2494);
+  assertNull(res[815].firstMatch("*** Failers"), 2495);
+  assertNull(res[815].firstMatch("xxx"), 2496);
+  assertToStringEquals("x123", res[816].firstMatch("x123"), 2497);
+  assertToStringEquals("xx123", res[816].firstMatch("xx123"), 2498);
+  assertToStringEquals("123456", res[816].firstMatch("123456"), 2499);
+  assertNull(res[816].firstMatch("*** Failers"), 2500);
+  assertNull(res[816].firstMatch("123"), 2501);
+  assertToStringEquals("x1234", res[816].firstMatch("x1234"), 2502);
+  assertToStringEquals("x123", res[817].firstMatch("x123"), 2503);
+  assertToStringEquals("xx123", res[817].firstMatch("xx123"), 2504);
+  assertToStringEquals("123456", res[817].firstMatch("123456"), 2505);
+  assertNull(res[817].firstMatch("*** Failers"), 2506);
+  assertNull(res[817].firstMatch("123"), 2507);
+  assertToStringEquals("x1234", res[817].firstMatch("x1234"), 2508);
+  assertToStringEquals("abc!pqr=apquxz.ixr.zzz.ac.uk,abc,pqr", res[818].firstMatch("abc!pqr=apquxz.ixr.zzz.ac.uk"), 2509);
+  assertNull(res[818].firstMatch("*** Failers"), 2510);
+  assertNull(res[818].firstMatch("!pqr=apquxz.ixr.zzz.ac.uk"), 2511);
+  assertNull(res[818].firstMatch("abc!=apquxz.ixr.zzz.ac.uk"), 2512);
+  assertNull(res[818].firstMatch("abc!pqr=apquxz:ixr.zzz.ac.uk"), 2513);
+  assertNull(res[818].firstMatch("abc!pqr=apquxz.ixr.zzz.ac.ukk"), 2514);
+  assertToStringEquals(":", res[819].firstMatch("Well, we need a colon: somewhere"), 2515);
+  assertNull(res[819].firstMatch("*** Fail if we don't"), 2516);
+  assertToStringEquals("0abc,0abc", res[820].firstMatch("0abc"), 2517);
+  assertToStringEquals("abc,abc", res[820].firstMatch("abc"), 2518);
+  assertToStringEquals("fed,fed", res[820].firstMatch("fed"), 2519);
+  assertToStringEquals("E,E", res[820].firstMatch("E"), 2520);
+  assertToStringEquals("::,::", res[820].firstMatch("::"), 2521);
+  assertToStringEquals("5f03:12C0::932e,5f03:12C0::932e", res[820].firstMatch("5f03:12C0::932e"), 2522);
+  assertToStringEquals("def,def", res[820].firstMatch("fed def"), 2523);
+  assertToStringEquals("ff,ff", res[820].firstMatch("Any old stuff"), 2524);
+  assertNull(res[820].firstMatch("*** Failers"), 2525);
+  assertNull(res[820].firstMatch("0zzz"), 2526);
+  assertNull(res[820].firstMatch("gzzz"), 2527);
+  assertNull(res[820].firstMatch("fed "), 2528);
+  assertNull(res[820].firstMatch("Any old rubbish"), 2529);
+  assertToStringEquals(".1.2.3,1,2,3", res[821].firstMatch(".1.2.3"), 2530);
+  assertToStringEquals("A.12.123.0,12,123,0", res[821].firstMatch("A.12.123.0"), 2531);
+  assertNull(res[821].firstMatch("*** Failers"), 2532);
+  assertNull(res[821].firstMatch(".1.2.3333"), 2533);
+  assertNull(res[821].firstMatch("1.2.3"), 2534);
+  assertNull(res[821].firstMatch("1234.2.3"), 2535);
+  assertToStringEquals("1 IN SOA non-sp1 non-sp2(,1,non-sp1,non-sp2", res[822].firstMatch("1 IN SOA non-sp1 non-sp2("), 2536);
+  assertToStringEquals("1    IN    SOA    non-sp1    non-sp2   (,1,non-sp1,non-sp2", res[822].firstMatch("1    IN    SOA    non-sp1    non-sp2   ("), 2537);
+  assertNull(res[822].firstMatch("*** Failers"), 2538);
+  assertNull(res[822].firstMatch("1IN SOA non-sp1 non-sp2("), 2539);
+  assertToStringEquals("a.,", res[823].firstMatch("a."), 2540);
+  assertToStringEquals("Z.,", res[823].firstMatch("Z."), 2541);
+  assertToStringEquals("2.,", res[823].firstMatch("2."), 2542);
+  assertToStringEquals("ab-c.pq-r.,.pq-r", res[823].firstMatch("ab-c.pq-r."), 2543);
+  assertToStringEquals("sxk.zzz.ac.uk.,.uk", res[823].firstMatch("sxk.zzz.ac.uk."), 2544);
+  assertToStringEquals("x-.y-.,.y-", res[823].firstMatch("x-.y-."), 2545);
+  assertNull(res[823].firstMatch("*** Failers"), 2546);
+  assertNull(res[823].firstMatch("-abc.peq."), 2547);
+  assertToStringEquals("*.a,,,", res[824].firstMatch("*.a"), 2548);
+  assertToStringEquals("*.b0-a,0-a,,", res[824].firstMatch("*.b0-a"), 2549);
+  assertToStringEquals("*.c3-b.c,3-b,.c,", res[824].firstMatch("*.c3-b.c"), 2550);
+  assertToStringEquals("*.c-a.b-c,-a,.b-c,-c", res[824].firstMatch("*.c-a.b-c"), 2551);
+  assertNull(res[824].firstMatch("*** Failers"), 2552);
+  assertNull(res[824].firstMatch("*.0"), 2553);
+  assertNull(res[824].firstMatch("*.a-"), 2554);
+  assertNull(res[824].firstMatch("*.a-b.c-"), 2555);
+  assertNull(res[824].firstMatch("*.c-a.0-c"), 2556);
+  assertToStringEquals("abde,de,abd,e", res[825].firstMatch("abde"), 2557);
+  assertToStringEquals("abdf,,abd,f", res[826].firstMatch("abdf"), 2558);
+  assertToStringEquals("ab,abcd,cd,ab", res[827].firstMatch("abcd"), 2559);
+  assertToStringEquals("a.b.c.d,.d", res[828].firstMatch("a.b.c.d"), 2560);
+  assertToStringEquals("A.B.C.D,.D", res[828].firstMatch("A.B.C.D"), 2561);
+  assertToStringEquals("a.b.c.1.2.3.C,.C", res[828].firstMatch("a.b.c.1.2.3.C"), 2562);
+  assertToStringEquals("\"1234\",", res[829].firstMatch("\"1234\""), 2563);
+  assertToStringEquals("\"abcd\" ;,;", res[829].firstMatch("\"abcd\" ;"), 2564);
+  assertToStringEquals("\"\" ; rhubarb,; rhubarb", res[829].firstMatch("\"\" ; rhubarb"), 2565);
+  assertNull(res[829].firstMatch("*** Failers"), 2566);
+  assertNull(res[829].firstMatch("\"1234\" : things"), 2567);
+  assertNull(res[830].firstMatch("\\"), 2568);
+  assertNull(res[830].firstMatch("*** Failers"), 2569);
+  assertToStringEquals("ab c", res[831].firstMatch("ab c"), 2570);
+  assertNull(res[831].firstMatch("*** Failers"), 2571);
+  assertNull(res[831].firstMatch("abc"), 2572);
+  assertNull(res[831].firstMatch("ab cde"), 2573);
+  assertToStringEquals("ab c", res[831].firstMatch("ab c"), 2574);
+  assertNull(res[831].firstMatch("*** Failers"), 2575);
+  assertNull(res[831].firstMatch("abc"), 2576);
+  assertNull(res[831].firstMatch("ab cde"), 2577);
+  assertToStringEquals("a bcd", res[832].firstMatch("a bcd"), 2578);
+  assertNull(res[832].firstMatch("a b d"), 2579);
+  assertNull(res[832].firstMatch("*** Failers"), 2580);
+  assertNull(res[832].firstMatch("abcd"), 2581);
+  assertNull(res[832].firstMatch("ab d"), 2582);
+  assertToStringEquals("abcdefhijklm,abc,bc,c,def,ef,f,hij,ij,j,klm,lm,m", res[833].firstMatch("abcdefhijklm"), 2583);
+  assertToStringEquals("abcdefhijklm,bc,c,ef,f,ij,j,lm,m", res[834].firstMatch("abcdefhijklm"), 2584);
+  assertNull(res[835].firstMatch("a+ Z0+\x08\n\x1d\x12"), 2585);
+  assertNull(res[835].firstMatch(".^\$(*+)|{?,?}"), 2586);
+  assertToStringEquals("z", res[836].firstMatch("z"), 2587);
+  assertToStringEquals("az", res[836].firstMatch("az"), 2588);
+  assertToStringEquals("aaaz", res[836].firstMatch("aaaz"), 2589);
+  assertToStringEquals("a", res[836].firstMatch("a"), 2590);
+  assertToStringEquals("aa", res[836].firstMatch("aa"), 2591);
+  assertToStringEquals("aaaa", res[836].firstMatch("aaaa"), 2592);
+  assertToStringEquals("a", res[836].firstMatch("a+"), 2593);
+  assertToStringEquals("aa", res[836].firstMatch("aa+"), 2594);
+  assertToStringEquals("z", res[837].firstMatch("z"), 2595);
+  assertToStringEquals("a", res[837].firstMatch("az"), 2596);
+  assertToStringEquals("a", res[837].firstMatch("aaaz"), 2597);
+  assertToStringEquals("a", res[837].firstMatch("a"), 2598);
+  assertToStringEquals("a", res[837].firstMatch("aa"), 2599);
+  assertToStringEquals("a", res[837].firstMatch("aaaa"), 2600);
+  assertToStringEquals("a", res[837].firstMatch("a+"), 2601);
+  assertToStringEquals("a", res[837].firstMatch("aa+"), 2602);
+  assertToStringEquals("az", res[838].firstMatch("az"), 2603);
+  assertToStringEquals("aaaz", res[838].firstMatch("aaaz"), 2604);
+  assertToStringEquals("aa", res[838].firstMatch("aa"), 2605);
+  assertToStringEquals("aaaa", res[838].firstMatch("aaaa"), 2606);
+  assertToStringEquals("aa", res[838].firstMatch("aa+"), 2607);
+  assertToStringEquals("az", res[839].firstMatch("az"), 2608);
+  assertToStringEquals("aa", res[839].firstMatch("aaaz"), 2609);
+  assertToStringEquals("aa", res[839].firstMatch("aa"), 2610);
+  assertToStringEquals("aa", res[839].firstMatch("aaaa"), 2611);
+  assertToStringEquals("aa", res[839].firstMatch("aa+"), 2612);
+  assertToStringEquals("1234567890", res[840].firstMatch("1234567890"), 2613);
+  assertToStringEquals("12345678ab", res[840].firstMatch("12345678ab"), 2614);
+  assertToStringEquals("12345678__", res[840].firstMatch("12345678__"), 2615);
+  assertNull(res[840].firstMatch("*** Failers"), 2616);
+  assertNull(res[840].firstMatch("1234567"), 2617);
+  assertToStringEquals("uoie", res[841].firstMatch("uoie"), 2618);
+  assertToStringEquals("1234", res[841].firstMatch("1234"), 2619);
+  assertToStringEquals("12345", res[841].firstMatch("12345"), 2620);
+  assertToStringEquals("aaaaa", res[841].firstMatch("aaaaa"), 2621);
+  assertNull(res[841].firstMatch("*** Failers"), 2622);
+  assertNull(res[841].firstMatch("123456"), 2623);
+  assertToStringEquals("uoie", res[842].firstMatch("uoie"), 2624);
+  assertToStringEquals("1234", res[842].firstMatch("1234"), 2625);
+  assertToStringEquals("1234", res[842].firstMatch("12345"), 2626);
+  assertToStringEquals("aaaa", res[842].firstMatch("aaaaa"), 2627);
+  assertToStringEquals("1234", res[842].firstMatch("123456"), 2628);
+  assertToStringEquals("From abcd  Mon Sep 01 12:33,abcd", res[843].firstMatch("From abcd  Mon Sep 01 12:33:02 1997"), 2629);
+  assertToStringEquals("From abcd  Mon Sep 01 12:33,Sep ", res[844].firstMatch("From abcd  Mon Sep 01 12:33:02 1997"), 2630);
+  assertToStringEquals("From abcd  Mon Sep  1 12:33,Sep  ", res[844].firstMatch("From abcd  Mon Sep  1 12:33:02 1997"), 2631);
+  assertNull(res[844].firstMatch("*** Failers"), 2632);
+  assertNull(res[844].firstMatch("From abcd  Sep 01 12:33:02 1997"), 2633);
+  assertNull(res[845].firstMatch("12\n34"), 2634);
+  assertNull(res[845].firstMatch("12\x0d34"), 2635);
+  assertToStringEquals("brown", res[846].firstMatch("the quick brown\x09 fox"), 2636);
+  assertToStringEquals("foolish see?,lish see?", res[847].firstMatch("foobar is foolish see?"), 2637);
+  assertToStringEquals("rowbar etc, etc", res[848].firstMatch("foobar crowbar etc"), 2638);
+  assertToStringEquals("barrel,rel", res[848].firstMatch("barrel"), 2639);
+  assertToStringEquals("2barrel,rel", res[848].firstMatch("2barrel"), 2640);
+  assertToStringEquals("A barrel,rel", res[848].firstMatch("A barrel"), 2641);
+  assertToStringEquals("abc,abc", res[849].firstMatch("abc456"), 2642);
+  assertNull(res[849].firstMatch("*** Failers"), 2643);
+  assertNull(res[849].firstMatch("abc123"), 2644);
+  assertToStringEquals("1234", res[850].firstMatch("1234"), 2645);
+  assertToStringEquals("1234", res[851].firstMatch("1234"), 2646);
+  assertToStringEquals("abcd", res[852].firstMatch("abcd"), 2647);
+  assertToStringEquals("abcd", res[853].firstMatch("abcd"), 2648);
+  assertToStringEquals("abc", res[854].firstMatch("the abc"), 2649);
+  assertNull(res[854].firstMatch("*** Failers"), 2650);
+  assertNull(res[854].firstMatch("abc"), 2651);
+  assertToStringEquals("abc", res[855].firstMatch("abc"), 2652);
+  assertNull(res[855].firstMatch("*** Failers"), 2653);
+  assertNull(res[855].firstMatch("the abc"), 2654);
+  assertToStringEquals("aabb,b", res[856].firstMatch("aabbbbb"), 2655);
+  assertToStringEquals("aabbbbb,abbbbb", res[857].firstMatch("aabbbbb"), 2656);
+  assertToStringEquals("aa,a", res[858].firstMatch("aabbbbb"), 2657);
+  assertToStringEquals("aabb,b", res[859].firstMatch("aabbbbb"), 2658);
+  assertToStringEquals("Alan Other <user@dom.ain>", res[860].firstMatch("Alan Other <user@dom.ain>"), 2659);
+  assertToStringEquals("user@dom.ain", res[860].firstMatch("<user@dom.ain>"), 2660);
+  assertToStringEquals("user@dom.ain", res[860].firstMatch("user@dom.ain"), 2661);
+  assertToStringEquals("\"A. Other\" <user.1234@dom.ain> (a comment)", res[860].firstMatch("\"A. Other\" <user.1234@dom.ain> (a comment)"), 2662);
+  assertToStringEquals(" Other <user.1234@dom.ain> (a comment)", res[860].firstMatch("A. Other <user.1234@dom.ain> (a comment)"), 2663);
+  assertToStringEquals("\"/s=user/ou=host/o=place/prmd=uu.yy/admd= /c=gb/\"@x400-re.lay", res[860].firstMatch("\"/s=user/ou=host/o=place/prmd=uu.yy/admd= /c=gb/\"@x400-re.lay"), 2664);
+  assertToStringEquals("user@some.where", res[860].firstMatch("A missing angle <user@some.where"), 2665);
+  assertNull(res[860].firstMatch("*** Failers"), 2666);
+  assertNull(res[860].firstMatch("The quick brown fox"), 2667);
+  assertToStringEquals("Alan Other <user@dom.ain>", res[861].firstMatch("Alan Other <user@dom.ain>"), 2668);
+  assertToStringEquals("user@dom.ain", res[861].firstMatch("<user@dom.ain>"), 2669);
+  assertToStringEquals("user@dom.ain", res[861].firstMatch("user@dom.ain"), 2670);
+  assertToStringEquals("\"A. Other\" <user.1234@dom.ain>", res[861].firstMatch("\"A. Other\" <user.1234@dom.ain> (a comment)"), 2671);
+  assertToStringEquals(" Other <user.1234@dom.ain>", res[861].firstMatch("A. Other <user.1234@dom.ain> (a comment)"), 2672);
+  assertToStringEquals("\"/s=user/ou=host/o=place/prmd=uu.yy/admd= /c=gb/\"@x400-re.lay", res[861].firstMatch("\"/s=user/ou=host/o=place/prmd=uu.yy/admd= /c=gb/\"@x400-re.lay"), 2673);
+  assertToStringEquals("user@some.where", res[861].firstMatch("A missing angle <user@some.where"), 2674);
+  assertNull(res[861].firstMatch("*** Failers"), 2675);
+  assertNull(res[861].firstMatch("The quick brown fox"), 2676);
+  assertNull(res[861].firstMatch("abc\x00def\x00pqr\x00xyz\x000AB"), 2677);
+  assertNull(res[861].firstMatch("abc456 abc\x00def\x00pqr\x00xyz\x000ABCDE"), 2678);
+  assertToStringEquals("abc\x0def\x00pqr\x000xyz\x0000AB", res[862].firstMatch("abc\x0def\x00pqr\x000xyz\x0000AB"), 2679);
+  assertToStringEquals("abc\x0def\x00pqr\x000xyz\x0000AB", res[862].firstMatch("abc456 abc\x0def\x00pqr\x000xyz\x0000ABCDE"), 2680);
+  assertToStringEquals("\x00", res[863].firstMatch("\x00A"), 2681);
+  assertToStringEquals("\x01", res[863].firstMatch("\x01B"), 2682);
+  assertToStringEquals("\x1f", res[863].firstMatch("\x1fC"), 2683);
+  assertToStringEquals("\x00\x00\x00\x00", res[864].firstMatch("\x00\x00\x00\x00"), 2684);
+  assertNull(res[865].firstMatch("The Ax0x0Z"), 2685);
+  assertNull(res[865].firstMatch("An A\x00x0\x00Z"), 2686);
+  assertNull(res[865].firstMatch("*** Failers"), 2687);
+  assertNull(res[865].firstMatch("A\x00Z"), 2688);
+  assertNull(res[865].firstMatch("A\x00x0\x00x0Z"), 2689);
+  assertToStringEquals(" ", res[866].firstMatch(" abc"), 2690);
+  assertToStringEquals("\x0c", res[866].firstMatch("\x0cabc"), 2691);
+  assertToStringEquals("\n", res[866].firstMatch("\nabc"), 2692);
+  assertToStringEquals("\x0d", res[866].firstMatch("\x0dabc"), 2693);
+  assertToStringEquals("\x09", res[866].firstMatch("\x09abc"), 2694);
+  assertNull(res[866].firstMatch("*** Failers"), 2695);
+  assertNull(res[866].firstMatch("abc"), 2696);
+  assertToStringEquals("abc", res[867].firstMatch("abc"), 2697);
+  assertToStringEquals("abbbbc", res[868].firstMatch("abbbbc"), 2698);
+  assertToStringEquals("abbbc", res[868].firstMatch("abbbc"), 2699);
+  assertToStringEquals("abbc", res[868].firstMatch("abbc"), 2700);
+  assertNull(res[868].firstMatch("*** Failers"), 2701);
+  assertNull(res[868].firstMatch("abc"), 2702);
+  assertNull(res[868].firstMatch("abbbbbc"), 2703);
+  assertToStringEquals("track1.title:TBlah blah blah,track1,title,Blah blah blah", res[869].firstMatch("track1.title:TBlah blah blah"), 2704);
+  assertToStringEquals("track1.title:TBlah blah blah,track1,title,Blah blah blah", res[870].firstMatch("track1.title:TBlah blah blah"), 2705);
+  assertToStringEquals("track1.title:TBlah blah blah,track1,title,Blah blah blah", res[871].firstMatch("track1.title:TBlah blah blah"), 2706);
+  assertToStringEquals("WXY_^abc", res[872].firstMatch("WXY_^abc"), 2707);
+  assertNull(res[872].firstMatch("*** Failers"), 2708);
+  assertNull(res[872].firstMatch("wxy"), 2709);
+  assertToStringEquals("WXY_^abc", res[873].firstMatch("WXY_^abc"), 2710);
+  assertToStringEquals("wxy_^ABC", res[873].firstMatch("wxy_^ABC"), 2711);
+  assertToStringEquals("WXY_^abc", res[874].firstMatch("WXY_^abc"), 2712);
+  assertToStringEquals("wxy_^ABC", res[874].firstMatch("wxy_^ABC"), 2713);
+  assertToStringEquals("abc", res[875].firstMatch("abc"), 2714);
+  assertToStringEquals("abc", res[875].firstMatch("qqq\nabc"), 2715);
+  assertToStringEquals("abc", res[875].firstMatch("abc\nzzz"), 2716);
+  assertToStringEquals("abc", res[875].firstMatch("qqq\nabc\nzzz"), 2717);
+  assertToStringEquals("abc", res[876].firstMatch("abc"), 2718);
+  assertNull(res[876].firstMatch("*** Failers"), 2719);
+  assertNull(res[876].firstMatch("qqq\nabc"), 2720);
+  assertNull(res[876].firstMatch("abc\nzzz"), 2721);
+  assertNull(res[876].firstMatch("qqq\nabc\nzzz"), 2722);
+  assertNull(res[877].firstMatch("abc"), 2723);
+  assertNull(res[877].firstMatch("abc\n "), 2724);
+  assertNull(res[877].firstMatch("*** Failers"), 2725);
+  assertNull(res[877].firstMatch("qqq\nabc"), 2726);
+  assertNull(res[877].firstMatch("abc\nzzz"), 2727);
+  assertNull(res[877].firstMatch("qqq\nabc\nzzz"), 2728);
+  assertNull(res[878].firstMatch("abc\ndef"), 2729);
+  assertNull(res[879].firstMatch("*** Failers"), 2730);
+  assertNull(res[879].firstMatch("abc\ndef"), 2731);
+  assertToStringEquals("b", res[880].firstMatch("b::c"), 2732);
+  assertToStringEquals("::", res[880].firstMatch("c::b"), 2733);
+  assertToStringEquals("az-", res[881].firstMatch("az-"), 2734);
+  assertToStringEquals("a", res[881].firstMatch("*** Failers"), 2735);
+  assertNull(res[881].firstMatch("b"), 2736);
+  assertToStringEquals("za-", res[882].firstMatch("za-"), 2737);
+  assertToStringEquals("a", res[882].firstMatch("*** Failers"), 2738);
+  assertNull(res[882].firstMatch("b"), 2739);
+  assertToStringEquals("a-z", res[883].firstMatch("a-z"), 2740);
+  assertToStringEquals("a", res[883].firstMatch("*** Failers"), 2741);
+  assertNull(res[883].firstMatch("b"), 2742);
+  assertToStringEquals("abcdxyz", res[884].firstMatch("abcdxyz"), 2743);
+  assertToStringEquals("12-34", res[885].firstMatch("12-34"), 2744);
+  assertNull(res[885].firstMatch("*** Failers"), 2745);
+  assertNull(res[885].firstMatch("aaa"), 2746);
+  assertToStringEquals("12-34z", res[886].firstMatch("12-34z"), 2747);
+  assertNull(res[886].firstMatch("*** Failers"), 2748);
+  assertNull(res[886].firstMatch("aaa"), 2749);
+  assertToStringEquals("\\", res[887].firstMatch("\\\\"), 2750);
+  assertToStringEquals(" Z", res[888].firstMatch("the Zoo"), 2751);
+  assertNull(res[888].firstMatch("*** Failers"), 2752);
+  assertNull(res[888].firstMatch("Zulu"), 2753);
+  assertToStringEquals("ab{3cd", res[889].firstMatch("ab{3cd"), 2754);
+  assertToStringEquals("ab{3,cd", res[890].firstMatch("ab{3,cd"), 2755);
+  assertToStringEquals("ab{3,4a}cd", res[891].firstMatch("ab{3,4a}cd"), 2756);
+  assertToStringEquals("{4,5a}bc", res[892].firstMatch("{4,5a}bc"), 2757);
+  assertNull(res[893].firstMatch("a\x0db"), 2758);
+  assertNull(res[893].firstMatch("*** Failers"), 2759);
+  assertNull(res[893].firstMatch("a\nb"), 2760);
+  assertToStringEquals("abc", res[894].firstMatch("abc"), 2761);
+  assertNull(res[894].firstMatch("abc\n"), 2762);
+  assertNull(res[894].firstMatch("*** Failers"), 2763);
+  assertNull(res[894].firstMatch("abc\ndef"), 2764);
+  assertToStringEquals("abcS,abc", res[895].firstMatch("abcS"), 2765);
+  assertToStringEquals("abc\x93,abc", res[896].firstMatch("abc\x93"), 2766);
+  assertToStringEquals("abc\xd3,abc", res[897].firstMatch("abc\xd3"), 2767);
+  assertToStringEquals("abc@,abc", res[898].firstMatch("abc@"), 2768);
+  assertToStringEquals("abc@,abc", res[898].firstMatch("abc@"), 2769);
+  assertToStringEquals("abc@,abc", res[898].firstMatch("abc@0"), 2770);
+  assertToStringEquals("abc@,abc", res[898].firstMatch("abc@0"), 2771);
+  assertToStringEquals("abc@,abc", res[898].firstMatch("abc@0"), 2772);
+  assertToStringEquals("abc@,abc", res[898].firstMatch("abc@0"), 2773);
+  assertToStringEquals("abc@,abc", res[898].firstMatch("abc@0"), 2774);
+  assertToStringEquals("abc@,abc", res[898].firstMatch("abc@0"), 2775);
+  assertNull(res[899].firstMatch("abc\x0081"), 2776);
+  assertNull(res[899].firstMatch("abc\x0081"), 2777);
+  assertNull(res[900].firstMatch("abc\x0091"), 2778);
+  assertNull(res[900].firstMatch("abc\x0091"), 2779);
+  assertToStringEquals("abcdefghijk\nS,a,b,c,d,e,f,g,h,i,j,k", res[901].firstMatch("abcdefghijk\nS"), 2780);
+  assertToStringEquals("abidef", res[902].firstMatch("abidef"), 2781);
+  assertToStringEquals("bc", res[903].firstMatch("bc"), 2782);
+  assertToStringEquals("xyz,,", res[904].firstMatch("xyz"), 2783);
+  assertToStringEquals("abc\x08de", res[905].firstMatch("abc\x08de"), 2784);
+  assertToStringEquals("abc\x01de", res[906].firstMatch("abc\x01de"), 2785);
+  assertToStringEquals("abc\x01de,abc", res[907].firstMatch("abc\x01de"), 2786);
+  assertNull(res[907].firstMatch("a\nb"), 2787);
+  assertToStringEquals("baNOTcccc,b,a,NOT,cccc", res[908].firstMatch("baNOTccccd"), 2788);
+  assertToStringEquals("baNOTccc,b,a,NOT,ccc", res[908].firstMatch("baNOTcccd"), 2789);
+  assertToStringEquals("baNOTcc,b,a,NO,Tcc", res[908].firstMatch("baNOTccd"), 2790);
+  assertToStringEquals("baccc,b,a,,ccc", res[908].firstMatch("bacccd"), 2791);
+  assertToStringEquals("*** Failers,*,*,* Fail,ers", res[908].firstMatch("*** Failers"), 2792);
+  assertNull(res[908].firstMatch("anything"), 2793);
+  assertNull(res[908].firstMatch("b\x08c   "), 2794);
+  assertNull(res[908].firstMatch("baccd"), 2795);
+  assertToStringEquals("A", res[909].firstMatch("Abc"), 2796);
+  assertToStringEquals("b", res[910].firstMatch("Abc "), 2797);
+  assertToStringEquals("AAA", res[911].firstMatch("AAAaAbc"), 2798);
+  assertToStringEquals("bc ", res[912].firstMatch("AAAaAbc "), 2799);
+  assertToStringEquals("bbb\nccc", res[913].firstMatch("bbb\nccc"), 2800);
+  assertToStringEquals("c", res[914].firstMatch("abc"), 2801);
+  assertToStringEquals("s", res[914].firstMatch("*** Failers"), 2802);
+  assertToStringEquals(" ", res[914].firstMatch("abk   "), 2803);
+  assertToStringEquals("abc", res[915].firstMatch("abc"), 2804);
+  assertToStringEquals("bc", res[915].firstMatch("kbc"), 2805);
+  assertToStringEquals("bc ", res[915].firstMatch("kabc "), 2806);
+  assertToStringEquals("ers", res[915].firstMatch("*** Failers"), 2807);
+  assertNull(res[915].firstMatch("abk"), 2808);
+  assertNull(res[915].firstMatch("akb"), 2809);
+  assertNull(res[915].firstMatch("akk "), 2810);
+  assertToStringEquals("12345678@a.b.c.d", res[916].firstMatch("12345678@a.b.c.d"), 2811);
+  assertToStringEquals("123456789@x.y.z", res[916].firstMatch("123456789@x.y.z"), 2812);
+  assertNull(res[916].firstMatch("*** Failers"), 2813);
+  assertNull(res[916].firstMatch("12345678@x.y.uk"), 2814);
+  assertNull(res[916].firstMatch("1234567@a.b.c.d       "), 2815);
+  assertToStringEquals("b", res[917].firstMatch("aaaabcd"), 2816);
+  assertToStringEquals("A", res[917].firstMatch("aaAabcd "), 2817);
+  assertToStringEquals("b", res[918].firstMatch("aaaabcd"), 2818);
+  assertToStringEquals("b", res[918].firstMatch("aaAabcd "), 2819);
+  assertToStringEquals("b", res[919].firstMatch("aaaabcd"), 2820);
+  assertToStringEquals("A", res[919].firstMatch("aaAabcd "), 2821);
+  assertToStringEquals("b", res[920].firstMatch("aaaabcd"), 2822);
+  assertToStringEquals("b", res[920].firstMatch("aaAabcd "), 2823);
+  assertToStringEquals("PSTAIREISLL", res[922].firstMatch("xxxxxxxxxxxPSTAIREISLLxxxxxxxxx"), 2824);
+  assertToStringEquals("PSTAIREISLL", res[923].firstMatch("xxxxxxxxxxxPSTAIREISLLxxxxxxxxx"), 2825);
+  assertToStringEquals(".230003938,.23", res[924].firstMatch("1.230003938"), 2826);
+  assertToStringEquals(".875000282,.875", res[924].firstMatch("1.875000282   "), 2827);
+  assertToStringEquals(".235,.23", res[924].firstMatch("1.235  "), 2828);
+  assertNull(res[924].firstMatch("              "), 2829);
+  assertToStringEquals(".23,.23,", res[925].firstMatch("1.230003938      "), 2830);
+  assertToStringEquals(".875,.875,5", res[925].firstMatch("1.875000282"), 2831);
+  assertNull(res[925].firstMatch("*** Failers "), 2832);
+  assertNull(res[925].firstMatch("1.235 "), 2833);
+  assertThrows(() => new RegExp(r"a(?)b"), 2834);
+  assertNull(res[925].firstMatch("ab "), 2835);
+  assertToStringEquals("foo table,foo,table", res[926].firstMatch("Food is on the foo table"), 2836);
+  assertToStringEquals("food is under the bar in the bar,d is under the bar in the ", res[927].firstMatch("The food is under the bar in the barn."), 2837);
+  assertToStringEquals("food is under the bar,d is under the ", res[928].firstMatch("The food is under the bar in the barn."), 2838);
+  assertToStringEquals("I have 2 numbers: 53147,I have 2 numbers: 53147,", res[929].firstMatch("I have 2 numbers: 53147"), 2839);
+  assertToStringEquals("I have 2 numbers: 53147,I have 2 numbers: 5314,7", res[930].firstMatch("I have 2 numbers: 53147"), 2840);
+  assertToStringEquals(",,", res[931].firstMatch("I have 2 numbers: 53147"), 2841);
+  assertToStringEquals("I have 2,I have ,2", res[932].firstMatch("I have 2 numbers: 53147"), 2842);
+  assertToStringEquals("I have 2 numbers: 53147,I have 2 numbers: 5314,7", res[933].firstMatch("I have 2 numbers: 53147"), 2843);
+  assertToStringEquals("I have 2 numbers: 53147,I have 2 numbers: ,53147", res[934].firstMatch("I have 2 numbers: 53147"), 2844);
+  assertToStringEquals("I have 2 numbers: 53147,I have 2 numbers: ,53147", res[935].firstMatch("I have 2 numbers: 53147"), 2845);
+  assertToStringEquals("I have 2 numbers: 53147,I have 2 numbers: ,53147", res[936].firstMatch("I have 2 numbers: 53147"), 2846);
+  assertToStringEquals("AB", res[937].firstMatch("ABC123"), 2847);
+  assertToStringEquals(" ", res[937].firstMatch(" "), 2848);
+  assertToStringEquals("ABC,ABC", res[938].firstMatch("ABC445"), 2849);
+  assertNull(res[938].firstMatch("*** Failers"), 2850);
+  assertNull(res[938].firstMatch("ABC123"), 2851);
+  assertToStringEquals("W46]", res[939].firstMatch("W46]789 "), 2852);
+  assertToStringEquals("-46]", res[939].firstMatch("-46]789"), 2853);
+  assertNull(res[939].firstMatch("*** Failers"), 2854);
+  assertNull(res[939].firstMatch("Wall"), 2855);
+  assertNull(res[939].firstMatch("Zebra"), 2856);
+  assertNull(res[939].firstMatch("42"), 2857);
+  assertNull(res[939].firstMatch("[abcd] "), 2858);
+  assertNull(res[939].firstMatch("]abcd["), 2859);
+  assertNull(res[939].firstMatch("   "), 2860);
+  assertToStringEquals("W", res[940].firstMatch("W46]789 "), 2861);
+  assertToStringEquals("W", res[940].firstMatch("Wall"), 2862);
+  assertToStringEquals("Z", res[940].firstMatch("Zebra"), 2863);
+  assertToStringEquals("X", res[940].firstMatch("Xylophone  "), 2864);
+  assertToStringEquals("4", res[940].firstMatch("42"), 2865);
+  assertToStringEquals("[", res[940].firstMatch("[abcd] "), 2866);
+  assertToStringEquals("]", res[940].firstMatch("]abcd["), 2867);
+  assertToStringEquals("\\", res[940].firstMatch("\\backslash "), 2868);
+  assertNull(res[940].firstMatch("*** Failers"), 2869);
+  assertNull(res[940].firstMatch("-46]789"), 2870);
+  assertNull(res[940].firstMatch("well"), 2871);
+  assertToStringEquals("01/01/2000", res[941].firstMatch("01/01/2000"), 2872);
+  assertToStringEquals("01/01/2000", res[941].firstMatch("01/01/2000"), 2872);
+  assertToStringEquals(",", res[944].firstMatch("bcd"), 2873);
+  assertToStringEquals(",", res[944].firstMatch("abc"), 2874);
+  assertToStringEquals(",", res[944].firstMatch("aab     "), 2875);
+  assertToStringEquals(",", res[945].firstMatch("bcd"), 2876);
+  assertToStringEquals("a,a", res[945].firstMatch("abc"), 2877);
+  assertToStringEquals("a,a", res[945].firstMatch("aab  "), 2878);
+  assertToStringEquals(",", res[946].firstMatch("bcd"), 2879);
+  assertToStringEquals("a,a", res[946].firstMatch("abc"), 2880);
+  assertToStringEquals("aa,a", res[946].firstMatch("aab  "), 2881);
+  assertToStringEquals(",", res[947].firstMatch("bcd"), 2882);
+  assertToStringEquals("a,a", res[947].firstMatch("abc"), 2883);
+  assertToStringEquals("aa,a", res[947].firstMatch("aab"), 2884);
+  assertToStringEquals("aaa,a", res[947].firstMatch("aaa   "), 2885);
+  assertToStringEquals(",", res[948].firstMatch("bcd"), 2886);
+  assertToStringEquals("a,a", res[948].firstMatch("abc"), 2887);
+  assertToStringEquals("aa,a", res[948].firstMatch("aab"), 2888);
+  assertToStringEquals("aaa,a", res[948].firstMatch("aaa"), 2889);
+  assertToStringEquals("aaaaaaaa,a", res[948].firstMatch("aaaaaaaa    "), 2890);
+  assertNull(res[949].firstMatch("bcd"), 2891);
+  assertToStringEquals("a,a", res[949].firstMatch("abc"), 2892);
+  assertToStringEquals("a,a", res[949].firstMatch("aab  "), 2893);
+  assertNull(res[950].firstMatch("bcd"), 2894);
+  assertToStringEquals("a,a", res[950].firstMatch("abc"), 2895);
+  assertToStringEquals("aa,a", res[950].firstMatch("aab  "), 2896);
+  assertNull(res[951].firstMatch("bcd"), 2897);
+  assertToStringEquals("a,a", res[951].firstMatch("abc"), 2898);
+  assertToStringEquals("aa,a", res[951].firstMatch("aab"), 2899);
+  assertToStringEquals("aaa,a", res[951].firstMatch("aaa   "), 2900);
+  assertNull(res[952].firstMatch("bcd"), 2901);
+  assertToStringEquals("a,a", res[952].firstMatch("abc"), 2902);
+  assertToStringEquals("aa,a", res[952].firstMatch("aab"), 2903);
+  assertToStringEquals("aaa,a", res[952].firstMatch("aaa"), 2904);
+  assertToStringEquals("aaaaaaaa,a", res[952].firstMatch("aaaaaaaa    "), 2905);
+  assertToStringEquals("bib.gif", res[953].firstMatch("borfle\nbib.gif\nno"), 2906);
+  assertToStringEquals("bib.gif", res[954].firstMatch("borfle\nbib.gif\nno"), 2907);
+  assertToStringEquals("bib.gif", res[955].firstMatch("borfle\nbib.gif\nno"), 2908);
+  assertToStringEquals("bib.gif", res[956].firstMatch("borfle\nbib.gif\nno"), 2909);
+  assertToStringEquals("bib.gif", res[957].firstMatch("borfle\nbib.gif\nno"), 2910);
+  assertToStringEquals("no", res[958].firstMatch("borfle\nbib.gif\nno"), 2911);
+  assertToStringEquals("borfle", res[959].firstMatch("borfle\nbib.gif\nno"), 2912);
+  assertToStringEquals("no", res[960].firstMatch("borfle\nbib.gif\nno"), 2913);
+  assertToStringEquals("borfle", res[961].firstMatch("borfle\nbib.gif\nno"), 2914);
+  assertToStringEquals("", res[962].firstMatch("borfle\nbib.gif\nno\n"), 2915);
+  assertToStringEquals("borfle", res[963].firstMatch("borfle\nbib.gif\nno\n"), 2916);
+  assertToStringEquals("", res[964].firstMatch("borfle\nbib.gif\nno\n"), 2917);
+  assertToStringEquals("borfle", res[965].firstMatch("borfle\nbib.gif\nno\n"), 2918);
+  assertToStringEquals("1234X,1234X", res[966].firstMatch("abcde\n1234Xyz"), 2919);
+  assertToStringEquals("B,B", res[966].firstMatch("BarFoo "), 2920);
+  assertNull(res[966].firstMatch("*** Failers"), 2921);
+  assertNull(res[966].firstMatch("abcde\nBar  "), 2922);
+  assertToStringEquals("1234X,1234X", res[967].firstMatch("abcde\n1234Xyz"), 2923);
+  assertToStringEquals("B,B", res[967].firstMatch("BarFoo "), 2924);
+  assertToStringEquals("B,B", res[967].firstMatch("abcde\nBar  "), 2925);
+  assertToStringEquals("1234X,1234X", res[968].firstMatch("abcde\n1234Xyz"), 2926);
+  assertToStringEquals("B,B", res[968].firstMatch("BarFoo "), 2927);
+  assertNull(res[968].firstMatch("*** Failers"), 2928);
+  assertNull(res[968].firstMatch("abcde\nBar  "), 2929);
+  assertToStringEquals("1234X,1234X", res[969].firstMatch("abcde\n1234Xyz"), 2930);
+  assertToStringEquals("B,B", res[969].firstMatch("BarFoo "), 2931);
+  assertToStringEquals("B,B", res[969].firstMatch("abcde\nBar  "), 2932);
+  assertToStringEquals("1234X,1234X", res[969].firstMatch("abcde\n1234Xyz"), 2933);
+  assertToStringEquals("B,B", res[969].firstMatch("BarFoo "), 2934);
+  assertNull(res[969].firstMatch("*** Failers "), 2935);
+  assertToStringEquals("B,B", res[969].firstMatch("abcde\nBar  "), 2936);
+  assertToStringEquals("1234X,1234X", res[969].firstMatch("abcde\n1234Xyz"), 2937);
+  assertToStringEquals("B,B", res[969].firstMatch("BarFoo "), 2938);
+  assertNull(res[969].firstMatch("*** Failers "), 2939);
+  assertToStringEquals("B,B", res[969].firstMatch("abcde\nBar  "), 2940);
+  assertNull(res[970].firstMatch("**** Failers"), 2941);
+  assertNull(res[970].firstMatch("abc\nB"), 2942);
+  assertNull(res[970].firstMatch(" "), 2943);
+  assertNull(res[970].firstMatch("abc\nB"), 2944);
+  assertNull(res[970].firstMatch("abc\nB"), 2945);
+  assertNull(res[970].firstMatch(" "), 2946);
+  assertNull(res[970].firstMatch("abc\nB"), 2947);
+  assertNull(res[970].firstMatch("abc\nB"), 2948);
+  assertToStringEquals("B", res[970].firstMatch("B\n"), 2949);
+  assertToStringEquals("123456654321", res[971].firstMatch("123456654321"), 2950);
+  assertToStringEquals("123456654321", res[972].firstMatch("123456654321 "), 2951);
+  assertToStringEquals("123456654321", res[973].firstMatch("123456654321"), 2952);
+  assertToStringEquals("abcabcabcabc", res[974].firstMatch("abcabcabcabc"), 2953);
+  assertToStringEquals("abcabcabcabc", res[975].firstMatch("abcabcabcabc"), 2954);
+  assertToStringEquals("abcabcabcabc,c", res[976].firstMatch("abcabcabcabc "), 2955);
+  assertToStringEquals("n", res[977].firstMatch("n"), 2956);
+  assertNull(res[977].firstMatch("*** Failers "), 2957);
+  assertNull(res[977].firstMatch("z "), 2958);
+  assertToStringEquals("abcd", res[978].firstMatch("abcd"), 2959);
+  assertNull(res[978].firstMatch("*** Failers"), 2960);
+  assertNull(res[978].firstMatch("abce  "), 2961);
+  assertToStringEquals("abe", res[979].firstMatch("abe"), 2962);
+  assertNull(res[979].firstMatch("*** Failers"), 2963);
+  assertNull(res[979].firstMatch("abcde "), 2964);
+  assertToStringEquals("abd,", res[980].firstMatch("abd"), 2965);
+  assertNull(res[980].firstMatch("*** Failers"), 2966);
+  assertNull(res[980].firstMatch("abcd   "), 2967);
+  assertToStringEquals("a,", res[981].firstMatch("a"), 2968);
+  assertToStringEquals("ab,b", res[981].firstMatch("ab"), 2969);
+  assertToStringEquals("abbbb,bbbb", res[981].firstMatch("abbbb"), 2970);
+  assertToStringEquals("a,", res[981].firstMatch("*** Failers"), 2971);
+  assertNull(res[981].firstMatch("bbbbb    "), 2972);
+  assertToStringEquals("abe", res[982].firstMatch("abe"), 2973);
+  assertNull(res[982].firstMatch("*** Failers"), 2974);
+  assertNull(res[982].firstMatch("ab1e   "), 2975);
+  assertToStringEquals("\"quick\",quick", res[983].firstMatch("the \"quick\" brown fox"), 2976);
+  assertToStringEquals("\"the \\\"quick\\\" brown fox\", brown fox", res[983].firstMatch("\"the \\\"quick\\\" brown fox\" "), 2977);
+  assertToStringEquals("", res[984].firstMatch("abc"), 2978);
+  assertToStringEquals("", res[985].firstMatch("abc "), 2979);
+  assertToStringEquals("", res[986].firstMatch("abc "), 2980);
+  // Dart does not have RegExp literals and thus no translatation of the below.
+  // assertThrows("var re = //;", 2981);
+  assertToStringEquals("", res[986].firstMatch("abc"), 2982);
+  assertToStringEquals("acb", res[988].firstMatch("acb"), 2983);
+  assertToStringEquals("a\nb", res[988].firstMatch("a\nb"), 2984);
+  assertToStringEquals("acb", res[989].firstMatch("acb"), 2985);
+  assertNull(res[989].firstMatch("*** Failers "), 2986);
+  assertNull(res[989].firstMatch("a\nb   "), 2987);
+  assertToStringEquals("acb", res[990].firstMatch("acb"), 2988);
+  assertToStringEquals("a\nb", res[990].firstMatch("a\nb  "), 2989);
+  assertToStringEquals("acb", res[991].firstMatch("acb"), 2990);
+  assertNull(res[991].firstMatch("a\nb  "), 2991);
+  assertToStringEquals("bac,a", res[992].firstMatch("bac"), 2992);
+  assertToStringEquals("bbac,a", res[992].firstMatch("bbac"), 2993);
+  assertToStringEquals("bbbac,a", res[992].firstMatch("bbbac"), 2994);
+  assertToStringEquals("bbbbac,a", res[992].firstMatch("bbbbac"), 2995);
+  assertToStringEquals("bbbbbac,a", res[992].firstMatch("bbbbbac "), 2996);
+  assertToStringEquals("bac,a", res[993].firstMatch("bac"), 2997);
+  assertToStringEquals("bbac,a", res[993].firstMatch("bbac"), 2998);
+  assertToStringEquals("bbbac,a", res[993].firstMatch("bbbac"), 2999);
+  assertToStringEquals("bbbbac,a", res[993].firstMatch("bbbbac"), 3000);
+  assertToStringEquals("bbbbbac,a", res[993].firstMatch("bbbbbac "), 3001);
+  assertToStringEquals("x", res[994].firstMatch("x\nb\n"), 3002);
+  assertToStringEquals("x", res[994].firstMatch("a\x08x\n  "), 3003);
+  assertNull(res[995].firstMatch("\x00{ab} "), 3004);
+  assertToStringEquals("CD,", res[996].firstMatch("CD "), 3005);
+  assertToStringEquals("CD,", res[997].firstMatch("CD "), 3006);
+  assertNull(res[997].firstMatch("foo"), 3007);
+  assertNull(res[997].firstMatch("catfood"), 3008);
+  assertNull(res[997].firstMatch("arfootle"), 3009);
+  assertNull(res[997].firstMatch("rfoosh"), 3010);
+  assertNull(res[997].firstMatch("*** Failers"), 3011);
+  assertNull(res[997].firstMatch("barfoo"), 3012);
+  assertNull(res[997].firstMatch("towbarfoo"), 3013);
+  assertNull(res[997].firstMatch("catfood"), 3014);
+  assertNull(res[997].firstMatch("*** Failers"), 3015);
+  assertNull(res[997].firstMatch("foo"), 3016);
+  assertNull(res[997].firstMatch("barfoo"), 3017);
+  assertNull(res[997].firstMatch("towbarfoo"), 3018);
+  assertNull(res[997].firstMatch("fooabar"), 3019);
+  assertNull(res[997].firstMatch("*** Failers"), 3020);
+  assertNull(res[997].firstMatch("bar"), 3021);
+  assertNull(res[997].firstMatch("foobbar"), 3022);
+  assertNull(res[997].firstMatch("  "), 3023);
+  assertNull(res[998].firstMatch("abc"), 3024);
+  assertNull(res[998].firstMatch("*** Failers"), 3025);
+  assertNull(res[998].firstMatch("abc\n   "), 3026);
+  assertNull(res[998].firstMatch("qqq\nabc"), 3027);
+  assertNull(res[998].firstMatch("abc\nzzz"), 3028);
+  assertNull(res[998].firstMatch("qqq\nabc\nzzz"), 3029);
+  assertNull(res[998].firstMatch("/this/is/a/very/long/line/in/deed/with/very/many/slashes/in/it/you/see/"), 3030);
+  assertNull(res[998].firstMatch("/this/is/a/very/long/line/in/deed/with/very/many/slashes/in/and/foo"), 3031);
+  assertNull(res[998].firstMatch("1.230003938"), 3032);
+  assertNull(res[998].firstMatch("1.875000282"), 3033);
+  assertNull(res[998].firstMatch("*** Failers "), 3034);
+  assertNull(res[998].firstMatch("1.235 "), 3035);
+  assertNull(res[998].firstMatch("now is the time for all good men to come to the aid of the party"), 3036);
+  assertNull(res[998].firstMatch("*** Failers"), 3037);
+  assertNull(res[998].firstMatch("this is not a line with only words and spaces!"), 3038);
+  assertToStringEquals("12345a,12345,a", res[999].firstMatch("12345a"), 3039);
+  assertToStringEquals("12345,1234,5", res[999].firstMatch("12345+ "), 3040);
+  assertToStringEquals("12345a,12345,a", res[999].firstMatch("12345a"), 3041);
+  assertNull(res[999].firstMatch("*** Failers"), 3042);
+  assertToStringEquals("12345,1234,5", res[999].firstMatch("12345+ "), 3043);
+  assertNull(res[999].firstMatch("aaab"), 3044);
+  assertNull(res[999].firstMatch("aaab"), 3045);
+  assertNull(res[999].firstMatch("aaab"), 3046);
+  assertNull(res[999].firstMatch("aaabbbccc"), 3047);
+  assertNull(res[999].firstMatch("aaabbbbccccd"), 3048);
+  assertToStringEquals("aaabbbbcccc,ccc", res[1000].firstMatch("aaabbbbccccd"), 3049);
+  assertToStringEquals("abc,b", res[1000].firstMatch("((abc(ade)ufh()()x"), 3050);
+  assertNull(res[1000].firstMatch(""), 3051);
+  assertToStringEquals("abc,b", res[1000].firstMatch("(abc)"), 3052);
+  assertToStringEquals("abc,b", res[1000].firstMatch("(abc(def)xyz)"), 3053);
+  assertNull(res[1000].firstMatch("*** Failers"), 3054);
+  assertNull(res[1000].firstMatch("ab"), 3055);
+  assertNull(res[1000].firstMatch("Ab"), 3056);
+  assertNull(res[1000].firstMatch("*** Failers "), 3057);
+  assertNull(res[1000].firstMatch("aB"), 3058);
+  assertNull(res[1000].firstMatch("AB"), 3059);
+  assertNull(res[1000].firstMatch("    "), 3060);
+  assertToStringEquals("bc,b", res[1000].firstMatch("a bcd e"), 3061);
+  assertNull(res[1000].firstMatch("*** Failers"), 3062);
+  assertToStringEquals("c,", res[1000].firstMatch("a b cd e"), 3063);
+  assertToStringEquals("abc,b", res[1000].firstMatch("abcd e   "), 3064);
+  assertToStringEquals("bc,b", res[1000].firstMatch("a bcde "), 3065);
+  assertToStringEquals("bc,b", res[1000].firstMatch("a bcde f"), 3066);
+  assertNull(res[1000].firstMatch("*** Failers"), 3067);
+  assertToStringEquals("abc,b", res[1000].firstMatch("abcdef  "), 3068);
+  assertToStringEquals("abc,b", res[1000].firstMatch("abc"), 3069);
+  assertToStringEquals("c,", res[1000].firstMatch("aBc"), 3070);
+  assertNull(res[1000].firstMatch("*** Failers"), 3071);
+  assertNull(res[1000].firstMatch("abC"), 3072);
+  assertNull(res[1000].firstMatch("aBC  "), 3073);
+  assertToStringEquals("bc,b", res[1000].firstMatch("Abc"), 3074);
+  assertToStringEquals("c,", res[1000].firstMatch("ABc"), 3075);
+  assertNull(res[1000].firstMatch("ABC"), 3076);
+  assertNull(res[1000].firstMatch("AbC"), 3077);
+  assertNull(res[1000].firstMatch(""), 3078);
+  assertToStringEquals("abc,b", res[1000].firstMatch("abc"), 3079);
+  assertToStringEquals("c,", res[1000].firstMatch("aBc"), 3080);
+  assertNull(res[1000].firstMatch("*** Failers "), 3081);
+  assertNull(res[1000].firstMatch("ABC"), 3082);
+  assertNull(res[1000].firstMatch("abC"), 3083);
+  assertNull(res[1000].firstMatch("aBC"), 3084);
+  assertNull(res[1000].firstMatch(""), 3085);
+  assertToStringEquals("c,", res[1000].firstMatch("aBc"), 3086);
+  assertToStringEquals("c,", res[1000].firstMatch("aBBc"), 3087);
+  assertNull(res[1000].firstMatch("*** Failers "), 3088);
+  assertNull(res[1000].firstMatch("aBC"), 3089);
+  assertNull(res[1000].firstMatch("aBBC"), 3090);
+  assertNull(res[1000].firstMatch(""), 3091);
+  assertToStringEquals("abc,b", res[1000].firstMatch("abcd"), 3092);
+  assertNull(res[1000].firstMatch("abCd"), 3093);
+  assertNull(res[1000].firstMatch("*** Failers"), 3094);
+  assertNull(res[1000].firstMatch("aBCd"), 3095);
+  assertToStringEquals("abc,b", res[1000].firstMatch("abcD     "), 3096);
+  assertNull(res[1000].firstMatch(""), 3097);
+  assertNull(res[1000].firstMatch("more than million"), 3098);
+  assertNull(res[1000].firstMatch("more than MILLION"), 3099);
+  assertNull(res[1000].firstMatch("more \n than Million "), 3100);
+  assertNull(res[1000].firstMatch("*** Failers"), 3101);
+  assertNull(res[1000].firstMatch("MORE THAN MILLION    "), 3102);
+  assertNull(res[1000].firstMatch("more \n than \n million "), 3103);
+  assertNull(res[1000].firstMatch("more than million"), 3104);
+  assertNull(res[1000].firstMatch("more than MILLION"), 3105);
+  assertNull(res[1000].firstMatch("more \n than Million "), 3106);
+  assertNull(res[1000].firstMatch("*** Failers"), 3107);
+  assertNull(res[1000].firstMatch("MORE THAN MILLION    "), 3108);
+  assertNull(res[1000].firstMatch("more \n than \n million "), 3109);
+  assertNull(res[1000].firstMatch(""), 3110);
+  assertToStringEquals("abc,b", res[1000].firstMatch("abc"), 3111);
+  assertToStringEquals("bc,b", res[1000].firstMatch("aBbc"), 3112);
+  assertToStringEquals("c,", res[1000].firstMatch("aBBc "), 3113);
+  assertNull(res[1000].firstMatch("*** Failers"), 3114);
+  assertToStringEquals("bc,b", res[1000].firstMatch("Abc"), 3115);
+  assertNull(res[1000].firstMatch("abAb    "), 3116);
+  assertNull(res[1000].firstMatch("abbC "), 3117);
+  assertNull(res[1000].firstMatch(""), 3118);
+  assertToStringEquals("abc,b", res[1000].firstMatch("abc"), 3119);
+  assertToStringEquals("c,", res[1000].firstMatch("aBc"), 3120);
+  assertNull(res[1000].firstMatch("*** Failers"), 3121);
+  assertNull(res[1000].firstMatch("Ab "), 3122);
+  assertNull(res[1000].firstMatch("abC"), 3123);
+  assertNull(res[1000].firstMatch("aBC     "), 3124);
+  assertNull(res[1000].firstMatch(""), 3125);
+  assertToStringEquals("c,", res[1000].firstMatch("abxxc"), 3126);
+  assertToStringEquals("c,", res[1000].firstMatch("aBxxc"), 3127);
+  assertNull(res[1000].firstMatch("*** Failers"), 3128);
+  assertToStringEquals("c,", res[1000].firstMatch("Abxxc"), 3129);
+  assertToStringEquals("c,", res[1000].firstMatch("ABxxc"), 3130);
+  assertNull(res[1000].firstMatch("abxxC      "), 3131);
+  assertToStringEquals("abc,b", res[1000].firstMatch("abc:"), 3132);
+  assertNull(res[1000].firstMatch("12"), 3133);
+  assertNull(res[1000].firstMatch("*** Failers"), 3134);
+  assertNull(res[1000].firstMatch("123"), 3135);
+  assertNull(res[1000].firstMatch("xyz    "), 3136);
+  assertToStringEquals("abc,b", res[1000].firstMatch("abc:"), 3137);
+  assertNull(res[1000].firstMatch("12"), 3138);
+  assertNull(res[1000].firstMatch("*** Failers"), 3139);
+  assertNull(res[1000].firstMatch("123"), 3140);
+  assertNull(res[1000].firstMatch("xyz    "), 3141);
+  assertNull(res[1000].firstMatch(""), 3142);
+  assertNull(res[1000].firstMatch("foobar"), 3143);
+  assertToStringEquals("c,", res[1000].firstMatch("cat"), 3144);
+  assertToStringEquals("c,", res[1000].firstMatch("fcat"), 3145);
+  assertToStringEquals("c,", res[1000].firstMatch("focat   "), 3146);
+  assertNull(res[1000].firstMatch("*** Failers"), 3147);
+  assertToStringEquals("c,", res[1000].firstMatch("foocat  "), 3148);
+  assertNull(res[1000].firstMatch("foobar"), 3149);
+  assertToStringEquals("c,", res[1000].firstMatch("cat"), 3150);
+  assertToStringEquals("c,", res[1000].firstMatch("fcat"), 3151);
+  assertToStringEquals("c,", res[1000].firstMatch("focat   "), 3152);
+  assertNull(res[1000].firstMatch("*** Failers"), 3153);
+  assertToStringEquals("c,", res[1000].firstMatch("foocat  "), 3154);
+  assertNull(res[1000].firstMatch("a"), 3155);
+  assertNull(res[1000].firstMatch("aa"), 3156);
+  assertNull(res[1000].firstMatch("aaaa"), 3157);
+  assertNull(res[1000].firstMatch(""), 3158);
+  assertToStringEquals("abc,abc", res[1001].firstMatch("abc"), 3159);
+  assertToStringEquals("abcabc,abc", res[1001].firstMatch("abcabc"), 3160);
+  assertToStringEquals("abcabcabc,abc", res[1001].firstMatch("abcabcabc"), 3161);
+  assertToStringEquals(",", res[1001].firstMatch("xyz      "), 3162);
+  assertToStringEquals("a,a", res[1002].firstMatch("a"), 3163);
+  assertToStringEquals("aaaaa,aaaaa", res[1002].firstMatch("aaaaa "), 3164);
+  assertToStringEquals("a,a", res[1003].firstMatch("a"), 3165);
+  assertToStringEquals("b,b", res[1003].firstMatch("b"), 3166);
+  assertToStringEquals("ababab,ababab", res[1003].firstMatch("ababab"), 3167);
+  assertToStringEquals("aaaab,aaaab", res[1003].firstMatch("aaaabcde"), 3168);
+  assertToStringEquals("bbbb,bbbb", res[1003].firstMatch("bbbb    "), 3169);
+  assertToStringEquals("b,b", res[1004].firstMatch("b"), 3170);
+  assertToStringEquals("bbbb,bbbb", res[1004].firstMatch("bbbb"), 3171);
+  assertToStringEquals(",", res[1004].firstMatch("aaa   "), 3172);
+  assertToStringEquals("cccc,cccc", res[1005].firstMatch("cccc"), 3173);
+  assertToStringEquals(",", res[1005].firstMatch("abab  "), 3174);
+  assertToStringEquals("a,a", res[1006].firstMatch("a"), 3175);
+  assertToStringEquals("aaaa,a", res[1006].firstMatch("aaaa "), 3176);
+  assertToStringEquals("a,a", res[1007].firstMatch("a"), 3177);
+  assertToStringEquals("b,b", res[1007].firstMatch("b"), 3178);
+  assertToStringEquals("abab,b", res[1007].firstMatch("abab"), 3179);
+  assertToStringEquals("baba,a", res[1007].firstMatch("baba   "), 3180);
+  assertToStringEquals("b,b", res[1008].firstMatch("b"), 3181);
+  assertToStringEquals("bbbb,b", res[1008].firstMatch("bbbb"), 3182);
+  assertToStringEquals(",", res[1008].firstMatch("aaa   "), 3183);
+  assertToStringEquals("c,c", res[1009].firstMatch("c"), 3184);
+  assertToStringEquals("cccc,c", res[1009].firstMatch("cccc"), 3185);
+  assertToStringEquals(",", res[1009].firstMatch("baba   "), 3186);
+  assertToStringEquals(",", res[1009].firstMatch("a"), 3187);
+  assertToStringEquals(",", res[1009].firstMatch("aaabcde "), 3188);
+  assertToStringEquals(",", res[1009].firstMatch("aaaaa"), 3189);
+  assertToStringEquals(",", res[1009].firstMatch("aabbaa "), 3190);
+  assertToStringEquals(",", res[1009].firstMatch("aaaaa"), 3191);
+  assertToStringEquals(",", res[1009].firstMatch("aabbaa "), 3192);
+  assertToStringEquals("12-sep-98,8", res[1009].firstMatch("12-sep-98"), 3193);
+  assertToStringEquals("12-09-98,8", res[1009].firstMatch("12-09-98"), 3194);
+  assertToStringEquals("*** F,F", res[1009].firstMatch("*** Failers"), 3195);
+  assertToStringEquals("sep-12-98,8", res[1009].firstMatch("sep-12-98"), 3196);
+  assertToStringEquals("    , ", res[1009].firstMatch("    "), 3197);
+  assertToStringEquals("s,s", res[1009].firstMatch("saturday"), 3198);
+  assertToStringEquals("sund,d", res[1009].firstMatch("sunday"), 3199);
+  assertToStringEquals("S,S", res[1009].firstMatch("Saturday"), 3200);
+  assertToStringEquals("Sund,d", res[1009].firstMatch("Sunday"), 3201);
+  assertToStringEquals("SATURDAY,Y", res[1009].firstMatch("SATURDAY"), 3202);
+  assertToStringEquals("SUNDAY,Y", res[1009].firstMatch("SUNDAY"), 3203);
+  assertToStringEquals("SunD,D", res[1009].firstMatch("SunDay"), 3204);
+  assertToStringEquals(",", res[1009].firstMatch("abcx"), 3205);
+  assertToStringEquals(",", res[1009].firstMatch("aBCx"), 3206);
+  assertToStringEquals(",", res[1009].firstMatch("bbx"), 3207);
+  assertToStringEquals("BBx,x", res[1009].firstMatch("BBx"), 3208);
+  assertToStringEquals("*** F,F", res[1009].firstMatch("*** Failers"), 3209);
+  assertToStringEquals(",", res[1009].firstMatch("abcX"), 3210);
+  assertToStringEquals(",", res[1009].firstMatch("aBCX"), 3211);
+  assertToStringEquals(",", res[1009].firstMatch("bbX"), 3212);
+  assertToStringEquals("BBX               , ", res[1009].firstMatch("BBX               "), 3213);
+  assertToStringEquals(",", res[1009].firstMatch("ac"), 3214);
+  assertToStringEquals(",", res[1009].firstMatch("aC"), 3215);
+  assertToStringEquals(",", res[1009].firstMatch("bD"), 3216);
+  assertToStringEquals("eleph,h", res[1009].firstMatch("elephant"), 3217);
+  assertToStringEquals("Europe , ", res[1009].firstMatch("Europe "), 3218);
+  assertToStringEquals("frog,g", res[1009].firstMatch("frog"), 3219);
+  assertToStringEquals("Fr,r", res[1009].firstMatch("France"), 3220);
+  assertToStringEquals("*** F,F", res[1009].firstMatch("*** Failers"), 3221);
+  assertToStringEquals("Afric,c", res[1009].firstMatch("Africa     "), 3222);
+  assertToStringEquals(",", res[1009].firstMatch("ab"), 3223);
+  assertToStringEquals(",", res[1009].firstMatch("aBd"), 3224);
+  assertToStringEquals("xy,y", res[1009].firstMatch("xy"), 3225);
+  assertToStringEquals("xY,Y", res[1009].firstMatch("xY"), 3226);
+  assertToStringEquals("ze,e", res[1009].firstMatch("zebra"), 3227);
+  assertToStringEquals("Z,Z", res[1009].firstMatch("Zambesi"), 3228);
+  assertToStringEquals("*** F,F", res[1009].firstMatch("*** Failers"), 3229);
+  assertToStringEquals(",", res[1009].firstMatch("aCD  "), 3230);
+  assertToStringEquals("XY  , ", res[1009].firstMatch("XY  "), 3231);
+  assertToStringEquals("foo\n,\n", res[1009].firstMatch("foo\nbar"), 3232);
+  assertToStringEquals("*** F,F", res[1009].firstMatch("*** Failers"), 3233);
+  assertToStringEquals(",", res[1009].firstMatch("bar"), 3234);
+  assertToStringEquals(",", res[1009].firstMatch("baz\nbar   "), 3235);
+  assertToStringEquals(",", res[1009].firstMatch("barbaz"), 3236);
+  assertToStringEquals(",", res[1009].firstMatch("barbarbaz "), 3237);
+  assertToStringEquals("koo,o", res[1009].firstMatch("koobarbaz "), 3238);
+  assertToStringEquals("*** F,F", res[1009].firstMatch("*** Failers"), 3239);
+  assertToStringEquals(",", res[1009].firstMatch("baz"), 3240);
+  assertToStringEquals("foo,o", res[1009].firstMatch("foobarbaz "), 3241);
+  assertToStringEquals("abc", res[1012].firstMatch("abc"), 3242);
+  assertToStringEquals("abc", res[1012].firstMatch("xabcy"), 3243);
+  assertToStringEquals("abc", res[1012].firstMatch("ababc"), 3244);
+  assertNull(res[1012].firstMatch("*** Failers"), 3245);
+  assertNull(res[1012].firstMatch("xbc"), 3246);
+  assertNull(res[1012].firstMatch("axc"), 3247);
+  assertNull(res[1012].firstMatch("abx"), 3248);
+  assertToStringEquals("abc", res[1013].firstMatch("abc"), 3249);
+  assertToStringEquals("abc", res[1014].firstMatch("abc"), 3250);
+  assertToStringEquals("abbc", res[1014].firstMatch("abbc"), 3251);
+  assertToStringEquals("abbbbc", res[1014].firstMatch("abbbbc"), 3252);
+  assertToStringEquals("a", res[1015].firstMatch("abbbbc"), 3253);
+  assertToStringEquals("abbb", res[1016].firstMatch("abbbbc"), 3254);
+  assertToStringEquals("abbbbc", res[1017].firstMatch("abbbbc"), 3255);
+  assertToStringEquals("abbc", res[1018].firstMatch("abbc"), 3256);
+  assertNull(res[1018].firstMatch("*** Failers"), 3257);
+  assertNull(res[1018].firstMatch("abc"), 3258);
+  assertNull(res[1018].firstMatch("abq"), 3259);
+  assertToStringEquals("abbbbc", res[1020].firstMatch("abbbbc"), 3260);
+  assertToStringEquals("abbbbc", res[1021].firstMatch("abbbbc"), 3261);
+  assertToStringEquals("abbbbc", res[1022].firstMatch("abbbbc"), 3262);
+  assertToStringEquals("abbbbc", res[1023].firstMatch("abbbbc"), 3263);
+  assertNull(res[1024].firstMatch("*** Failers"), 3264);
+  assertNull(res[1024].firstMatch("abq"), 3265);
+  assertNull(res[1024].firstMatch("abbbbc"), 3266);
+  assertToStringEquals("abbc", res[1025].firstMatch("abbc"), 3267);
+  assertToStringEquals("abc", res[1025].firstMatch("abc"), 3268);
+  assertToStringEquals("abc", res[1026].firstMatch("abc"), 3269);
+  assertToStringEquals("abc", res[1028].firstMatch("abc"), 3270);
+  assertToStringEquals("abc", res[1029].firstMatch("abc"), 3271);
+  assertToStringEquals("abc", res[1030].firstMatch("abc"), 3272);
+  assertNull(res[1030].firstMatch("*** Failers"), 3273);
+  assertNull(res[1030].firstMatch("abbbbc"), 3274);
+  assertNull(res[1030].firstMatch("abcc"), 3275);
+  assertToStringEquals("abc", res[1031].firstMatch("abcc"), 3276);
+  assertToStringEquals("abc", res[1033].firstMatch("aabc"), 3277);
+  assertNull(res[1033].firstMatch("*** Failers"), 3278);
+  assertToStringEquals("abc", res[1033].firstMatch("aabc"), 3279);
+  assertNull(res[1033].firstMatch("aabcd"), 3280);
+  assertToStringEquals("", res[1034].firstMatch("abc"), 3281);
+  assertToStringEquals("", res[1035].firstMatch("abc"), 3282);
+  assertToStringEquals("abc", res[1036].firstMatch("abc"), 3283);
+  assertToStringEquals("axc", res[1036].firstMatch("axc"), 3284);
+  assertToStringEquals("axyzc", res[1037].firstMatch("axyzc"), 3285);
+  assertToStringEquals("abd", res[1038].firstMatch("abd"), 3286);
+  assertNull(res[1038].firstMatch("*** Failers"), 3287);
+  assertNull(res[1038].firstMatch("axyzd"), 3288);
+  assertNull(res[1038].firstMatch("abc"), 3289);
+  assertToStringEquals("ace", res[1039].firstMatch("ace"), 3290);
+  assertToStringEquals("ac", res[1040].firstMatch("aac"), 3291);
+  assertToStringEquals("a-", res[1041].firstMatch("a-"), 3292);
+  assertToStringEquals("a-", res[1042].firstMatch("a-"), 3293);
+  assertToStringEquals("a]", res[1043].firstMatch("a]"), 3294);
+  assertNull(res[1044].firstMatch("a]b"), 3295);
+  assertToStringEquals("aed", res[1045].firstMatch("aed"), 3296);
+  assertNull(res[1045].firstMatch("*** Failers"), 3297);
+  assertNull(res[1045].firstMatch("abd"), 3298);
+  assertNull(res[1045].firstMatch("abd"), 3299);
+  assertToStringEquals("adc", res[1046].firstMatch("adc"), 3300);
+  assertNull(res[1047].firstMatch("adc"), 3301);
+  assertNull(res[1047].firstMatch("*** Failers"), 3302);
+  assertNull(res[1047].firstMatch("a-c"), 3303);
+  assertNull(res[1047].firstMatch("a]c"), 3304);
+  assertToStringEquals("a", res[1048].firstMatch("a-"), 3305);
+  assertToStringEquals("a", res[1048].firstMatch("-a"), 3306);
+  assertToStringEquals("a", res[1048].firstMatch("-a-"), 3307);
+  assertNull(res[1049].firstMatch("*** Failers"), 3308);
+  assertNull(res[1049].firstMatch("xy"), 3309);
+  assertNull(res[1049].firstMatch("yz"), 3310);
+  assertNull(res[1049].firstMatch("xyz"), 3311);
+  assertToStringEquals("a", res[1050].firstMatch("*** Failers"), 3312);
+  assertNull(res[1050].firstMatch("a-"), 3313);
+  assertNull(res[1050].firstMatch("-a"), 3314);
+  assertNull(res[1050].firstMatch("-a-"), 3315);
+  assertToStringEquals("y", res[1051].firstMatch("xy"), 3316);
+  assertToStringEquals("y", res[1052].firstMatch("yz"), 3317);
+  assertToStringEquals("y", res[1053].firstMatch("xyz"), 3318);
+  assertToStringEquals("a", res[1054].firstMatch("a"), 3319);
+  assertToStringEquals("-", res[1055].firstMatch("-"), 3320);
+  assertToStringEquals("*", res[1055].firstMatch("*** Failers"), 3321);
+  assertToStringEquals("-", res[1055].firstMatch("-"), 3322);
+  assertNull(res[1055].firstMatch("a"), 3323);
+  assertToStringEquals("a b", res[1056].firstMatch("a b"), 3324);
+  assertToStringEquals("a-b", res[1057].firstMatch("a-b"), 3325);
+  assertNull(res[1057].firstMatch("*** Failers"), 3326);
+  assertToStringEquals("a-b", res[1057].firstMatch("a-b"), 3327);
+  assertNull(res[1057].firstMatch("a b"), 3328);
+  assertToStringEquals("1", res[1058].firstMatch("1"), 3329);
+  assertToStringEquals("-", res[1059].firstMatch("-"), 3330);
+  assertToStringEquals("*", res[1059].firstMatch("*** Failers"), 3331);
+  assertToStringEquals("-", res[1059].firstMatch("-"), 3332);
+  assertNull(res[1059].firstMatch("1"), 3333);
+  assertToStringEquals("a", res[1060].firstMatch("a"), 3334);
+  assertToStringEquals("-", res[1061].firstMatch("-"), 3335);
+  assertToStringEquals("*", res[1061].firstMatch("*** Failers"), 3336);
+  assertToStringEquals("-", res[1061].firstMatch("-"), 3337);
+  assertNull(res[1061].firstMatch("a"), 3338);
+  assertToStringEquals("a b", res[1062].firstMatch("a b"), 3339);
+  assertToStringEquals("a-b", res[1063].firstMatch("a-b"), 3340);
+  assertNull(res[1063].firstMatch("*** Failers"), 3341);
+  assertToStringEquals("a-b", res[1063].firstMatch("a-b"), 3342);
+  assertNull(res[1063].firstMatch("a b"), 3343);
+  assertToStringEquals("1", res[1064].firstMatch("1"), 3344);
+  assertToStringEquals("-", res[1065].firstMatch("-"), 3345);
+  assertToStringEquals("*", res[1065].firstMatch("*** Failers"), 3346);
+  assertToStringEquals("-", res[1065].firstMatch("-"), 3347);
+  assertNull(res[1065].firstMatch("1"), 3348);
+  assertToStringEquals("ab", res[1066].firstMatch("abc"), 3349);
+  assertToStringEquals("ab", res[1066].firstMatch("abcd"), 3350);
+  assertToStringEquals("ef,", res[1067].firstMatch("def"), 3351);
+  assertToStringEquals("a(b", res[1069].firstMatch("a(b"), 3352);
+  assertNull(res[1069].firstMatch("ab"), 3353);
+  assertNull(res[1069].firstMatch("a((b"), 3354);
+  assertNull(res[1070].firstMatch("a\x08"), 3355);
+  assertToStringEquals("a,a,a", res[1071].firstMatch("abc"), 3356);
+  assertToStringEquals("abc,a,c", res[1072].firstMatch("abc"), 3357);
+  assertToStringEquals("abc", res[1073].firstMatch("aabbabc"), 3358);
+  assertToStringEquals("abc", res[1074].firstMatch("aabbabc"), 3359);
+  assertToStringEquals("abc", res[1075].firstMatch("abcabc"), 3360);
+  assertToStringEquals("ab,b", res[1076].firstMatch("ab"), 3361);
+  assertToStringEquals("ab,b", res[1077].firstMatch("ab"), 3362);
+  assertToStringEquals("ab,b", res[1078].firstMatch("ab"), 3363);
+  assertToStringEquals("ab,b", res[1079].firstMatch("ab"), 3364);
+  assertToStringEquals("a,a", res[1080].firstMatch("ab"), 3365);
+  assertToStringEquals("a,a", res[1081].firstMatch("ab"), 3366);
+  assertToStringEquals("cde", res[1082].firstMatch("cde"), 3367);
+  assertNull(res[1083].firstMatch("*** Failers"), 3368);
+  assertNull(res[1083].firstMatch("b"), 3369);
+  assertToStringEquals("abbbcd,c", res[1085].firstMatch("abbbcd"), 3370);
+  assertToStringEquals("abcd,a", res[1086].firstMatch("abcd"), 3371);
+  assertToStringEquals("e", res[1087].firstMatch("e"), 3372);
+  assertToStringEquals("ef,e", res[1088].firstMatch("ef"), 3373);
+  assertToStringEquals("abcdefg", res[1089].firstMatch("abcdefg"), 3374);
+  assertToStringEquals("ab", res[1090].firstMatch("xabyabbbz"), 3375);
+  assertToStringEquals("a", res[1090].firstMatch("xayabbbz"), 3376);
+  assertToStringEquals("cde,cd", res[1091].firstMatch("abcde"), 3377);
+  assertToStringEquals("hij", res[1092].firstMatch("hij"), 3378);
+  assertToStringEquals("ef,", res[1094].firstMatch("abcdef"), 3379);
+  assertToStringEquals("bcd,b", res[1095].firstMatch("abcd"), 3380);
+  assertToStringEquals("abc,a", res[1096].firstMatch("abc"), 3381);
+  assertToStringEquals("abc,bc", res[1097].firstMatch("abc"), 3382);
+  assertToStringEquals("abcd,bc,d", res[1098].firstMatch("abcd"), 3383);
+  assertToStringEquals("abcd,bc,d", res[1099].firstMatch("abcd"), 3384);
+  assertToStringEquals("abcd,b,cd", res[1100].firstMatch("abcd"), 3385);
+  assertToStringEquals("adcdcde", res[1101].firstMatch("adcdcde"), 3386);
+  assertNull(res[1102].firstMatch("*** Failers"), 3387);
+  assertNull(res[1102].firstMatch("abcde"), 3388);
+  assertNull(res[1102].firstMatch("adcdcde"), 3389);
+  assertToStringEquals("abc,ab", res[1103].firstMatch("abc"), 3390);
+  assertToStringEquals("abcd,abc,a,b,d", res[1104].firstMatch("abcd"), 3391);
+  assertToStringEquals("alpha", res[1105].firstMatch("alpha"), 3392);
+  assertToStringEquals("bh,", res[1106].firstMatch("abh"), 3393);
+  assertToStringEquals("effgz,effgz,", res[1107].firstMatch("effgz"), 3394);
+  assertToStringEquals("ij,ij,j", res[1107].firstMatch("ij"), 3395);
+  assertToStringEquals("effgz,effgz,", res[1107].firstMatch("reffgz"), 3396);
+  assertNull(res[1107].firstMatch("*** Failers"), 3397);
+  assertNull(res[1107].firstMatch("effg"), 3398);
+  assertNull(res[1107].firstMatch("bcdd"), 3399);
+  assertToStringEquals("a,a,a,a,a,a,a,a,a,a,a", res[1108].firstMatch("a"), 3400);
+  assertToStringEquals("a,a,a,a,a,a,a,a,a,a", res[1109].firstMatch("a"), 3401);
+  assertNull(res[1110].firstMatch("*** Failers"), 3402);
+  assertNull(res[1110].firstMatch("aa"), 3403);
+  assertNull(res[1110].firstMatch("uh-uh"), 3404);
+  assertToStringEquals("multiple words", res[1111].firstMatch("multiple words, yeah"), 3405);
+  assertToStringEquals("abcde,ab,de", res[1112].firstMatch("abcde"), 3406);
+  assertToStringEquals("(a, b),a,b", res[1113].firstMatch("(a, b)"), 3407);
+  assertToStringEquals("abcd", res[1115].firstMatch("abcd"), 3408);
+  assertToStringEquals("abcd,bc", res[1116].firstMatch("abcd"), 3409);
+  assertToStringEquals("ac", res[1117].firstMatch("ac"), 3410);
+  assertToStringEquals("ABC", res[1118].firstMatch("ABC"), 3411);
+  assertToStringEquals("ABC", res[1118].firstMatch("XABCY"), 3412);
+  assertToStringEquals("ABC", res[1118].firstMatch("ABABC"), 3413);
+  assertNull(res[1118].firstMatch("*** Failers"), 3414);
+  assertNull(res[1118].firstMatch("aaxabxbaxbbx"), 3415);
+  assertNull(res[1118].firstMatch("XBC"), 3416);
+  assertNull(res[1118].firstMatch("AXC"), 3417);
+  assertNull(res[1118].firstMatch("ABX"), 3418);
+  assertToStringEquals("ABC", res[1119].firstMatch("ABC"), 3419);
+  assertToStringEquals("ABC", res[1120].firstMatch("ABC"), 3420);
+  assertToStringEquals("ABBC", res[1120].firstMatch("ABBC"), 3421);
+  assertToStringEquals("ABBBBC", res[1121].firstMatch("ABBBBC"), 3422);
+  assertToStringEquals("ABBBBC", res[1122].firstMatch("ABBBBC"), 3423);
+  assertToStringEquals("ABBC", res[1123].firstMatch("ABBC"), 3424);
+  assertNull(res[1124].firstMatch("*** Failers"), 3425);
+  assertNull(res[1124].firstMatch("ABC"), 3426);
+  assertNull(res[1124].firstMatch("ABQ"), 3427);
+  assertToStringEquals("ABBBBC", res[1126].firstMatch("ABBBBC"), 3428);
+  assertToStringEquals("ABBBBC", res[1127].firstMatch("ABBBBC"), 3429);
+  assertToStringEquals("ABBBBC", res[1128].firstMatch("ABBBBC"), 3430);
+  assertToStringEquals("ABBBBC", res[1129].firstMatch("ABBBBC"), 3431);
+  assertNull(res[1130].firstMatch("*** Failers"), 3432);
+  assertNull(res[1130].firstMatch("ABQ"), 3433);
+  assertNull(res[1130].firstMatch("ABBBBC"), 3434);
+  assertToStringEquals("ABBC", res[1131].firstMatch("ABBC"), 3435);
+  assertToStringEquals("ABC", res[1131].firstMatch("ABC"), 3436);
+  assertToStringEquals("ABC", res[1132].firstMatch("ABC"), 3437);
+  assertToStringEquals("ABC", res[1134].firstMatch("ABC"), 3438);
+  assertToStringEquals("ABC", res[1135].firstMatch("ABC"), 3439);
+  assertToStringEquals("ABC", res[1136].firstMatch("ABC"), 3440);
+  assertNull(res[1136].firstMatch("*** Failers"), 3441);
+  assertNull(res[1136].firstMatch("ABBBBC"), 3442);
+  assertNull(res[1136].firstMatch("ABCC"), 3443);
+  assertToStringEquals("ABC", res[1137].firstMatch("ABCC"), 3444);
+  assertToStringEquals("ABC", res[1139].firstMatch("AABC"), 3445);
+  assertToStringEquals("", res[1140].firstMatch("ABC"), 3446);
+  assertToStringEquals("", res[1141].firstMatch("ABC"), 3447);
+  assertToStringEquals("ABC", res[1142].firstMatch("ABC"), 3448);
+  assertToStringEquals("AXC", res[1142].firstMatch("AXC"), 3449);
+  assertToStringEquals("AXYZC", res[1143].firstMatch("AXYZC"), 3450);
+  assertNull(res[1144].firstMatch("*** Failers"), 3451);
+  assertToStringEquals("AABC", res[1144].firstMatch("AABC"), 3452);
+  assertNull(res[1144].firstMatch("AXYZD"), 3453);
+  assertToStringEquals("ABD", res[1145].firstMatch("ABD"), 3454);
+  assertToStringEquals("ACE", res[1146].firstMatch("ACE"), 3455);
+  assertNull(res[1146].firstMatch("*** Failers"), 3456);
+  assertNull(res[1146].firstMatch("ABC"), 3457);
+  assertNull(res[1146].firstMatch("ABD"), 3458);
+  assertToStringEquals("AC", res[1147].firstMatch("AAC"), 3459);
+  assertToStringEquals("A-", res[1148].firstMatch("A-"), 3460);
+  assertToStringEquals("A-", res[1149].firstMatch("A-"), 3461);
+  assertToStringEquals("A]", res[1150].firstMatch("A]"), 3462);
+  assertNull(res[1151].firstMatch("A]B"), 3463);
+  assertToStringEquals("AED", res[1152].firstMatch("AED"), 3464);
+  assertToStringEquals("ADC", res[1153].firstMatch("ADC"), 3465);
+  assertNull(res[1153].firstMatch("*** Failers"), 3466);
+  assertNull(res[1153].firstMatch("ABD"), 3467);
+  assertNull(res[1153].firstMatch("A-C"), 3468);
+  assertNull(res[1154].firstMatch("ADC"), 3469);
+  assertToStringEquals("AB", res[1155].firstMatch("ABC"), 3470);
+  assertToStringEquals("AB", res[1155].firstMatch("ABCD"), 3471);
+  assertToStringEquals("EF,", res[1156].firstMatch("DEF"), 3472);
+  assertNull(res[1157].firstMatch("*** Failers"), 3473);
+  assertNull(res[1157].firstMatch("A]C"), 3474);
+  assertNull(res[1157].firstMatch("B"), 3475);
+  assertToStringEquals("A(B", res[1158].firstMatch("A(B"), 3476);
+  assertNull(res[1158].firstMatch("AB"), 3477);
+  assertNull(res[1158].firstMatch("A((B"), 3478);
+  assertNull(res[1159].firstMatch("AB"), 3479);
+  assertToStringEquals("A,A,A", res[1160].firstMatch("ABC"), 3480);
+  assertToStringEquals("ABC,A,C", res[1161].firstMatch("ABC"), 3481);
+  assertToStringEquals("ABC", res[1162].firstMatch("AABBABC"), 3482);
+  assertToStringEquals("ABC", res[1163].firstMatch("AABBABC"), 3483);
+  assertToStringEquals("ABC", res[1164].firstMatch("ABCABC"), 3484);
+  assertToStringEquals("ABC", res[1165].firstMatch("ABCABC"), 3485);
+  assertToStringEquals("ABC", res[1166].firstMatch("ABCABC"), 3486);
+  assertToStringEquals("AB,B", res[1167].firstMatch("AB"), 3487);
+  assertToStringEquals("AB,B", res[1168].firstMatch("AB"), 3488);
+  assertToStringEquals("AB,B", res[1169].firstMatch("AB"), 3489);
+  assertToStringEquals("AB,B", res[1170].firstMatch("AB"), 3490);
+  assertToStringEquals("A,A", res[1171].firstMatch("AB"), 3491);
+  assertToStringEquals("A,A", res[1172].firstMatch("AB"), 3492);
+  assertToStringEquals(",", res[1173].firstMatch("AB"), 3493);
+  assertToStringEquals("CDE", res[1174].firstMatch("CDE"), 3494);
+  assertToStringEquals("ABBBCD,C", res[1177].firstMatch("ABBBCD"), 3495);
+  assertToStringEquals("ABCD,A", res[1178].firstMatch("ABCD"), 3496);
+  assertToStringEquals("E", res[1179].firstMatch("E"), 3497);
+  assertToStringEquals("EF,E", res[1180].firstMatch("EF"), 3498);
+  assertToStringEquals("ABCDEFG", res[1181].firstMatch("ABCDEFG"), 3499);
+  assertToStringEquals("AB", res[1182].firstMatch("XABYABBBZ"), 3500);
+  assertToStringEquals("A", res[1182].firstMatch("XAYABBBZ"), 3501);
+  assertToStringEquals("CDE,CD", res[1183].firstMatch("ABCDE"), 3502);
+  assertToStringEquals("HIJ", res[1184].firstMatch("HIJ"), 3503);
+  assertNull(res[1185].firstMatch("ABCDE"), 3504);
+  assertToStringEquals("EF,", res[1186].firstMatch("ABCDEF"), 3505);
+  assertToStringEquals("BCD,B", res[1187].firstMatch("ABCD"), 3506);
+  assertToStringEquals("ABC,A", res[1188].firstMatch("ABC"), 3507);
+  assertToStringEquals("ABC,BC", res[1189].firstMatch("ABC"), 3508);
+  assertToStringEquals("ABCD,BC,D", res[1190].firstMatch("ABCD"), 3509);
+  assertToStringEquals("ABCD,BC,D", res[1191].firstMatch("ABCD"), 3510);
+  assertToStringEquals("ABCD,B,CD", res[1192].firstMatch("ABCD"), 3511);
+  assertToStringEquals("ADCDCDE", res[1193].firstMatch("ADCDCDE"), 3512);
+  assertToStringEquals("ABC,AB", res[1195].firstMatch("ABC"), 3513);
+  assertToStringEquals("ABCD,ABC,A,B,D", res[1196].firstMatch("ABCD"), 3514);
+  assertToStringEquals("ALPHA", res[1197].firstMatch("ALPHA"), 3515);
+  assertToStringEquals("BH,", res[1198].firstMatch("ABH"), 3516);
+  assertToStringEquals("EFFGZ,EFFGZ,", res[1199].firstMatch("EFFGZ"), 3517);
+  assertToStringEquals("IJ,IJ,J", res[1199].firstMatch("IJ"), 3518);
+  assertToStringEquals("EFFGZ,EFFGZ,", res[1199].firstMatch("REFFGZ"), 3519);
+  assertNull(res[1199].firstMatch("*** Failers"), 3520);
+  assertNull(res[1199].firstMatch("ADCDCDE"), 3521);
+  assertNull(res[1199].firstMatch("EFFG"), 3522);
+  assertNull(res[1199].firstMatch("BCDD"), 3523);
+  assertToStringEquals("A,A,A,A,A,A,A,A,A,A,A", res[1200].firstMatch("A"), 3524);
+  assertToStringEquals("A,A,A,A,A,A,A,A,A,A", res[1201].firstMatch("A"), 3525);
+  assertToStringEquals("A,A", res[1202].firstMatch("A"), 3526);
+  assertToStringEquals("C,C", res[1203].firstMatch("C"), 3527);
+  assertNull(res[1204].firstMatch("*** Failers"), 3528);
+  assertNull(res[1204].firstMatch("AA"), 3529);
+  assertNull(res[1204].firstMatch("UH-UH"), 3530);
+  assertToStringEquals("MULTIPLE WORDS", res[1205].firstMatch("MULTIPLE WORDS, YEAH"), 3531);
+  assertToStringEquals("ABCDE,AB,DE", res[1206].firstMatch("ABCDE"), 3532);
+  assertToStringEquals("(A, B),A,B", res[1207].firstMatch("(A, B)"), 3533);
+  assertToStringEquals("ABCD", res[1209].firstMatch("ABCD"), 3534);
+  assertToStringEquals("ABCD,BC", res[1210].firstMatch("ABCD"), 3535);
+  assertToStringEquals("AC", res[1211].firstMatch("AC"), 3536);
+  assertToStringEquals("ad", res[1212].firstMatch("abad"), 3537);
+  assertToStringEquals("ad", res[1213].firstMatch("abad"), 3538);
+  assertToStringEquals("ad", res[1214].firstMatch("abad"), 3539);
+  assertToStringEquals("ace,e", res[1215].firstMatch("ace"), 3540);
+  assertToStringEquals("ace,e", res[1216].firstMatch("ace"), 3541);
+  assertToStringEquals("ace,e", res[1217].firstMatch("ace"), 3542);
+  assertToStringEquals("acd,d", res[1217].firstMatch("acdbcdbe"), 3543);
+  assertToStringEquals("acdbcdbe,e", res[1218].firstMatch("acdbcdbe"), 3544);
+  assertToStringEquals("acdb,b", res[1219].firstMatch("acdbcdbe"), 3545);
+  assertToStringEquals("acdbcdb,b", res[1220].firstMatch("acdbcdbe"), 3546);
+  assertToStringEquals("acdbcd,d", res[1221].firstMatch("acdbcdbe"), 3547);
+  assertToStringEquals("foobar,bar,,bar", res[1222].firstMatch("foobar"), 3548);
+  assertToStringEquals("acdbcdbe,e", res[1223].firstMatch("acdbcdbe"), 3549);
+  assertToStringEquals("acdbcdbe,e", res[1224].firstMatch("acdbcdbe"), 3550);
+  assertToStringEquals("acdbcdbe,e", res[1225].firstMatch("acdbcdbe"), 3551);
+  assertToStringEquals("acdbcdb,b", res[1226].firstMatch("acdbcdbe"), 3552);
+  assertToStringEquals("acdbcdbe,e", res[1227].firstMatch("acdbcdbe"), 3553);
+  assertToStringEquals("acdbcdb,b", res[1228].firstMatch("acdbcdbe"), 3554);
+  assertToStringEquals("ace,c,e", res[1229].firstMatch("ace"), 3555);
+  assertToStringEquals("AB,A", res[1230].firstMatch("AB"), 3556);
+  assertToStringEquals(".,.,", res[1231].firstMatch("."), 3557);
+  assertToStringEquals("<&", res[1232].firstMatch("<&OUT"), 3558);
+  assertToStringEquals("foobar,,,,b,a,r", res[1233].firstMatch("foobar"), 3559);
+  assertToStringEquals(",,,,,,", res[1233].firstMatch("ab"), 3560);
+  assertToStringEquals(",,,,,,", res[1233].firstMatch("*** Failers"), 3561);
+  assertToStringEquals(",,,,,,", res[1233].firstMatch("cb"), 3562);
+  assertToStringEquals(",,,,,,", res[1233].firstMatch("b"), 3563);
+  assertToStringEquals(",,,,,,", res[1233].firstMatch("ab"), 3564);
+  assertToStringEquals(",,,,,,", res[1233].firstMatch("b"), 3565);
+  assertToStringEquals(",,,,,,", res[1233].firstMatch("b"), 3566);
+  assertToStringEquals("aba", res[1234].firstMatch("aba"), 3567);
+  assertToStringEquals("a", res[1235].firstMatch("aba"), 3568);
+  assertToStringEquals(",", res[1236].firstMatch("abc"), 3569);
+  assertToStringEquals("aax,a", res[1237].firstMatch("aax"), 3570);
+  assertToStringEquals("aax,a,a", res[1238].firstMatch("aax"), 3571);
+  assertToStringEquals("aax,a,a", res[1239].firstMatch("aax"), 3572);
+  assertToStringEquals("ab,", res[1240].firstMatch("cab"), 3573);
+  assertToStringEquals("ab,", res[1241].firstMatch("cab"), 3574);
+  assertToStringEquals("ab,", res[1241].firstMatch("ab"), 3575);
+  assertToStringEquals("ab,", res[1241].firstMatch("ab"), 3576);
+  assertNull(res[1241].firstMatch("Ab"), 3577);
+  assertNull(res[1241].firstMatch("Ab"), 3578);
+  assertNull(res[1241].firstMatch("*** Failers"), 3579);
+  assertNull(res[1241].firstMatch("cb"), 3580);
+  assertNull(res[1241].firstMatch("aB"), 3581);
+  assertToStringEquals("ab,", res[1241].firstMatch("ab"), 3582);
+  assertToStringEquals("ab,", res[1241].firstMatch("ab"), 3583);
+  assertNull(res[1241].firstMatch("Ab"), 3584);
+  assertNull(res[1241].firstMatch("Ab"), 3585);
+  assertNull(res[1241].firstMatch("*** Failers"), 3586);
+  assertNull(res[1241].firstMatch("aB"), 3587);
+  assertNull(res[1241].firstMatch("aB"), 3588);
+  assertToStringEquals("ab,", res[1241].firstMatch("ab"), 3589);
+  assertToStringEquals("ab,", res[1241].firstMatch("ab"), 3590);
+  assertNull(res[1241].firstMatch("aB"), 3591);
+  assertNull(res[1241].firstMatch("aB"), 3592);
+  assertNull(res[1241].firstMatch("*** Failers"), 3593);
+  assertNull(res[1241].firstMatch("aB"), 3594);
+  assertNull(res[1241].firstMatch("Ab"), 3595);
+  assertNull(res[1241].firstMatch("aB"), 3596);
+  assertNull(res[1241].firstMatch("aB"), 3597);
+  assertNull(res[1241].firstMatch("*** Failers"), 3598);
+  assertNull(res[1241].firstMatch("Ab"), 3599);
+  assertNull(res[1241].firstMatch("AB"), 3600);
+  assertToStringEquals("ab,", res[1241].firstMatch("ab"), 3601);
+  assertToStringEquals("ab,", res[1241].firstMatch("ab"), 3602);
+  assertNull(res[1241].firstMatch("aB"), 3603);
+  assertNull(res[1241].firstMatch("aB"), 3604);
+  assertNull(res[1241].firstMatch("*** Failers"), 3605);
+  assertNull(res[1241].firstMatch("AB"), 3606);
+  assertNull(res[1241].firstMatch("Ab"), 3607);
+  assertNull(res[1241].firstMatch("aB"), 3608);
+  assertNull(res[1241].firstMatch("aB"), 3609);
+  assertNull(res[1241].firstMatch("*** Failers"), 3610);
+  assertNull(res[1241].firstMatch("Ab"), 3611);
+  assertNull(res[1241].firstMatch("AB"), 3612);
+  assertNull(res[1241].firstMatch("*** Failers"), 3613);
+  assertNull(res[1241].firstMatch("AB"), 3614);
+  assertNull(res[1241].firstMatch("a\nB"), 3615);
+  assertNull(res[1241].firstMatch("a\nB"), 3616);
+  assertToStringEquals("cabbbb", res[1242].firstMatch("cabbbb"), 3617);
+  assertToStringEquals("caaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", res[1243].firstMatch("caaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"), 3618);
+  assertToStringEquals("foobar1234baz", res[1244].firstMatch("foobar1234baz"), 3619);
+  assertToStringEquals("x~~,~~", res[1245].firstMatch("x~~"), 3620);
+  assertToStringEquals("aaac", res[1246].firstMatch("aaac"), 3621);
+  assertToStringEquals("aaac", res[1247].firstMatch("aaac"), 3622);
+  assertNull(res[1247].firstMatch("*** Failers"), 3623);
+  assertNull(res[1247].firstMatch("B\nB"), 3624);
+  assertNull(res[1247].firstMatch("dbcb"), 3625);
+  assertNull(res[1247].firstMatch("dbaacb"), 3626);
+  assertNull(res[1247].firstMatch("dbaacb"), 3627);
+  assertNull(res[1247].firstMatch("cdaccb"), 3628);
+  assertNull(res[1248].firstMatch("*** Failers"), 3629);
+  assertNull(res[1248].firstMatch("dbcb"), 3630);
+  assertNull(res[1248].firstMatch("a--"), 3631);
+  assertNull(res[1248].firstMatch("a\nb\nc\n"), 3632);
+  assertNull(res[1248].firstMatch("a\nb\nc\n"), 3633);
+  assertNull(res[1248].firstMatch("a\nb\n"), 3634);
+  assertNull(res[1248].firstMatch("a\nb\n"), 3635);
+  assertNull(res[1248].firstMatch("a\nb\n"), 3636);
+  assertNull(res[1248].firstMatch("a\nb\n"), 3637);
+  assertNull(res[1248].firstMatch("a\nb\nc\n"), 3638);
+  assertNull(res[1248].firstMatch("a\nb\nc\n"), 3639);
+  assertNull(res[1248].firstMatch("a\nb\nc\n"), 3640);
+  assertNull(res[1248].firstMatch("a\nb\nc\n"), 3641);
+  assertNull(res[1250].firstMatch("*** Failers"), 3642);
+  assertNull(res[1250].firstMatch("a\nb\nc\n"), 3643);
+  assertNull(res[1250].firstMatch("a\nb\nc\n"), 3644);
+  assertNull(res[1250].firstMatch("a\nb\nc\n"), 3645);
+  assertNull(res[1250].firstMatch("a"), 3646);
+  assertNull(res[1250].firstMatch("*** Failers"), 3647);
+  assertNull(res[1250].firstMatch("a"), 3648);
+  assertNull(res[1250].firstMatch("a"), 3649);
+  assertNull(res[1250].firstMatch("a"), 3650);
+  assertToStringEquals("one:,one:", res[1251].firstMatch("one:"), 3651);
+  assertNull(res[1251].firstMatch("a"), 3652);
+  assertToStringEquals("abcd,,abcd", res[1252].firstMatch("abcd"), 3653);
+  assertToStringEquals("xy:z:::abcd,xy:z:::,abcd", res[1252].firstMatch("xy:z:::abcd"), 3654);
+  assertToStringEquals("aexyc,c", res[1253].firstMatch("aexycd"), 3655);
+  assertToStringEquals("aab,aa", res[1254].firstMatch("caab"), 3656);
+  assertToStringEquals("abcd,,abcd", res[1255].firstMatch("abcd"), 3657);
+  assertToStringEquals("xy:z:::abcd,xy:z:::,abcd", res[1255].firstMatch("xy:z:::abcd"), 3658);
+  assertToStringEquals("Failers,,Failers", res[1255].firstMatch("*** Failers"), 3659);
+  assertNull(res[1255].firstMatch("abcd:"), 3660);
+  assertNull(res[1255].firstMatch("abcd:"), 3661);
+  assertToStringEquals("aexyc,c", res[1256].firstMatch("aexycd"), 3662);
+  assertNull(res[1257].firstMatch("aaab"), 3663);
+  assertToStringEquals(":[,:[", res[1258].firstMatch("a:[b]:"), 3664);
+  assertToStringEquals("=[,=[", res[1259].firstMatch("a=[b]="), 3665);
+  assertToStringEquals(".[,.[", res[1260].firstMatch("a.[b]."), 3666);
+  assertNull(res[1260].firstMatch("aaab"), 3667);
+  assertNull(res[1260].firstMatch("aaab"), 3668);
+  assertNull(res[1260].firstMatch("((abc(ade)ufh()()x"), 3669);
+  assertNull(res[1261].firstMatch("*** Failers"), 3670);
+  assertNull(res[1261].firstMatch("aaab"), 3671);
+  assertNull(res[1261].firstMatch("a\nb\n"), 3672);
+  assertNull(res[1262].firstMatch("a\nb\n"), 3673);
+  assertNull(res[1264].firstMatch("a\nb"), 3674);
+  assertNull(res[1265].firstMatch("a\nb"), 3675);
+  assertNull(res[1265].firstMatch("*** Failers"), 3676);
+  assertNull(res[1265].firstMatch("alphabetabcd"), 3677);
+  assertNull(res[1265].firstMatch("endingwxyz"), 3678);
+  assertNull(res[1265].firstMatch("*** Failers"), 3679);
+  assertNull(res[1265].firstMatch("a rather long string that doesn't end with one of them"), 3680);
+  assertNull(res[1265].firstMatch("word cat dog elephant mussel cow horse canary baboon snake shark otherword"), 3681);
+  assertNull(res[1265].firstMatch("word cat dog elephant mussel cow horse canary baboon snake shark"), 3682);
+  assertNull(res[1265].firstMatch("word cat dog elephant mussel cow horse canary baboon snake shark the quick brown fox and the lazy dog and several other words getting close to thirty by now I hope"), 3683);
+  assertNull(res[1265].firstMatch("999foo"), 3684);
+  assertNull(res[1265].firstMatch("123999foo "), 3685);
+  assertNull(res[1265].firstMatch("*** Failers"), 3686);
+  assertNull(res[1265].firstMatch("123abcfoo"), 3687);
+  assertNull(res[1265].firstMatch("999foo"), 3688);
+  assertNull(res[1265].firstMatch("123999foo "), 3689);
+  assertNull(res[1265].firstMatch("*** Failers"), 3690);
+  assertNull(res[1265].firstMatch("123abcfoo"), 3691);
+  assertNull(res[1265].firstMatch("123abcfoo"), 3692);
+  assertNull(res[1265].firstMatch("123456foo "), 3693);
+  assertNull(res[1265].firstMatch("*** Failers"), 3694);
+  assertNull(res[1265].firstMatch("123999foo  "), 3695);
+  assertNull(res[1265].firstMatch("123abcfoo   "), 3696);
+  assertNull(res[1265].firstMatch("123456foo "), 3697);
+  assertNull(res[1265].firstMatch("*** Failers"), 3698);
+  assertNull(res[1265].firstMatch("123999foo  "), 3699);
+  assertToStringEquals("ZA,A,", res[1266].firstMatch("ZABCDEFG"), 3700);
+  assertToStringEquals("ZA,A,", res[1267].firstMatch("ZABCDEFG"), 3701);
+  assertToStringEquals("ZA,A,,", res[1268].firstMatch("ZABCDEFG"), 3702);
+  assertToStringEquals("ZA,A,,", res[1268].firstMatch("ZABCDEFG"), 3703);
+  assertToStringEquals("ZA,A,,", res[1268].firstMatch("ZABCDEFG"), 3704);
+  assertToStringEquals("a", res[1269].firstMatch("abbab"), 3705);
+  assertToStringEquals("a", res[1270].firstMatch("abcde"), 3711);
+  assertToStringEquals("-", res[1270].firstMatch("-things"), 3712);
+  assertToStringEquals("0", res[1270].firstMatch("0digit"), 3713);
+  assertNull(res[1270].firstMatch("*** Failers"), 3714);
+  assertNull(res[1270].firstMatch("bcdef    "), 3715);
+  assertNull(res[1271].firstMatch("> \x09\n\x0c\x0d\x0b<"), 3716);
+  assertNull(res[1271].firstMatch(" "), 3717);
+  assertNull(res[1272].firstMatch("> \x09\n\x0c\x0d\x0b<"), 3718);
+  assertNull(res[1272].firstMatch(" "), 3719);
+  assertToStringEquals(" \x09\n\x0c\x0d\x0b", res[1273].firstMatch("> \x09\n\x0c\x0d\x0b<"), 3720);
+  assertToStringEquals(" ", res[1273].firstMatch(" "), 3721);
+  assertToStringEquals(" \x09\n\x0c\x0d\x0b", res[1274].firstMatch("> \x09\n\x0c\x0d\x0b<"), 3722);
+  assertToStringEquals(" ", res[1274].firstMatch(" "), 3723);
+  assertNull(res[1275].firstMatch("ab"), 3724);
+  assertNull(res[1278].firstMatch("abcabcabc"), 3725);
+  assertNull(res[1278].firstMatch("abc(*+|abc "), 3726);
+  assertNull(res[1279].firstMatch("abc abcabc"), 3727);
+  assertNull(res[1279].firstMatch("*** Failers"), 3728);
+  assertNull(res[1279].firstMatch("abcabcabc  "), 3729);
+  assertNull(res[1280].firstMatch("abc#not comment\n    literal     "), 3730);
+  assertNull(res[1281].firstMatch("abc#not comment\n    literal     "), 3731);
+  assertNull(res[1282].firstMatch("abc#not comment\n    literal     "), 3732);
+  assertNull(res[1283].firstMatch("abc#not comment\n    literal     "), 3733);
+  assertNull(res[1284].firstMatch("abc\\\$xyz"), 3734);
+  assertNull(res[1285].firstMatch("abc\\\$xyz"), 3735);
+  assertNull(res[1286].firstMatch("abc"), 3736);
+  assertNull(res[1286].firstMatch("*** Failers"), 3737);
+  assertNull(res[1286].firstMatch("xyzabc  "), 3738);
+  assertNull(res[1287].firstMatch("abc1abc2xyzabc3"), 3739);
+  assertToStringEquals("abc1", res[1288].firstMatch("abc1abc2xyzabc3 "), 3740);
+  assertNull(res[1288].firstMatch("*** Failers "), 3742);
+  assertNull(res[1288].firstMatch("Xa b c d Y "), 3743);
+  assertToStringEquals("abcY", res[1288].firstMatch("XabcY"), 3744);
+  assertNull(res[1288].firstMatch("AxyzB "), 3745);
+  assertNull(res[1288].firstMatch("XabCY"), 3746);
+  assertNull(res[1288].firstMatch("*** Failers"), 3747);
+  assertToStringEquals("abcY", res[1288].firstMatch("XabcY  "), 3748);
+  assertNull(res[1288].firstMatch("abCE"), 3749);
+  assertNull(res[1288].firstMatch("DE"), 3750);
+  assertNull(res[1288].firstMatch("*** Failers"), 3751);
+  assertToStringEquals("abcE", res[1288].firstMatch("abcE"), 3752);
+  assertNull(res[1288].firstMatch("abCe  "), 3753);
+  assertNull(res[1288].firstMatch("dE"), 3754);
+  assertNull(res[1288].firstMatch("De    "), 3755);
+  assertNull(res[1289].firstMatch("z"), 3756);
+  assertNull(res[1289].firstMatch("a"), 3757);
+  assertNull(res[1289].firstMatch("-"), 3758);
+  assertNull(res[1289].firstMatch("d"), 3759);
+  assertNull(res[1289].firstMatch("] "), 3760);
+  assertNull(res[1289].firstMatch("*** Failers"), 3761);
+  assertNull(res[1289].firstMatch("b     "), 3762);
+  assertToStringEquals("z", res[1290].firstMatch("z"), 3763);
+  assertToStringEquals("C", res[1290].firstMatch("C "), 3764);
+  assertToStringEquals("M", res[1291].firstMatch("M "), 3765);
+  assertNull(res[1292].firstMatch(""), 3766);
+  assertNull(res[1292].firstMatch("REGular"), 3767);
+  assertNull(res[1292].firstMatch("regulaer"), 3768);
+  assertNull(res[1292].firstMatch("Regex  "), 3769);
+  assertNull(res[1292].firstMatch("regul\ufffdr "), 3770);
+  assertNull(res[1292].firstMatch("\ufffd\ufffd\ufffd\ufffd\ufffd"), 3771);
+  assertNull(res[1292].firstMatch("\ufffd\ufffd\ufffd\ufffd\ufffd"), 3772);
+  assertNull(res[1292].firstMatch("\ufffd\ufffd\ufffd\ufffd\ufffd"), 3773);
+  assertNull(res[1292].firstMatch("\ufffd\ufffd\ufffd\ufffd\ufffd"), 3774);
+  assertNull(res[1292].firstMatch("\x84XAZXB"), 3775);
+  assertNull(res[1292].firstMatch("123a"), 3776);
+  assertNull(res[1292].firstMatch("ac"), 3777);
+  assertToStringEquals("b,", res[1292].firstMatch("bbbbc"), 3778);
+  assertToStringEquals("ab,a", res[1292].firstMatch("abc"), 3779);
+  assertNull(res[1292].firstMatch("*** Failers"), 3780);
+  assertToStringEquals("b,", res[1292].firstMatch("bca"), 3781);
+  assertNull(res[1292].firstMatch(""), 3782);
+  assertToStringEquals("ab,a", res[1292].firstMatch("abc"), 3783);
+  assertNull(res[1292].firstMatch("*** Failers"), 3784);
+  assertToStringEquals("b,", res[1292].firstMatch("bca"), 3785);
+  assertToStringEquals("ab,a", res[1292].firstMatch("abc"), 3786);
+  assertNull(res[1292].firstMatch("*** Failers"), 3787);
+  assertNull(res[1292].firstMatch("def  "), 3788);
+  assertNull(res[1292].firstMatch(""), 3789);
+  assertToStringEquals("ab,a", res[1292].firstMatch("abc"), 3790);
+  assertNull(res[1292].firstMatch("*** Failers"), 3791);
+  assertNull(res[1292].firstMatch("def  "), 3792);
+  assertNull(res[1292].firstMatch(""), 3793);
+  assertToStringEquals("line\nbreak", res[1293].firstMatch("this is a line\nbreak"), 3794);
+  assertToStringEquals("line\nbreak", res[1293].firstMatch("line one\nthis is a line\nbreak in the second line "), 3795);
+  assertToStringEquals("line\nbreak", res[1294].firstMatch("this is a line\nbreak"), 3796);
+  assertNull(res[1294].firstMatch("** Failers "), 3797);
+  assertToStringEquals("line\nbreak", res[1294].firstMatch("line one\nthis is a line\nbreak in the second line "), 3798);
+  assertToStringEquals("line\nbreak", res[1295].firstMatch("this is a line\nbreak"), 3799);
+  assertNull(res[1295].firstMatch("** Failers "), 3800);
+  assertToStringEquals("line\nbreak", res[1295].firstMatch("line one\nthis is a line\nbreak in the second line "), 3801);
+  assertNull(res[1296].firstMatch("123P"), 3802);
+  assertNull(res[1296].firstMatch("a4PR"), 3803);
+  assertNull(res[1297].firstMatch("123P"), 3804);
+  assertNull(res[1297].firstMatch("4PR"), 3805);
+  assertToStringEquals("", res[1298].firstMatch("a\nb\nc\n"), 3806);
+  assertToStringEquals("", res[1298].firstMatch(" "), 3807);
+  assertToStringEquals("", res[1298].firstMatch("A\nC\nC\n "), 3808);
+  assertToStringEquals("", res[1298].firstMatch("AB"), 3809);
+  assertToStringEquals("", res[1298].firstMatch("aB  "), 3810);
+  assertToStringEquals("", res[1298].firstMatch("AB"), 3811);
+  assertToStringEquals("", res[1298].firstMatch("aB  "), 3812);
+  assertToStringEquals("", res[1298].firstMatch("AB"), 3813);
+  assertToStringEquals("", res[1298].firstMatch("aB  "), 3814);
+  assertToStringEquals("", res[1298].firstMatch("AB"), 3815);
+  assertToStringEquals("", res[1298].firstMatch("aB  "), 3816);
+  assertToStringEquals("Content-Type:xxxxxyyy ", res[1299].firstMatch("Content-Type:xxxxxyyy "), 3817);
+  assertToStringEquals("Content-Type:xxxxxyyyz", res[1300].firstMatch("Content-Type:xxxxxyyyz"), 3818);
+  assertToStringEquals("Content-Type:xxxyyy ", res[1301].firstMatch("Content-Type:xxxyyy "), 3819);
+  assertToStringEquals("Content-Type:xxxyyyz", res[1302].firstMatch("Content-Type:xxxyyyz"), 3820);
+  assertToStringEquals("abc", res[1303].firstMatch("xyz\nabc"), 3821);
+  assertToStringEquals("abc", res[1303].firstMatch("xyz\nabc<lf>"), 3822);
+  assertToStringEquals("abc", res[1303].firstMatch("xyz\x0d\nabc<lf>"), 3823);
+  assertToStringEquals("abc", res[1303].firstMatch("xyz\x0dabc<cr>"), 3824);
+  assertToStringEquals("abc", res[1303].firstMatch("xyz\x0d\nabc<crlf>"), 3825);
+  assertNull(res[1303].firstMatch("** Failers "), 3826);
+  assertToStringEquals("abc", res[1303].firstMatch("xyz\nabc<cr>"), 3827);
+  assertToStringEquals("abc", res[1303].firstMatch("xyz\x0d\nabc<cr>"), 3828);
+  assertToStringEquals("abc", res[1303].firstMatch("xyz\nabc<crlf>"), 3829);
+  assertToStringEquals("abc", res[1303].firstMatch("xyz\x0dabc<crlf>"), 3830);
+  assertToStringEquals("abc", res[1303].firstMatch("xyz\x0dabc<lf>"), 3831);
+  assertToStringEquals("abc", res[1304].firstMatch("xyzabc"), 3832);
+  assertToStringEquals("abc", res[1304].firstMatch("xyzabc\n "), 3833);
+  assertToStringEquals("abc", res[1304].firstMatch("xyzabc\npqr "), 3834);
+  assertToStringEquals("abc", res[1304].firstMatch("xyzabc\x0d<cr> "), 3835);
+  assertToStringEquals("abc", res[1304].firstMatch("xyzabc\x0dpqr<cr> "), 3836);
+  assertToStringEquals("abc", res[1304].firstMatch("xyzabc\x0d\n<crlf> "), 3837);
+  assertToStringEquals("abc", res[1304].firstMatch("xyzabc\x0d\npqr<crlf> "), 3838);
+  assertNull(res[1304].firstMatch("** Failers"), 3839);
+  assertToStringEquals("abc", res[1304].firstMatch("xyzabc\x0d "), 3840);
+  assertToStringEquals("abc", res[1304].firstMatch("xyzabc\x0dpqr "), 3841);
+  assertToStringEquals("abc", res[1304].firstMatch("xyzabc\x0d\n "), 3842);
+  assertToStringEquals("abc", res[1304].firstMatch("xyzabc\x0d\npqr "), 3843);
+  assertToStringEquals("abc", res[1305].firstMatch("xyz\x0dabcdef"), 3844);
+  assertToStringEquals("abc", res[1305].firstMatch("xyz\nabcdef<lf>"), 3845);
+  assertNull(res[1305].firstMatch("** Failers  "), 3846);
+  assertToStringEquals("abc", res[1305].firstMatch("xyz\nabcdef"), 3847);
+  assertNull(res[1305].firstMatch("   "), 3848);
+  assertToStringEquals("abc", res[1306].firstMatch("xyz\nabcdef"), 3849);
+  assertToStringEquals("abc", res[1306].firstMatch("xyz\x0dabcdef<cr>"), 3850);
+  assertNull(res[1306].firstMatch("** Failers  "), 3851);
+  assertToStringEquals("abc", res[1306].firstMatch("xyz\x0dabcdef"), 3852);
+  assertNull(res[1306].firstMatch("   "), 3853);
+  assertToStringEquals("abc", res[1307].firstMatch("xyz\x0d\nabcdef"), 3854);
+  assertToStringEquals("abc", res[1307].firstMatch("xyz\x0dabcdef<cr>"), 3855);
+  assertNull(res[1307].firstMatch("** Failers  "), 3856);
+  assertToStringEquals("abc", res[1307].firstMatch("xyz\x0dabcdef"), 3857);
+  assertToStringEquals("abc", res[1308].firstMatch("abc\ndef"), 3858);
+  assertToStringEquals("abc", res[1308].firstMatch("abc\x0ddef"), 3859);
+  assertToStringEquals("abc", res[1308].firstMatch("abc\x0d\ndef"), 3860);
+  assertToStringEquals("<cr>abc", res[1308].firstMatch("<cr>abc\ndef"), 3861);
+  assertToStringEquals("<cr>abc", res[1308].firstMatch("<cr>abc\x0ddef"), 3862);
+  assertToStringEquals("<cr>abc", res[1308].firstMatch("<cr>abc\x0d\ndef"), 3863);
+  assertToStringEquals("<crlf>abc", res[1308].firstMatch("<crlf>abc\ndef"), 3864);
+  assertToStringEquals("<crlf>abc", res[1308].firstMatch("<crlf>abc\x0ddef"), 3865);
+  assertToStringEquals("<crlf>abc", res[1308].firstMatch("<crlf>abc\x0d\ndef"), 3866);
+  assertNull(res[1309].firstMatch("abc\ndef"), 3867);
+  assertNull(res[1309].firstMatch("abc\x0ddef"), 3868);
+  assertNull(res[1309].firstMatch("abc\x0d\ndef"), 3869);
+  assertToStringEquals("abc=xyz\\,", res[1310].firstMatch("abc=xyz\\\npqr"), 3870);
+  assertToStringEquals("aaaa,a,", res[1311].firstMatch("aaaa"), 3871);
+  assertToStringEquals("aaaa", res[1312].firstMatch("aaaa"), 3872);
+  assertToStringEquals("aaaa,a,", res[1313].firstMatch("aaaa"), 3873);
+  assertToStringEquals("aaaa", res[1314].firstMatch("aaaa"), 3874);
+  assertNull(res[1317].firstMatch("a\x0db"), 3875);
+  assertNull(res[1317].firstMatch("a\nb<cr> "), 3876);
+  assertNull(res[1317].firstMatch("** Failers"), 3877);
+  assertNull(res[1317].firstMatch("a\nb"), 3878);
+  assertNull(res[1317].firstMatch("a\nb<any>"), 3879);
+  assertNull(res[1317].firstMatch("a\x0db<cr>   "), 3880);
+  assertNull(res[1317].firstMatch("a\x0db<any>   "), 3881);
+  assertToStringEquals("abc1", res[1318].firstMatch("abc1 \nabc2 \x0babc3xx \x0cabc4 \x0dabc5xx \x0d\nabc6 \x85abc7 JUNK"), 3882);
+  assertToStringEquals("abc1", res[1319].firstMatch("abc1\n abc2\x0b abc3\x0c abc4\x0d abc5\x0d\n abc6\x85 abc9"), 3883);
+  assertNull(res[1320].firstMatch("a\nb"), 3884);
+  assertNull(res[1320].firstMatch("a\x0db"), 3885);
+  assertNull(res[1320].firstMatch("a\x0d\nb"), 3886);
+  assertNull(res[1320].firstMatch("a\x0bb"), 3887);
+  assertNull(res[1320].firstMatch("a\x0cb"), 3888);
+  assertNull(res[1320].firstMatch("a\x85b   "), 3889);
+  assertNull(res[1320].firstMatch("** Failers"), 3890);
+  assertNull(res[1320].firstMatch("a\n\x0db    "), 3891);
+  assertToStringEquals("ab", res[1321].firstMatch("ab"), 3892);
+  assertNull(res[1321].firstMatch("a\nb"), 3893);
+  assertNull(res[1321].firstMatch("a\x0db"), 3894);
+  assertNull(res[1321].firstMatch("a\x0d\nb"), 3895);
+  assertNull(res[1321].firstMatch("a\x0bb"), 3896);
+  assertNull(res[1321].firstMatch("a\x0cb"), 3897);
+  assertNull(res[1321].firstMatch("a\x85b   "), 3898);
+  assertNull(res[1321].firstMatch("a\n\x0db    "), 3899);
+  assertNull(res[1321].firstMatch("a\n\x0d\x85\x0cb "), 3900);
+  assertNull(res[1322].firstMatch("a\nb"), 3901);
+  assertNull(res[1322].firstMatch("a\x0db"), 3902);
+  assertNull(res[1322].firstMatch("a\x0d\nb"), 3903);
+  assertNull(res[1322].firstMatch("a\x0bb"), 3904);
+  assertNull(res[1322].firstMatch("a\x0cb"), 3905);
+  assertNull(res[1322].firstMatch("a\x85b   "), 3906);
+  assertNull(res[1322].firstMatch("a\n\x0db    "), 3907);
+  assertNull(res[1322].firstMatch("a\n\x0d\x85\x0cb "), 3908);
+  assertNull(res[1322].firstMatch("** Failers"), 3909);
+  assertNull(res[1322].firstMatch("ab  "), 3910);
+  assertNull(res[1323].firstMatch("a\nb"), 3911);
+  assertNull(res[1323].firstMatch("a\n\x0db"), 3912);
+  assertNull(res[1323].firstMatch("a\n\x0d\x85b"), 3913);
+  assertNull(res[1323].firstMatch("a\x0d\n\x0d\nb "), 3914);
+  assertNull(res[1323].firstMatch("a\x0d\n\x0d\n\x0d\nb "), 3915);
+  assertNull(res[1323].firstMatch("a\n\x0d\n\x0db"), 3916);
+  assertNull(res[1323].firstMatch("a\n\n\x0d\nb "), 3917);
+  assertNull(res[1323].firstMatch("** Failers"), 3918);
+  assertNull(res[1323].firstMatch("a\n\n\n\x0db"), 3919);
+  assertNull(res[1323].firstMatch("a\x0d"), 3920);
+  assertToStringEquals("aRb", res[1324].firstMatch("aRb"), 3921);
+  assertNull(res[1324].firstMatch("** Failers"), 3922);
+  assertNull(res[1324].firstMatch("a\nb  "), 3923);
+  assertToStringEquals("afoo", res[1325].firstMatch("afoo"), 3924);
+  assertNull(res[1325].firstMatch("** Failers "), 3925);
+  assertNull(res[1325].firstMatch("\x0d\nfoo "), 3926);
+  assertNull(res[1325].firstMatch("\nfoo "), 3927);
+  assertToStringEquals("afoo", res[1326].firstMatch("afoo"), 3928);
+  assertNull(res[1326].firstMatch("\nfoo "), 3929);
+  assertNull(res[1326].firstMatch("** Failers "), 3930);
+  assertNull(res[1326].firstMatch("\x0d\nfoo "), 3931);
+  assertToStringEquals("afoo", res[1327].firstMatch("afoo"), 3932);
+  assertNull(res[1327].firstMatch("** Failers "), 3933);
+  assertNull(res[1327].firstMatch("\nfoo "), 3934);
+  assertNull(res[1327].firstMatch("\x0d\nfoo "), 3935);
+  assertToStringEquals("afoo", res[1328].firstMatch("afoo"), 3936);
+  assertNull(res[1328].firstMatch("\x0d\nfoo "), 3937);
+  assertNull(res[1328].firstMatch("\nfoo "), 3938);
+  assertToStringEquals("", res[1329].firstMatch("abc\x0d\x0dxyz"), 3939);
+  assertToStringEquals("", res[1329].firstMatch("abc\n\x0dxyz  "), 3940);
+  assertNull(res[1329].firstMatch("** Failers "), 3941);
+  assertToStringEquals("", res[1329].firstMatch("abc\x0d\nxyz"), 3942);
+  assertToStringEquals("X", res[1330].firstMatch("XABC"), 3943);
+  assertNull(res[1330].firstMatch("** Failers "), 3944);
+  assertToStringEquals("X", res[1330].firstMatch("XABCB"), 3945);
+  assertNull(res[1330].firstMatch("abc\x0d\n\x0d\n"), 3946);
+  assertNull(res[1330].firstMatch("abc\x0d\n\x0d\n"), 3947);
+  assertNull(res[1330].firstMatch("abc\x0d\n\x0d\n"), 3948);
+  assertThrows(() => new RegExp(r"(?|(abc)|(xyz))"), 3949);
+  assertThrows(() => new RegExp(r"(x)(?|(abc)|(xyz))(x)"), 3950);
+  assertNull(res[1330].firstMatch("xabcx"), 3951);
+  assertNull(res[1330].firstMatch("xxyzx "), 3952);
+  assertThrows(() => new RegExp(r"(x)(?|(abc)(pqr)|(xyz))(x)"), 3953);
+  assertNull(res[1330].firstMatch("xabcpqrx"), 3954);
+  assertNull(res[1330].firstMatch("xxyzx "), 3955);
+  assertNull(res[1330].firstMatch("abcabc"), 3956);
+  assertNull(res[1330].firstMatch("xyzabc "), 3957);
+  assertNull(res[1330].firstMatch("** Failers "), 3958);
+  assertNull(res[1330].firstMatch("xyzxyz "), 3959);
+  assertNull(res[1331].firstMatch("X X\n"), 3960);
+  assertNull(res[1331].firstMatch("X\x09X\x0b"), 3961);
+  assertNull(res[1331].firstMatch("** Failers"), 3962);
+  assertNull(res[1331].firstMatch("\xa0 X\n   "), 3963);
+  assertNull(res[1332].firstMatch("\x09 \xa0X\n\x0b\x0c\x0d\n"), 3964);
+  assertNull(res[1332].firstMatch("\x09 \xa0\n\x0b\x0c\x0d\n"), 3965);
+  assertNull(res[1332].firstMatch("\x09 \xa0\n\x0b\x0c"), 3966);
+  assertNull(res[1332].firstMatch("** Failers "), 3967);
+  assertNull(res[1332].firstMatch("\x09 \xa0\n\x0b"), 3968);
+  assertNull(res[1332].firstMatch(" "), 3969);
+  assertNull(res[1333].firstMatch("XY  ABCDE"), 3970);
+  assertNull(res[1333].firstMatch("XY  PQR ST "), 3971);
+  assertNull(res[1334].firstMatch("XY  AB    PQRS"), 3972);
+  assertNull(res[1335].firstMatch(">XNNNYZ"), 3973);
+  assertNull(res[1335].firstMatch(">  X NYQZ"), 3974);
+  assertNull(res[1335].firstMatch("** Failers"), 3975);
+  assertNull(res[1335].firstMatch(">XYZ   "), 3976);
+  assertNull(res[1335].firstMatch(">  X NY Z"), 3977);
+  assertNull(res[1336].firstMatch(">XY\nZ\nA\x0bNN\x0c"), 3978);
+  assertNull(res[1336].firstMatch(">\n\x0dX\nY\n\x0bZZZ\nAAA\x0bNNN\x0c"), 3979);
+  assertNull(res[1337].firstMatch("\x0d\nA"), 3980);
+  assertToStringEquals("\nA", res[1338].firstMatch("\x0d\nA "), 3981);
+  assertToStringEquals("\nA", res[1339].firstMatch("\x0d\nA "), 3982);
+  assertToStringEquals("\nA,\n", res[1340].firstMatch("\x0d\nA "), 3983);
+  assertNull(res[1341].firstMatch("a\x0db"), 3984);
+  assertNull(res[1341].firstMatch("a\nb"), 3985);
+  assertNull(res[1341].firstMatch("a\x0d\nb"), 3986);
+  assertNull(res[1341].firstMatch("** Failers"), 3987);
+  assertNull(res[1341].firstMatch("a\x85b"), 3988);
+  assertNull(res[1341].firstMatch("a\x0bb     "), 3989);
+  assertNull(res[1342].firstMatch("a\x0db"), 3990);
+  assertNull(res[1342].firstMatch("a\nb"), 3991);
+  assertNull(res[1342].firstMatch("a\x0d\nb"), 3992);
+  assertNull(res[1342].firstMatch("a\x85b"), 3993);
+  assertNull(res[1342].firstMatch("a\x0bb     "), 3994);
+  assertNull(res[1342].firstMatch("** Failers "), 3995);
+  assertNull(res[1342].firstMatch("a\x85b<bsr_anycrlf>"), 3996);
+  assertNull(res[1342].firstMatch("a\x0bb<bsr_anycrlf>"), 3997);
+  assertNull(res[1343].firstMatch("a\x0db"), 3998);
+  assertNull(res[1343].firstMatch("a\nb"), 3999);
+  assertNull(res[1343].firstMatch("a\x0d\nb"), 4000);
+  assertNull(res[1343].firstMatch("** Failers"), 4001);
+  assertNull(res[1343].firstMatch("a\x85b"), 4002);
+  assertNull(res[1343].firstMatch("a\x0bb     "), 4003);
+  assertNull(res[1344].firstMatch("a\x0db"), 4004);
+  assertNull(res[1344].firstMatch("a\nb"), 4005);
+  assertNull(res[1344].firstMatch("a\x0d\nb"), 4006);
+  assertNull(res[1344].firstMatch("a\x85b"), 4007);
+  assertNull(res[1344].firstMatch("a\x0bb     "), 4008);
+  assertNull(res[1344].firstMatch("** Failers "), 4009);
+  assertNull(res[1344].firstMatch("a\x85b<bsr_anycrlf>"), 4010);
+  assertNull(res[1344].firstMatch("a\x0bb<bsr_anycrlf>"), 4011);
+  assertNull(res[1345].firstMatch("a\x0d\n\nb"), 4012);
+  assertNull(res[1345].firstMatch("a\n\x0d\x0db"), 4013);
+  assertNull(res[1345].firstMatch("a\x0d\n\x0d\n\x0d\n\x0d\nb"), 4014);
+  assertNull(res[1345].firstMatch("** Failers"), 4015);
+  assertNull(res[1345].firstMatch("a\x8585b"), 4016);
+  assertNull(res[1345].firstMatch("a\x0b\x00bb     "), 4017);
+  assertNull(res[1346].firstMatch("a\x0d\x0db"), 4018);
+  assertNull(res[1346].firstMatch("a\n\n\nb"), 4019);
+  assertNull(res[1346].firstMatch("a\x0d\n\n\x0d\x0db"), 4020);
+  assertNull(res[1346].firstMatch("a\x8585b"), 4021);
+  assertNull(res[1346].firstMatch("a\x0b\x00bb     "), 4022);
+  assertNull(res[1346].firstMatch("** Failers "), 4023);
+  assertNull(res[1346].firstMatch("a\x0d\x0d\x0d\x0d\x0db "), 4024);
+  assertNull(res[1346].firstMatch("a\x8585b<bsr_anycrlf>"), 4025);
+  assertNull(res[1346].firstMatch("a\x0b\x00bb<bsr_anycrlf>"), 4026);
+  assertToStringEquals("abc", res[1347].firstMatch("abc "), 4027);
+  assertNull(res[1348].firstMatch("** Failers"), 4028);
+  assertNull(res[1348].firstMatch("ab"), 4029);
+  assertNull(res[1349].firstMatch("** Failers"), 4030);
+  assertNull(res[1349].firstMatch("ab "), 4031);
+  assertNull(res[1349].firstMatch("** Failers"), 4032);
+  assertNull(res[1349].firstMatch("ab "), 4033);
+  assertToStringEquals("aXb", res[1350].firstMatch("aXb"), 4034);
+  assertToStringEquals("a\nb", res[1350].firstMatch("a\nb "), 4035);
+  assertNull(res[1350].firstMatch("** Failers"), 4036);
+  assertNull(res[1350].firstMatch("ab  "), 4037);
+  assertToStringEquals("aXb", res[1351].firstMatch("aXb"), 4038);
+  assertToStringEquals("a\nX\nXb", res[1351].firstMatch("a\nX\nXb "), 4039);
+  assertNull(res[1351].firstMatch("** Failers"), 4040);
+  assertNull(res[1351].firstMatch("ab  "), 4041);
+  assertNull(res[1352].firstMatch("ab"), 4042);
+  assertNull(res[1352].firstMatch("ax{100}b  "), 4043);
+  assertNull(res[1352].firstMatch("ax{100}x{100}b  "), 4044);
+  assertNull(res[1352].firstMatch("ax{100}b  "), 4045);
+  assertNull(res[1352].firstMatch("ax{100}x{100}b  "), 4046);
+  assertNull(res[1352].firstMatch("*** Failers "), 4047);
+  assertNull(res[1352].firstMatch("ab"), 4048);
+  assertNull(res[1352].firstMatch(" "), 4049);
+  assertToStringEquals("X", res[1353].firstMatch("Xoanon"), 4050);
+  assertToStringEquals("X", res[1353].firstMatch("+Xoanon"), 4051);
+  assertToStringEquals("X", res[1353].firstMatch("x{300}Xoanon "), 4052);
+  assertNull(res[1353].firstMatch("*** Failers "), 4053);
+  assertNull(res[1353].firstMatch("YXoanon  "), 4054);
+  assertToStringEquals("X", res[1354].firstMatch("YXoanon"), 4055);
+  assertNull(res[1354].firstMatch("*** Failers"), 4056);
+  assertNull(res[1354].firstMatch("Xoanon"), 4057);
+  assertNull(res[1354].firstMatch("+Xoanon    "), 4058);
+  assertNull(res[1354].firstMatch("x{300}Xoanon "), 4059);
+  assertToStringEquals("X", res[1355].firstMatch("X+oanon"), 4060);
+  assertNull(res[1355].firstMatch("ZXx{300}oanon "), 4061);
+  assertToStringEquals("X", res[1355].firstMatch("FAX "), 4062);
+  assertNull(res[1355].firstMatch("*** Failers "), 4063);
+  assertNull(res[1355].firstMatch("Xoanon  "), 4064);
+  assertToStringEquals("X", res[1356].firstMatch("Xoanon  "), 4065);
+  assertNull(res[1356].firstMatch("*** Failers"), 4066);
+  assertNull(res[1356].firstMatch("X+oanon"), 4067);
+  assertToStringEquals("X", res[1356].firstMatch("ZXx{300}oanon "), 4068);
+  assertNull(res[1356].firstMatch("FAX "), 4069);
+  assertToStringEquals("b", res[1357].firstMatch("abcd"), 4070);
+  assertToStringEquals("x", res[1357].firstMatch("ax{100}   "), 4071);
+  assertToStringEquals("b", res[1357].firstMatch("ab99"), 4072);
+  assertToStringEquals("x", res[1357].firstMatch("x{123}x{123}45"), 4073);
+  assertToStringEquals("x", res[1357].firstMatch("x{400}x{401}x{402}6  "), 4074);
+  assertToStringEquals("*", res[1357].firstMatch("*** Failers"), 4075);
+  assertToStringEquals("d", res[1357].firstMatch("d99"), 4076);
+  assertToStringEquals("x", res[1357].firstMatch("x{123}x{122}4   "), 4077);
+  assertToStringEquals("x", res[1357].firstMatch("x{400}x{403}6  "), 4078);
+  assertToStringEquals("x", res[1357].firstMatch("x{400}x{401}x{402}x{402}6  "), 4079);
+  assertNull(res[1358].firstMatch("\ufffd]"), 4080);
+  assertNull(res[1358].firstMatch("\ufffd"), 4081);
+  assertNull(res[1358].firstMatch("\ufffd\ufffd\ufffd"), 4082);
+  assertNull(res[1358].firstMatch("\ufffd\ufffd\ufffd?"), 4083);
+  assertToStringEquals("acb", res[1359].firstMatch("acb"), 4084);
+  assertToStringEquals("ab", res[1359].firstMatch("ab"), 4085);
+  assertNull(res[1359].firstMatch("ax{100}b "), 4086);
+  assertNull(res[1359].firstMatch("*** Failers"), 4087);
+  assertNull(res[1359].firstMatch("a\nb  "), 4088);
+  assertNull(res[1360].firstMatch("ax{4000}xyb "), 4089);
+  assertNull(res[1360].firstMatch("ax{4000}yb "), 4090);
+  assertNull(res[1360].firstMatch("ax{4000}x{100}yb "), 4091);
+  assertNull(res[1360].firstMatch("*** Failers"), 4092);
+  assertNull(res[1360].firstMatch("ax{4000}b "), 4093);
+  assertNull(res[1360].firstMatch("ac\ncb "), 4094);
+  assertToStringEquals("a\xc0,,\xc0", res[1361].firstMatch("a\xc0\x88b"), 4095);
+  assertToStringEquals("ax,,x", res[1362].firstMatch("ax{100}b"), 4096);
+  assertToStringEquals("a\xc0\x88b,\xc0\x88,b", res[1363].firstMatch("a\xc0\x88b"), 4097);
+  assertToStringEquals("ax{100}b,x{100},b", res[1364].firstMatch("ax{100}b"), 4098);
+  assertToStringEquals("a\xc0\x92,\xc0,\x92", res[1365].firstMatch("a\xc0\x92bcd"), 4099);
+  assertToStringEquals("ax{,x,{", res[1366].firstMatch("ax{240}bcd"), 4100);
+  assertToStringEquals("a\xc0\x92,\xc0,\x92", res[1367].firstMatch("a\xc0\x92bcd"), 4101);
+  assertToStringEquals("ax{,x,{", res[1368].firstMatch("ax{240}bcd"), 4102);
+  assertToStringEquals("a\xc0,,\xc0", res[1369].firstMatch("a\xc0\x92bcd"), 4103);
+  assertToStringEquals("ax,,x", res[1370].firstMatch("ax{240}bcd"), 4104);
+  assertNull(res[1371].firstMatch("ax{1234}xyb "), 4105);
+  assertNull(res[1371].firstMatch("ax{1234}x{4321}yb "), 4106);
+  assertNull(res[1371].firstMatch("ax{1234}x{4321}x{3412}b "), 4107);
+  assertNull(res[1371].firstMatch("*** Failers"), 4108);
+  assertNull(res[1371].firstMatch("ax{1234}b "), 4109);
+  assertNull(res[1371].firstMatch("ac\ncb "), 4110);
+  assertToStringEquals("ax{1234}xyb,x{1234}xy", res[1372].firstMatch("ax{1234}xyb "), 4111);
+  assertToStringEquals("ax{1234}x{4321}yb,x{1234}x{4321}y", res[1372].firstMatch("ax{1234}x{4321}yb "), 4112);
+  assertToStringEquals("ax{1234}x{4321}x{3412}b,x{1234}x{4321}x{3412}", res[1372].firstMatch("ax{1234}x{4321}x{3412}b "), 4113);
+  assertToStringEquals("axxxxbcdefghijb,xxxxbcdefghij", res[1372].firstMatch("axxxxbcdefghijb "), 4114);
+  assertToStringEquals("ax{1234}x{4321}x{3412}x{3421}b,x{1234}x{4321}x{3412}x{3421}", res[1372].firstMatch("ax{1234}x{4321}x{3412}x{3421}b "), 4115);
+  assertNull(res[1372].firstMatch("*** Failers"), 4116);
+  assertToStringEquals("ax{1234}b,x{1234}", res[1372].firstMatch("ax{1234}b "), 4117);
+  assertToStringEquals("ax{1234}xyb,x{1234}xy", res[1373].firstMatch("ax{1234}xyb "), 4118);
+  assertToStringEquals("ax{1234}x{4321}yb,x{1234}x{4321}y", res[1373].firstMatch("ax{1234}x{4321}yb "), 4119);
+  assertToStringEquals("ax{1234}x{4321}x{3412}b,x{1234}x{4321}x{3412}", res[1373].firstMatch("ax{1234}x{4321}x{3412}b "), 4120);
+  assertToStringEquals("axxxxb,xxxx", res[1373].firstMatch("axxxxbcdefghijb "), 4121);
+  assertToStringEquals("ax{1234}x{4321}x{3412}x{3421}b,x{1234}x{4321}x{3412}x{3421}", res[1373].firstMatch("ax{1234}x{4321}x{3412}x{3421}b "), 4122);
+  assertNull(res[1373].firstMatch("*** Failers"), 4123);
+  assertToStringEquals("ax{1234}b,x{1234}", res[1373].firstMatch("ax{1234}b "), 4124);
+  assertNull(res[1374].firstMatch("ax{1234}xyb "), 4125);
+  assertNull(res[1374].firstMatch("ax{1234}x{4321}yb "), 4126);
+  assertNull(res[1374].firstMatch("ax{1234}x{4321}x{3412}b "), 4127);
+  assertToStringEquals("axxxxb,xxxx", res[1374].firstMatch("axxxxbcdefghijb "), 4128);
+  assertNull(res[1374].firstMatch("ax{1234}x{4321}x{3412}x{3421}b "), 4129);
+  assertToStringEquals("axbxxb,xbxx", res[1374].firstMatch("axbxxbcdefghijb "), 4130);
+  assertToStringEquals("axxxxxb,xxxxx", res[1374].firstMatch("axxxxxbcdefghijb "), 4131);
+  assertNull(res[1374].firstMatch("*** Failers"), 4132);
+  assertNull(res[1374].firstMatch("ax{1234}b "), 4133);
+  assertNull(res[1374].firstMatch("axxxxxxbcdefghijb "), 4134);
+  assertNull(res[1375].firstMatch("ax{1234}xyb "), 4135);
+  assertNull(res[1375].firstMatch("ax{1234}x{4321}yb "), 4136);
+  assertNull(res[1375].firstMatch("ax{1234}x{4321}x{3412}b "), 4137);
+  assertToStringEquals("axxxxb,xxxx", res[1375].firstMatch("axxxxbcdefghijb "), 4138);
+  assertNull(res[1375].firstMatch("ax{1234}x{4321}x{3412}x{3421}b "), 4139);
+  assertToStringEquals("axbxxb,xbxx", res[1375].firstMatch("axbxxbcdefghijb "), 4140);
+  assertToStringEquals("axxxxxb,xxxxx", res[1375].firstMatch("axxxxxbcdefghijb "), 4141);
+  assertNull(res[1375].firstMatch("*** Failers"), 4142);
+  assertNull(res[1375].firstMatch("ax{1234}b "), 4143);
+  assertNull(res[1375].firstMatch("axxxxxxbcdefghijb "), 4144);
+  assertNull(res[1375].firstMatch("*** Failers"), 4145);
+  assertNull(res[1375].firstMatch("x{100}"), 4146);
+  assertNull(res[1375].firstMatch("aXbcd"), 4147);
+  assertNull(res[1375].firstMatch("ax{100}bcd"), 4148);
+  assertNull(res[1375].firstMatch("ax{100000}bcd"), 4149);
+  assertNull(res[1375].firstMatch("x{100}x{100}x{100}b"), 4150);
+  assertNull(res[1375].firstMatch("*** Failers "), 4151);
+  assertNull(res[1375].firstMatch("x{100}x{100}b"), 4152);
+  assertNull(res[1375].firstMatch("x{ab} "), 4153);
+  assertNull(res[1375].firstMatch("\xc2\xab"), 4154);
+  assertNull(res[1375].firstMatch("*** Failers "), 4155);
+  assertNull(res[1375].firstMatch("\x00{ab}"), 4156);
+  assertNull(res[1375].firstMatch("WXYZ"), 4157);
+  assertNull(res[1375].firstMatch("x{256}XYZ "), 4158);
+  assertNull(res[1375].firstMatch("*** Failers"), 4159);
+  assertNull(res[1375].firstMatch("XYZ "), 4160);
+  assertToStringEquals("bcd", res[1376].firstMatch("bcd"), 4161);
+  assertToStringEquals("x{", res[1377].firstMatch("x{100}bc"), 4163);
+  assertToStringEquals("x{100}bcA", res[1378].firstMatch("x{100}bcAa"), 4164);
+  assertToStringEquals("x{", res[1379].firstMatch("x{100}bca"), 4165);
+  assertToStringEquals("bcd", res[1380].firstMatch("bcd"), 4166);
+  assertToStringEquals("x{", res[1381].firstMatch("x{100}bc"), 4168);
+  assertToStringEquals("x{100}bc", res[1382].firstMatch("x{100}bcAa"), 4169);
+  assertToStringEquals("x{", res[1383].firstMatch("x{100}bca"), 4170);
+  assertNull(res[1383].firstMatch("abcd"), 4171);
+  assertNull(res[1383].firstMatch("abcd"), 4172);
+  assertToStringEquals("x{", res[1383].firstMatch("x{100}x{100} "), 4173);
+  assertToStringEquals("x{", res[1383].firstMatch("x{100}x{100} "), 4174);
+  assertToStringEquals("x{", res[1383].firstMatch("x{100}x{100}x{100}x{100} "), 4175);
+  assertNull(res[1383].firstMatch("abce"), 4176);
+  assertToStringEquals("x{", res[1383].firstMatch("x{100}x{100}x{100}x{100} "), 4177);
+  assertNull(res[1383].firstMatch("abcdx{100}x{100}x{100}x{100} "), 4178);
+  assertNull(res[1383].firstMatch("abcdx{100}x{100}x{100}x{100} "), 4179);
+  assertNull(res[1383].firstMatch("abcdx{100}x{100}x{100}x{100} "), 4180);
+  assertNull(res[1383].firstMatch("abcdx{100}x{100}x{100}XX"), 4181);
+  assertNull(res[1383].firstMatch("abcdx{100}x{100}x{100}x{100}x{100}x{100}x{100}XX"), 4182);
+  assertNull(res[1383].firstMatch("abcdx{100}x{100}x{100}x{100}x{100}x{100}x{100}XX"), 4183);
+  assertToStringEquals("Xy", res[1383].firstMatch("Xyyyax{100}x{100}bXzzz"), 4184);
+  assertToStringEquals("X", res[1386].firstMatch("1X2"), 4185);
+  assertToStringEquals("x", res[1386].firstMatch("1x{100}2 "), 4186);
+  assertToStringEquals(">X", res[1387].firstMatch("> >X Y"), 4187);
+  assertToStringEquals(">x", res[1387].firstMatch("> >x{100} Y"), 4188);
+  assertToStringEquals("1", res[1388].firstMatch("x{100}3"), 4189);
+  assertToStringEquals(" ", res[1389].firstMatch("x{100} X"), 4190);
+  assertToStringEquals("abcd", res[1390].firstMatch("12abcd34"), 4191);
+  assertToStringEquals("*** Failers", res[1390].firstMatch("*** Failers"), 4192);
+  assertToStringEquals("  ", res[1390].firstMatch("1234  "), 4193);
+  assertToStringEquals("abc", res[1391].firstMatch("12abcd34"), 4194);
+  assertToStringEquals("ab", res[1391].firstMatch("12ab34"), 4195);
+  assertToStringEquals("***", res[1391].firstMatch("*** Failers  "), 4196);
+  assertNull(res[1391].firstMatch("1234"), 4197);
+  assertToStringEquals("  ", res[1391].firstMatch("12a34  "), 4198);
+  assertToStringEquals("ab", res[1392].firstMatch("12abcd34"), 4199);
+  assertToStringEquals("ab", res[1392].firstMatch("12ab34"), 4200);
+  assertToStringEquals("**", res[1392].firstMatch("*** Failers  "), 4201);
+  assertNull(res[1392].firstMatch("1234"), 4202);
+  assertToStringEquals("  ", res[1392].firstMatch("12a34  "), 4203);
+  assertToStringEquals("12", res[1393].firstMatch("12abcd34"), 4204);
+  assertNull(res[1393].firstMatch("*** Failers"), 4205);
+  assertToStringEquals("12", res[1394].firstMatch("12abcd34"), 4206);
+  assertToStringEquals("123", res[1394].firstMatch("1234abcd"), 4207);
+  assertNull(res[1394].firstMatch("*** Failers  "), 4208);
+  assertNull(res[1394].firstMatch("1.4 "), 4209);
+  assertToStringEquals("12", res[1395].firstMatch("12abcd34"), 4210);
+  assertToStringEquals("12", res[1395].firstMatch("1234abcd"), 4211);
+  assertNull(res[1395].firstMatch("*** Failers  "), 4212);
+  assertNull(res[1395].firstMatch("1.4 "), 4213);
+  assertToStringEquals("12abcd34", res[1396].firstMatch("12abcd34"), 4214);
+  assertToStringEquals("***", res[1396].firstMatch("*** Failers"), 4215);
+  assertNull(res[1396].firstMatch("     "), 4216);
+  assertToStringEquals("12a", res[1397].firstMatch("12abcd34"), 4217);
+  assertToStringEquals("123", res[1397].firstMatch("1234abcd"), 4218);
+  assertToStringEquals("***", res[1397].firstMatch("*** Failers"), 4219);
+  assertNull(res[1397].firstMatch("       "), 4220);
+  assertToStringEquals("12", res[1398].firstMatch("12abcd34"), 4221);
+  assertToStringEquals("12", res[1398].firstMatch("1234abcd"), 4222);
+  assertToStringEquals("**", res[1398].firstMatch("*** Failers"), 4223);
+  assertNull(res[1398].firstMatch("       "), 4224);
+  assertToStringEquals(">      <", res[1399].firstMatch("12>      <34"), 4225);
+  assertNull(res[1399].firstMatch("*** Failers"), 4226);
+  assertToStringEquals(">  <", res[1400].firstMatch("ab>  <cd"), 4227);
+  assertToStringEquals(">   <", res[1400].firstMatch("ab>   <ce"), 4228);
+  assertNull(res[1400].firstMatch("*** Failers"), 4229);
+  assertNull(res[1400].firstMatch("ab>    <cd "), 4230);
+  assertToStringEquals(">  <", res[1401].firstMatch("ab>  <cd"), 4231);
+  assertToStringEquals(">   <", res[1401].firstMatch("ab>   <ce"), 4232);
+  assertNull(res[1401].firstMatch("*** Failers"), 4233);
+  assertNull(res[1401].firstMatch("ab>    <cd "), 4234);
+  assertToStringEquals("12", res[1402].firstMatch("12      34"), 4235);
+  assertToStringEquals("Failers", res[1402].firstMatch("*** Failers"), 4236);
+  assertNull(res[1402].firstMatch("+++=*! "), 4237);
+  assertToStringEquals("ab", res[1403].firstMatch("ab  cd"), 4238);
+  assertToStringEquals("abc", res[1403].firstMatch("abcd ce"), 4239);
+  assertToStringEquals("Fai", res[1403].firstMatch("*** Failers"), 4240);
+  assertNull(res[1403].firstMatch("a.b.c"), 4241);
+  assertToStringEquals("ab", res[1404].firstMatch("ab  cd"), 4242);
+  assertToStringEquals("ab", res[1404].firstMatch("abcd ce"), 4243);
+  assertToStringEquals("Fa", res[1404].firstMatch("*** Failers"), 4244);
+  assertNull(res[1404].firstMatch("a.b.c"), 4245);
+  assertToStringEquals("====", res[1405].firstMatch("12====34"), 4246);
+  assertToStringEquals("*** ", res[1405].firstMatch("*** Failers"), 4247);
+  assertToStringEquals(" ", res[1405].firstMatch("abcd "), 4248);
+  assertToStringEquals("===", res[1406].firstMatch("ab====cd"), 4249);
+  assertToStringEquals("==", res[1406].firstMatch("ab==cd"), 4250);
+  assertToStringEquals("***", res[1406].firstMatch("*** Failers"), 4251);
+  assertNull(res[1406].firstMatch("a.b.c"), 4252);
+  assertToStringEquals("==", res[1407].firstMatch("ab====cd"), 4253);
+  assertToStringEquals("==", res[1407].firstMatch("ab==cd"), 4254);
+  assertToStringEquals("**", res[1407].firstMatch("*** Failers"), 4255);
+  assertNull(res[1407].firstMatch("a.b.c"), 4256);
+  assertNull(res[1407].firstMatch("x{100}"), 4257);
+  assertNull(res[1407].firstMatch("Zx{100}"), 4258);
+  assertNull(res[1407].firstMatch("x{100}Z"), 4259);
+  assertToStringEquals("**", res[1407].firstMatch("*** Failers "), 4260);
+  assertNull(res[1407].firstMatch("Zx{100}"), 4261);
+  assertNull(res[1407].firstMatch("x{100}"), 4262);
+  assertNull(res[1407].firstMatch("x{100}Z"), 4263);
+  assertToStringEquals("**", res[1407].firstMatch("*** Failers "), 4264);
+  assertNull(res[1407].firstMatch("abcx{200}X"), 4265);
+  assertNull(res[1407].firstMatch("abcx{100}X "), 4266);
+  assertToStringEquals("**", res[1407].firstMatch("*** Failers"), 4267);
+  assertToStringEquals("  ", res[1407].firstMatch("X  "), 4268);
+  assertNull(res[1407].firstMatch("abcx{200}X"), 4269);
+  assertNull(res[1407].firstMatch("abcx{100}X "), 4270);
+  assertNull(res[1407].firstMatch("abQX "), 4271);
+  assertToStringEquals("**", res[1407].firstMatch("*** Failers"), 4272);
+  assertToStringEquals("  ", res[1407].firstMatch("X  "), 4273);
+  assertNull(res[1407].firstMatch("abcx{100}x{200}x{100}X"), 4274);
+  assertToStringEquals("**", res[1407].firstMatch("*** Failers"), 4275);
+  assertNull(res[1407].firstMatch("abcx{200}X"), 4276);
+  assertToStringEquals("  ", res[1407].firstMatch("X  "), 4277);
+  assertNull(res[1407].firstMatch("AX"), 4278);
+  assertNull(res[1407].firstMatch("x{150}X"), 4279);
+  assertNull(res[1407].firstMatch("x{500}X "), 4280);
+  assertToStringEquals("**", res[1407].firstMatch("*** Failers"), 4281);
+  assertNull(res[1407].firstMatch("x{100}X"), 4282);
+  assertToStringEquals("  ", res[1407].firstMatch("x{200}X   "), 4283);
+  assertNull(res[1407].firstMatch("AX"), 4284);
+  assertNull(res[1407].firstMatch("x{150}X"), 4285);
+  assertNull(res[1407].firstMatch("x{500}X "), 4286);
+  assertToStringEquals("**", res[1407].firstMatch("*** Failers"), 4287);
+  assertNull(res[1407].firstMatch("x{100}X"), 4288);
+  assertToStringEquals("  ", res[1407].firstMatch("x{200}X   "), 4289);
+  assertNull(res[1407].firstMatch("QX "), 4290);
+  assertNull(res[1407].firstMatch("AX"), 4291);
+  assertNull(res[1407].firstMatch("x{500}X "), 4292);
+  assertToStringEquals("**", res[1407].firstMatch("*** Failers"), 4293);
+  assertNull(res[1407].firstMatch("x{100}X"), 4294);
+  assertNull(res[1407].firstMatch("x{150}X"), 4295);
+  assertToStringEquals("  ", res[1407].firstMatch("x{200}X   "), 4296);
+  assertNull(res[1407].firstMatch("z"), 4297);
+  assertNull(res[1407].firstMatch("Z "), 4298);
+  assertNull(res[1407].firstMatch("x{100}"), 4299);
+  assertToStringEquals("**", res[1407].firstMatch("*** Failers"), 4300);
+  assertNull(res[1407].firstMatch("x{102}"), 4301);
+  assertToStringEquals("  ", res[1407].firstMatch("y    "), 4302);
+  assertToStringEquals("\xff", res[1408].firstMatch(">\xff<"), 4303);
+  assertNull(res[1409].firstMatch(">x{ff}<"), 4304);
+  assertToStringEquals("X", res[1410].firstMatch("XYZ"), 4305);
+  assertToStringEquals("X", res[1411].firstMatch("XYZ"), 4306);
+  assertToStringEquals("x", res[1411].firstMatch("x{123} "), 4307);
+  assertToStringEquals(",", res[1416].firstMatch("catac"), 4308);
+  assertToStringEquals(",", res[1416].firstMatch("ax{256}a "), 4309);
+  assertToStringEquals(",", res[1416].firstMatch("x{85}"), 4310);
+  assertToStringEquals("abc1", res[1417].firstMatch("abc1 \nabc2 \x0babc3xx \x0cabc4 \x0dabc5xx \x0d\nabc6 x{0085}abc7 x{2028}abc8 x{2029}abc9 JUNK"), 4311);
+  assertToStringEquals("abc1", res[1418].firstMatch("abc1\n abc2\x0b abc3\x0c abc4\x0d abc5\x0d\n abc6x{0085} abc7x{2028} abc8x{2029} abc9"), 4312);
+  assertNull(res[1419].firstMatch("a\nb"), 4313);
+  assertNull(res[1419].firstMatch("a\x0db"), 4314);
+  assertNull(res[1419].firstMatch("a\x0d\nb"), 4315);
+  assertNull(res[1419].firstMatch("a\x0bb"), 4316);
+  assertNull(res[1419].firstMatch("a\x0cb"), 4317);
+  assertNull(res[1419].firstMatch("ax{85}b   "), 4318);
+  assertNull(res[1419].firstMatch("ax{2028}b "), 4319);
+  assertNull(res[1419].firstMatch("ax{2029}b "), 4320);
+  assertNull(res[1419].firstMatch("** Failers"), 4321);
+  assertNull(res[1419].firstMatch("a\n\x0db    "), 4322);
+  assertToStringEquals("ab", res[1420].firstMatch("ab"), 4323);
+  assertNull(res[1420].firstMatch("a\nb"), 4324);
+  assertNull(res[1420].firstMatch("a\x0db"), 4325);
+  assertNull(res[1420].firstMatch("a\x0d\nb"), 4326);
+  assertNull(res[1420].firstMatch("a\x0bb"), 4327);
+  assertNull(res[1420].firstMatch("a\x0cx{2028}x{2029}b"), 4328);
+  assertNull(res[1420].firstMatch("ax{85}b   "), 4329);
+  assertNull(res[1420].firstMatch("a\n\x0db    "), 4330);
+  assertNull(res[1420].firstMatch("a\n\x0dx{85}\x0cb "), 4331);
+  assertNull(res[1421].firstMatch("a\nb"), 4332);
+  assertNull(res[1421].firstMatch("a\x0db"), 4333);
+  assertNull(res[1421].firstMatch("a\x0d\nb"), 4334);
+  assertNull(res[1421].firstMatch("a\x0bb"), 4335);
+  assertNull(res[1421].firstMatch("a\x0cx{2028}x{2029}b"), 4336);
+  assertNull(res[1421].firstMatch("ax{85}b   "), 4337);
+  assertNull(res[1421].firstMatch("a\n\x0db    "), 4338);
+  assertNull(res[1421].firstMatch("a\n\x0dx{85}\x0cb "), 4339);
+  assertNull(res[1421].firstMatch("** Failers"), 4340);
+  assertNull(res[1421].firstMatch("ab  "), 4341);
+  assertNull(res[1422].firstMatch("a\nb"), 4342);
+  assertNull(res[1422].firstMatch("a\n\x0db"), 4343);
+  assertNull(res[1422].firstMatch("a\n\x0dx{85}b"), 4344);
+  assertNull(res[1422].firstMatch("a\x0d\n\x0d\nb "), 4345);
+  assertNull(res[1422].firstMatch("a\x0d\n\x0d\n\x0d\nb "), 4346);
+  assertNull(res[1422].firstMatch("a\n\x0d\n\x0db"), 4347);
+  assertNull(res[1422].firstMatch("a\n\n\x0d\nb "), 4348);
+  assertNull(res[1422].firstMatch("** Failers"), 4349);
+  assertNull(res[1422].firstMatch("a\n\n\n\x0db"), 4350);
+  assertNull(res[1422].firstMatch("a\x0d"), 4351);
+  assertNull(res[1423].firstMatch("\x09 x{a0}X\n\x0b\x0c\x0d\n"), 4352);
+  assertNull(res[1424].firstMatch(" x{a0}X\n\x0b\x0c\x0d\n"), 4353);
+  assertNull(res[1425].firstMatch(">\x09 x{a0}X\n\n\n<"), 4354);
+  assertNull(res[1426].firstMatch(">\x09 x{a0}X\n\n\n<"), 4355);
+  assertNull(res[1427].firstMatch("X X\n"), 4356);
+  assertNull(res[1427].firstMatch("X\x09X\x0b"), 4357);
+  assertNull(res[1427].firstMatch("** Failers"), 4358);
+  assertNull(res[1427].firstMatch("x{a0} X\n   "), 4359);
+  assertNull(res[1428].firstMatch("\x09 x{a0}X\n\x0b\x0c\x0d\n"), 4360);
+  assertNull(res[1428].firstMatch("\x09 x{a0}\n\x0b\x0c\x0d\n"), 4361);
+  assertNull(res[1428].firstMatch("\x09 x{a0}\n\x0b\x0c"), 4362);
+  assertNull(res[1428].firstMatch("** Failers "), 4363);
+  assertNull(res[1428].firstMatch("\x09 x{a0}\n\x0b"), 4364);
+  assertNull(res[1428].firstMatch(" "), 4365);
+  assertNull(res[1429].firstMatch("x{3001}x{3000}x{2030}x{2028}"), 4366);
+  assertNull(res[1429].firstMatch("Xx{180e}Xx{85}"), 4367);
+  assertNull(res[1429].firstMatch("** Failers"), 4368);
+  assertNull(res[1429].firstMatch("x{2009} X\n   "), 4369);
+  assertNull(res[1430].firstMatch("x{1680}x{180e}x{2007}Xx{2028}x{2029}\x0c\x0d\n"), 4370);
+  assertNull(res[1430].firstMatch("\x09x{205f}x{a0}\nx{2029}\x0cx{2028}\n"), 4371);
+  assertNull(res[1430].firstMatch("\x09 x{202f}\n\x0b\x0c"), 4372);
+  assertNull(res[1430].firstMatch("** Failers "), 4373);
+  assertNull(res[1430].firstMatch("\x09x{200a}x{a0}x{2028}\x0b"), 4374);
+  assertNull(res[1430].firstMatch(" "), 4375);
+  assertNull(res[1431].firstMatch("a\x0db"), 4376);
+  assertNull(res[1431].firstMatch("a\nb"), 4377);
+  assertNull(res[1431].firstMatch("a\x0d\nb"), 4378);
+  assertNull(res[1431].firstMatch("** Failers"), 4379);
+  assertNull(res[1431].firstMatch("ax{85}b"), 4380);
+  assertNull(res[1431].firstMatch("a\x0bb     "), 4381);
+  assertNull(res[1432].firstMatch("a\x0db"), 4382);
+  assertNull(res[1432].firstMatch("a\nb"), 4383);
+  assertNull(res[1432].firstMatch("a\x0d\nb"), 4384);
+  assertNull(res[1432].firstMatch("ax{85}b"), 4385);
+  assertNull(res[1432].firstMatch("a\x0bb     "), 4386);
+  assertNull(res[1432].firstMatch("** Failers "), 4387);
+  assertNull(res[1432].firstMatch("ax{85}b<bsr_anycrlf>"), 4388);
+  assertNull(res[1432].firstMatch("a\x0bb<bsr_anycrlf>"), 4389);
+  assertNull(res[1433].firstMatch("a\x0db"), 4390);
+  assertNull(res[1433].firstMatch("a\nb"), 4391);
+  assertNull(res[1433].firstMatch("a\x0d\nb"), 4392);
+  assertNull(res[1433].firstMatch("** Failers"), 4393);
+  assertNull(res[1433].firstMatch("ax{85}b"), 4394);
+  assertNull(res[1433].firstMatch("a\x0bb     "), 4395);
+  assertNull(res[1434].firstMatch("a\x0db"), 4396);
+  assertNull(res[1434].firstMatch("a\nb"), 4397);
+  assertNull(res[1434].firstMatch("a\x0d\nb"), 4398);
+  assertNull(res[1434].firstMatch("ax{85}b"), 4399);
+  assertNull(res[1434].firstMatch("a\x0bb     "), 4400);
+  assertNull(res[1434].firstMatch("** Failers "), 4401);
+  assertNull(res[1434].firstMatch("ax{85}b<bsr_anycrlf>"), 4402);
+  assertNull(res[1434].firstMatch("a\x0bb<bsr_anycrlf>"), 4403);
+  assertToStringEquals("X", res[1435].firstMatch("Ax{1ec5}ABCXYZ"), 4404);
+  assertNull(res[1437].firstMatch("AB"), 4405);
+  assertNull(res[1437].firstMatch("*** Failers"), 4406);
+  assertNull(res[1437].firstMatch("A0"), 4407);
+  assertNull(res[1437].firstMatch("00   "), 4408);
+  assertNull(res[1438].firstMatch("AB"), 4409);
+  assertNull(res[1438].firstMatch("Ax{300}BC "), 4410);
+  assertNull(res[1438].firstMatch("Ax{300}x{301}x{302}BC "), 4411);
+  assertNull(res[1438].firstMatch("*** Failers"), 4412);
+  assertNull(res[1438].firstMatch("x{300}  "), 4413);
+  assertNull(res[1439].firstMatch("ABC"), 4414);
+  assertNull(res[1439].firstMatch("Ax{300}Bx{300}x{301}C "), 4415);
+  assertNull(res[1439].firstMatch("Ax{300}x{301}x{302}BC "), 4416);
+  assertNull(res[1439].firstMatch("*** Failers"), 4417);
+  assertNull(res[1439].firstMatch("x{300}  "), 4418);
+  assertNull(res[1440].firstMatch("abcd"), 4419);
+  assertNull(res[1440].firstMatch("a "), 4420);
+  assertNull(res[1440].firstMatch("*** Failers "), 4421);
+  assertNull(res[1441].firstMatch("1234"), 4422);
+  assertNull(res[1441].firstMatch("= "), 4423);
+  assertNull(res[1441].firstMatch("*** Failers "), 4424);
+  assertNull(res[1441].firstMatch("abcd "), 4425);
+  assertNull(res[1442].firstMatch("abcdAx{300}x{301}x{302}"), 4426);
+  assertNull(res[1442].firstMatch("Ax{300}x{301}x{302}"), 4427);
+  assertNull(res[1442].firstMatch("Ax{300}x{301}x{302}Ax{300}x{301}x{302}"), 4428);
+  assertNull(res[1442].firstMatch("a "), 4429);
+  assertNull(res[1442].firstMatch("*** Failers "), 4430);
+  assertNull(res[1442].firstMatch("x{300}x{301}x{302}"), 4431);
+  assertToStringEquals("abc", res[1443].firstMatch("abc"), 4432);
+  assertToStringEquals("abc", res[1443].firstMatch("Ax{300}abc"), 4433);
+  assertToStringEquals("abc", res[1443].firstMatch("Ax{300}x{301}x{302}Ax{300}Ax{300}Ax{300}abcxyz"), 4434);
+  assertToStringEquals("abc", res[1443].firstMatch("x{300}abc  "), 4435);
+  assertNull(res[1443].firstMatch("*** Failers"), 4436);
+  assertToStringEquals("abc", res[1444].firstMatch("abc"), 4437);
+  assertNull(res[1444].firstMatch("Ax{300}abc"), 4438);
+  assertNull(res[1444].firstMatch("*** Failers"), 4439);
+  assertNull(res[1444].firstMatch("Ax{300}x{301}x{302}Ax{300}Ax{300}Ax{300}abcxyz"), 4440);
+  assertNull(res[1444].firstMatch("x{300}abc  "), 4441);
+  assertToStringEquals("abc", res[1445].firstMatch("abc"), 4442);
+  assertToStringEquals("abc", res[1445].firstMatch("Ax{300}abc"), 4443);
+  assertToStringEquals("abc", res[1445].firstMatch("Ax{300}x{301}x{302}Ax{300}Ax{300}Ax{300}abcxyz"), 4444);
+  assertToStringEquals("abc", res[1445].firstMatch("x{300}abc  "), 4445);
+  assertNull(res[1445].firstMatch("*** Failers"), 4446);
+  assertToStringEquals("abc", res[1446].firstMatch("abc"), 4447);
+  assertNull(res[1446].firstMatch("Ax{300}abc"), 4448);
+  assertNull(res[1446].firstMatch("Ax{300}x{301}x{302}Ax{300}Ax{300}Ax{300}abcxyz"), 4449);
+  assertNull(res[1446].firstMatch("*** Failers"), 4450);
+  assertNull(res[1446].firstMatch("x{300}abc  "), 4451);
+  assertNull(res[1447].firstMatch("A=b"), 4452);
+  assertNull(res[1447].firstMatch("=c "), 4453);
+  assertNull(res[1447].firstMatch("*** Failers"), 4454);
+  assertNull(res[1447].firstMatch("1=2 "), 4455);
+  assertNull(res[1447].firstMatch("AAAA=b  "), 4456);
+  assertNull(res[1448].firstMatch("AAAA=b"), 4457);
+  assertNull(res[1448].firstMatch("=c "), 4458);
+  assertNull(res[1448].firstMatch("*** Failers"), 4459);
+  assertNull(res[1448].firstMatch("1=2  "), 4460);
+  assertNull(res[1449].firstMatch("Ax{300}x{301}x{302}Ax{300}x{301}x{302}X"), 4461);
+  assertNull(res[1449].firstMatch("Ax{300}x{301}x{302}Ax{300}x{301}x{302}Ax{300}x{301}x{302}X "), 4462);
+  assertNull(res[1449].firstMatch("*** Failers"), 4463);
+  assertNull(res[1449].firstMatch("X"), 4464);
+  assertNull(res[1449].firstMatch("Ax{300}x{301}x{302}X"), 4465);
+  assertNull(res[1449].firstMatch("Ax{300}x{301}x{302}Ax{300}x{301}x{302}Ax{300}x{301}x{302}Ax{300}x{301}x{302}X"), 4466);
+  assertNull(res[1450].firstMatch("x{c0}x{30f}x{660}x{66c}x{f01}x{1680}<"), 4467);
+  assertNull(res[1450].firstMatch("\npx{300}9!\$ < "), 4468);
+  assertNull(res[1450].firstMatch("** Failers "), 4469);
+  assertNull(res[1450].firstMatch("apx{300}9!\$ < "), 4470);
+  assertNull(res[1451].firstMatch("X"), 4471);
+  assertNull(res[1451].firstMatch("** Failers "), 4472);
+  assertNull(res[1451].firstMatch(""), 4473);
+  assertNull(res[1452].firstMatch("9"), 4474);
+  assertNull(res[1452].firstMatch("** Failers "), 4475);
+  assertNull(res[1452].firstMatch("x{c0}"), 4476);
+  assertNull(res[1453].firstMatch("X"), 4477);
+  assertNull(res[1453].firstMatch("** Failers "), 4478);
+  assertNull(res[1453].firstMatch("x{30f}"), 4479);
+  assertNull(res[1454].firstMatch("X"), 4480);
+  assertNull(res[1454].firstMatch("** Failers "), 4481);
+  assertNull(res[1454].firstMatch("x{660}"), 4482);
+  assertNull(res[1455].firstMatch("X"), 4483);
+  assertNull(res[1455].firstMatch("** Failers "), 4484);
+  assertNull(res[1455].firstMatch("x{66c}"), 4485);
+  assertNull(res[1456].firstMatch("X"), 4486);
+  assertNull(res[1456].firstMatch("** Failers "), 4487);
+  assertNull(res[1456].firstMatch("x{f01}"), 4488);
+  assertNull(res[1457].firstMatch("X"), 4489);
+  assertNull(res[1457].firstMatch("** Failers "), 4490);
+  assertNull(res[1457].firstMatch("x{1680}"), 4491);
+  assertNull(res[1458].firstMatch("x{017}"), 4492);
+  assertNull(res[1458].firstMatch("x{09f} "), 4493);
+  assertNull(res[1458].firstMatch("** Failers"), 4494);
+  assertNull(res[1458].firstMatch("x{0600} "), 4495);
+  assertNull(res[1459].firstMatch("x{601}"), 4496);
+  assertNull(res[1459].firstMatch("** Failers"), 4497);
+  assertNull(res[1459].firstMatch("x{09f} "), 4498);
+  assertNull(res[1460].firstMatch("** Failers"), 4499);
+  assertNull(res[1460].firstMatch("x{09f} "), 4500);
+  assertNull(res[1461].firstMatch("x{f8ff}"), 4501);
+  assertNull(res[1461].firstMatch("** Failers"), 4502);
+  assertNull(res[1461].firstMatch("x{09f} "), 4503);
+  assertNull(res[1462].firstMatch("?x{dfff}"), 4504);
+  assertNull(res[1462].firstMatch("** Failers"), 4505);
+  assertNull(res[1462].firstMatch("x{09f} "), 4506);
+  assertNull(res[1463].firstMatch("a"), 4507);
+  assertNull(res[1463].firstMatch("** Failers "), 4508);
+  assertNull(res[1463].firstMatch("Z"), 4509);
+  assertNull(res[1463].firstMatch("x{e000}  "), 4510);
+  assertNull(res[1464].firstMatch("x{2b0}"), 4511);
+  assertNull(res[1464].firstMatch("** Failers"), 4512);
+  assertNull(res[1464].firstMatch("a "), 4513);
+  assertNull(res[1465].firstMatch("x{1bb}"), 4514);
+  assertNull(res[1465].firstMatch("** Failers"), 4515);
+  assertNull(res[1465].firstMatch("a "), 4516);
+  assertNull(res[1465].firstMatch("x{2b0}"), 4517);
+  assertNull(res[1466].firstMatch("x{1c5}"), 4518);
+  assertNull(res[1466].firstMatch("** Failers"), 4519);
+  assertNull(res[1466].firstMatch("a "), 4520);
+  assertNull(res[1466].firstMatch("x{2b0}"), 4521);
+  assertNull(res[1467].firstMatch("A"), 4522);
+  assertNull(res[1467].firstMatch("** Failers"), 4523);
+  assertNull(res[1467].firstMatch("x{2b0}"), 4524);
+  assertNull(res[1468].firstMatch("x{903}"), 4525);
+  assertNull(res[1468].firstMatch("** Failers"), 4526);
+  assertNull(res[1468].firstMatch("X"), 4527);
+  assertNull(res[1468].firstMatch("x{300}"), 4528);
+  assertNull(res[1468].firstMatch("   "), 4529);
+  assertNull(res[1469].firstMatch("x{488}"), 4530);
+  assertNull(res[1469].firstMatch("** Failers"), 4531);
+  assertNull(res[1469].firstMatch("X"), 4532);
+  assertNull(res[1469].firstMatch("x{903}"), 4533);
+  assertNull(res[1469].firstMatch("x{300}"), 4534);
+  assertNull(res[1470].firstMatch("x{300}"), 4535);
+  assertNull(res[1470].firstMatch("** Failers"), 4536);
+  assertNull(res[1470].firstMatch("X"), 4537);
+  assertNull(res[1470].firstMatch("x{903}"), 4538);
+  assertNull(res[1470].firstMatch("0123456789x{660}x{661}x{662}x{663}x{664}x{665}x{666}x{667}x{668}x{669}x{66a}"), 4539);
+  assertNull(res[1470].firstMatch("x{6f0}x{6f1}x{6f2}x{6f3}x{6f4}x{6f5}x{6f6}x{6f7}x{6f8}x{6f9}x{6fa}"), 4540);
+  assertNull(res[1470].firstMatch("x{966}x{967}x{968}x{969}x{96a}x{96b}x{96c}x{96d}x{96e}x{96f}x{970}"), 4541);
+  assertNull(res[1470].firstMatch("** Failers"), 4542);
+  assertNull(res[1470].firstMatch("X"), 4543);
+  assertNull(res[1471].firstMatch("x{16ee}"), 4544);
+  assertNull(res[1471].firstMatch("** Failers"), 4545);
+  assertNull(res[1471].firstMatch("X"), 4546);
+  assertNull(res[1471].firstMatch("x{966}"), 4547);
+  assertNull(res[1472].firstMatch("x{b2}"), 4548);
+  assertNull(res[1472].firstMatch("x{b3}"), 4549);
+  assertNull(res[1472].firstMatch("** Failers"), 4550);
+  assertNull(res[1472].firstMatch("X"), 4551);
+  assertNull(res[1472].firstMatch("x{16ee}"), 4552);
+  assertNull(res[1473].firstMatch("_"), 4553);
+  assertNull(res[1473].firstMatch("x{203f}"), 4554);
+  assertNull(res[1473].firstMatch("** Failers"), 4555);
+  assertNull(res[1473].firstMatch("X"), 4556);
+  assertNull(res[1473].firstMatch("-"), 4557);
+  assertNull(res[1473].firstMatch("x{58a}"), 4558);
+  assertNull(res[1474].firstMatch("-"), 4559);
+  assertNull(res[1474].firstMatch("x{58a}"), 4560);
+  assertNull(res[1474].firstMatch("** Failers"), 4561);
+  assertNull(res[1474].firstMatch("X"), 4562);
+  assertNull(res[1474].firstMatch("x{203f}"), 4563);
+  assertNull(res[1475].firstMatch(")"), 4564);
+  assertNull(res[1475].firstMatch("]"), 4565);
+  assertNull(res[1475].firstMatch("}"), 4566);
+  assertNull(res[1475].firstMatch("x{f3b}"), 4567);
+  assertNull(res[1475].firstMatch("** Failers"), 4568);
+  assertNull(res[1475].firstMatch("X"), 4569);
+  assertNull(res[1475].firstMatch("x{203f}"), 4570);
+  assertNull(res[1475].firstMatch("("), 4571);
+  assertNull(res[1475].firstMatch("["), 4572);
+  assertNull(res[1475].firstMatch("{"), 4573);
+  assertNull(res[1475].firstMatch("x{f3c}"), 4574);
+  assertNull(res[1476].firstMatch("x{bb}"), 4575);
+  assertNull(res[1476].firstMatch("x{2019}"), 4576);
+  assertNull(res[1476].firstMatch("** Failers"), 4577);
+  assertNull(res[1476].firstMatch("X"), 4578);
+  assertNull(res[1476].firstMatch("x{203f}"), 4579);
+  assertNull(res[1477].firstMatch("x{ab}"), 4580);
+  assertNull(res[1477].firstMatch("x{2018}"), 4581);
+  assertNull(res[1477].firstMatch("** Failers"), 4582);
+  assertNull(res[1477].firstMatch("X"), 4583);
+  assertNull(res[1477].firstMatch("x{203f}"), 4584);
+  assertNull(res[1478].firstMatch("!"), 4585);
+  assertNull(res[1478].firstMatch("x{37e}"), 4586);
+  assertNull(res[1478].firstMatch("** Failers"), 4587);
+  assertNull(res[1478].firstMatch("X"), 4588);
+  assertNull(res[1478].firstMatch("x{203f}"), 4589);
+  assertNull(res[1479].firstMatch("("), 4590);
+  assertNull(res[1479].firstMatch("["), 4591);
+  assertNull(res[1479].firstMatch("{"), 4592);
+  assertNull(res[1479].firstMatch("x{f3c}"), 4593);
+  assertNull(res[1479].firstMatch("** Failers"), 4594);
+  assertNull(res[1479].firstMatch("X"), 4595);
+  assertNull(res[1479].firstMatch(")"), 4596);
+  assertNull(res[1479].firstMatch("]"), 4597);
+  assertNull(res[1479].firstMatch("}"), 4598);
+  assertNull(res[1479].firstMatch("x{f3b}"), 4599);
+  assertNull(res[1479].firstMatch("\$x{a2}x{a3}x{a4}x{a5}x{a6}"), 4600);
+  assertNull(res[1479].firstMatch("x{9f2}"), 4601);
+  assertNull(res[1479].firstMatch("** Failers"), 4602);
+  assertNull(res[1479].firstMatch("X"), 4603);
+  assertNull(res[1479].firstMatch("x{2c2}"), 4604);
+  assertNull(res[1480].firstMatch("x{2c2}"), 4605);
+  assertNull(res[1480].firstMatch("** Failers"), 4606);
+  assertNull(res[1480].firstMatch("X"), 4607);
+  assertNull(res[1480].firstMatch("x{9f2}"), 4608);
+  assertNull(res[1480].firstMatch("+<|~x{ac}x{2044}"), 4609);
+  assertNull(res[1480].firstMatch("** Failers"), 4610);
+  assertNull(res[1480].firstMatch("X"), 4611);
+  assertNull(res[1480].firstMatch("x{9f2}"), 4612);
+  assertNull(res[1481].firstMatch("x{a6}"), 4613);
+  assertNull(res[1481].firstMatch("x{482} "), 4614);
+  assertNull(res[1481].firstMatch("** Failers"), 4615);
+  assertNull(res[1481].firstMatch("X"), 4616);
+  assertNull(res[1481].firstMatch("x{9f2}"), 4617);
+  assertNull(res[1482].firstMatch("x{2028}"), 4618);
+  assertNull(res[1482].firstMatch("** Failers"), 4619);
+  assertNull(res[1482].firstMatch("X"), 4620);
+  assertNull(res[1482].firstMatch("x{2029}"), 4621);
+  assertNull(res[1483].firstMatch("x{2029}"), 4622);
+  assertNull(res[1483].firstMatch("** Failers"), 4623);
+  assertNull(res[1483].firstMatch("X"), 4624);
+  assertNull(res[1483].firstMatch("x{2028}"), 4625);
+  assertNull(res[1484].firstMatch("\\ \\"), 4626);
+  assertNull(res[1484].firstMatch("x{a0}"), 4627);
+  assertNull(res[1484].firstMatch("x{1680}"), 4628);
+  assertNull(res[1484].firstMatch("x{180e}"), 4629);
+  assertNull(res[1484].firstMatch("x{2000}"), 4630);
+  assertNull(res[1484].firstMatch("x{2001}     "), 4631);
+  assertNull(res[1484].firstMatch("** Failers"), 4632);
+  assertNull(res[1484].firstMatch("x{2028}"), 4633);
+  assertNull(res[1484].firstMatch("x{200d} "), 4634);
+  assertNull(res[1484].firstMatch("  x{660}x{661}x{662}ABC"), 4635);
+  assertNull(res[1484].firstMatch("  x{660}x{661}x{662}ABC"), 4636);
+  assertNull(res[1485].firstMatch("  x{660}x{661}x{662}ABC"), 4637);
+  assertNull(res[1486].firstMatch("  x{660}x{661}x{662}ABC"), 4638);
+  assertNull(res[1487].firstMatch("  x{660}x{661}x{662}ABC"), 4639);
+  assertNull(res[1488].firstMatch("  x{660}x{661}x{662}ABC"), 4640);
+  assertNull(res[1489].firstMatch("  x{660}x{661}x{662}ABC"), 4641);
+  assertNull(res[1490].firstMatch("  x{660}x{661}x{662}ABC"), 4642);
+  assertNull(res[1491].firstMatch("  x{660}x{661}x{662}ABC"), 4643);
+  assertNull(res[1492].firstMatch("  x{660}x{661}x{662}ABC"), 4644);
+  assertNull(res[1493].firstMatch("  x{660}x{661}x{662}ABC"), 4645);
+  assertNull(res[1493].firstMatch("  x{660}x{661}x{662}ABC"), 4646);
+  assertNull(res[1493].firstMatch("  x{660}x{661}x{662}ABC"), 4647);
+  assertNull(res[1493].firstMatch("  ** Failers"), 4648);
+  assertNull(res[1493].firstMatch("  x{660}x{661}x{662}ABC"), 4649);
+  assertNull(res[1494].firstMatch("A"), 4650);
+  assertNull(res[1494].firstMatch("ax{10a0}B "), 4651);
+  assertNull(res[1494].firstMatch("** Failers "), 4652);
+  assertNull(res[1494].firstMatch("a"), 4653);
+  assertNull(res[1494].firstMatch("x{1d00}  "), 4654);
+  assertNull(res[1495].firstMatch("1234"), 4655);
+  assertNull(res[1495].firstMatch("** Failers"), 4656);
+  assertNull(res[1495].firstMatch("ABC "), 4657);
+  assertNull(res[1496].firstMatch("1234"), 4658);
+  assertNull(res[1496].firstMatch("** Failers"), 4659);
+  assertNull(res[1496].firstMatch("ABC "), 4660);
+  assertNull(res[1496].firstMatch("A2XYZ"), 4661);
+  assertNull(res[1496].firstMatch("123A5XYZPQR"), 4662);
+  assertNull(res[1496].firstMatch("ABAx{660}XYZpqr"), 4663);
+  assertNull(res[1496].firstMatch("** Failers"), 4664);
+  assertNull(res[1496].firstMatch("AXYZ"), 4665);
+  assertNull(res[1496].firstMatch("XYZ     "), 4666);
+  assertNull(res[1496].firstMatch("1XYZ"), 4667);
+  assertNull(res[1496].firstMatch("AB=XYZ.. "), 4668);
+  assertNull(res[1496].firstMatch("XYZ "), 4669);
+  assertNull(res[1496].firstMatch("** Failers"), 4670);
+  assertNull(res[1496].firstMatch("WXYZ "), 4671);
+  assertNull(res[1497].firstMatch("1234"), 4672);
+  assertNull(res[1497].firstMatch("1234"), 4673);
+  assertNull(res[1497].firstMatch("12-34"), 4674);
+  assertToStringEquals("{", res[1497].firstMatch("12+x{661}-34  "), 4675);
+  assertNull(res[1497].firstMatch("** Failers"), 4676);
+  assertToStringEquals("d", res[1497].firstMatch("abcd  "), 4677);
+  assertToStringEquals("d", res[1498].firstMatch("abcd"), 4678);
+  assertNull(res[1498].firstMatch("** Failers"), 4679);
+  assertNull(res[1498].firstMatch("1234"), 4680);
+  assertNull(res[1499].firstMatch("11111111111111111111111111111111111111111111111111111111111111111111111"), 4681);
+  assertToStringEquals("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", res[1499].firstMatch("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"), 4682);
+  assertToStringEquals(" ", res[1499].firstMatch(" "), 4683);
+  assertNull(res[1499].firstMatch("11111111111111111111111111111111111111111111111111111111111111111111111"), 4684);
+  assertToStringEquals("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", res[1499].firstMatch("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"), 4685);
+  assertNull(res[1500].firstMatch("11111111111111111111111111111111111111111111111111111111111111111111111"), 4686);
+  assertToStringEquals("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", res[1500].firstMatch("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"), 4687);
+  assertNull(res[1501].firstMatch("11111111111111111111111111111111111111111111111111111111111111111111111"), 4688);
+  assertNull(res[1501].firstMatch("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"), 4689);
+  assertNull(res[1502].firstMatch("11111111111111111111111111111111111111111111111111111111111111111111111"), 4690);
+  assertToStringEquals("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", res[1502].firstMatch("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"), 4691);
+  assertNull(res[1503].firstMatch("a"), 4692);
+  assertNull(res[1503].firstMatch("A "), 4693);
+  assertNull(res[1504].firstMatch("a"), 4694);
+  assertNull(res[1504].firstMatch("A "), 4695);
+  assertNull(res[1505].firstMatch("A"), 4696);
+  assertNull(res[1505].firstMatch("aZ"), 4697);
+  assertNull(res[1505].firstMatch("** Failers"), 4698);
+  assertNull(res[1505].firstMatch("abc   "), 4699);
+  assertNull(res[1506].firstMatch("A"), 4700);
+  assertNull(res[1506].firstMatch("aZ"), 4701);
+  assertNull(res[1506].firstMatch("** Failers"), 4702);
+  assertNull(res[1506].firstMatch("abc   "), 4703);
+  assertNull(res[1507].firstMatch("a"), 4704);
+  assertNull(res[1507].firstMatch("Az"), 4705);
+  assertNull(res[1507].firstMatch("** Failers"), 4706);
+  assertNull(res[1507].firstMatch("ABC   "), 4707);
+  assertNull(res[1508].firstMatch("a"), 4708);
+  assertNull(res[1508].firstMatch("Az"), 4709);
+  assertNull(res[1508].firstMatch("** Failers"), 4710);
+  assertNull(res[1508].firstMatch("ABC   "), 4711);
+  assertNull(res[1508].firstMatch("x{c0}"), 4712);
+  assertNull(res[1508].firstMatch("x{e0} "), 4713);
+  assertNull(res[1508].firstMatch("x{c0}"), 4714);
+  assertNull(res[1508].firstMatch("x{e0} "), 4715);
+  assertNull(res[1508].firstMatch("Ax{391}x{10427}x{ff3a}x{1fb0}"), 4716);
+  assertNull(res[1508].firstMatch("** Failers"), 4717);
+  assertNull(res[1508].firstMatch("ax{391}x{10427}x{ff3a}x{1fb0}   "), 4718);
+  assertNull(res[1508].firstMatch("Ax{3b1}x{10427}x{ff3a}x{1fb0}"), 4719);
+  assertNull(res[1508].firstMatch("Ax{391}x{1044F}x{ff3a}x{1fb0}"), 4720);
+  assertNull(res[1508].firstMatch("Ax{391}x{10427}x{ff5a}x{1fb0}"), 4721);
+  assertNull(res[1508].firstMatch("Ax{391}x{10427}x{ff3a}x{1fb8}"), 4722);
+  assertNull(res[1508].firstMatch("Ax{391}x{10427}x{ff3a}x{1fb0}"), 4723);
+  assertNull(res[1508].firstMatch("ax{391}x{10427}x{ff3a}x{1fb0}   "), 4724);
+  assertNull(res[1508].firstMatch("Ax{3b1}x{10427}x{ff3a}x{1fb0}"), 4725);
+  assertNull(res[1508].firstMatch("Ax{391}x{1044F}x{ff3a}x{1fb0}"), 4726);
+  assertNull(res[1508].firstMatch("Ax{391}x{10427}x{ff5a}x{1fb0}"), 4727);
+  assertNull(res[1508].firstMatch("Ax{391}x{10427}x{ff3a}x{1fb8}"), 4728);
+  assertNull(res[1508].firstMatch("x{391}x{3b1}x{3b1}x{3b1}x{391}"), 4729);
+  assertNull(res[1508].firstMatch("x{391}x{3b1}x{3b1}x{3b1}x{391}X"), 4730);
+  assertNull(res[1508].firstMatch("x{391}x{3b1}x{3b1}x{3b1}x{391}X"), 4731);
+  assertNull(res[1508].firstMatch("x{391}"), 4732);
+  assertNull(res[1508].firstMatch("x{ff3a}"), 4733);
+  assertNull(res[1508].firstMatch("x{3b1}"), 4734);
+  assertNull(res[1508].firstMatch("x{ff5a}   "), 4735);
+  assertNull(res[1508].firstMatch("x{c0}"), 4736);
+  assertNull(res[1508].firstMatch("x{e0} "), 4737);
+  assertNull(res[1508].firstMatch("x{104}"), 4738);
+  assertNull(res[1508].firstMatch("x{105}"), 4739);
+  assertNull(res[1508].firstMatch("x{109}  "), 4740);
+  assertNull(res[1508].firstMatch("** Failers"), 4741);
+  assertNull(res[1508].firstMatch("x{100}"), 4742);
+  assertNull(res[1508].firstMatch("x{10a} "), 4743);
+  assertNull(res[1508].firstMatch("Z"), 4744);
+  assertNull(res[1508].firstMatch("z"), 4745);
+  assertNull(res[1508].firstMatch("x{39c}"), 4746);
+  assertNull(res[1508].firstMatch("x{178}"), 4747);
+  assertNull(res[1508].firstMatch("|"), 4748);
+  assertNull(res[1508].firstMatch("x{80}"), 4749);
+  assertNull(res[1508].firstMatch("x{ff}"), 4750);
+  assertNull(res[1508].firstMatch("x{100}"), 4751);
+  assertNull(res[1508].firstMatch("x{101} "), 4752);
+  assertNull(res[1508].firstMatch("** Failers"), 4753);
+  assertNull(res[1508].firstMatch("x{102}"), 4754);
+  assertNull(res[1508].firstMatch("Y"), 4755);
+  assertNull(res[1508].firstMatch("y           "), 4756);
+  assertNull(res[1509].firstMatch("A"), 4757);
+  assertNull(res[1509].firstMatch("Ax{300}BC "), 4758);
+  assertNull(res[1509].firstMatch("Ax{300}x{301}x{302}BC "), 4759);
+  assertNull(res[1509].firstMatch("*** Failers"), 4760);
+  assertNull(res[1509].firstMatch("x{300}  "), 4761);
+  assertToStringEquals("X", res[1510].firstMatch("X123"), 4762);
+  assertNull(res[1510].firstMatch("*** Failers"), 4763);
+  assertNull(res[1510].firstMatch("AXYZ"), 4764);
+  assertNull(res[1511].firstMatch("Ax{300}x{301}x{302}BCAx{300}x{301} "), 4765);
+  assertNull(res[1511].firstMatch("Ax{300}x{301}x{302}BCAx{300}x{301}C "), 4766);
+  assertNull(res[1512].firstMatch("Ax{300}x{301}x{302}BCAx{300}x{301} "), 4767);
+  assertNull(res[1512].firstMatch("Ax{300}x{301}x{302}BCAx{300}x{301}C "), 4768);
+  assertToStringEquals("A,,A", res[1513].firstMatch("Ax{300}x{301}x{302}BCAx{300}x{301} "), 4769);
+  assertToStringEquals("A,,A", res[1513].firstMatch("Ax{300}x{301}x{302}BCAx{300}x{301}C "), 4770);
+  assertToStringEquals("A,,A", res[1514].firstMatch("Ax{300}x{301}x{302}BCAx{300}x{301} "), 4771);
+  assertToStringEquals("A,,A", res[1514].firstMatch("Ax{300}x{301}x{302}BCAx{300}x{301}C "), 4772);
+  assertNull(res[1515].firstMatch("*** Failers"), 4773);
+  assertNull(res[1515].firstMatch("Ax{300}x{301}x{302}"), 4774);
+  assertNull(res[1516].firstMatch("Ax{300}x{301}Bx{300}X"), 4775);
+  assertNull(res[1516].firstMatch("Ax{300}x{301}Bx{300}Cx{300}x{301}"), 4776);
+  assertNull(res[1516].firstMatch("Ax{300}x{301}Bx{300}Cx{300}x{301}X"), 4777);
+  assertNull(res[1516].firstMatch("Ax{300}x{301}Bx{300}Cx{300}x{301}DAx{300}X"), 4778);
+  assertNull(res[1517].firstMatch("Ax{300}x{301}Bx{300}X"), 4779);
+  assertNull(res[1517].firstMatch("Ax{300}x{301}Bx{300}Cx{300}x{301}"), 4780);
+  assertNull(res[1517].firstMatch("Ax{300}x{301}Bx{300}Cx{300}x{301}X"), 4781);
+  assertNull(res[1517].firstMatch("Ax{300}x{301}Bx{300}Cx{300}x{301}DAx{300}X"), 4782);
+  assertNull(res[1518].firstMatch("12X"), 4783);
+  assertNull(res[1518].firstMatch("123X"), 4784);
+  assertNull(res[1518].firstMatch("*** Failers"), 4785);
+  assertNull(res[1518].firstMatch("X"), 4786);
+  assertNull(res[1518].firstMatch("1X"), 4787);
+  assertNull(res[1518].firstMatch("1234X     "), 4788);
+  assertNull(res[1518].firstMatch("x{100}   "), 4789);
+  assertNull(res[1518].firstMatch("x{101} "), 4790);
+  assertNull(res[1518].firstMatch("x{2e81}x{3007}x{2f804}x{31a0}"), 4791);
+  assertNull(res[1518].firstMatch("** Failers"), 4792);
+  assertNull(res[1518].firstMatch("x{2e7f}  "), 4793);
+  assertNull(res[1518].firstMatch("x{3105}"), 4794);
+  assertNull(res[1518].firstMatch("** Failers"), 4795);
+  assertNull(res[1518].firstMatch("x{30ff}  "), 4796);
+  assertNull(res[1519].firstMatch("x{06e9}"), 4797);
+  assertNull(res[1519].firstMatch("x{060b}"), 4798);
+  assertNull(res[1519].firstMatch("** Failers"), 4799);
+  assertNull(res[1519].firstMatch("Xx{06e9}   "), 4800);
+  assertNull(res[1520].firstMatch("x{2f800}"), 4801);
+  assertNull(res[1520].firstMatch("** Failers"), 4802);
+  assertNull(res[1520].firstMatch("x{a014}"), 4803);
+  assertNull(res[1520].firstMatch("x{a4c6}   "), 4804);
+  assertNull(res[1521].firstMatch("AXYZ"), 4805);
+  assertNull(res[1521].firstMatch("x{1234}XYZ "), 4806);
+  assertNull(res[1521].firstMatch("** Failers"), 4807);
+  assertNull(res[1521].firstMatch("X  "), 4808);
+  assertNull(res[1522].firstMatch("** Failers"), 4809);
+  assertNull(res[1522].firstMatch("AX"), 4810);
+  assertNull(res[1523].firstMatch("XYZ"), 4811);
+  assertNull(res[1523].firstMatch("AXYZ"), 4812);
+  assertNull(res[1523].firstMatch("x{1234}XYZ "), 4813);
+  assertNull(res[1523].firstMatch("** Failers"), 4814);
+  assertNull(res[1523].firstMatch("ABXYZ   "), 4815);
+  assertNull(res[1524].firstMatch("XYZ"), 4816);
+  assertNull(res[1524].firstMatch("** Failers"), 4817);
+  assertNull(res[1524].firstMatch("AXYZ"), 4818);
+  assertNull(res[1524].firstMatch("x{1234}XYZ "), 4819);
+  assertNull(res[1524].firstMatch("ABXYZ   "), 4820);
+  assertNull(res[1524].firstMatch("AXYZ"), 4821);
+  assertNull(res[1524].firstMatch("x{1234}XYZ"), 4822);
+  assertNull(res[1524].firstMatch("Ax{1234}XYZ"), 4823);
+  assertNull(res[1524].firstMatch("** Failers"), 4824);
+  assertNull(res[1524].firstMatch("XYZ"), 4825);
+  assertNull(res[1524].firstMatch("** Failers"), 4826);
+  assertNull(res[1524].firstMatch("AXYZ"), 4827);
+  assertNull(res[1524].firstMatch("x{1234}XYZ"), 4828);
+  assertNull(res[1524].firstMatch("Ax{1234}XYZ"), 4829);
+  assertNull(res[1524].firstMatch("XYZ"), 4830);
+  assertNull(res[1525].firstMatch("XYZ"), 4831);
+  assertNull(res[1525].firstMatch("AXYZ"), 4832);
+  assertNull(res[1525].firstMatch("x{1234}XYZ"), 4833);
+  assertNull(res[1525].firstMatch("Ax{1234}XYZ"), 4834);
+  assertNull(res[1525].firstMatch("** Failers"), 4835);
+  assertNull(res[1526].firstMatch("XYZ"), 4836);
+  assertNull(res[1526].firstMatch("** Failers"), 4837);
+  assertNull(res[1526].firstMatch("AXYZ"), 4838);
+  assertNull(res[1526].firstMatch("x{1234}XYZ"), 4839);
+  assertNull(res[1526].firstMatch("Ax{1234}XYZ"), 4840);
+  assertToStringEquals("AX", res[1527].firstMatch("AXYZ"), 4841);
+  assertNull(res[1527].firstMatch("x{1234}XYZ "), 4842);
+  assertNull(res[1527].firstMatch("** Failers"), 4843);
+  assertNull(res[1527].firstMatch("X  "), 4844);
+  assertNull(res[1528].firstMatch("** Failers"), 4845);
+  assertToStringEquals("AX", res[1528].firstMatch("AX"), 4846);
+  assertToStringEquals("X", res[1529].firstMatch("XYZ"), 4847);
+  assertToStringEquals("AX", res[1529].firstMatch("AXYZ"), 4848);
+  assertNull(res[1529].firstMatch("x{1234}XYZ "), 4849);
+  assertNull(res[1529].firstMatch("** Failers"), 4850);
+  assertNull(res[1529].firstMatch("ABXYZ   "), 4851);
+  assertToStringEquals("X", res[1530].firstMatch("XYZ"), 4852);
+  assertNull(res[1530].firstMatch("** Failers"), 4853);
+  assertToStringEquals("AX", res[1530].firstMatch("AXYZ"), 4854);
+  assertNull(res[1530].firstMatch("x{1234}XYZ "), 4855);
+  assertNull(res[1530].firstMatch("ABXYZ   "), 4856);
+  assertToStringEquals("AX", res[1531].firstMatch("AXYZ"), 4857);
+  assertNull(res[1531].firstMatch("x{1234}XYZ"), 4858);
+  assertNull(res[1531].firstMatch("Ax{1234}XYZ"), 4859);
+  assertNull(res[1531].firstMatch("** Failers"), 4860);
+  assertNull(res[1531].firstMatch("XYZ"), 4861);
+  assertNull(res[1532].firstMatch("** Failers"), 4862);
+  assertToStringEquals("AX", res[1532].firstMatch("AXYZ"), 4863);
+  assertNull(res[1532].firstMatch("x{1234}XYZ"), 4864);
+  assertNull(res[1532].firstMatch("Ax{1234}XYZ"), 4865);
+  assertNull(res[1532].firstMatch("XYZ"), 4866);
+  assertToStringEquals("X", res[1533].firstMatch("XYZ"), 4867);
+  assertToStringEquals("AX", res[1533].firstMatch("AXYZ"), 4868);
+  assertNull(res[1533].firstMatch("x{1234}XYZ"), 4869);
+  assertNull(res[1533].firstMatch("Ax{1234}XYZ"), 4870);
+  assertNull(res[1533].firstMatch("** Failers"), 4871);
+  assertToStringEquals("X", res[1534].firstMatch("XYZ"), 4872);
+  assertNull(res[1534].firstMatch("** Failers"), 4873);
+  assertToStringEquals("AX", res[1534].firstMatch("AXYZ"), 4874);
+  assertNull(res[1534].firstMatch("x{1234}XYZ"), 4875);
+  assertNull(res[1534].firstMatch("Ax{1234}XYZ"), 4876);
+  assertNull(res[1535].firstMatch("abcdefgh"), 4877);
+  assertNull(res[1535].firstMatch("x{1234}\n\x0dx{3456}xyz "), 4878);
+  assertNull(res[1536].firstMatch("abcdefgh"), 4879);
+  assertNull(res[1536].firstMatch("x{1234}\n\x0dx{3456}xyz "), 4880);
+  assertNull(res[1537].firstMatch("** Failers"), 4881);
+  assertNull(res[1537].firstMatch("abcdefgh"), 4882);
+  assertNull(res[1537].firstMatch("x{1234}\n\x0dx{3456}xyz "), 4883);
+  assertNull(res[1538].firstMatch(" AXY"), 4884);
+  assertNull(res[1538].firstMatch(" aXY"), 4885);
+  assertNull(res[1538].firstMatch(" x{1c5}XY"), 4886);
+  assertNull(res[1538].firstMatch(" ** Failers"), 4887);
+  assertNull(res[1538].firstMatch(" x{1bb}XY"), 4888);
+  assertNull(res[1538].firstMatch(" x{2b0}XY"), 4889);
+  assertNull(res[1538].firstMatch(" !XY      "), 4890);
+  assertNull(res[1539].firstMatch(" AXY"), 4891);
+  assertNull(res[1539].firstMatch(" aXY"), 4892);
+  assertNull(res[1539].firstMatch(" x{1c5}XY"), 4893);
+  assertNull(res[1539].firstMatch(" ** Failers"), 4894);
+  assertNull(res[1539].firstMatch(" x{1bb}XY"), 4895);
+  assertNull(res[1539].firstMatch(" x{2b0}XY"), 4896);
+  assertNull(res[1539].firstMatch(" !XY      "), 4897);
+  assertNull(res[1539].firstMatch(" AXY"), 4898);
+  assertNull(res[1539].firstMatch(" aXY"), 4899);
+  assertNull(res[1539].firstMatch(" AbcdeXyz "), 4900);
+  assertNull(res[1539].firstMatch(" x{1c5}AbXY"), 4901);
+  assertNull(res[1539].firstMatch(" abcDEXypqreXlmn "), 4902);
+  assertNull(res[1539].firstMatch(" ** Failers"), 4903);
+  assertNull(res[1539].firstMatch(" x{1bb}XY"), 4904);
+  assertNull(res[1539].firstMatch(" x{2b0}XY"), 4905);
+  assertNull(res[1539].firstMatch(" !XY      "), 4906);
+  assertNull(res[1540].firstMatch(" AXY"), 4907);
+  assertNull(res[1540].firstMatch(" aXY"), 4908);
+  assertNull(res[1540].firstMatch(" AbcdeXyz "), 4909);
+  assertNull(res[1540].firstMatch(" x{1c5}AbXY"), 4910);
+  assertNull(res[1540].firstMatch(" abcDEXypqreXlmn "), 4911);
+  assertNull(res[1540].firstMatch(" ** Failers"), 4912);
+  assertNull(res[1540].firstMatch(" x{1bb}XY"), 4913);
+  assertNull(res[1540].firstMatch(" x{2b0}XY"), 4914);
+  assertNull(res[1540].firstMatch(" !XY      "), 4915);
+  assertNull(res[1540].firstMatch(" AXY"), 4916);
+  assertNull(res[1540].firstMatch(" aXY"), 4917);
+  assertNull(res[1540].firstMatch(" AbcdeXyz "), 4918);
+  assertNull(res[1540].firstMatch(" x{1c5}AbXY"), 4919);
+  assertNull(res[1540].firstMatch(" abcDEXypqreXlmn "), 4920);
+  assertNull(res[1540].firstMatch(" ** Failers"), 4921);
+  assertNull(res[1540].firstMatch(" x{1bb}XY"), 4922);
+  assertNull(res[1540].firstMatch(" x{2b0}XY"), 4923);
+  assertNull(res[1540].firstMatch(" !XY      "), 4924);
+  assertNull(res[1541].firstMatch(" AXY"), 4925);
+  assertNull(res[1541].firstMatch(" aXY"), 4926);
+  assertNull(res[1541].firstMatch(" AbcdeXyz "), 4927);
+  assertNull(res[1541].firstMatch(" x{1c5}AbXY"), 4928);
+  assertNull(res[1541].firstMatch(" abcDEXypqreXlmn "), 4929);
+  assertNull(res[1541].firstMatch(" ** Failers"), 4930);
+  assertNull(res[1541].firstMatch(" x{1bb}XY"), 4931);
+  assertNull(res[1541].firstMatch(" x{2b0}XY"), 4932);
+  assertNull(res[1541].firstMatch(" !XY      "), 4933);
+  assertNull(res[1542].firstMatch(" !XY"), 4934);
+  assertNull(res[1542].firstMatch(" x{1bb}XY"), 4935);
+  assertNull(res[1542].firstMatch(" x{2b0}XY"), 4936);
+  assertNull(res[1542].firstMatch(" ** Failers"), 4937);
+  assertNull(res[1542].firstMatch(" x{1c5}XY"), 4938);
+  assertNull(res[1542].firstMatch(" AXY      "), 4939);
+  assertNull(res[1543].firstMatch(" !XY"), 4940);
+  assertNull(res[1543].firstMatch(" x{1bb}XY"), 4941);
+  assertNull(res[1543].firstMatch(" x{2b0}XY"), 4942);
+  assertNull(res[1543].firstMatch(" ** Failers"), 4943);
+  assertNull(res[1543].firstMatch(" x{1c5}XY"), 4944);
+  assertNull(res[1543].firstMatch(" AXY      "), 4945);
+  assertNull(res[1543].firstMatch("x{c0}x{e0}x{116}x{117}"), 4946);
+  assertNull(res[1543].firstMatch("x{c0}x{e0}x{116}x{117}"), 4947);
+  assertNull(res[1545].firstMatch("123abcdefg"), 4948);
+  assertNull(res[1545].firstMatch("123abc\xc4\xc5zz"), 4949);
+  assertNull(res[1546].firstMatch("x{102A4}x{AA52}x{A91D}x{1C46}x{10283}x{1092E}x{1C6B}x{A93B}x{A8BF}x{1BA0}x{A50A}===="), 4950);
+  assertNull(res[1546].firstMatch("x{a77d}x{1d79}"), 4951);
+  assertNull(res[1546].firstMatch("x{1d79}x{a77d} "), 4952);
+  assertNull(res[1546].firstMatch("x{a77d}x{1d79}"), 4953);
+  assertNull(res[1546].firstMatch("** Failers "), 4954);
+  assertNull(res[1546].firstMatch("x{1d79}x{a77d} "), 4955);
+  // Dart does not have RegExp literals and thus no translatation of the below.
+  // assertThrows("var re = //;", 4956);
+}
diff --git a/tests/corelib/regexp/quantified-assertions_test.dart b/tests/corelib/regexp/quantified-assertions_test.dart
new file mode 100644
index 0000000..0ed670c
--- /dev/null
+++ b/tests/corelib/regexp/quantified-assertions_test.dart
@@ -0,0 +1,48 @@
+// Copyright (c) 2014, the Dart project authors. All rights reserved.
+// Copyright 2013 the V8 project authors. All rights reserved.
+// Copyright (C) 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1.  Redistributions of source code must retain the above copyright
+//     notice, this list of conditions and the following disclaimer.
+// 2.  Redistributions in binary form must reproduce the above copyright
+//     notice, this list of conditions and the following disclaimer in the
+//     documentation and/or other materials provided with the distribution.
+//
+// THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
+// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+import 'v8_regexp_utils.dart';
+import 'package:expect/expect.dart';
+
+void main() {
+  description(
+  "This page tests assertions followed by quantifiers."
+  );
+
+  var regexp;
+
+  regexp = new RegExp(r"(?=a){0}", multiLine: true);
+  shouldBeTrue(regexp.hasMatch('a'));
+
+  regexp = new RegExp(r"(?=a){1}", multiLine: true);
+  shouldBeTrue(regexp.hasMatch('a'));
+
+  regexp = new RegExp(r"(?!a){0}", multiLine: true);
+  shouldBeTrue(regexp.hasMatch('b'));
+
+  regexp = new RegExp(r"(?!a){1}", multiLine: true);
+  shouldBeTrue(regexp.hasMatch('b'));
+
+  shouldBeTrue(new RegExp(r"^(?=a)?b$").hasMatch("b"));
+}
diff --git a/tests/corelib/regexp/range-bound-ffff_test.dart b/tests/corelib/regexp/range-bound-ffff_test.dart
new file mode 100644
index 0000000..29d5a77
--- /dev/null
+++ b/tests/corelib/regexp/range-bound-ffff_test.dart
@@ -0,0 +1,34 @@
+// Copyright (c) 2014, the Dart project authors. All rights reserved.
+// Copyright 2013 the V8 project authors. All rights reserved.
+// Copyright (C) 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1.  Redistributions of source code must retain the above copyright
+//     notice, this list of conditions and the following disclaimer.
+// 2.  Redistributions in binary form must reproduce the above copyright
+//     notice, this list of conditions and the following disclaimer in the
+//     documentation and/or other materials provided with the distribution.
+//
+// THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
+// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+import 'v8_regexp_utils.dart';
+import 'package:expect/expect.dart';
+
+void main() {
+  description(
+  'Test for rdar:/68455379, a case-insensitive regex containing a character class containing a range with an upper bound of \uFFFF can lead to an infinite-loop.'
+  );
+
+  shouldBe(firstMatch("A", new RegExp(r"[\u0001-\uFFFF]", caseSensitive: false)), ["A"]);
+}
diff --git a/tests/corelib/regexp/range-out-of-order_test.dart b/tests/corelib/regexp/range-out-of-order_test.dart
new file mode 100644
index 0000000..252c08f
--- /dev/null
+++ b/tests/corelib/regexp/range-out-of-order_test.dart
@@ -0,0 +1,34 @@
+// Copyright (c) 2014, the Dart project authors. All rights reserved.
+// Copyright 2013 the V8 project authors. All rights reserved.
+// Copyright (C) 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1.  Redistributions of source code must retain the above copyright
+//     notice, this list of conditions and the following disclaimer.
+// 2.  Redistributions in binary form must reproduce the above copyright
+//     notice, this list of conditions and the following disclaimer in the
+//     documentation and/or other materials provided with the distribution.
+//
+// THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
+// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+import 'v8_regexp_utils.dart';
+import 'package:expect/expect.dart';
+
+void main() {
+  description(
+  'Test for <a href="http://bugs.webkit.org/show_bug.cgi?id=16129">bug 16129</a>: REGRESSION (r27761-r27811): malloc error while visiting http://mysit.es (crashes release build).'
+  );
+
+  assertThrows(() => new RegExp(r"^[\s{-.\[\]\(\)]$"));
+}
diff --git a/tests/corelib/regexp/ranges-and-escaped-hyphens_test.dart b/tests/corelib/regexp/ranges-and-escaped-hyphens_test.dart
new file mode 100644
index 0000000..5b8611b
--- /dev/null
+++ b/tests/corelib/regexp/ranges-and-escaped-hyphens_test.dart
@@ -0,0 +1,81 @@
+// Copyright (c) 2014, the Dart project authors. All rights reserved.
+// Copyright 2013 the V8 project authors. All rights reserved.
+// Copyright (C) 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1.  Redistributions of source code must retain the above copyright
+//     notice, this list of conditions and the following disclaimer.
+// 2.  Redistributions in binary form must reproduce the above copyright
+//     notice, this list of conditions and the following disclaimer in the
+//     documentation and/or other materials provided with the distribution.
+//
+// THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
+// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+import 'v8_regexp_utils.dart';
+import 'package:expect/expect.dart';
+
+void main() {
+  description(
+  'Tests for bug <a href="https://bugs.webkit.org/show_bug.cgi?id=21232">#21232</a>, and related range issues described in bug.'
+  );
+
+  // Basic test for ranges - one to three and five are in regexp, four is not, and '-' should not match
+  var regexp01 = new RegExp(r"[1-35]+").firstMatch("-12354");
+  shouldBe(regexp01, ["1235"]);
+  // Tests inserting an escape character class into the above pattern - where the spaces fall within the
+  // range it is no longer a range - hyphens should now match, two should not.
+  var regexp01a = new RegExp(r"[\s1-35]+").firstMatch("-123 54");
+  shouldBe(regexp01a, ["123 5"]);
+
+  // These are invalid ranges, according to ECMA-262, but we allow them.
+  var regexp01b = new RegExp(r"[1\s-35]+").firstMatch("21-3 54");
+  shouldBe(regexp01b, ["1-3 5"]);
+  var regexp01c = new RegExp(r"[1-\s35]+").firstMatch("21-3 54");
+  shouldBe(regexp01c, ["1-3 5"]);
+
+  var regexp01d = new RegExp(r"[1-3\s5]+").firstMatch("-123 54");
+  shouldBe(regexp01d, ["123 5"]);
+  var regexp01e = new RegExp(r"[1-35\s5]+").firstMatch("-123 54");
+  shouldBe(regexp01e, ["123 5"]);
+  // hyphens are normal charaters if a range is not fully specified.
+  var regexp01f = new RegExp(r"[-3]+").firstMatch("2-34");
+  shouldBe(regexp01f, ["-3"]);
+  var regexp01g = new RegExp(r"[2-]+").firstMatch("12-3");
+  shouldBe(regexp01g, ["2-"]);
+
+  // Similar to the above tests, but where the hyphen is escaped this is never a range.
+  var regexp02 = new RegExp(r"[1\-35]+").firstMatch("21-354");
+  shouldBe(regexp02, ["1-35"]);
+  // As above.
+  var regexp02a = new RegExp(r"[\s1\-35]+").firstMatch("21-3 54");
+  shouldBe(regexp02a, ["1-3 5"]);
+  var regexp02b = new RegExp(r"[1\s\-35]+").firstMatch("21-3 54");
+  shouldBe(regexp02b, ["1-3 5"]);
+  var regexp02c = new RegExp(r"[1\-\s35]+").firstMatch("21-3 54");
+  shouldBe(regexp02c, ["1-3 5"]);
+  var regexp02d = new RegExp(r"[1\-3\s5]+").firstMatch("21-3 54");
+  shouldBe(regexp02d, ["1-3 5"]);
+  var regexp02e = new RegExp(r"[1\-35\s5]+").firstMatch("21-3 54");
+  shouldBe(regexp02e, ["1-3 5"]);
+
+  // Test that an escaped hyphen can be used as a bound on a range.
+  var regexp03a = new RegExp(r"[\--0]+").firstMatch(",-.01");
+  shouldBe(regexp03a, ["-.0"]);
+  var regexp03b = new RegExp(r"[+-\-]+").firstMatch("*+,-.");
+  shouldBe(regexp03b, ["+,-"]);
+
+  // The actual bug reported.
+  var bug21232 = (new RegExp(r"^[,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t]*$")).hasMatch('@');
+  shouldBeFalse(bug21232);
+}
diff --git a/tests/corelib/regexp/regexp_kde_test.dart b/tests/corelib/regexp/regexp_kde_test.dart
new file mode 100644
index 0000000..b4873c4
--- /dev/null
+++ b/tests/corelib/regexp/regexp_kde_test.dart
@@ -0,0 +1,89 @@
+// Copyright (c) 2014, the Dart project authors. All rights reserved.
+// Copyright 2013 the V8 project authors. All rights reserved.
+// Copyright (C) 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1.  Redistributions of source code must retain the above copyright
+//     notice, this list of conditions and the following disclaimer.
+// 2.  Redistributions in binary form must reproduce the above copyright
+//     notice, this list of conditions and the following disclaimer in the
+//     documentation and/or other materials provided with the distribution.
+//
+// THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
+// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+import 'v8_regexp_utils.dart';
+import 'package:expect/expect.dart';
+
+void main() {
+  description("KDE JS Test");
+
+  var ri = new RegExp(r"a", caseSensitive: false);
+  var rm = new RegExp(r"a", multiLine: true);
+  var rg = new RegExp(r"a");
+
+  shouldBe(new RegExp(r"(b)c").firstMatch('abcd'), ["bc", "b"]);
+
+  shouldBe(firstMatch('abcdefghi', new RegExp(r"(abc)def(ghi)")), ['abcdefghi', 'abc', 'ghi']);
+  shouldBe(new RegExp(r"(abc)def(ghi)").firstMatch('abcdefghi'), ['abcdefghi', 'abc', 'ghi']);
+
+  shouldBe(firstMatch('abcdefghi', new RegExp(r"(a(b(c(d(e)f)g)h)i)")), ['abcdefghi', 'abcdefghi', 'bcdefgh', 'cdefg', 'def', 'e']);
+
+  shouldBe(firstMatch('(100px 200px 150px 15px)', new RegExp(r"\((\d+)(px)* (\d+)(px)* (\d+)(px)* (\d+)(px)*\)")),
+          ['(100px 200px 150px 15px)', '100', 'px', '200', 'px', '150', 'px', '15', 'px']);
+  shouldBeNull(firstMatch('', new RegExp(r"\((\d+)(px)* (\d+)(px)* (\d+)(px)* (\d+)(px)*\)")));
+
+  var invalidChars = new RegExp(r"[^@\.\w]"); // #47092
+  shouldBeTrue(firstMatch('faure@kde.org', invalidChars) == null);
+  shouldBeFalse(firstMatch('faure-kde@kde.org', invalidChars) == null);
+
+  assertEquals('test1test2'.replaceAll('test','X'),'X1X2');
+  assertEquals('test1test2'.replaceAll(new RegExp(r"\d"),'X'),'testXtestX');
+  assertEquals('1test2test3'.replaceAll(new RegExp(r"\d"),''),'testtest');
+  assertEquals('test1test2'.replaceAll(new RegExp(r"test"),'X'),'X1X2');
+  assertEquals('1test2test3'.replaceAll(new RegExp(r"\d"),''),'testtest');
+  assertEquals('1test2test3'.replaceAll(new RegExp(r"x"),''),'1test2test3');
+  assertEquals('test1test2'.replaceAllMapped(new RegExp(r"(te)(st)"),
+              (m) => "${m.group(2)}${m.group(1)}"),'stte1stte2');
+  assertEquals('foo+bar'.replaceAll(new RegExp(r"\+"),'%2B'), 'foo%2Bbar');
+  var caught = false; try { new RegExp("+"); } catch (e) { caught = true; }
+  shouldBeTrue(caught); // #40435
+  assertEquals('foo'.replaceAll(new RegExp(r"z?"),'x'), 'xfxoxox');
+  assertEquals('test test'.replaceAll(new RegExp(r"\s*"),''),'testtest'); // #50985
+  assertEquals('abc\$%@'.replaceAll(new RegExp(r"[^0-9a-z]*", caseSensitive: false),''),'abc'); // #50848
+  assertEquals('ab'.replaceAll(new RegExp(r"[^\d\.]*", caseSensitive: false),''),''); // #75292
+  assertEquals('1ab'.replaceAll(new RegExp(r"[^\d\.]*", caseSensitive: false),''),'1'); // #75292
+
+  Expect.listEquals('1test2test3blah'.split(new RegExp(r"test")), ['1', '2', '3blah']);
+  var reg = new RegExp(r"(\d\d )");
+  var str = '98 76 blah';
+  shouldBe(reg.firstMatch(str),['98 ', '98 ']);
+
+  str = "For more information, see Chapter 3.4.5.1";
+  var re = new RegExp(r"(chapter \d+(\.\d)*)", caseSensitive: false);
+  // This returns the array containing Chapter 3.4.5.1,Chapter 3.4.5.1,.1
+  // 'Chapter 3.4.5.1' is the first match and the first value remembered from (Chapter \d+(\.\d)*).
+  // '.1' is the second value remembered from (\.\d)
+  shouldBe(firstMatch(str, re),['Chapter 3.4.5.1', 'Chapter 3.4.5.1', '.1']);
+
+  str = "abcDdcba";
+  // The returned array contains D, d.
+  re = new RegExp(r"d", caseSensitive: false);
+  var matches = re.allMatches(str);
+  Expect.listEquals(
+      matches.map((m) => m.group(0)).toList(),
+      ['D', 'd']);
+
+  // unicode escape sequence
+  shouldBe(firstMatch('abc', new RegExp(r"\u0062")), ['b']);
+}
diff --git a/tests/corelib/regexp/regexp_test.dart b/tests/corelib/regexp/regexp_test.dart
new file mode 100644
index 0000000..60483ba
--- /dev/null
+++ b/tests/corelib/regexp/regexp_test.dart
@@ -0,0 +1,594 @@
+// Copyright (c) 2014, the Dart project authors. All rights reserved.
+// Copyright 2012 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+//       copyright notice, this list of conditions and the following
+//       disclaimer in the documentation and/or other materials provided
+//       with the distribution.
+//     * Neither the name of Google Inc. nor the names of its
+//       contributors may be used to endorse or promote products derived
+//       from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+import "package:expect/expect.dart";
+
+void testEscape(str, regex) {
+  assertEquals("foo:bar:baz", str.split(regex).join(":"));
+}
+
+void assertEquals(actual, expected, [message]) =>
+    Expect.equals(actual, expected, message);
+void assertTrue(actual, [message]) => Expect.isTrue(actual, message);
+void assertFalse(actual, [message]) => Expect.isFalse(actual, message);
+void assertThrows(fn) => Expect.throws(fn);
+
+void main() {
+  testEscape("foo\nbar\nbaz", new RegExp(r"\n"));
+  testEscape("foo bar baz", new RegExp(r"\s"));
+  testEscape("foo\tbar\tbaz", new RegExp(r"\s"));
+  testEscape("foo-bar-baz", new RegExp(r"\u002D"));
+
+  // Test containing null char in regexp.
+  var s = '[' + new String.fromCharCode(0) + ']';
+  var re = new RegExp(s);
+  assertEquals(re.allMatches(s).length, 1);
+  assertEquals(re.stringMatch(s), new String.fromCharCode(0));
+
+  final _vmFrame = new RegExp(
+    r'^#\d+\s+(\S.*) \((.+?):(\d+)(?::(\d+))?\)$');
+  final _traceLine =
+    "#0      Trace.Trace.parse (package:stack_trace/src/trace.dart:130:7)";
+  Expect.equals(_vmFrame.firstMatch(_traceLine).group(0), _traceLine);
+
+  // Test the UTF16 case insensitive comparison.
+  re = new RegExp(r"x(a)\1x", caseSensitive: false);
+  Expect.equals(re.firstMatch("xaAx\u1234").group(0), "xaAx");
+
+  // Test strings containing all line separators
+  s = 'aA\nbB\rcC\r\ndD\u2028eE\u2029fF';
+  // any non-newline character at the beginning of a line
+  re = new RegExp(r"^.", multiLine: true);
+  var result = re.allMatches(s).toList();
+  assertEquals(result.length, 6);
+  assertEquals(result[0][0], 'a');
+  assertEquals(result[1][0], 'b');
+  assertEquals(result[2][0], 'c');
+  assertEquals(result[3][0], 'd');
+  assertEquals(result[4][0], 'e');
+  assertEquals(result[5][0], 'f');
+
+  // any non-newline character at the end of a line
+  re = new RegExp(r".$", multiLine: true);
+  result = re.allMatches(s).toList();
+  assertEquals(result.length, 6);
+  assertEquals(result[0][0], 'A');
+  assertEquals(result[1][0], 'B');
+  assertEquals(result[2][0], 'C');
+  assertEquals(result[3][0], 'D');
+  assertEquals(result[4][0], 'E');
+  assertEquals(result[5][0], 'F');
+
+  // *any* character at the beginning of a line
+  re = new RegExp(r"^[^]", multiLine: true);
+  result = re.allMatches(s).toList();
+  assertEquals(result.length, 7);
+  assertEquals(result[0][0], 'a');
+  assertEquals(result[1][0], 'b');
+  assertEquals(result[2][0], 'c');
+  assertEquals(result[3][0], '\n');
+  assertEquals(result[4][0], 'd');
+  assertEquals(result[5][0], 'e');
+  assertEquals(result[6][0], 'f');
+
+  // *any* character at the end of a line
+  re = new RegExp(r"[^]$", multiLine: true);
+  result = re.allMatches(s).toList();
+  assertEquals(result.length, 7);
+  assertEquals(result[0][0], 'A');
+  assertEquals(result[1][0], 'B');
+  assertEquals(result[2][0], 'C');
+  assertEquals(result[3][0], '\r');
+  assertEquals(result[4][0], 'D');
+  assertEquals(result[5][0], 'E');
+  assertEquals(result[6][0], 'F');
+
+  // Some tests from the Mozilla tests, where our behavior used to differ
+  // from SpiderMonkey.
+  // From ecma_3/RegExp/regress-334158.js
+  assertTrue( "\x01" .contains(new RegExp(r"\ca")));
+  assertFalse( "\\ca" .contains(new RegExp(r"\ca")));
+  assertFalse( "ca" .contains(new RegExp(r"\ca")));
+  assertTrue( "\\ca" .contains(new RegExp(r"\c[a/]")));
+  assertTrue( "\\c/" .contains(new RegExp(r"\c[a/]")));
+
+  // Test \c in character class
+  re = r"^[\cM]$";
+  assertTrue("\r".contains(new RegExp(re)));
+  assertFalse("M".contains(new RegExp(re)));
+  assertFalse("c".contains(new RegExp(re)));
+  assertFalse("\\".contains(new RegExp(re)));
+  assertFalse("\x03".contains(new RegExp(re)));  // I.e., read as \cc
+
+  re = r"^[\c]]$";
+  assertTrue("c]".contains(new RegExp(re)));
+  assertTrue("\\]".contains(new RegExp(re)));
+  assertFalse("\x1d".contains(new RegExp(re)));  // ']' & 0x1f
+  assertFalse("\x03]".contains(new RegExp(re)));  // I.e., read as \cc
+
+  // Digit control characters are masked in character classes.
+  re = r"^[\c1]$";
+  assertTrue("\x11".contains(new RegExp(re)));
+  assertFalse("\\".contains(new RegExp(re)));
+  assertFalse("c".contains(new RegExp(re)));
+  assertFalse("1".contains(new RegExp(re)));
+
+  // Underscore control character is masked in character classes.
+  re = r"^[\c_]$";
+  assertTrue("\x1f".contains(new RegExp(re)));
+  assertFalse("\\".contains(new RegExp(re)));
+  assertFalse("c".contains(new RegExp(re)));
+  assertFalse("_".contains(new RegExp(re)));
+
+  re = r"^[\c$]$";  // Other characters are interpreted literally.
+  assertFalse("\x04".contains(new RegExp(re)));
+  assertTrue("\\".contains(new RegExp(re)));
+  assertTrue("c".contains(new RegExp(re)));
+  assertTrue(r"$".contains(new RegExp(re)));
+
+  assertTrue("Z[\\cde".contains(new RegExp(r"^[Z-\c-e]*$")));
+
+  // Test that we handle \s and \S correctly on special Unicode characters.
+  re = r"\s";
+  assertTrue("\u2028".contains(new RegExp(re)));
+  assertTrue("\u2029".contains(new RegExp(re)));
+  assertTrue("\uFEFF".contains(new RegExp(re)));
+
+  re = r"\S";
+  assertFalse("\u2028".contains(new RegExp(re)));
+  assertFalse("\u2029".contains(new RegExp(re)));
+  assertFalse("\uFEFF".contains(new RegExp(re)));
+
+  // Test that we handle \s and \S correctly inside some bizarre
+  // character classes.
+  re = r"[\s-:]";
+  assertTrue('-'.contains(new RegExp(re)));
+  assertTrue(':'.contains(new RegExp(re)));
+  assertTrue(' '.contains(new RegExp(re)));
+  assertTrue('\t'.contains(new RegExp(re)));
+  assertTrue('\n'.contains(new RegExp(re)));
+  assertFalse('a'.contains(new RegExp(re)));
+  assertFalse('Z'.contains(new RegExp(re)));
+
+  re = r"[\S-:]";
+  assertTrue('-'.contains(new RegExp(re)));
+  assertTrue(':'.contains(new RegExp(re)));
+  assertFalse(' '.contains(new RegExp(re)));
+  assertFalse('\t'.contains(new RegExp(re)));
+  assertFalse('\n'.contains(new RegExp(re)));
+  assertTrue('a'.contains(new RegExp(re)));
+  assertTrue('Z'.contains(new RegExp(re)));
+
+  re = r"[^\s-:]";
+  assertFalse('-'.contains(new RegExp(re)));
+  assertFalse(':'.contains(new RegExp(re)));
+  assertFalse(' '.contains(new RegExp(re)));
+  assertFalse('\t'.contains(new RegExp(re)));
+  assertFalse('\n'.contains(new RegExp(re)));
+  assertTrue('a'.contains(new RegExp(re)));
+  assertTrue('Z'.contains(new RegExp(re)));
+
+  re = r"[^\S-:]";
+  assertFalse('-'.contains(new RegExp(re)));
+  assertFalse(':'.contains(new RegExp(re)));
+  assertTrue(' '.contains(new RegExp(re)));
+  assertTrue('\t'.contains(new RegExp(re)));
+  assertTrue('\n'.contains(new RegExp(re)));
+  assertFalse('a'.contains(new RegExp(re)));
+  assertFalse('Z'.contains(new RegExp(re)));
+
+  re = r"[\s]";
+  assertFalse('-'.contains(new RegExp(re)));
+  assertFalse(':'.contains(new RegExp(re)));
+  assertTrue(' '.contains(new RegExp(re)));
+  assertTrue('\t'.contains(new RegExp(re)));
+  assertTrue('\n'.contains(new RegExp(re)));
+  assertFalse('a'.contains(new RegExp(re)));
+  assertFalse('Z'.contains(new RegExp(re)));
+
+  re = r"[^\s]";
+  assertTrue('-'.contains(new RegExp(re)));
+  assertTrue(':'.contains(new RegExp(re)));
+  assertFalse(' '.contains(new RegExp(re)));
+  assertFalse('\t'.contains(new RegExp(re)));
+  assertFalse('\n'.contains(new RegExp(re)));
+  assertTrue('a'.contains(new RegExp(re)));
+  assertTrue('Z'.contains(new RegExp(re)));
+
+  re = r"[\S]";
+  assertTrue('-'.contains(new RegExp(re)));
+  assertTrue(':'.contains(new RegExp(re)));
+  assertFalse(' '.contains(new RegExp(re)));
+  assertFalse('\t'.contains(new RegExp(re)));
+  assertFalse('\n'.contains(new RegExp(re)));
+  assertTrue('a'.contains(new RegExp(re)));
+  assertTrue('Z'.contains(new RegExp(re)));
+
+  re = r"[^\S]";
+  assertFalse('-'.contains(new RegExp(re)));
+  assertFalse(':'.contains(new RegExp(re)));
+  assertTrue(' '.contains(new RegExp(re)));
+  assertTrue('\t'.contains(new RegExp(re)));
+  assertTrue('\n'.contains(new RegExp(re)));
+  assertFalse('a'.contains(new RegExp(re)));
+  assertFalse('Z'.contains(new RegExp(re)));
+
+  re = r"[\s\S]";
+  assertTrue('-'.contains(new RegExp(re)));
+  assertTrue(':'.contains(new RegExp(re)));
+  assertTrue(' '.contains(new RegExp(re)));
+  assertTrue('\t'.contains(new RegExp(re)));
+  assertTrue('\n'.contains(new RegExp(re)));
+  assertTrue('a'.contains(new RegExp(re)));
+  assertTrue('Z'.contains(new RegExp(re)));
+
+  re = r"[^\s\S]";
+  assertFalse('-'.contains(new RegExp(re)));
+  assertFalse(':'.contains(new RegExp(re)));
+  assertFalse(' '.contains(new RegExp(re)));
+  assertFalse('\t'.contains(new RegExp(re)));
+  assertFalse('\n'.contains(new RegExp(re)));
+  assertFalse('a'.contains(new RegExp(re)));
+  assertFalse('Z'.contains(new RegExp(re)));
+
+  // First - is treated as range operator, second as literal minus.
+  // This follows the specification in parsing, but doesn't throw on
+  // the \s at the beginning of the range.
+  re = r"[\s-0-9]";
+  assertTrue(' '.contains(new RegExp(re)));
+  assertTrue('\xA0'.contains(new RegExp(re)));
+  assertTrue('-'.contains(new RegExp(re)));
+  assertTrue('0'.contains(new RegExp(re)));
+  assertTrue('9'.contains(new RegExp(re)));
+  assertFalse('1'.contains(new RegExp(re)));
+
+  // Test beginning and end of line assertions with or without the
+  // multiline flag.
+  re = r"^\d+";
+  assertFalse("asdf\n123".contains(new RegExp(re)));
+  re = new RegExp(r"^\d+", multiLine: true);
+  assertTrue("asdf\n123".contains(re));
+
+  re = r"\d+$";
+  assertFalse("123\nasdf".contains(new RegExp(re)));
+  re = new RegExp(r"\d+$", multiLine: true);
+  assertTrue("123\nasdf".contains(re));
+
+  // Test that empty matches are handled correctly for multiline global
+  // regexps.
+  re = new RegExp(r"^(.*)", multiLine: true);
+  assertEquals(3, re.allMatches("a\n\rb").length);
+  assertEquals("*a\n*b\r*c\n*\r*d\r*\n*e",
+      "a\nb\rc\n\rd\r\ne".replaceAllMapped(
+        re, (Match m) => "*${m.group(1)}"));
+
+  // Test that empty matches advance one character
+  re = new RegExp("");
+  assertEquals("xAx", "A".replaceAll(re, "x"));
+  assertEquals(3, new String.fromCharCode(161).replaceAll(re, "x").length);
+
+  // Check for lazy RegExp literal creation
+  lazyLiteral(doit) {
+    if (doit) return "".replaceAll(
+        new RegExp(r"foo(", caseSensitive: false), "");
+    return true;
+  }
+
+  assertTrue(lazyLiteral(false));
+  assertThrows(() => lazyLiteral(true));
+
+  // Check $01 and $10
+  re = new RegExp("(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)");
+  assertEquals("t", "123456789t".replaceAllMapped(
+        re, (Match m) => m.group(10)));
+  assertEquals("15", "123456789t".replaceAllMapped(
+        re, (Match m) => "${m.group(1)}5"));
+  assertEquals("1", "123456789t".replaceAllMapped(
+        re, (Match m) => m.group(1)));
+
+  assertFalse("football".contains(new RegExp(r"()foo$\1")), "football1");
+  assertFalse("football".contains(new RegExp(r"foo$(?=ball)")), "football2");
+  assertFalse("football".contains(new RegExp(r"foo$(?!bar)")), "football3");
+  assertTrue("foo".contains(new RegExp(r"()foo$\1")), "football4");
+  assertTrue("foo".contains(new RegExp(r"foo$(?=(ball)?)")), "football5");
+  assertTrue("foo".contains(new RegExp(r"()foo$(?!bar)")), "football6");
+  assertFalse("football".contains(new RegExp(r"(x?)foo$\1")), "football7");
+  assertFalse("football".contains(new RegExp(r"foo$(?=ball)")), "football8");
+  assertFalse("football".contains(new RegExp(r"foo$(?!bar)")), "football9");
+  assertTrue("foo".contains(new RegExp(r"(x?)foo$\1")), "football10");
+  assertTrue("foo".contains(new RegExp(r"foo$(?=(ball)?)")), "football11");
+  assertTrue("foo".contains(new RegExp(r"foo$(?!bar)")), "football12");
+
+  // Check that the back reference has two successors.  See
+  // BackReferenceNode::PropagateForward.
+  assertFalse('foo'.contains(new RegExp(r"f(o)\b\1")));
+  assertTrue('foo'.contains(new RegExp(r"f(o)\B\1")));
+
+  // Back-reference, ignore case:
+  // ASCII
+  assertEquals("a", new RegExp(r"x(a)\1x", caseSensitive: false)
+      .firstMatch("xaAx").group(1), "backref-ASCII");
+  assertFalse("xaaaaa".contains(new RegExp(r"x(...)\1",
+                                caseSensitive: false)),
+      "backref-ASCII-short");
+  assertTrue("xx".contains(new RegExp(r"x((?:))\1\1x", caseSensitive: false)),
+      "backref-ASCII-empty");
+  assertTrue("xabcx".contains(
+        new RegExp(r"x(?:...|(...))\1x", caseSensitive: false)),
+      "backref-ASCII-uncaptured");
+  assertTrue("xabcABCx".contains(
+        new RegExp(r"x(?:...|(...))\1x", caseSensitive: false)),
+      "backref-ASCII-backtrack");
+  assertEquals("aBc", new RegExp(r"x(...)\1\1x", caseSensitive: false)
+      .firstMatch("xaBcAbCABCx").group(1), "backref-ASCII-twice");
+
+  for (var i = 0; i < 128; i++) {
+    var testName = "backref-ASCII-char-$i,,${i^0x20}";
+    var test = new String.fromCharCodes([i, i ^ 0x20])
+      .contains(new RegExp(r"^(.)\1$", caseSensitive: false));
+    if (('A'.codeUnitAt(0) <= i && i <= 'Z'.codeUnitAt(0)) ||
+        ('a'.codeUnitAt(0) <= i && i <= 'z'.codeUnitAt(0))) {
+      assertTrue(test, testName);
+    } else {
+      assertFalse(test, testName);
+    }
+  }
+
+  assertFalse('foo'.contains(new RegExp(r"f(o)$\1")),
+              "backref detects at_end");
+
+  // Check decimal escapes doesn't overflow.
+  // (Note: \214 is interpreted as octal).
+  assertEquals("\x8c7483648", new RegExp(r"\2147483648")
+      .firstMatch("\x8c7483648").group(0), "Overflow decimal escape");
+
+  // Check numbers in quantifiers doesn't overflow and doesn't throw on
+  // too large numbers.
+  assertFalse('b'.contains(
+        new RegExp(r"a{111111111111111111111111111111111111111111111}")),
+              "overlarge1");
+  assertFalse('b'.contains(
+        new RegExp(r"a{999999999999999999999999999999999999999999999}")),
+              "overlarge2");
+  assertFalse('b'.contains(
+        new RegExp(r"a{1,111111111111111111111111111111111111111111111}")),
+              "overlarge3");
+  assertFalse('b'.contains(
+        new RegExp(r"a{1,999999999999999999999999999999999999999999999}")),
+              "overlarge4");
+  assertFalse('b'.contains(new RegExp(r"a{2147483648}")),
+              "overlarge5");
+  assertFalse('b'.contains(new RegExp(r"a{21474836471}")),
+              "overlarge6");
+  assertFalse('b'.contains(new RegExp(r"a{1,2147483648}")),
+              "overlarge7");
+  assertFalse('b'.contains(new RegExp(r"a{1,21474836471}")),
+              "overlarge8");
+  assertFalse('b'.contains(new RegExp(r"a{2147483648,2147483648}")),
+              "overlarge9");
+  assertFalse('b'.contains(new RegExp(r"a{21474836471,21474836471}")),
+              "overlarge10");
+  assertFalse('b'.contains(new RegExp(r"a{2147483647}")),
+              "overlarge11");
+  assertFalse('b'.contains(new RegExp(r"a{1,2147483647}")),
+              "overlarge12");
+  assertTrue('a'.contains(new RegExp(r"a{1,2147483647}")),
+              "overlarge13");
+  assertFalse('a'.contains(new RegExp(r"a{2147483647,2147483647}")),
+              "overlarge14");
+
+  // Check that we don't read past the end of the string.
+  assertFalse('b'.contains(new RegExp(r"f")));
+  assertFalse('x'.contains(new RegExp(r"[abc]f")));
+  assertFalse('xa'.contains(new RegExp(r"[abc]f")));
+  assertFalse('x'.contains(new RegExp(r"[abc]<")));
+  assertFalse('xa'.contains(new RegExp(r"[abc]<")));
+  assertFalse('b'.contains(new RegExp(r"f", caseSensitive: false)));
+  assertFalse('x'.contains(new RegExp(r"[abc]f", caseSensitive: false)));
+  assertFalse('xa'.contains(new RegExp(r"[abc]f", caseSensitive: false)));
+  assertFalse('x'.contains(new RegExp(r"[abc]<", caseSensitive: false)));
+  assertFalse('xa'.contains(new RegExp(r"[abc]<", caseSensitive: false)));
+  assertFalse('x'.contains(new RegExp(r"f[abc]")));
+  assertFalse('xa'.contains(new RegExp(r"f[abc]")));
+  assertFalse('x'.contains(new RegExp(r"<[abc]")));
+  assertFalse('xa'.contains(new RegExp(r"<[abc]")));
+  assertFalse('x'.contains(new RegExp(r"f[abc]", caseSensitive: false)));
+  assertFalse('xa'.contains(new RegExp(r"f[abc]", caseSensitive: false)));
+  assertFalse('x'.contains(new RegExp(r"<[abc]", caseSensitive: false)));
+  assertFalse('xa'.contains(new RegExp(r"<[abc]", caseSensitive: false)));
+
+  // Test that merging of quick test masks gets it right.
+  assertFalse('x7%%y'.contains(new RegExp(r"x([0-7]%%x|[0-6]%%y)")), 'qt');
+  assertFalse('xy7%%%y'.contains(
+        new RegExp(r"()x\1(y([0-7]%%%x|[0-6]%%%y)|dkjasldkas)")), 'qt2');
+  assertFalse('xy%%%y'.contains(
+        new RegExp(r"()x\1(y([0-7]%%%x|[0-6]%%%y)|dkjasldkas)")), 'qt3');
+  assertFalse('xy7%%%y'.contains(
+        new RegExp(r"()x\1y([0-7]%%%x|[0-6]%%%y)")), 'qt4');
+  assertFalse('xy%%%y'.contains(
+        new RegExp(r"()x\1(y([0-7]%%%x|[0-6]%%%y)|dkjasldkas)")), 'qt5');
+  assertFalse('xy7%%%y'.contains(
+        new RegExp(r"()x\1y([0-7]%%%x|[0-6]%%%y)")), 'qt6');
+  assertFalse('xy7%%%y'.contains(
+        new RegExp(r"xy([0-7]%%%x|[0-6]%%%y)")), 'qt7');
+  assertFalse('x7%%%y'.contains(new RegExp(r"x([0-7]%%%x|[0-6]%%%y)")),
+              'qt8');
+
+
+  // Don't hang on this one.
+  "".contains(new RegExp(r"[^\xfe-\xff]*"));
+
+  var longbuffer = new StringBuffer("a");
+  for (var i = 0; i < 100000; i++) {
+    longbuffer.write("a?");
+  }
+  var long = longbuffer.toString();
+
+  // Don't crash on this one, but maybe throw an exception.
+  try {
+    new RegExp(long).allMatches("a");
+  } catch (e) {
+    assertTrue(e.toString().indexOf("Stack overflow") >= 0, "overflow");
+  }
+
+
+  // Test boundary-checks.
+  void assertRegExpTest(re, input, test) {
+    assertEquals(test, input.contains(
+          new RegExp(re)), "test:" + re + ":" + input);
+  }
+
+  assertRegExpTest(r"b\b", "b", true);
+  assertRegExpTest(r"b\b$", "b", true);
+  assertRegExpTest(r"\bb", "b", true);
+  assertRegExpTest(r"^\bb", "b", true);
+  assertRegExpTest(r",\b", ",", false);
+  assertRegExpTest(r",\b$", ",", false);
+  assertRegExpTest(r"\b,", ",", false);
+  assertRegExpTest(r"^\b,", ",", false);
+
+  assertRegExpTest(r"b\B", "b", false);
+  assertRegExpTest(r"b\B$", "b", false);
+  assertRegExpTest(r"\Bb", "b", false);
+  assertRegExpTest(r"^\Bb", "b", false);
+  assertRegExpTest(r",\B", ",", true);
+  assertRegExpTest(r",\B$", ",", true);
+  assertRegExpTest(r"\B,", ",", true);
+  assertRegExpTest(r"^\B,", ",", true);
+
+  assertRegExpTest(r"b\b", "b,", true);
+  assertRegExpTest(r"b\b", "ba", false);
+  assertRegExpTest(r"b\B", "b,", false);
+  assertRegExpTest(r"b\B", "ba", true);
+
+  assertRegExpTest(r"b\Bb", "bb", true);
+  assertRegExpTest(r"b\bb", "bb", false);
+
+  assertRegExpTest(r"b\b[,b]", "bb", false);
+  assertRegExpTest(r"b\B[,b]", "bb", true);
+  assertRegExpTest(r"b\b[,b]", "b,", true);
+  assertRegExpTest(r"b\B[,b]", "b,", false);
+
+  assertRegExpTest(r"[,b]\bb", "bb", false);
+  assertRegExpTest(r"[,b]\Bb", "bb", true);
+  assertRegExpTest(r"[,b]\bb", ",b", true);
+  assertRegExpTest(r"[,b]\Bb", ",b", false);
+
+  assertRegExpTest(r"[,b]\b[,b]", "bb", false);
+  assertRegExpTest(r"[,b]\B[,b]", "bb", true);
+  assertRegExpTest(r"[,b]\b[,b]", ",b", true);
+  assertRegExpTest(r"[,b]\B[,b]", ",b", false);
+  assertRegExpTest(r"[,b]\b[,b]", "b,", true);
+  assertRegExpTest(r"[,b]\B[,b]", "b,", false);
+
+  // Skipped tests from V8:
+
+  // Test that caching of result doesn't share result objects.
+  // More iterations increases the chance of hitting a GC.
+
+  // Test that we perform the spec required conversions in the correct order.
+
+  // Check that properties of RegExp have the correct permissions.
+
+  // Check that end-anchored regexps are optimized correctly.
+  re = r"(?:a|bc)g$";
+  assertTrue("ag".contains(new RegExp(re)));
+  assertTrue("bcg".contains(new RegExp(re)));
+  assertTrue("abcg".contains(new RegExp(re)));
+  assertTrue("zimbag".contains(new RegExp(re)));
+  assertTrue("zimbcg".contains(new RegExp(re)));
+
+  assertFalse("g".contains(new RegExp(re)));
+  assertFalse("".contains(new RegExp(re)));
+
+  // Global regexp (non-zero start).
+  re = r"(?:a|bc)g$";
+  assertTrue("ag".contains(new RegExp(re)));
+  // Near start of string.
+  assertTrue(new RegExp(re).allMatches("zimbag", 1).isNotEmpty);
+  // At end of string.
+  assertTrue(new RegExp(re).allMatches("zimbag", 6).isEmpty);
+  // Near end of string.
+  assertTrue(new RegExp(re).allMatches("zimbag", 5).isEmpty);
+  assertTrue(new RegExp(re).allMatches("zimbag", 4).isNotEmpty);
+
+  // Anchored at both ends.
+  re = r"^(?:a|bc)g$";
+  assertTrue("ag".contains(new RegExp(re)));
+  assertTrue(new RegExp(re).allMatches("ag", 1).isEmpty);
+  assertTrue(new RegExp(re).allMatches("zag", 1).isEmpty);
+
+  // Long max_length of RegExp.
+  re = r"VeryLongRegExp!{1,1000}$";
+  assertTrue("BahoolaVeryLongRegExp!!!!!!".contains(new RegExp(re)));
+  assertFalse("VeryLongRegExp".contains(new RegExp(re)));
+  assertFalse("!".contains(new RegExp(re)));
+
+  // End anchor inside disjunction.
+  re = r"(?:a$|bc$)";
+  assertTrue("a".contains(new RegExp(re)));
+  assertTrue("bc".contains(new RegExp(re)));
+  assertTrue("abc".contains(new RegExp(re)));
+  assertTrue("zimzamzumba".contains(new RegExp(re)));
+  assertTrue("zimzamzumbc".contains(new RegExp(re)));
+  assertFalse("c".contains(new RegExp(re)));
+  assertFalse("".contains(new RegExp(re)));
+
+  // Only partially anchored.
+  re = r"(?:a|bc$)";
+  assertTrue("a".contains(new RegExp(re)));
+  assertTrue("bc".contains(new RegExp(re)));
+  assertEquals("a", new RegExp(re).firstMatch("abc").group(0));
+  assertEquals(4, new RegExp(re).firstMatch("zimzamzumba").start);
+  assertEquals("bc", new RegExp(re).firstMatch("zimzomzumbc").group(0));
+  assertFalse("c".contains(new RegExp(re)));
+  assertFalse("".contains(new RegExp(re)));
+
+  // Valid syntax in ES5.
+  re = new RegExp("(?:x)*");
+  re = new RegExp("(x)*");
+
+  // Syntax extension relative to ES5, for matching JSC (and ES3).
+  // Shouldn't throw.
+  re = new RegExp("(?=x)*");
+  re = new RegExp("(?!x)*");
+
+  // Should throw. Shouldn't hit asserts in debug mode.
+  assertThrows(() => new RegExp('(*)'));
+  assertThrows(() => new RegExp('(?:*)'));
+  assertThrows(() => new RegExp('(?=*)'));
+  assertThrows(() => new RegExp('(?!*)'));
+
+  // Test trimmed regular expression for RegExp.test().
+  assertTrue("abc".contains(new RegExp(r".*abc")));
+  assertFalse("q".contains(new RegExp(r".*\d+")));
+
+  // Tests skipped from V8:
+  // Test that RegExp.prototype.toString() throws TypeError for
+  // incompatible receivers (ES5 section 15.10.6 and 15.10.6.4).
+}
diff --git a/tests/corelib/regexp/regress-6-9-regexp_test.dart b/tests/corelib/regexp/regress-6-9-regexp_test.dart
new file mode 100644
index 0000000..3fbef87
--- /dev/null
+++ b/tests/corelib/regexp/regress-6-9-regexp_test.dart
@@ -0,0 +1,36 @@
+// Copyright (c) 2014, the Dart project authors. All rights reserved.
+// Copyright 2009 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+//       copyright notice, this list of conditions and the following
+//       disclaimer in the documentation and/or other materials provided
+//       with the distribution.
+//     * Neither the name of Google Inc. nor the names of its
+//       contributors may be used to endorse or promote products derived
+//       from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+import 'v8_regexp_utils.dart';
+import 'package:expect/expect.dart';
+
+void main() {
+  // Check that the perfect mask check isn't overly optimistic.
+
+  assertFalse(new RegExp(r"[6-9]").hasMatch('2'));
+}
diff --git a/tests/corelib/regexp/regress-regexp-codeflush_test.dart b/tests/corelib/regexp/regress-regexp-codeflush_test.dart
new file mode 100644
index 0000000..23a4954
--- /dev/null
+++ b/tests/corelib/regexp/regress-regexp-codeflush_test.dart
@@ -0,0 +1,61 @@
+// Copyright (c) 2014, the Dart project authors. All rights reserved.
+// Copyright 2011 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+//       copyright notice, this list of conditions and the following
+//       disclaimer in the documentation and/or other materials provided
+//       with the distribution.
+//     * Neither the name of Google Inc. nor the names of its
+//       contributors may be used to endorse or promote products derived
+//       from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+import 'v8_regexp_utils.dart';
+import 'package:expect/expect.dart';
+
+void main() {
+  // Flags: --gc_global
+
+  // Regression test for regexp that has multiple matches and which
+  // internally calls RegExpImpl::IrregexpExecOnce more than once without
+  // ensuring that the regexp is compiled.
+  // This can create a crash if the code was exchanged with the sweep
+  // generation (for code flushing support) in GC durring the matching.
+
+  var re = new RegExp('(s)');
+
+  dynamic foo(Match m) {
+    return "42";
+  }
+
+  // Run enough times to get a number of GC's (all mark sweep because of the
+  // --gc_global) flag.
+  for ( var i = 0; i < 10; i++) {
+    // Make a long string with plenty of matches for re.
+    var x = "s foo s bar s foo s bar s";
+    x = x + x;
+    x = x + x;
+    x = x + x;
+    x = x + x;
+    x = x + x;
+    x = x + x;
+    x = x + x;
+    x.replaceAllMapped(re, foo);
+  }
+}
diff --git a/tests/corelib/regexp/regress-regexp-construct-result_test.dart b/tests/corelib/regexp/regress-regexp-construct-result_test.dart
new file mode 100644
index 0000000..ac9c032
--- /dev/null
+++ b/tests/corelib/regexp/regress-regexp-construct-result_test.dart
@@ -0,0 +1,50 @@
+// Copyright (c) 2014, the Dart project authors. All rights reserved.
+// Copyright 2013 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+//       copyright notice, this list of conditions and the following
+//       disclaimer in the documentation and/or other materials provided
+//       with the distribution.
+//     * Neither the name of Google Inc. nor the names of its
+//       contributors may be used to endorse or promote products derived
+//       from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+import 'v8_regexp_utils.dart';
+import 'package:expect/expect.dart';
+
+void main() {
+  // Create a huge regexp with many alternative capture groups, most of
+  // which do not capture anything, but the corresponding capture slot
+  // in the result object has to exist, even though filled with null.
+  // Having a large result array helps stressing GC.
+
+  var num_captures = 1000;
+  var regexp_string = "(a)";
+  for (var i = 0; i < num_captures - 1; i++) {
+    regexp_string += "|(b)";
+  }
+  var regexp = new RegExp(regexp_string);
+
+  for (var i = 0; i < 10; i++) {
+    var matches = regexp.firstMatch("a");
+    var count = 0;
+    assertEquals(num_captures + 1, matches.groupCount + 1);
+  }
+}
diff --git a/tests/corelib/regexp/repeat-match-waldemar_test.dart b/tests/corelib/regexp/repeat-match-waldemar_test.dart
new file mode 100644
index 0000000..3adc775
--- /dev/null
+++ b/tests/corelib/regexp/repeat-match-waldemar_test.dart
@@ -0,0 +1,59 @@
+// Copyright (c) 2014, the Dart project authors. All rights reserved.
+// Copyright 2013 the V8 project authors. All rights reserved.
+// Copyright (C) 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1.  Redistributions of source code must retain the above copyright
+//     notice, this list of conditions and the following disclaimer.
+// 2.  Redistributions in binary form must reproduce the above copyright
+//     notice, this list of conditions and the following disclaimer in the
+//     documentation and/or other materials provided with the distribution.
+//
+// THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
+// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+import 'v8_regexp_utils.dart';
+import 'package:expect/expect.dart';
+
+void main() {
+  // "Some test cases identified by Waldemar Horwat in response to this bug:
+  // https:new RegExp(r"/bugs.webkit.org")show_bug.cgi?id=48101"
+
+  shouldBe(new RegExp(r"(?:a*?){2,}").firstMatch("aa"), ["aa"]);
+  shouldBe(new RegExp(r"(?:a*?){2,}").firstMatch("a"), ["a"]);
+  shouldBe(new RegExp(r"(?:a*?){2,}").firstMatch(""), [""]);
+
+  shouldBe(new RegExp(r"(?:a*?)").firstMatch("aa"), [""]);
+  shouldBe(new RegExp(r"(?:a*?)").firstMatch("a"), [""]);
+  shouldBe(new RegExp(r"(?:a*?)").firstMatch(""), [""]);
+
+  shouldBe(new RegExp(r"(?:a*?)(?:a*?)(?:a*?)").firstMatch("aa"), [""]);
+  shouldBe(new RegExp(r"(?:a*?)(?:a*?)(?:a*?)").firstMatch("a"), [""]);
+  shouldBe(new RegExp(r"(?:a*?)(?:a*?)(?:a*?)").firstMatch(""), [""]);
+
+  shouldBe(new RegExp(r"(?:a*?){2}").firstMatch("aa"), [""]);
+  shouldBe(new RegExp(r"(?:a*?){2}").firstMatch("a"), [""]);
+  shouldBe(new RegExp(r"(?:a*?){2}").firstMatch(""), [""]);
+
+  shouldBe(new RegExp(r"(?:a*?){2,3}").firstMatch("aa"), ["a"]);
+  shouldBe(new RegExp(r"(?:a*?){2,3}").firstMatch("a"), ["a"]);
+  shouldBe(new RegExp(r"(?:a*?){2,3}").firstMatch(""), [""]);
+
+  shouldBe(new RegExp(r"(?:a*?)?").firstMatch("aa"), ["a"]);
+  shouldBe(new RegExp(r"(?:a*?)?").firstMatch("a"), ["a"]);
+  shouldBe(new RegExp(r"(?:a*?)?").firstMatch(""), [""]);
+
+  shouldBe(new RegExp(r"(?:a*?)*").firstMatch("aa"), ["aa"]);
+  shouldBe(new RegExp(r"(?:a*?)*").firstMatch("a"), ["a"]);
+  shouldBe(new RegExp(r"(?:a*?)*").firstMatch(""), [""]);
+}
diff --git a/tests/corelib/regexp/results-cache_test.dart b/tests/corelib/regexp/results-cache_test.dart
new file mode 100644
index 0000000..45226e1
--- /dev/null
+++ b/tests/corelib/regexp/results-cache_test.dart
@@ -0,0 +1,83 @@
+// Copyright (c) 2014, the Dart project authors. All rights reserved.
+// Copyright 2012 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+//       copyright notice, this list of conditions and the following
+//       disclaimer in the documentation and/or other materials provided
+//       with the distribution.
+//     * Neither the name of Google Inc. nor the names of its
+//       contributors may be used to endorse or promote products derived
+//       from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+import 'v8_regexp_utils.dart';
+import 'package:expect/expect.dart';
+
+void main() {
+  // Long string to trigger caching.
+  var string =
+  """Friends, Romans, countrymen, lend me your ears!  
+  I come to bury Caesar, not to praise him.        
+  The evil that men do lives after them,           
+  The good is oft interred with their bones;       
+  So let it be with Caesar. The noble Brutus       
+  Hath told you Caesar was ambitious;              
+  If it were so, it was a grievous fault,          
+  And grievously hath Caesar answer'd it.          
+  Here, under leave of Brutus and the rest-        
+  For Brutus is an honorable man;                  
+  So are they all, all honorable men-              
+  Come I to speak in Caesar's funeral.             
+  He was my friend, faithful and just to me;       
+  But Brutus says he was ambitious,                
+  And Brutus is an honorable man.                  
+  He hath brought many captives home to Rome,      
+  Whose ransoms did the general coffers fill.      
+  Did this in Caesar seem ambitious?               
+  When that the poor have cried, Caesar hath wept; 
+  Ambition should be made of sterner stuff:        
+  Yet Brutus says he was ambitious,                
+  And Brutus is an honorable man.                  
+  You all did see that on the Lupercal             
+  I thrice presented him a kingly crown,           
+  Which he did thrice refuse. Was this ambition?   
+  Yet Brutus says he was ambitious,                
+  And sure he is an honorable man.                 
+  I speak not to disprove what Brutus spoke,       
+  But here I am to speak what I do know.           
+  You all did love him once, not without cause;    
+  What cause withholds you then to mourn for him?  
+  O judgement, thou art fled to brutish beasts,    
+  And men have lost their reason. Bear with me;    
+  My heart is in the coffin there with Caesar,     
+  And I must pause till it come back to me.""";
+
+  var replaced = string.replaceAll(new RegExp(r"\b\w+\b"), "foo");
+  for (var i = 0; i < 3; i++) {
+    assertEquals(replaced,
+                string.replaceAll(new RegExp(r"\b\w+\b"), "foo"));
+  }
+
+  // Check that the result is in a COW array.
+  var words = string.split(" ");
+  assertEquals("Friends,", words[0]);
+  words[0] = "Enemies,";
+  words = string.split(" ");
+  assertEquals("Friends,", words[0]);
+}
diff --git a/tests/corelib/regexp/stack-overflow2_test.dart b/tests/corelib/regexp/stack-overflow2_test.dart
new file mode 100644
index 0000000..6bc2b78
--- /dev/null
+++ b/tests/corelib/regexp/stack-overflow2_test.dart
@@ -0,0 +1,17 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for 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 'v8_regexp_utils.dart';
+import 'package:expect/expect.dart';
+
+// Failing tests extracted from pcre_test.dart. Large generated functions
+// cause a stack overflow in DiscoverBlocks().
+
+void main() {
+  var res149 = new RegExp(r"(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\w+)\s+(\270)", caseSensitive: false);
+
+  assertToStringEquals("1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 ABC ABC,1 ,2 ,3 ,4 ,5 ,6 ,7 ,8 ,9 ,10 ,11 ,12 ,13 ,14 ,15 ,16 ,17 ,18 ,19 ,20 ,21 ,22 ,23 ,24 ,25 ,26 ,27 ,28 ,29 ,30 ,31 ,32 ,33 ,34 ,35 ,36 ,37 ,38 ,39 ,40 ,41 ,42 ,43 ,44 ,45 ,46 ,47 ,48 ,49 ,50 ,51 ,52 ,53 ,54 ,55 ,56 ,57 ,58 ,59 ,60 ,61 ,62 ,63 ,64 ,65 ,66 ,67 ,68 ,69 ,70 ,71 ,72 ,73 ,74 ,75 ,76 ,77 ,78 ,79 ,80 ,81 ,82 ,83 ,84 ,85 ,86 ,87 ,88 ,89 ,90 ,91 ,92 ,93 ,94 ,95 ,96 ,97 ,98 ,99 ,100 ,101 ,102 ,103 ,104 ,105 ,106 ,107 ,108 ,109 ,110 ,111 ,112 ,113 ,114 ,115 ,116 ,117 ,118 ,119 ,120 ,121 ,122 ,123 ,124 ,125 ,126 ,127 ,128 ,129 ,130 ,131 ,132 ,133 ,134 ,135 ,136 ,137 ,138 ,139 ,140 ,141 ,142 ,143 ,144 ,145 ,146 ,147 ,148 ,149 ,150 ,151 ,152 ,153 ,154 ,155 ,156 ,157 ,158 ,159 ,160 ,161 ,162 ,163 ,164 ,165 ,166 ,167 ,168 ,169 ,170 ,171 ,172 ,173 ,174 ,175 ,176 ,177 ,178 ,179 ,180 ,181 ,182 ,183 ,184 ,185 ,186 ,187 ,188 ,189 ,190 ,191 ,192 ,193 ,194 ,195 ,196 ,197 ,198 ,199 ,200 ,201 ,202 ,203 ,204 ,205 ,206 ,207 ,208 ,209 ,210 ,211 ,212 ,213 ,214 ,215 ,216 ,217 ,218 ,219 ,220 ,221 ,222 ,223 ,224 ,225 ,226 ,227 ,228 ,229 ,230 ,231 ,232 ,233 ,234 ,235 ,236 ,237 ,238 ,239 ,240 ,241 ,242 ,243 ,244 ,245 ,246 ,247 ,248 ,249 ,250 ,251 ,252 ,253 ,254 ,255 ,256 ,257 ,258 ,259 ,260 ,261 ,262 ,263 ,264 ,265 ,266 ,267 ,268 ,269 ,ABC,ABC",
+      res149.firstMatch("O900 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 ABC ABC"), 242);
+}
+
diff --git a/tests/corelib/regexp/stack-overflow_test.dart b/tests/corelib/regexp/stack-overflow_test.dart
new file mode 100644
index 0000000..2669b6f
--- /dev/null
+++ b/tests/corelib/regexp/stack-overflow_test.dart
@@ -0,0 +1,38 @@
+// Copyright (c) 2014, the Dart project authors. All rights reserved.
+// Copyright 2013 the V8 project authors. All rights reserved.
+// Copyright (C) 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1.  Redistributions of source code must retain the above copyright
+//     notice, this list of conditions and the following disclaimer.
+// 2.  Redistributions in binary form must reproduce the above copyright
+//     notice, this list of conditions and the following disclaimer in the
+//     documentation and/or other materials provided with the distribution.
+//
+// THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
+// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+import 'v8_regexp_utils.dart';
+import 'package:expect/expect.dart';
+
+void main() {
+  description(
+  'Test for <a href="https://bugs.webkit.org/show_bug.cgi?id=8870">bug 8870</a>: Crash typing in Yahoo auto-complete widget.'
+  );
+
+  var re = new RegExp(r'^(\s+|[,:{}\[\]]|"(\\["\\\/bfnrtu]|[^\u0000-\u001f"\\]+)*"|-?\d+(\.\d*)?([eE][+-]?\d+)?|true|false|null)+$');
+
+  var result= re.firstMatch('{"ResultSet":{"totalResultsAvailable":"101000000","totalResultsReturned":100,"firstResultPosition":1,"Result":[{"Title":"Solar Eclipses of Saros 132","Summary":"Solar Eclipses of Saros 132 Solar Eclipses of Saros 132 The periodicity and recurrence of solar (and lunar) eclipses is governed by the Saros cycle, a period of approximately 6,585. 3 days (18 years 11 days 8 hours). When two eclipses are ...","Url":"http:\\/\\/sunearth.gsfc.nasa.gov\\/eclipse\\/SEsaros\\/SEsaros132.html","ClickUrl":"http:\\/\\/uk.wrs.yahoo.com\\/_ylt=A0Je5VwQjWVEsGcBUBzdmMwF;_ylu=X3oDMTB2cXVjNTM5BGNvbG8DdwRsA1dTMQRwb3MDMQRzZWMDc3IEdnRpZAM-\\/SIG=19ip3vo9u\\/EXP=1147592336\\/**http%3a\\/\\/rdrw1.yahoo.com\\/click%3fu=http%3a\\/\\/sunearth.gsfc.nasa.gov\\/eclipse\\/SEsaros\\/SEsaros132.html%26y=0405DC60F30D6DD673%26i=482%26c=15685%26q=02%255ESSHPM%255BL7.,-6%26e=utf-8%26r=0%26d=wow%7eWBSV-en-us%26n=3O6KG7JU5PIK8T7I%26s=6%26t=%26m=44658D10%26x=05A6B5FDC2F29725CD6EE467684E0FE76D","ModificationDate":1146207600,"MimeType":"text\\/html"},{"Title":"Psalms 132 -Matthew Henry\'s Commentary - Bible Software by johnhurt.com","Summary":"Psalms 132 - Matthew Henry Commentary - Bible Software by johnhurt.com ... Henry\'s Psalms 131. Psalms 132. Outline of Psalms 132. David\'s care for the ark ...","Url":"http:\\/\\/www.htmlbible.com\\/kjv30\\/henry\\/H19C132.htm","ClickUrl":"http:\\/\\/uk.wrs.yahoo.com\\/_ylt=A0Je5VwQjWVEsGcBVhzdmMwF;_ylu=X3oDMTB2ZjQ4dDExBGNvbG8DdwRsA1dTMQRwb3MDMgRzZWMDc3IEdnRpZAM-\\/SIG=1246fjpfq\\/EXP=1147592336\\/**http%3a\\/\\/www.htmlbible.com\\/kjv30\\/henry\\/H19C132.htm","ModificationDate":1015660800,"MimeType":"text\\/html","Cache":{"Url":"http:\\/\\/uk.wrs.yahoo.com\\/_ylt=A0Je5VwQjWVEsGcBWxzdmMwF;_ylu=X3oDMTBwZG5hOWwzBGNvbG8DdwRwb3MDMgRzZWMDc3IEdnRpZAM-\\/SIG=16llm3b1a\\/EXP=1147592336\\/**http%3a\\/\\/66.218.69.11\\/search\\/cache%3fei=UTF-8%26query=132%26output=json%26results=100%26appid=jennyhan_ac%26u=www.htmlbible.com\\/kjv30\\/henry\\/H19C132.htm%26w=132%26d=XlIIG0aqMlsm%26icp=1%26.intl=us","Size":"4160"}},{"Title":"General requirements. - 1910.132","Summary":"General%20requirements.%20-%201910.132 ... Regulations (Standards - 29 CFR) General requirements. - 1910.132 ... of any part of the body through absorption, inhalation or physical contact. 1910.132(b) Employee-owned equipment ...","Url":"http:\\/\\/www.osha.gov\\/pls\\/oshaweb\\/owadisp.show_document?p_table=STANDARDS&p_id=9777","ClickUrl":"http:\\/\\/uk.wrs.yahoo.com\\/_ylt=A0Je5VwQjWVEsGcBXRzdmMwF;_ylu=X3oDMTB2M3MzdmZoBGNvbG8DdwRsA1dTMQRwb3MDMwRzZWMDc3IEdnRpZAM-\\/SIG=13916ebti\\/EXP=1147592336\\/**http%3a\\/\\/www.osha.gov\\/pls\\/oshaweb\\/owadisp.show_document%3fp_table=STANDARDS%26p_id=9777","ModificationDate":1147330800,"MimeType":"text\\/html","Cache":{"Url":"http:\\/\\/uk.wrs.yahoo.com\\/_ylt=A0Je5VwQjWVEsGcBYhzdmMwF;_ylu=X3oDMTBwZ2dpZ2ZkBGNvbG8DdwRwb3MDMwRzZWMDc3IEdnRpZAM-\\/SIG=186osem1n\\/EXP=1147592336\\/**http%3a\\/\\/66.218.69.11\\/search\\/cache%3fei=UTF-8%26query=132%26output=json%26results=100%26appid=jennyhan_ac%26u=www.osha.gov\\/pls\\/oshaweb\\/owadisp.show_document%253Fp_table%253DSTANDARDS%2526p_id%253D9777%26w=132%26d=Ujn5sEaqMw88%26icp=1%26.intl=us","Size":"29922"}},{"Title":"USCCB - NAB - Psalm 132","Summary":"Chapter 132. 1. 1 A song of ascents. 2 LORD, remember David and all his anxious care; 2. 3 How he swore an oath to the LORD, vowed to the Mighty One of Jacob: 3. \\"I will not enter the house where I live, nor lie on the couch where I sleep; ... 1 [Psalm 132] A song for a liturgical ceremony in which the ark, the throne of Israel\'s God, was carried in ...","Url":"http:\\/\\/www.usccb.org\\/nab\\/bible\\/psalms\\/psalm132.htm","ClickUrl":"http:\\/\\/uk.wrs.yahoo.com\\/_ylt=A0Je5VwQjWVEsGcBZBzdmMwF;_ylu=X3oDMTB2OWM1MXQ5BGNvbG8DdwRsA1dTMQRwb3MDNARzZWMDc3IEdnRpZAM-\\/SIG=126n03p75\\/EXP=1147592336\\/**http%3a\\/\\/www.usccb.org\\/nab\\/bible\\/psalms\\/psalm132.htm","ModificationDate":1054623600,"MimeType":"text\\/html","Cache":{"Url":"http:\\/\\/uk.wrs.yahoo.com\\/_ylt=A0Je5VwQjWVEsGcBaRzdmMwF;_ylu=X3oDMTBwYzFnNmkxBGNvbG8DdwRwb3MDNARzZWMDc3IEdnRpZAM-\\/SIG=16nvcm74b\\/EXP=1147592336\\/**http%3a\\/\\/66.218.69.11\\/search\\/cache%3fei=UTF-8%26query=132%26output=json%26results=100%26appid=jennyhan_ac%26u=www.usccb.org\\/nab\\/bible\\/psalms\\/psalm132.htm%26w=132%26d=FMBGyUaqMh-a%26icp=1%26.intl=us","Size":"8840"}},{"Title":"* City of Lost Dreams Mod *","Summary":"Mafia game modification","Url":"http:\\/\\/www.citizen-132.com\\/","ClickUrl":"http:\\/\\/uk.wrs.yahoo.com\\/_ylt=A0Je5VwQjWVEsGcBaxzdmMwF;_ylu=X3oDMTB2NW50aG1hBGNvbG8DdwRsA1dTMQRwb3MDNQRzZWMDc3IEdnRpZAM-\\/SIG=11fnqlf31\\/EXP=1147592336\\/**http%3a\\/\\/www.citizen-132.com\\/","ModificationDate":1107676800,"MimeType":"text\\/html","Cache":{"Url":"http:\\/\\/uk.wrs.yahoo.com\\/_ylt=A0Je5VwQjWVEsGcBcBzdmMwF;_ylu=X3oDMTBwdDJ0dDBoBGNvbG8DdwRwb3MDNQRzZWMDc3IEdnRpZAM-\\/SIG=160jdk4g3\\/EXP=1147592336\\/**http%3a\\/\\/66.218.69.11\\/search\\/cache%3fei=UTF-8%26query=132%26output=json%26results=100%26appid=jennyhan_ac%26u=www.citizen-132.com\\/%26w=132%26d=ZiSHAkaqMuny%26icp=1%26.intl=us","Size":"6861"}},{"Title":"BibleGateway.com: Search for a Bible passage in over 35 languages and 50 versions.","Summary":"English (EN) Espa\\u00f1ol (ES) Passage results ... Footnotes: Psalm 132:6 That is, Kiriath Jearim. Psalm 132:6 Or heard of it in ...","Url":"http:\\/\\/www.biblegateway.com\\/passage\\/?book_id=23&chapter=132&version=31","ClickUrl":"http:\\/\\/uk.wrs.yahoo.com\\/_ylt=A0Je5VwQjWVEsGcBchzdmMwF;_ylu=X3oDMTB2azJrdmpwBGNvbG8DdwRsA1dTMQRwb3MDNgRzZWMDc3IEdnRpZAM-\\/SIG=1300p6cfh\\/EXP=1147592336\\/**http%3a\\/\\/www.biblegateway.com\\/passage\\/%3fbook_id=23%26chapter=132%26version=31","ModificationDate":1147158000,"MimeType":"text\\/html","Cache":{"Url":"http:\\/\\/uk.wrs.yahoo.com\\/_ylt=A0Je5VwQjWVEsGcBdxzdmMwF;_ylu=X3oDMTBwYmwxdWo4BGNvbG8DdwRwb3MDNgRzZWMDc3IEdnRpZAM-\\/SIG=183q9adk2\\/EXP=1147592336\\/**http%3a\\/\\/66.218.69.11\\/search\\/cache%3fei=UTF-8%26query=132%26output=json%26results=100%26appid=jennyhan_ac%26u=www.biblegateway.com\\/passage\\/%253Fbook_id%253D23%2526chapter%253D132%2526version%253D31%26w=132%26d=XUM-1kaqMwKY%26icp=1%26.intl=us","Size":"27373"}},{"Title":"132 - Wikipedia, the free encyclopedia","Summary":"From Wikipedia, the free encyclopedia. This article is about the year. For other uses, see 132 (number). Events. Roman Empire. The Olympeion in Athens is completed ... Your continued donations keep Wikipedia running! 132. From Wikipedia, the free encyclopedia ... For other uses, see 132 (number). Years: 128 129 130 131 - 132 - 133 134 135 136 ...","Url":"http:\\/\\/en.wikipedia.org\\/wiki\\/132","ClickUrl":"http:\\/\\/uk.wrs.yahoo.com\\/_ylt=A0Je5VwQjWVEsGcBeRzdmMwF;_ylu=X3oDMTB2bDEyNXM5BGNvbG8DdwRsA1dTMQRwb3MDNwRzZWMDc3IEdnRpZAM-\\/SIG=11k81281i\\/EXP=1147592336\\/**http%3a\\/\\/en.wikipedia.org\\/wiki\\/132","ModificationDate":1145862000,"MimeType":"text\\/html","Cache":{"Url":"http:\\/\\/uk.wrs.yahoo.com\\/_ylt=A0Je5VwQjWVEsGcBfhzdmMwF;_ylu=X3oDMTBwMTB0ZWFoBGNvbG8DdwRwb3MDNwRzZWMDc3IEdnRpZAM-\\/SIG=165kmnv8l\\/EXP=1147592336\\/**http%3a\\/\\/66.218.69.11\\/search\\/cache%3fei=UTF-8%26query=132%26output=json%26results=100%26appid=jennyhan_ac%26u=en.wikipedia.org\\/wiki\\/132%26w=132%26d=OcxF4UaqMuf2%26icp=1%26.intl=us","Size":"15956"}},{"Title":"BBC SPORT | Football | Internationals","Summary":"Visit BBC Sport for all the action as it happens - up-to-the-minute news, results, breaking news, video, audio and feature stories. BBC Sport covers the major events and all the professional football clubs in the UK, plus cricket, rugby, golf, ...","Url":"http:\\/\\/news.bbc.co.uk\\/sport1\\/hi\\/football\\/internationals\\/default.stm","ClickUrl":"http:\\/\\/uk.wrs.yahoo.com\\/_ylt=A0Je5VwQjWVEsGcBgBzdmMwF;_ylu=X3oDMTB2bTU4Zm85BGNvbG8DdwRsA1dTMQRwb3MDOARzZWMDc3IEdnRpZAM-\\/SIG=12n3aafin\\/EXP=1147592336\\/**http%3a\\/\\/news.bbc.co.uk\\/sport1\\/hi\\/football\\/internationals\\/default.stm","ModificationDate":1147417200,"MimeType":"text\\/html","Cache":{"Url":"http:\\/\\/uk.wrs.yahoo.com\\/_ylt=A0Je5VwQjWVEsGcBhRzdmMwF;_ylu=X3oDMTBwYTZ1aGtmBGNvbG8DdwRwb3MDOARzZWMDc3IEdnRpZAM-\\/SIG=178rplb9d\\/EXP=1147592336\\/**http%3a\\/\\/66.218.69.11\\/search\\/cache%3fei=UTF-8%26query=132%26output=json%26results=100%26appid=jennyhan_ac%26u=news.bbc.co.uk\\/sport1\\/hi\\/football\\/internationals\\/default.stm%26w=132%26d=PmSx-kaqMw8o%26icp=1%26.intl=us","Size":"52634"}},{"Title":"Metro Route 132 Timetable, Weekday","Summary":"... Custom Print Help. 132. Weekday: Feb. 11 thru June 2, 2006 ...","Url":"http:\\/\\/transit.metrokc.gov\\/tops\\/bus\\/schedules\\/s132_0_.html","ClickUrl":"http:\\/\\/uk.wrs.yahoo.com\\/_ylt=A0Je5VwQjWVEsGcBhxzdmMwF;_ylu=X3oDMTB2dW8yNmN0BGNvbG8DdwRsA1dTMQRwb3MDOQRzZWMDc3IEdnRpZAM-\\/SIG=12eusl28m\\/EXP=1147592336\\/**http%3a\\/\\/transit.metrokc.gov\\/tops\\/bus\\/schedules\\/s132_0_.html","ModificationDate":1146553200,"MimeType":"text\\/html","Cache":{"Url":"http:\\/\\/uk.wrs.yahoo.com\\/_ylt=A0Je5VwQjWVEsGcBjBzdmMwF;_ylu=X3oDMTBwOTRzYmZlBGNvbG8DdwRwb3MDOQRzZWMDc3IEdnRpZAM-\\/SIG=16vd4gkvv\\/EXP=1147592336\\/**http%3a\\/\\/66.218.69.11\\/search\\/cache%3fei=UTF-8%26query=132%26output=json%26results=100%26appid=jennyhan_ac%26u=transit.metrokc.gov\\/tops\\/bus\\/schedules\\/s132_0_.html%26w=132%26d=Nvq_ekaqMulb%26icp=1%26.intl=us","Size":"27482"}},{"Title":"BBC NEWS | Politics | Bush arrives for state visit","Summary":"George Bush arrives in the UK for the first state visit by a US president amid some of the tightest security London has seen.","Url":"http:\\/\\/news.bbc.co.uk\\/1\\/hi\\/uk_politics\\/3279179.stm","ClickUrl":"http:\\/\\/uk.wrs.yahoo.com\\/_ylt=A0Je5VwQjWVEsGcBjhzdmMwF;_ylu=X3oDMTEwc3RuNTk4BGNvbG8DdwRsA1dTMQRwb3MDMTAEc2VjA3NyBHZ0aWQD\\/SIG=126am8694\\/EXP=1147592336\\/**http%3a\\/\\/news.bbc.co.uk\\/1\\/hi\\/uk_politics\\/3279179.stm","ModificationDate":1147417200,"MimeType":"text\\/html","Cache":{"Url":"http:\\/\\/uk.wrs.yahoo.com\\/_ylt=A0Je5VwQjWVEsGcBkxzdmMwF;_ylu=X3oDMTBxNTUzbTg4BGNvbG8DdwRwb3MDMTAEc2VjA3NyBHZ0aWQD\\/SIG=16nt5u57o\\/EXP=1147592336\\/**http%3a\\/\\/66.218.69.11\\/search\\/cache%3fei=UTF-8%26query=132%26output=json%26results=100%26appid=jennyhan_ac%26u=news.bbc.co.uk\\/1\\/hi\\/uk_politics\\/3279179.stm%26w=132%26d=CxDE2UaqMw8U%26icp=1%26.intl=us","Size":"43537"}},{"Title":"132 (number) - Wikipedia, the free encyclopedia","Summary":"... you can make from 132, you get 132: 12 + 13 + 21 + 23 + 31 + 32 = 132. 132 is the smallest number ...","Url":"http:\\/\\/en.wikipedia.org\\/wiki\\/132_(number)","ClickUrl":"http:\\/\\/uk.wrs.yahoo.com\\/_ylt=A0Je5VwQjWVEsGcBlRzdmMwF;_ylu=X3oDMTEwNXN0b3YwBGNvbG8DdwRsA1dTMQRwb3MDMTEEc2VjA3NyBHZ0aWQD\\/SIG=11thbnu67\\/EXP=1147592336\\/**http%3a\\/\\/en.wikipedia.org\\/wiki\\/132_(number)","ModificationDate":1145430000,"MimeType":"text\\/html","Cache":{"Url":"http:\\/\\/uk.wrs.yahoo.com\\/_ylt=A0Je5VwQjWVEsGcBmhzdmMwF;_ylu=X3oDMTBxYnA3amlzBGNvbG8DdwRwb3MDMTEEc2VjA3NyBHZ0aWQD\\/SIG=16m4qjjlq\\/EXP=1147592336\\/**http%3a\\/\\/66.218.69.11\\/search\\/cache%3fei=UTF-8%26query=132%26output=json%26results=100%26appid=jennyhan_ac%26u=en.wikipedia.org\\/wiki\\/132_%2528number%2529%26w=132%26d=Ygdh6EaqMsBb%26icp=1%26.intl=us","Size":"13154"}},{"Title":"Psalms, Chapter 132","Summary":"King James Reference Suite - Bible Software by johnhurt.com ... Chapter 132. 1. Lord, remember David, and all his afflictions ... Notes on Chapter 132. 1. 2. 3 ...","Url":"http:\\/\\/www.htmlbible.com\\/kjv30\\/B19C132.htm","ClickUrl":"http:\\/\\/uk.wrs.yahoo.com\\/_ylt=A0Je5VwQjWVEsGcBnBzdmMwF;_ylu=X3oDMTEwNmgxNTZoBGNvbG8DdwRsA1dTMQRwb3MDMTIEc2VjA3NyBHZ0aWQD\\/SIG=11uujk8hq\\/EXP=1147592336\\/**http%3a\\/\\/www.htmlbible.com\\/kjv30\\/B19C132.htm","ModificationDate":1079942400,"MimeType":"text\\/html","Cache":{"Url":"http:\\/\\/uk.wrs.yahoo.com\\/_ylt=A0Je5VwQjWVEsGcBoRzdmMwF;_ylu=X3oDMTBxN2cybDkwBGNvbG8DdwRwb3MDMTIEc2VjA3NyBHZ0aWQD\\/SIG=16fpgk3vj\\/EXP=1147592336\\/**http%3a\\/\\/66.218.69.11\\/search\\/cache%3fei=UTF-8%26query=132%26output=json%26results=100%26appid=jennyhan_ac%26u=www.htmlbible.com\\/kjv30\\/B19C132.htm%26w=132%26d=TaFtBUaqMwcr%26icp=1%26.intl=us","Size":"8721"}},{"Title":"SPACE.com -- Privately Funded SpaceShipOne Breaks Sound Barrier","Summary":"A privately financed passenger-carrying sub-orbital rocket plane screamed its way through the sound barrier today, the 100th anniversary of the Wright Brothers historic 12-second flight over Kitty Hawk, North Carolina.","Url":"http:\\/\\/www.space.com\\/businesstechnology\\/technology\\/rutan_update_031217.html","ClickUrl":"http:\\/\\/uk.wrs.yahoo.com\\/_ylt=A0Je5VwQjWVEsGcBoxzdmMwF;_ylu=X3oDMTEwNHRmcnV0BGNvbG8DdwRsA1dTMQRwb3MDMTMEc2VjA3NyBHZ0aWQD\\/SIG=12vltjpcd\\/EXP=1147592336\\/**http%3a\\/\\/www.space.com\\/businesstechnology\\/technology\\/rutan_update_031217.html","ModificationDate":1147330800,"MimeType":"text\\/html","Cache":{"Url":"http:\\/\\/uk.wrs.yahoo.com\\/_ylt=A0Je5VwQjWVEsGcBqBzdmMwF;_ylu=X3oDMTBxajcxM3AwBGNvbG8DdwRwb3MDMTMEc2VjA3NyBHZ0aWQD\\/SIG=17g6i6br5\\/EXP=1147592336\\/**http%3a\\/\\/66.218.69.11\\/search\\/cache%3fei=UTF-8%26query=132%26output=json%26results=100%26appid=jennyhan_ac%26u=www.space.com\\/businesstechnology\\/technology\\/rutan_update_031217.html%26w=132%26d=CklT2kaqMwqb%26icp=1%26.intl=us","Size":"39319"}},{"Title":"D&C 132","Summary":"THE DOCTRINE AND COVENANTS. SECTION 132 ... LDS HomeScriptures Doctrine and Covenants Sections Section 132. Prev | Next ... SECTION 132. Revelation given through Joseph Smith the Prophet, at Nauvoo, Illinois, recorded July 12, 1843 ...","Url":"http:\\/\\/scriptures.lds.org\\/dc\\/132","ClickUrl":"http:\\/\\/uk.wrs.yahoo.com\\/_ylt=A0Je5VwQjWVEsGcBqhzdmMwF;_ylu=X3oDMTEwamo4ZjVjBGNvbG8DdwRsA1dTMQRwb3MDMTQEc2VjA3NyBHZ0aWQD\\/SIG=11k67f7oi\\/EXP=1147592336\\/**http%3a\\/\\/scriptures.lds.org\\/dc\\/132","ModificationDate":1146985200,"MimeType":"text\\/html","Cache":{"Url":"http:\\/\\/uk.wrs.yahoo.com\\/_ylt=A0Je5VwQjWVEsGcBrxzdmMwF;_ylu=X3oDMTBxcDhuOXFrBGNvbG8DdwRwb3MDMTQEc2VjA3NyBHZ0aWQD\\/SIG=165qbp40u\\/EXP=1147592336\\/**http%3a\\/\\/66.218.69.11\\/search\\/cache%3fei=UTF-8%26query=132%26output=json%26results=100%26appid=jennyhan_ac%26u=scriptures.lds.org\\/dc\\/132%26w=132%26d=KIW1S0aqMwF3%26icp=1%26.intl=us","Size":"51549"}},{"Title":"State Representative District 132","Summary":"State Representative District 132. State Representative District 132 is shaded area. SACO. BIDDEFORD. 127. 132. 133. 136. OLD ORCHARD BEACH. SACO","Url":"http:\\/\\/mainegov-images.informe.org\\/sos\\/cec\\/elec\\/apport\\/House\\/h132.pdf","ClickUrl":"http:\\/\\/mainegov-images.informe.org\\/sos\\/cec\\/elec\\/apport\\/House\\/h132.pdf#search=\'\'","ModificationDate":1075968000,"MimeType":"application\\/pdf","Cache":{"Url":"http:\\/\\/uk.wrs.yahoo.com\\/_ylt=A0Je5VwQjWVEsGcBtBzdmMwF;_ylu=X3oDMTBxbnZxbGc1BGNvbG8DdwRwb3MDMTUEc2VjA3NyBHZ0aWQD\\/SIG=17at7erej\\/EXP=1147592336\\/**http%3a\\/\\/66.218.69.11\\/search\\/cache%3fei=UTF-8%26query=132%26output=json%26results=100%26appid=jennyhan_ac%26u=mainegov-images.informe.org\\/sos\\/cec\\/elec\\/apport\\/House\\/h132.pdf%26w=132%26d=DsRim0aqMiIQ%26icp=1%26.intl=us","Size":"129767"}},{"Title":"BLB Psa 132","Summary":"We apologize, but the page layout is not visible because you are using an older browser. We recommend upgrading to a standards-compliant browser. Without such, this page will remain viewable, though unformatted.","Url":"http:\\/\\/www.blueletterbible.org\\/kjv\\/Psa\\/Psa132.html","ClickUrl":"http:\\/\\/uk.wrs.yahoo.com\\/_ylt=A0Je5VwQjWVEsGcBthzdmMwF;_ylu=X3oDMTEwdXRzN2p1BGNvbG8DdwRsA1dTMQRwb3MDMTYEc2VjA3NyBHZ0aWQD\\/SIG=126nkscdr\\/EXP=1147592336\\/**http%3a\\/\\/www.blueletterbible.org\\/kjv\\/Psa\\/Psa132.html","ModificationDate":1146985200,"MimeType":"text\\/html","Cache":{"Url":"http:\\/\\/uk.wrs.yahoo.com\\/_ylt=A0Je5VwQjWVEsGcBuxzdmMwF;_ylu=X3oDMTBxdWpsMnAxBGNvbG8DdwRwb3MDMTYEc2VjA3NyBHZ0aWQD\\/SIG=16nmo95in\\/EXP=1147592336\\/**http%3a\\/\\/66.218.69.11\\/search\\/cache%3fei=UTF-8%26query=132%26output=json%26results=100%26appid=jennyhan_ac%26u=www.blueletterbible.org\\/kjv\\/Psa\\/Psa132.html%26w=132%26d=RzXlkkaqMwDE%26icp=1%26.intl=us","Size":"40835"}},{"Title":"ADL Found Guilty Of Spying By California Court","Summary":"ADL Found Guilty Of Spying. By California Court. By Barbara Ferguson. Arab News Correspondent. 4-27-2","Url":"http:\\/\\/www.rense.com\\/general24\\/adl.htm","ClickUrl":"http:\\/\\/uk.wrs.yahoo.com\\/_ylt=A0Je5VwQjWVEsGcBvRzdmMwF;_ylu=X3oDMTEwcm5pb3BuBGNvbG8DdwRsA1dTMQRwb3MDMTcEc2VjA3NyBHZ0aWQD\\/SIG=11qjguns4\\/EXP=1147592336\\/**http%3a\\/\\/www.rense.com\\/general24\\/adl.htm","ModificationDate":1019890800,"MimeType":"text\\/html","Cache":{"Url":"http:\\/\\/uk.wrs.yahoo.com\\/_ylt=A0Je5VwQjWVEsGcBwhzdmMwF;_ylu=X3oDMTBxN2RrOGV1BGNvbG8DdwRwb3MDMTcEc2VjA3NyBHZ0aWQD\\/SIG=16bnmcrht\\/EXP=1147592336\\/**http%3a\\/\\/66.218.69.11\\/search\\/cache%3fei=UTF-8%26query=132%26output=json%26results=100%26appid=jennyhan_ac%26u=www.rense.com\\/general24\\/adl.htm%26w=132%26d=Xkre4EaqMuwO%26icp=1%26.intl=us","Size":"5916"}},{"Title":"FindLaw for Legal Professionals - Case Law, Federal and State Resources, Forms, and Code","Summary":"FindLaw for Legal Professionals is a free resource for attorneys that includes online case law, free state codes, free federal codes, free legal forms, and a directory of products and services for lawyers. This online legal Web site also includes...","Url":"http:\\/\\/caselaw.lp.findlaw.com\\/cgi-bin\\/getcase.pl?court=US&vol=391&invol=936","ClickUrl":"http:\\/\\/uk.wrs.yahoo.com\\/_ylt=A0Je5VwQjWVEsGcBxBzdmMwF;_ylu=X3oDMTEwa2drb20xBGNvbG8DdwRsA1dTMQRwb3MDMTgEc2VjA3NyBHZ0aWQD\\/SIG=135rsl3q8\\/EXP=1147592336\\/**http%3a\\/\\/caselaw.lp.findlaw.com\\/cgi-bin\\/getcase.pl%3fcourt=US%26vol=391%26invol=936","ModificationDate":1147330800,"MimeType":"text\\/html","Cache":{"Url":"http:\\/\\/uk.wrs.yahoo.com\\/_ylt=A0Je5VwQjWVEsGcByRzdmMwF;_ylu=X3oDMTBxZGJndmNzBGNvbG8DdwRwb3MDMTgEc2VjA3NyBHZ0aWQD\\/SIG=188s7bq1v\\/EXP=1147592336\\/**http%3a\\/\\/66.218.69.11\\/search\\/cache%3fei=UTF-8%26query=132%26output=json%26results=100%26appid=jennyhan_ac%26u=caselaw.lp.findlaw.com\\/cgi-bin\\/getcase.pl%253Fcourt%253DUS%2526vol%253D391%2526invol%253D936%26w=132%26d=GCWYIUaqMwZK%26icp=1%26.intl=us","Size":"57332"}},{"Title":"Chapter 132","Summary":"... Public Records. \\u00a7 132\\u20101. \\" Public records\\" defined ... Public records, as defined in G.S. 132\\u20101, shall not include written communications (and copies thereof) to any public ...","Url":"http:\\/\\/www.ncleg.net\\/EnactedLegislation\\/Statutes\\/HTML\\/ByChapter\\/Chapter_132.html","ClickUrl":"http:\\/\\/uk.wrs.yahoo.com\\/_ylt=A0Je5VwQjWVEsGcByxzdmMwF;_ylu=X3oDMTEwdjV0NWw0BGNvbG8DdwRsA1dTMQRwb3MDMTkEc2VjA3NyBHZ0aWQD\\/SIG=1349nldcc\\/EXP=1147592336\\/**http%3a\\/\\/www.ncleg.net\\/EnactedLegislation\\/Statutes\\/HTML\\/ByChapter\\/Chapter_132.html","ModificationDate":1141027200,"MimeType":"text\\/html","Cache":{"Url":"http:\\/\\/uk.wrs.yahoo.com\\/_ylt=A0Je5VwQjWVEsGcB0BzdmMwF;_ylu=X3oDMTBxdDJjbXM4BGNvbG8DdwRwb3MDMTkEc2VjA3NyBHZ0aWQD\\/SIG=17lgm2hmb\\/EXP=1147592336\\/**http%3a\\/\\/66.218.69.11\\/search\\/cache%3fei=UTF-8%26query=132%26output=json%26results=100%26appid=jennyhan_ac%26u=www.ncleg.net\\/EnactedLegislation\\/Statutes\\/HTML\\/ByChapter\\/Chapter_132.html%26w=132%26d=akl3I0aqMt5y%26icp=1%26.intl=us","Size":"76411"}},{"Title":"oremus Bible Browser : Psalm 132","Summary":"Psalm 132. A Song of Ascents. 1O Lord, remember in David\'s favour. all the hardships he endured; 2how he swore to the Lord. and vowed to the Mighty One of Jacob, 3 I will not enter my house. or get into my bed;","Url":"http:\\/\\/bible.oremus.org\\/?passage=Psalm+132","ClickUrl":"http:\\/\\/uk.wrs.yahoo.com\\/_ylt=A0Je5VwQjWVEsGcB0hzdmMwF;_ylu=X3oDMTEwcDU0bmdlBGNvbG8DdwRsA1dTMQRwb3MDMjAEc2VjA3NyBHZ0aWQD\\/SIG=122hghelb\\/EXP=1147592336\\/**http%3a\\/\\/bible.oremus.org\\/%3fpassage=Psalm%2b132","ModificationDate":1138003200,"MimeType":"text\\/html","Cache":{"Url":"http:\\/\\/uk.wrs.yahoo.com\\/_ylt=A0Je5VwQjWVEsGcB1xzdmMwF;_ylu=X3oDMTBxbjVuNnZxBGNvbG8DdwRwb3MDMjAEc2VjA3NyBHZ0aWQD\\/SIG=16ppk73gi\\/EXP=1147592336\\/**http%3a\\/\\/66.218.69.11\\/search\\/cache%3fei=UTF-8%26query=132%26output=json%26results=100%26appid=jennyhan_ac%26u=bible.oremus.org\\/%253Fpassage%253DPsalm%2b132%26w=132%26d=MBPBT0aqMkLR%26icp=1%26.intl=us","Size":"6083"}},{"Title":"Electronic Code of Federal Regulations:","Summary":"... Application of part 132 requirements in Great Lakes States and Tribes ... Appendix A to Part 132 --Great Lakes Water Quality Initiative Methodologies for Development of Aquatic Life ...","Url":"http:\\/\\/ecfr.gpoaccess.gov\\/cgi\\/t\\/text\\/text-idx?c=ecfr&tpl=\\/ecfrbrowse\\/Title40\\/40cfr132_main_02.tpl","ClickUrl":"http:\\/\\/uk.wrs.yahoo.com\\/_ylt=A0Je5VwQjWVEsGcB2RzdmMwF;_ylu=X3oDMTEwMGRnbnZ2BGNvbG8DdwRsA1dTMQRwb3MDMjEEc2VjA3NyBHZ0aWQD\\/SIG=13p811gl2\\/EXP=1147592336\\/**http%3a\\/\\/ecfr.gpoaccess.gov\\/cgi\\/t\\/text\\/text-idx%3fc=ecfr%26tpl=\\/ecfrbrowse\\/Title40\\/40cfr132_main_02.tpl","ModificationDate":1147244400,"MimeType":"text\\/html","Cache":{"Url":"http:\\/\\/uk.wrs.yahoo.com\\/_ylt=A0Je5VwQjWVEsGcB3hzdmMwF;_ylu=X3oDMTBxb2QzaXJsBGNvbG8DdwRwb3MDMjEEc2VjA3NyBHZ0aWQD\\/SIG=18m524f9v\\/EXP=1147592336\\/**http%3a\\/\\/66.218.69.11\\/search\\/cache%3fei=UTF-8%26query=132%26output=json%26results=100%26appid=jennyhan_ac%26u=ecfr.gpoaccess.gov\\/cgi\\/t\\/text\\/text-idx%253Fc%253Decfr%2526tpl%253D\\/ecfrbrowse\\/Title40\\/40cfr132_main_02.tpl%26w=132%26d=OC6Oa0aqMwQa%26icp=1%26.intl=us","Size":"24321"}},{"Title":"BibleGateway.com - Passage Lookup: Psalms 132;","Summary":"English (EN) Espa\\u00f1ol (ES) Passage results ... View commentary related to this passage : Psalm 132. Psalm 132 (Amplified Bible ...","Url":"http:\\/\\/www.biblegateway.com\\/passage?search=Psalms+132;&version=45;","ClickUrl":"http:\\/\\/uk.wrs.yahoo.com\\/_ylt=A0Je5VwQjWVEsGcB4BzdmMwF;_ylu=X3oDMTEwMmJvNjYwBGNvbG8DdwRsA1dTMQRwb3MDMjIEc2VjA3NyBHZ0aWQD\\/SIG=12s5v8a5i\\/EXP=1147592336\\/**http%3a\\/\\/www.biblegateway.com\\/passage%3fsearch=Psalms%2b132;%26version=45;","ModificationDate":1139990400,"MimeType":"text\\/html","Cache":{"Url":"http:\\/\\/uk.wrs.yahoo.com\\/_ylt=A0Je5VwQjWVEsGcB5RzdmMwF;_ylu=X3oDMTBxOTdwc3RpBGNvbG8DdwRwb3MDMjIEc2VjA3NyBHZ0aWQD\\/SIG=1810cufkn\\/EXP=1147592336\\/**http%3a\\/\\/66.218.69.11\\/search\\/cache%3fei=UTF-8%26query=132%26output=json%26results=100%26appid=jennyhan_ac%26u=www.biblegateway.com\\/passage%253Fsearch%253DPsalms%2b132%253B%2526version%253D45%253B%26w=132%26d=KJ4R3EaqMjLm%26icp=1%26.intl=us","Size":"27611"}},{"Title":"N-132: Wu-ftpd Buffer Overflow Vulnerability","Summary":"INFORMATION BULLETIN. N-132: Wu-ftpd Buffer Overflow Vulnerability. [Red Hat Security Advisory RHSA-2003:245-15] July 31, 2003 18:00 GMT. [Revised 13 Aug 2003] [Revised 14 Aug 2003] [Revised 5 Sept 2003] [Revised 8 Oct 2003]","Url":"http:\\/\\/www.ciac.org\\/ciac\\/bulletins\\/n-132.shtml","ClickUrl":"http:\\/\\/uk.wrs.yahoo.com\\/_ylt=A0Je5VwQjWVEsGcB5xzdmMwF;_ylu=X3oDMTEwZXVqN2J0BGNvbG8DdwRsA1dTMQRwb3MDMjMEc2VjA3NyBHZ0aWQD\\/SIG=122msf6uh\\/EXP=1147592336\\/**http%3a\\/\\/www.ciac.org\\/ciac\\/bulletins\\/n-132.shtml","ModificationDate":1146812400,"MimeType":"text\\/html","Cache":{"Url":"http:\\/\\/uk.wrs.yahoo.com\\/_ylt=A0Je5VwQjWVEsGcB7BzdmMwF;_ylu=X3oDMTBxbm8wZ2ZmBGNvbG8DdwRwb3MDMjMEc2VjA3NyBHZ0aWQD\\/SIG=16jq98ra6\\/EXP=1147592336\\/**http%3a\\/\\/66.218.69.11\\/search\\/cache%3fei=UTF-8%26query=132%26output=json%26results=100%26appid=jennyhan_ac%26u=www.ciac.org\\/ciac\\/bulletins\\/n-132.shtml%26w=132%26d=cBzeO0aqMu2t%26icp=1%26.intl=us","Size":"12337"}},{"Title":"Bumpy Objects","Summary":"Bumpy Objects","Url":"http:\\/\\/acm.uva.es\\/p\\/v1\\/132.html","ClickUrl":"http:\\/\\/uk.wrs.yahoo.com\\/_ylt=A0Je5VwQjWVEsGcB7hzdmMwF;_ylu=X3oDMTEwZmNyM2VjBGNvbG8DdwRsA1dTMQRwb3MDMjQEc2VjA3NyBHZ0aWQD\\/SIG=11j1o5t64\\/EXP=1147592336\\/**http%3a\\/\\/acm.uva.es\\/p\\/v1\\/132.html","ModificationDate":1057820400,"MimeType":"text\\/html","Cache":{"Url":"http:\\/\\/uk.wrs.yahoo.com\\/_ylt=A0Je5VwQjWVEsGcB8xzdmMwF;_ylu=X3oDMTBxNWw4M3FvBGNvbG8DdwRwb3MDMjQEc2VjA3NyBHZ0aWQD\\/SIG=164vlv52k\\/EXP=1147592336\\/**http%3a\\/\\/66.218.69.11\\/search\\/cache%3fei=UTF-8%26query=132%26output=json%26results=100%26appid=jennyhan_ac%26u=acm.uva.es\\/p\\/v1\\/132.html%26w=132%26d=ZSctVkaqMvQs%26icp=1%26.intl=us","Size":"2803"}},{"Title":"The Hayes memo is important\\u2014but bogus. By Daniel Benjamin","Summary":"When they published their \\" Case Closed\\" cover story three weeks ago on the relationship between Saddam Hussein\'s Iraq and al-Qaida, the editors of the Weekly Standard aimed to set off a bomb. The article was centered on a sizable leak\\u2014a gusher...","Url":"http:\\/\\/www.slate.com\\/id\\/2092180\\/","ClickUrl":"http:\\/\\/uk.wrs.yahoo.com\\/_ylt=A0Je5VwQjWVEsGcB9RzdmMwF;_ylu=X3oDMTEwamxzbHY1BGNvbG8DdwRsA1dTMQRwb3MDMjUEc2VjA3NyBHZ0aWQD\\/SIG=11kj0d4q1\\/EXP=1147592336\\/**http%3a\\/\\/www.slate.com\\/id\\/2092180\\/","ModificationDate":1147071600,"MimeType":"text\\/html","Cache":{"Url":"http:\\/\\/uk.wrs.yahoo.com\\/_ylt=A0Je5VwQjWVEsGcB.hzdmMwF;_ylu=X3oDMTBxdGc1MmltBGNvbG8DdwRwb3MDMjUEc2VjA3NyBHZ0aWQD\\/SIG=16507c1iu\\/EXP=1147592336\\/**http%3a\\/\\/66.218.69.11\\/search\\/cache%3fei=UTF-8%26query=132%26output=json%26results=100%26appid=jennyhan_ac%26u=slate.msn.com\\/id\\/2092180\\/%26w=132%26d=bWigBUaqMvyd%26icp=1%26.intl=us","Size":"40222"}},{"Title":"FNMOC WXMAP: North America","Summary":"UNCLASSIFIED. FNMOC WXMAP. Model: NOGAPS. Area: North America. DTG: 2006050500. UNCLASSIFIED","Url":"https:\\/\\/www.fnmoc.navy.mil\\/CGI\\/PUBLIC\\/wxmap_single.cgi?area=ngp_namer&prod=850&tau=132","ClickUrl":"http:\\/\\/uk.wrs.yahoo.com\\/_ylt=A0Je5VwQjWVEsGcB_BzdmMwF;_ylu=X3oDMTEwNDNwbjA5BGNvbG8DdwRsA1dTMQRwb3MDMjYEc2VjA3NyBHZ0aWQD\\/SIG=13g43sejj\\/EXP=1147592336\\/**https%3a\\/\\/www.fnmoc.navy.mil\\/CGI\\/PUBLIC\\/wxmap_single.cgi%3farea=ngp_namer%26prod=850%26tau=132","ModificationDate":1146812400,"MimeType":"text\\/html","Cache":{"Url":"http:\\/\\/uk.wrs.yahoo.com\\/_ylt=A0Je5VwQjWVEsGcBAR3dmMwF;_ylu=X3oDMTBxN2ZrcnVrBGNvbG8DdwRwb3MDMjYEc2VjA3NyBHZ0aWQD\\/SIG=18s7gc72v\\/EXP=1147592336\\/**http%3a\\/\\/66.218.69.11\\/search\\/cache%3fei=UTF-8%26query=132%26output=json%26results=100%26appid=jennyhan_ac%26u=https%3a\\/\\/www.fnmoc.navy.mil\\/CGI\\/PUBLIC\\/wxmap_single.cgi%253Farea%253Dngp_namer%2526prod%253D850%2526tau%253D132%26w=132%26d=KiW5fUaqMvIm%26icp=1%26.intl=us","Size":"9048"}},{"Title":"O-132: BEA WebLogic Server and Express Certificate Spoofing Vulnerability","Summary":"INFORMATION BULLETIN. O-132: BEA WebLogic Server and Express Certificate Spoofing Vulnerability. [BEA Security Advisory: BEA04-54.00] April 30, 2004 20:00 GMT. PROBLEM:","Url":"http:\\/\\/ciac.llnl.gov\\/ciac\\/bulletins\\/o-132.shtml","ClickUrl":"http:\\/\\/uk.wrs.yahoo.com\\/_ylt=A0Je5VwQjWVEsGcBAx3dmMwF;_ylu=X3oDMTEwb2lhN21nBGNvbG8DdwRsA1dTMQRwb3MDMjcEc2VjA3NyBHZ0aWQD\\/SIG=1231gt787\\/EXP=1147592336\\/**http%3a\\/\\/ciac.llnl.gov\\/ciac\\/bulletins\\/o-132.shtml","ModificationDate":1142064000,"MimeType":"text\\/html","Cache":{"Url":"http:\\/\\/uk.wrs.yahoo.com\\/_ylt=A0Je5VwQjWVEsGcBCB3dmMwF;_ylu=X3oDMTBxaGVsMDBlBGNvbG8DdwRwb3MDMjcEc2VjA3NyBHZ0aWQD\\/SIG=16k4puak0\\/EXP=1147592336\\/**http%3a\\/\\/66.218.69.11\\/search\\/cache%3fei=UTF-8%26query=132%26output=json%26results=100%26appid=jennyhan_ac%26u=ciac.llnl.gov\\/ciac\\/bulletins\\/o-132.shtml%26w=132%26d=ZZgzx0aqMjzn%26icp=1%26.intl=us","Size":"10701"}},{"Title":"NET Bible\\u00ae - Psalms 132","Summary":"... Psalms 132. Psalm 1321. A song of ascents.2. 132:1 O Lord, for David\'s sake remember ...","Url":"http:\\/\\/www.bible.org\\/netbible\\/psa132.htm","ClickUrl":"http:\\/\\/uk.wrs.yahoo.com\\/_ylt=A0Je5VwQjWVEsGcBCh3dmMwF;_ylu=X3oDMTEwYjBiNjdsBGNvbG8DdwRsA1dTMQRwb3MDMjgEc2VjA3NyBHZ0aWQD\\/SIG=11sp4034c\\/EXP=1147592336\\/**http%3a\\/\\/www.bible.org\\/netbible\\/psa132.htm","ModificationDate":1133769600,"MimeType":"text\\/html","Cache":{"Url":"http:\\/\\/uk.wrs.yahoo.com\\/_ylt=A0Je5VwQjWVEsGcBDx3dmMwF;_ylu=X3oDMTBxOWNtc2JjBGNvbG8DdwRwb3MDMjgEc2VjA3NyBHZ0aWQD\\/SIG=16duuokm4\\/EXP=1147592336\\/**http%3a\\/\\/66.218.69.11\\/search\\/cache%3fei=UTF-8%26query=132%26output=json%26results=100%26appid=jennyhan_ac%26u=www.bible.org\\/netbible\\/psa132.htm%26w=132%26d=aVzzT0aqMwNl%26icp=1%26.intl=us","Size":"6048"}},{"Title":"HoustonChronicle.com - Sports: Fran Blinebury","Summary":"06, 2006. Column archive 2002. [an error occurred while processing this directive]","Url":"http:\\/\\/www.chron.com\\/content\\/chronicle\\/sports\\/blinebury\\/home","ClickUrl":"http:\\/\\/uk.wrs.yahoo.com\\/_ylt=A0Je5VwQjWVEsGcBER3dmMwF;_ylu=X3oDMTEwcmlvNjMyBGNvbG8DdwRsA1dTMQRwb3MDMjkEc2VjA3NyBHZ0aWQD\\/SIG=12gac009r\\/EXP=1147592336\\/**http%3a\\/\\/www.chron.com\\/content\\/chronicle\\/sports\\/blinebury\\/home","ModificationDate":1146898800,"MimeType":"text\\/html","Cache":{"Url":"http:\\/\\/uk.wrs.yahoo.com\\/_ylt=A0Je5VwQjWVEsGcBFh3dmMwF;_ylu=X3oDMTBxNTVsY25mBGNvbG8DdwRwb3MDMjkEc2VjA3NyBHZ0aWQD\\/SIG=171sgehbh\\/EXP=1147592336\\/**http%3a\\/\\/66.218.69.11\\/search\\/cache%3fei=UTF-8%26query=132%26output=json%26results=100%26appid=jennyhan_ac%26u=www.chron.com\\/content\\/chronicle\\/sports\\/blinebury\\/home%26w=132%26d=I3QMYEaqMuxa%26icp=1%26.intl=us","Size":"27335"}},{"Title":"FNMOC WXMAP: North America","Summary":"UNCLASSIFIED. FNMOC WXMAP. Model: NOGAPS. Area: North America. DTG: 2006050512. UNCLASSIFIED","Url":"https:\\/\\/www.fnmoc.navy.mil\\/CGI\\/PUBLIC\\/wxmap_single.cgi?area=ngp_namer&prod=prp&tau=132","ClickUrl":"http:\\/\\/uk.wrs.yahoo.com\\/_ylt=A0Je5VwQjWVEsGcBGB3dmMwF;_ylu=X3oDMTEwN2g4ZWdqBGNvbG8DdwRsA1dTMQRwb3MDMzAEc2VjA3NyBHZ0aWQD\\/SIG=13g08kode\\/EXP=1147592336\\/**https%3a\\/\\/www.fnmoc.navy.mil\\/CGI\\/PUBLIC\\/wxmap_single.cgi%3farea=ngp_namer%26prod=prp%26tau=132","ModificationDate":1146812400,"MimeType":"text\\/html","Cache":{"Url":"http:\\/\\/uk.wrs.yahoo.com\\/_ylt=A0Je5VwQjWVEsGcBHR3dmMwF;_ylu=X3oDMTBxaGdhODhjBGNvbG8DdwRwb3MDMzAEc2VjA3NyBHZ0aWQD\\/SIG=18solhmco\\/EXP=1147592336\\/**http%3a\\/\\/66.218.69.11\\/search\\/cache%3fei=UTF-8%26query=132%26output=json%26results=100%26appid=jennyhan_ac%26u=https%3a\\/\\/www.fnmoc.navy.mil\\/CGI\\/PUBLIC\\/wxmap_single.cgi%253Farea%253Dngp_namer%2526prod%253Dprp%2526tau%253D132%26w=132%26d=MKdCgkaqMuri%26icp=1%26.intl=us","Size":"9048"}},{"Title":"US CODE: Title 36,132. National School Lunch Week","Summary":"National School Lunch Week. Release date: 2005-10-11. (a) Designation.\\u2014. The week beginning on the second Sunday in October is National School Lunch Week. (b) Proclamation.\\u2014 ... TITLE 36 &gt; Subtitle I &gt; Part A &gt; CHAPTER 1 &gt; \\u00a7 132. Prev | Next. \\u00a7 132. National School Lunch Week ...","Url":"http:\\/\\/www4.law.cornell.edu\\/uscode\\/html\\/uscode36\\/usc_sec_36_00000132----000-.html","ClickUrl":"http:\\/\\/uk.wrs.yahoo.com\\/_ylt=A0Je5VwQjWVEsGcBHx3dmMwF;_ylu=X3oDMTEwN3BsMm9vBGNvbG8DdwRsA1dTMQRwb3MDMzEEc2VjA3NyBHZ0aWQD\\/SIG=1359dp76s\\/EXP=1147592336\\/**http%3a\\/\\/www4.law.cornell.edu\\/uscode\\/html\\/uscode36\\/usc_sec_36_00000132----000-.html","ModificationDate":1145343600,"MimeType":"text\\/html","Cache":{"Url":"http:\\/\\/uk.wrs.yahoo.com\\/_ylt=A0Je5VwQjWVEsGcBJB3dmMwF;_ylu=X3oDMTBxNG81cnMxBGNvbG8DdwRwb3MDMzEEc2VjA3NyBHZ0aWQD\\/SIG=17m1he9ur\\/EXP=1147592336\\/**http%3a\\/\\/66.218.69.11\\/search\\/cache%3fei=UTF-8%26query=132%26output=json%26results=100%26appid=jennyhan_ac%26u=www4.law.cornell.edu\\/uscode\\/html\\/uscode36\\/usc_sec_36_00000132----000-.html%26w=132%26d=NTi8bUaqMpvs%26icp=1%26.intl=us","Size":"8976"}},{"Title":"ATel #132: IGR J17464-3213","Summary":"Outside. Other. Present Time: 7 May 2006; 4:08 UT. RSS. XML Gamma Ray Bursts. IGR J17464-3213 ... IGR J17464-3213. ATel #132; M. Revnivtsev (IKI, Moscow; MPA, Garching), M ... XTE J1746-322 = IGR J17464-3213 = H1743-322. 132. IGR J17464-3213 ...","Url":"http:\\/\\/www.astronomerstelegram.org\\/?read=132","ClickUrl":"http:\\/\\/uk.wrs.yahoo.com\\/_ylt=A0Je5VwQjWVEsGcBJh3dmMwF;_ylu=X3oDMTEwYWI0N2o2BGNvbG8DdwRsA1dTMQRwb3MDMzIEc2VjA3NyBHZ0aWQD\\/SIG=122qvcsd1\\/EXP=1147592336\\/**http%3a\\/\\/www.astronomerstelegram.org\\/%3fread=132","ModificationDate":1146985200,"MimeType":"text\\/html","Cache":{"Url":"http:\\/\\/uk.wrs.yahoo.com\\/_ylt=A0Je5VwQjWVEsGcBKx3dmMwF;_ylu=X3oDMTBxYmt2ZDZzBGNvbG8DdwRwb3MDMzIEc2VjA3NyBHZ0aWQD\\/SIG=16pipao89\\/EXP=1147592336\\/**http%3a\\/\\/66.218.69.11\\/search\\/cache%3fei=UTF-8%26query=132%26output=json%26results=100%26appid=jennyhan_ac%26u=www.astronomerstelegram.org\\/%253Fread%253D132%26w=132%26d=Pb4lcUaqMvBj%26icp=1%26.intl=us","Size":"9056"}},{"Title":"Vashegyite Mineral Data","Summary":"Vashegyite Mineral Data + General Vashegyite Information. Chemical Formula: Al11(PO4)9(OH)6\\u00b738(H2O) or Al6(PO4)5(OH)3\\u00b723(H2O) Composition: Molecular Weight = 1,938.16 gm. Aluminum 15.31 % Al 28.93 % Al2O3","Url":"http:\\/\\/www.webmineral.com\\/data\\/Vashegyite.shtml","ClickUrl":"http:\\/\\/uk.wrs.yahoo.com\\/_ylt=A0Je5VwQjWVEsGcBLR3dmMwF;_ylu=X3oDMTEwNHFvMGppBGNvbG8DdwRsA1dTMQRwb3MDMzMEc2VjA3NyBHZ0aWQD\\/SIG=123ajp144\\/EXP=1147592336\\/**http%3a\\/\\/www.webmineral.com\\/data\\/Vashegyite.shtml","ModificationDate":1146898800,"MimeType":"text\\/html","Cache":{"Url":"http:\\/\\/uk.wrs.yahoo.com\\/_ylt=A0Je5VwQjWVEsGcBMh3dmMwF;_ylu=X3oDMTBxNzAwNWY0BGNvbG8DdwRwb3MDMzMEc2VjA3NyBHZ0aWQD\\/SIG=16ktl9ibf\\/EXP=1147592336\\/**http%3a\\/\\/66.218.69.11\\/search\\/cache%3fei=UTF-8%26query=132%26output=json%26results=100%26appid=jennyhan_ac%26u=www.webmineral.com\\/data\\/Vashegyite.shtml%26w=132%26d=W38GQkaqMvCt%26icp=1%26.intl=us","Size":"29234"}},{"Title":"2003 CFR Title 40, Volume 19","Summary":"... CHAPTER I--ENVIRONMENTAL PROTECTION AGENCY. PART 132--WATER QUALITY GUIDANCE FOR THE GREAT LAKES SYSTEM. 132.1. Scope, purpose, and availability of documents ...","Url":"http:\\/\\/www.access.gpo.gov\\/nara\\/cfr\\/waisidx_03\\/40cfr132_03.html","ClickUrl":"http:\\/\\/uk.wrs.yahoo.com\\/_ylt=A0Je5VwQjWVEsGcBNB3dmMwF;_ylu=X3oDMTEwdHZ0ZXZxBGNvbG8DdwRsA1dTMQRwb3MDMzQEc2VjA3NyBHZ0aWQD\\/SIG=12imj9jh5\\/EXP=1147592336\\/**http%3a\\/\\/www.access.gpo.gov\\/nara\\/cfr\\/waisidx_03\\/40cfr132_03.html","ModificationDate":1123916400,"MimeType":"text\\/html","Cache":{"Url":"http:\\/\\/uk.wrs.yahoo.com\\/_ylt=A0Je5VwQjWVEsGcBOR3dmMwF;_ylu=X3oDMTBxcml1MjI5BGNvbG8DdwRwb3MDMzQEc2VjA3NyBHZ0aWQD\\/SIG=173ahs683\\/EXP=1147592336\\/**http%3a\\/\\/66.218.69.11\\/search\\/cache%3fei=UTF-8%26query=132%26output=json%26results=100%26appid=jennyhan_ac%26u=www.access.gpo.gov\\/nara\\/cfr\\/waisidx_03\\/40cfr132_03.html%26w=132%26d=c8h16UaqMjB2%26icp=1%26.intl=us","Size":"4704"}},{"Title":"Chapter HFS 132","Summary":"... 145. HFS 132.13. DEPARTMENT OF HEALTH AND FAMILY SERVICES ... Subchapter I \\u2014 General. HFS 132.11. Statutory authority. HFS 132.12 ...","Url":"http:\\/\\/www.legis.state.wi.us\\/rsb\\/code\\/hfs\\/hfs132.pdf","ClickUrl":"http:\\/\\/www.legis.state.wi.us\\/rsb\\/code\\/hfs\\/hfs132.pdf#search=\'\'","ModificationDate":1099033200,"MimeType":"application\\/pdf","Cache":{"Url":"http:\\/\\/uk.wrs.yahoo.com\\/_ylt=A0Je5VwQjWVEsGcBPh3dmMwF;_ylu=X3oDMTBxaXI5cmVpBGNvbG8DdwRwb3MDMzUEc2VjA3NyBHZ0aWQD\\/SIG=16p8cmh99\\/EXP=1147592336\\/**http%3a\\/\\/66.218.69.11\\/search\\/cache%3fei=UTF-8%26query=132%26output=json%26results=100%26appid=jennyhan_ac%26u=www.legis.state.wi.us\\/rsb\\/code\\/hfs\\/hfs132.pdf%26w=132%26d=CN-yI0aqMkhi%26icp=1%26.intl=us","Size":"283151"}},{"Title":"U.S. Senate: Legislation & Records Home &gt; Votes &gt; Roll Call Vote","Summary":"... Vote Number: 132. Vote Date: June 8, 2005, 05:30 PM ...","Url":"http:\\/\\/www.senate.gov\\/legislative\\/LIS\\/roll_call_lists\\/roll_call_vote_cfm.cfm?congress=109&session=1&vote=00132","ClickUrl":"http:\\/\\/uk.wrs.yahoo.com\\/_ylt=A0Je5VwQjWVEsGcBQB3dmMwF;_ylu=X3oDMTEwdTlzNmU2BGNvbG8DdwRsA1dTMQRwb3MDMzYEc2VjA3NyBHZ0aWQD\\/SIG=148g3pmm4\\/EXP=1147592336\\/**http%3a\\/\\/www.senate.gov\\/legislative\\/LIS\\/roll_call_lists\\/roll_call_vote_cfm.cfm%3fcongress=109%26session=1%26vote=00132","ModificationDate":1143360000,"MimeType":"text\\/html","Cache":{"Url":"http:\\/\\/uk.wrs.yahoo.com\\/_ylt=A0Je5VwQjWVEsGcBRR3dmMwF;_ylu=X3oDMTBxOTlsaWYxBGNvbG8DdwRwb3MDMzYEc2VjA3NyBHZ0aWQD\\/SIG=19b3rasjc\\/EXP=1147592336\\/**http%3a\\/\\/66.218.69.11\\/search\\/cache%3fei=UTF-8%26query=132%26output=json%26results=100%26appid=jennyhan_ac%26u=www.senate.gov\\/legislative\\/LIS\\/roll_call_lists\\/roll_call_vote_cfm.cfm%253Fcongress%253D109%2526session%253D1%2526vote%253D00132%26w=132%26d=dtev60aqMh1g%26icp=1%26.intl=us","Size":"51433"}},{"Title":"Storm Prediction Center Tornado Watch 132","Summary":"Severe weather, tornado, thunderstorm, fire weather, storm report, tornado watch, severe thunderstorm watch, mesoscale discussion, convective outlook products from the Storm Prediction Center. ... SEL2 URGENT - IMMEDIATE BROADCAST REQUESTED TORNADO WATCH NUMBER 132 NWS STORM PREDICTION CENTER NORMAN OK 325 PM CDT ...","Url":"http:\\/\\/www.spc.noaa.gov\\/products\\/watch\\/ww0132.html","ClickUrl":"http:\\/\\/uk.wrs.yahoo.com\\/_ylt=A0Je5VwQjWVEsGcBRx3dmMwF;_ylu=X3oDMTEwanQ3MzU2BGNvbG8DdwRsA1dTMQRwb3MDMzcEc2VjA3NyBHZ0aWQD\\/SIG=126urlun7\\/EXP=1147592336\\/**http%3a\\/\\/www.spc.noaa.gov\\/products\\/watch\\/ww0132.html","ModificationDate":1146812400,"MimeType":"text\\/html","Cache":{"Url":"http:\\/\\/uk.wrs.yahoo.com\\/_ylt=A0Je5VwQjWVEsGcBTB3dmMwF;_ylu=X3oDMTBxNDRkc3R1BGNvbG8DdwRwb3MDMzcEc2VjA3NyBHZ0aWQD\\/SIG=16n3e4s74\\/EXP=1147592336\\/**http%3a\\/\\/66.218.69.11\\/search\\/cache%3fei=UTF-8%26query=132%26output=json%26results=100%26appid=jennyhan_ac%26u=www.spc.noaa.gov\\/products\\/watch\\/ww0132.html%26w=132%26d=N4g-pUaqMusz%26icp=1%26.intl=us","Size":"19990"}},{"Title":"PLANT PHYSIOLOGY ONLINE -- Table of Contents (132 [2])","Summary":"To see an article, click its [Full Text] link. To review many abstracts, check the boxes to the left of the titles you want, and click the \'Get All Checked Abstract(s)\' button. To see one abstract at a time, click its [Abstract] link.","Url":"http:\\/\\/www.plantphysiol.org\\/content\\/vol132\\/issue2\\/index.shtml","ClickUrl":"http:\\/\\/uk.wrs.yahoo.com\\/_ylt=A0Je5VwQjWVEsGcBTh3dmMwF;_ylu=X3oDMTEwa2NtaWpsBGNvbG8DdwRsA1dTMQRwb3MDMzgEc2VjA3NyBHZ0aWQD\\/SIG=12hg0jpkp\\/EXP=1147592336\\/**http%3a\\/\\/www.plantphysiol.org\\/content\\/vol132\\/issue2\\/index.shtml","ModificationDate":1141804800,"MimeType":"text\\/html","Cache":{"Url":"http:\\/\\/uk.wrs.yahoo.com\\/_ylt=A0Je5VwQjWVEsGcBUx3dmMwF;_ylu=X3oDMTBxYnZvM21yBGNvbG8DdwRwb3MDMzgEc2VjA3NyBHZ0aWQD\\/SIG=172cps28k\\/EXP=1147592336\\/**http%3a\\/\\/66.218.69.11\\/search\\/cache%3fei=UTF-8%26query=132%26output=json%26results=100%26appid=jennyhan_ac%26u=www.plantphysiol.org\\/content\\/vol132\\/issue2\\/index.shtml%26w=132%26d=Yvs4KUaqMjZc%26icp=1%26.intl=us","Size":"79038"}},{"Title":"AgGPS 132","Summary":"... The AgGPS 132 outputs sub- meter accuracy DGPS positions ... lightbar is connected to the. AgGPS 132. The AgGPS 132. can output positions up to 10 ...","Url":"http:\\/\\/www.farmgis.com\\/products\\/hardware\\/gps\\/aggps132.pdf","ClickUrl":"http:\\/\\/www.farmgis.com\\/products\\/hardware\\/gps\\/aggps132.pdf#search=\'\'","ModificationDate":1098169200,"MimeType":"application\\/pdf","Cache":{"Url":"http:\\/\\/uk.wrs.yahoo.com\\/_ylt=A0Je5VwQjWVEsGcBWB3dmMwF;_ylu=X3oDMTBxcXNibWtvBGNvbG8DdwRwb3MDMzkEc2VjA3NyBHZ0aWQD\\/SIG=16us46bp9\\/EXP=1147592336\\/**http%3a\\/\\/66.218.69.11\\/search\\/cache%3fei=UTF-8%26query=132%26output=json%26results=100%26appid=jennyhan_ac%26u=www.farmgis.com\\/products\\/hardware\\/gps\\/aggps132.pdf%26w=132%26d=EvLM70aqMkiV%26icp=1%26.intl=us","Size":"162160"}},{"Title":"Chapter 132 \\u2014 Grand Jury, Indictments and Other Accusatory Instruments","Summary":"The text appearing in this database was produced from material provided by the Legislative Counsel Committee of the Oregon Legislative Assembly. The official record copy is the printed published copy of the Oregon Revised Statutes. ... 132.010 Composition. A grand jury is a body of seven persons drawn from the jurors in attendance ... 132.030 Challenge of juror prohibited; when juror may be excused. Neither ...","Url":"http:\\/\\/www.leg.state.or.us\\/ors\\/132.html","ClickUrl":"http:\\/\\/uk.wrs.yahoo.com\\/_ylt=A0Je5VwQjWVEsGcBWh3dmMwF;_ylu=X3oDMTEwYTAzbTUxBGNvbG8DdwRsA1dTMQRwb3MDNDAEc2VjA3NyBHZ0aWQD\\/SIG=11r91jes0\\/EXP=1147592336\\/**http%3a\\/\\/www.leg.state.or.us\\/ors\\/132.html","ModificationDate":1144220400,"MimeType":"text\\/html","Cache":{"Url":"http:\\/\\/uk.wrs.yahoo.com\\/_ylt=A0Je5VwQjWVEsGcBXx3dmMwF;_ylu=X3oDMTBxdGU5a2FhBGNvbG8DdwRwb3MDNDAEc2VjA3NyBHZ0aWQD\\/SIG=16cbqvrlb\\/EXP=1147592336\\/**http%3a\\/\\/66.218.69.11\\/search\\/cache%3fei=UTF-8%26query=132%26output=json%26results=100%26appid=jennyhan_ac%26u=www.leg.state.or.us\\/ors\\/132.html%26w=132%26d=MFh3EUaqMk41%26icp=1%26.intl=us","Size":"73717"}},{"Title":"Downloaded 19 Aug 2002 to 132.163.136.56. Redistribution subject to AIP license or copyright, see http:\\/\\/ojps.aip... ","Summary":"Downloaded 19 Aug 2002 to 132.163.136.56. Redistribution subject to AIP license or copyright, see http:\\/\\/ojps.aip.org\\/japo\\/japcr.jsp. Downloaded 19 Aug 2002 to 132.163.136.56.","Url":"http:\\/\\/tf.nist.gov\\/general\\/pdf\\/550.pdf","ClickUrl":"http:\\/\\/tf.nist.gov\\/general\\/pdf\\/550.pdf#search=\'\'","ModificationDate":1029740400,"MimeType":"application\\/pdf","Cache":{"Url":"http:\\/\\/uk.wrs.yahoo.com\\/_ylt=A0Je5VwQjWVEsGcBZB3dmMwF;_ylu=X3oDMTBxcDdtZjJoBGNvbG8DdwRwb3MDNDEEc2VjA3NyBHZ0aWQD\\/SIG=16bgqks5e\\/EXP=1147592336\\/**http%3a\\/\\/66.218.69.11\\/search\\/cache%3fei=UTF-8%26query=132%26output=json%26results=100%26appid=jennyhan_ac%26u=tf.nist.gov\\/general\\/pdf\\/550.pdf%26w=132%26d=PNXPXkaqMkLS%26icp=1%26.intl=us","Size":"2485625"}},{"Title":"Father Tom Inspired Pflugerville #132 To Evolve Into A Strong Fraternal Society","Summary":"... Monsignor Tom Frank is presented with the 2002 Society #132. Service Award by President Ray Pokorney ... ach year Society #132. of Pflugerville honors ...","Url":"http:\\/\\/www.kjtnet.org\\/web\\/benefits\\/newsletter\\/march03.pdf","ClickUrl":"http:\\/\\/www.kjtnet.org\\/web\\/benefits\\/newsletter\\/march03.pdf#search=\'\'","ModificationDate":1105603200,"MimeType":"application\\/pdf","Cache":{"Url":"http:\\/\\/uk.wrs.yahoo.com\\/_ylt=A0Je5VwQjWVEsGcBaR3dmMwF;_ylu=X3oDMTBxMWU2b2h1BGNvbG8DdwRwb3MDNDIEc2VjA3NyBHZ0aWQD\\/SIG=16u12rqgg\\/EXP=1147592336\\/**http%3a\\/\\/66.218.69.11\\/search\\/cache%3fei=UTF-8%26query=132%26output=json%26results=100%26appid=jennyhan_ac%26u=www.kjtnet.org\\/web\\/benefits\\/newsletter\\/march03.pdf%26w=132%26d=fjH4hEaqMwZd%26icp=1%26.intl=us","Size":"2791412"}},{"Title":"Alsakharovite-Zn Mineral Data","Summary":"Alsakharovite-Zn Mineral Data. [Log In] [Current Auction] [Register to Bid] [FAQ] [About Us] Tired of Ebay rip-offs, scams, and dishonest people?","Url":"http:\\/\\/www.webmineral.com\\/data\\/Alsakharovite-Zn.shtml","ClickUrl":"http:\\/\\/uk.wrs.yahoo.com\\/_ylt=A0Je5VwQjWVEsGcBax3dmMwF;_ylu=X3oDMTEwN2JwMzlhBGNvbG8DdwRsA1dTMQRwb3MDNDMEc2VjA3NyBHZ0aWQD\\/SIG=129j54b3c\\/EXP=1147592336\\/**http%3a\\/\\/www.webmineral.com\\/data\\/Alsakharovite-Zn.shtml","ModificationDate":1147158000,"MimeType":"text\\/html","Cache":{"Url":"http:\\/\\/uk.wrs.yahoo.com\\/_ylt=A0Je5VwQjWVEsGcBcB3dmMwF;_ylu=X3oDMTBxamhmc2lnBGNvbG8DdwRwb3MDNDMEc2VjA3NyBHZ0aWQD\\/SIG=16q6pnttb\\/EXP=1147592336\\/**http%3a\\/\\/66.218.69.11\\/search\\/cache%3fei=UTF-8%26query=132%26output=json%26results=100%26appid=jennyhan_ac%26u=www.webmineral.com\\/data\\/Alsakharovite-Zn.shtml%26w=132%26d=B_smj0aqMwJU%26icp=1%26.intl=us","Size":"38594"}},{"Title":"Psalm 132","Summary":"... Psalm 132. The Eternal Dwelling of God in Zion ...","Url":"http:\\/\\/www.hope.edu\\/academic\\/religion\\/bandstra\\/BIBLE\\/PSA\\/PSA132.HTM","ClickUrl":"http:\\/\\/uk.wrs.yahoo.com\\/_ylt=A0Je5VwQjWVEsGcBch3dmMwF;_ylu=X3oDMTEwdXE2dm1tBGNvbG8DdwRsA1dTMQRwb3MDNDQEc2VjA3NyBHZ0aWQD\\/SIG=12n448u4t\\/EXP=1147592336\\/**http%3a\\/\\/www.hope.edu\\/academic\\/religion\\/bandstra\\/BIBLE\\/PSA\\/PSA132.HTM","ModificationDate":1114758000,"MimeType":"text\\/html","Cache":{"Url":"http:\\/\\/uk.wrs.yahoo.com\\/_ylt=A0Je5VwQjWVEsGcBdx3dmMwF;_ylu=X3oDMTBxMjBjZXRuBGNvbG8DdwRwb3MDNDQEc2VjA3NyBHZ0aWQD\\/SIG=17829d5da\\/EXP=1147592336\\/**http%3a\\/\\/66.218.69.11\\/search\\/cache%3fei=UTF-8%26query=132%26output=json%26results=100%26appid=jennyhan_ac%26u=www.hope.edu\\/academic\\/religion\\/bandstra\\/BIBLE\\/PSA\\/PSA132.HTM%26w=132%26d=Gs9Yt0aqMhg_%26icp=1%26.intl=us","Size":"5137"}},{"Title":"Bug 132 - Heartbeat requires all nodes to be pre-configured in ha.cf","Summary":"... Bugzilla Bug 132. Heartbeat requires all nodes to be pre-configured in ha.cf ... Bug#: 132. Platform: All DEC HP Macintosh PC SGI Sun Other ...","Url":"http:\\/\\/www.osdl.org\\/developer_bugzilla\\/show_bug.cgi?id=132","ClickUrl":"http:\\/\\/uk.wrs.yahoo.com\\/_ylt=A0Je5VwQjWVEsGcBeR3dmMwF;_ylu=X3oDMTEwa3QxajIyBGNvbG8DdwRsA1dTMQRwb3MDNDUEc2VjA3NyBHZ0aWQD\\/SIG=12g1vvd06\\/EXP=1147592336\\/**http%3a\\/\\/www.osdl.org\\/developer_bugzilla\\/show_bug.cgi%3fid=132","ModificationDate":1146553200,"MimeType":"text\\/html","Cache":{"Url":"http:\\/\\/uk.wrs.yahoo.com\\/_ylt=A0Je5VwQjWVEsGcBfh3dmMwF;_ylu=X3oDMTBxbHY2NGw5BGNvbG8DdwRwb3MDNDUEc2VjA3NyBHZ0aWQD\\/SIG=177hj2go7\\/EXP=1147592336\\/**http%3a\\/\\/66.218.69.11\\/search\\/cache%3fei=UTF-8%26query=132%26output=json%26results=100%26appid=jennyhan_ac%26u=www.osdl.org\\/developer_bugzilla\\/show_bug.cgi%253Fid%253D132%26w=132%26d=Uzd0n0aqMtwg%26icp=1%26.intl=us","Size":"40101"}},{"Title":"Bug 132 - ChargeDispositionPlea and ChargeDispositionVerdict","Summary":"... Bugzilla Bug 132. ChargeDispositionPlea and ChargeDispositionVerdict ... Bug#: 132. Domain: AAMVA Corrections Courts Juvenile Law Enforcement Parole Probation Prosecution Other ...","Url":"http:\\/\\/justicexml.gtri.gatech.edu\\/feedback\\/show_bug.cgi?id=132","ClickUrl":"http:\\/\\/uk.wrs.yahoo.com\\/_ylt=A0Je5VwQjWVEsGcBgB3dmMwF;_ylu=X3oDMTEwdmhtYjA4BGNvbG8DdwRsA1dTMQRwb3MDNDYEc2VjA3NyBHZ0aWQD\\/SIG=12klknku3\\/EXP=1147592336\\/**http%3a\\/\\/justicexml.gtri.gatech.edu\\/feedback\\/show_bug.cgi%3fid=132","ModificationDate":1143360000,"MimeType":"text\\/html","Cache":{"Url":"http:\\/\\/uk.wrs.yahoo.com\\/_ylt=A0Je5VwQjWVEsGcBhR3dmMwF;_ylu=X3oDMTBxa2g2bWNnBGNvbG8DdwRwb3MDNDYEc2VjA3NyBHZ0aWQD\\/SIG=17bcs6mrt\\/EXP=1147592336\\/**http%3a\\/\\/66.218.69.11\\/search\\/cache%3fei=UTF-8%26query=132%26output=json%26results=100%26appid=jennyhan_ac%26u=justicexml.gtri.gatech.edu\\/feedback\\/show_bug.cgi%253Fid%253D132%26w=132%26d=e0Zoy0aqMjBn%26icp=1%26.intl=us","Size":"16410"}},{"Title":"Publications","Summary":"... Bulletin 132, Management of the California State Water Project, is a series of annual reports that describe the ... annual Appendix E to Bulletin 132 and the final edition of the ...","Url":"http:\\/\\/www.swpao.water.ca.gov\\/publications","ClickUrl":"http:\\/\\/uk.wrs.yahoo.com\\/_ylt=A0Je5VwQjWVEsGcBhx3dmMwF;_ylu=X3oDMTEwZjVhYXMzBGNvbG8DdwRsA1dTMQRwb3MDNDcEc2VjA3NyBHZ0aWQD\\/SIG=11ud1cv0a\\/EXP=1147592336\\/**http%3a\\/\\/www.swpao.water.ca.gov\\/publications","ModificationDate":1143187200,"MimeType":"text\\/html","Cache":{"Url":"http:\\/\\/uk.wrs.yahoo.com\\/_ylt=A0Je5VwQjWVEsGcBjB3dmMwF;_ylu=X3oDMTBxcjNocmY0BGNvbG8DdwRwb3MDNDcEc2VjA3NyBHZ0aWQD\\/SIG=16fvue890\\/EXP=1147592336\\/**http%3a\\/\\/66.218.69.11\\/search\\/cache%3fei=UTF-8%26query=132%26output=json%26results=100%26appid=jennyhan_ac%26u=www.swpao.water.ca.gov\\/publications%26w=132%26d=CDqKvkaqMhfi%26icp=1%26.intl=us","Size":"27835"}},{"Title":"Sampling at Head Crater and Bench Crater","Summary":"... 132:10:41 Bean: Boy, this Hand Tool Carrier is light and nice compared to carrying it around ... 132:11:20 Bean: I can see everything from fine-grain basalt ...","Url":"http:\\/\\/www.hq.nasa.gov\\/alsj\\/a12\\/a12.head_bench.html","ClickUrl":"http:\\/\\/uk.wrs.yahoo.com\\/_ylt=A0Je5VwQjWVEsGcBjh3dmMwF;_ylu=X3oDMTEwYjFmcHI4BGNvbG8DdwRsA1dTMQRwb3MDNDgEc2VjA3NyBHZ0aWQD\\/SIG=127h6jrgp\\/EXP=1147592336\\/**http%3a\\/\\/www.hq.nasa.gov\\/alsj\\/a12\\/a12.head_bench.html","ModificationDate":1139731200,"MimeType":"text\\/html","Cache":{"Url":"http:\\/\\/uk.wrs.yahoo.com\\/_ylt=A0Je5VwQjWVEsGcBkx3dmMwF;_ylu=X3oDMTBxazBuMTN2BGNvbG8DdwRwb3MDNDgEc2VjA3NyBHZ0aWQD\\/SIG=16of05gsq\\/EXP=1147592336\\/**http%3a\\/\\/66.218.69.11\\/search\\/cache%3fei=UTF-8%26query=132%26output=json%26results=100%26appid=jennyhan_ac%26u=www.hq.nasa.gov\\/alsj\\/a12\\/a12.head_bench.html%26w=132%26d=O2JTbEaqMul1%26icp=1%26.intl=us","Size":"91895"}},{"Title":"Psalms 132","Summary":"Psalms 132. 132:1 A Song of degrees.","Url":"http:\\/\\/www.masterstech-home.com\\/The_Library\\/The_Bible\\/Bible_Chapters\\/Psalms\\/132.html","ClickUrl":"http:\\/\\/uk.wrs.yahoo.com\\/_ylt=A0Je5VwQjWVEsGcBlR3dmMwF;_ylu=X3oDMTEwOG85MWM5BGNvbG8DdwRsA1dTMQRwb3MDNDkEc2VjA3NyBHZ0aWQD\\/SIG=1381oeor0\\/EXP=1147592336\\/**http%3a\\/\\/www.masterstech-home.com\\/The_Library\\/The_Bible\\/Bible_Chapters\\/Psalms\\/132.html","ModificationDate":1135152000,"MimeType":"text\\/html","Cache":{"Url":"http:\\/\\/uk.wrs.yahoo.com\\/_ylt=A0Je5VwQjWVEsGcBmh3dmMwF;_ylu=X3oDMTBxNWpuM3FoBGNvbG8DdwRwb3MDNDkEc2VjA3NyBHZ0aWQD\\/SIG=17p7bjs0u\\/EXP=1147592336\\/**http%3a\\/\\/66.218.69.11\\/search\\/cache%3fei=UTF-8%26query=132%26output=json%26results=100%26appid=jennyhan_ac%26u=www.masterstech-home.com\\/The_Library\\/The_Bible\\/Bible_Chapters\\/Psalms\\/132.html%26w=132%26d=TUYYg0aqMhg4%26icp=1%26.intl=us","Size":"11669"}},{"Title":"California Highways (www.cahighways.org): Routes 129 through 136","Summary":"... The 2005 Transportation Bill included \$14.4 million to widen Route 132 from Route 99 west to Dakota Avenue ... between Coulterville and Mariposa was cosigned as Route 49 and Route 132 ...","Url":"http:\\/\\/www.cahighways.org\\/129-136.html","ClickUrl":"http:\\/\\/uk.wrs.yahoo.com\\/_ylt=A0Je5VwQjWVEsGcBnB3dmMwF;_ylu=X3oDMTEwaXBqZ2lxBGNvbG8DdwRsA1dTMQRwb3MDNTAEc2VjA3NyBHZ0aWQD\\/SIG=11q1ne7f6\\/EXP=1147592336\\/**http%3a\\/\\/www.cahighways.org\\/129-136.html","ModificationDate":1145689200,"MimeType":"text\\/html","Cache":{"Url":"http:\\/\\/uk.wrs.yahoo.com\\/_ylt=A0Je5VwQjWVEsGcBoR3dmMwF;_ylu=X3oDMTBxbmZjMXVuBGNvbG8DdwRwb3MDNTAEc2VjA3NyBHZ0aWQD\\/SIG=16bhah065\\/EXP=1147592336\\/**http%3a\\/\\/66.218.69.11\\/search\\/cache%3fei=UTF-8%26query=132%26output=json%26results=100%26appid=jennyhan_ac%26u=www.cahighways.org\\/129-136.html%26w=132%26d=fRBtE0aqMqve%26icp=1%26.intl=us","Size":"49110"}},{"Title":"Downloaded 11 Nov 2002 to 132.64.1.37. Redistribution subject to AIP license or copyright, see http:\\/\\/ojps.aip.org\\/... ","Summary":"Downloaded 11 Nov 2002 to 132.64.1.37. Redistribution subject to AIP license or copyright, see http:\\/\\/ojps.aip.org\\/rsio\\/rsicr.jsp. Downloaded 11 Nov 2002 to 132.64.1.37.","Url":"http:\\/\\/chem.ch.huji.ac.il\\/~porath\\/NST2\\/Lecture%205\\/Kuk%20and%20Silverman%20Rev_Sci_Inst_60_165_1989.pdf","ClickUrl":"http:\\/\\/chem.ch.huji.ac.il\\/~porath\\/NST2\\/Lecture%205\\/Kuk%20and%20Silverman%20Rev_Sci_Inst_60_165_1989.pdf#search=\'\'","ModificationDate":1069660800,"MimeType":"application\\/pdf","Cache":{"Url":"http:\\/\\/uk.wrs.yahoo.com\\/_ylt=A0Je5VwQjWVEsGcBph3dmMwF;_ylu=X3oDMTBxZHJldXUyBGNvbG8DdwRwb3MDNTEEc2VjA3NyBHZ0aWQD\\/SIG=190pnnu1n\\/EXP=1147592336\\/**http%3a\\/\\/66.218.69.11\\/search\\/cache%3fei=UTF-8%26query=132%26output=json%26results=100%26appid=jennyhan_ac%26u=chem.ch.huji.ac.il\\/%257Eporath\\/NST2\\/Lecture%2525205\\/Kuk%252520and%252520Silverman%252520Rev_Sci_Inst_60_165_1989.pdf%26w=132%26d=F4c-T0aqMhfn%26icp=1%26.intl=us","Size":"3386219"}},{"Title":"Phelps Personnel Associates","Summary":"Welcome to Phelps Personnel Associates. Recruiting and Placing Engineers and Management Professionals since 1976. Concentration in the Carolinas and Southeastern job market. Permanent, Company fee-paid positions only. Confidential, courteous service","Url":"http:\\/\\/www.phelpspersonnel.com\\/","ClickUrl":"http:\\/\\/uk.wrs.yahoo.com\\/_ylt=A0Je5VwQjWVEsGcBqB3dmMwF;_ylu=X3oDMTEwazlldjdwBGNvbG8DdwRsA1dTMQRwb3MDNTIEc2VjA3NyBHZ0aWQD\\/SIG=11j85rkug\\/EXP=1147592336\\/**http%3a\\/\\/www.phelpspersonnel.com\\/","ModificationDate":1060239600,"MimeType":"text\\/html","Cache":{"Url":"http:\\/\\/uk.wrs.yahoo.com\\/_ylt=A0Je5VwQjWVEsGcBrR3dmMwF;_ylu=X3oDMTBxZWJqMW1lBGNvbG8DdwRwb3MDNTIEc2VjA3NyBHZ0aWQD\\/SIG=164jn86me\\/EXP=1147592336\\/**http%3a\\/\\/66.218.69.11\\/search\\/cache%3fei=UTF-8%26query=132%26output=json%26results=100%26appid=jennyhan_ac%26u=www.phelpspersonnel.com\\/%26w=132%26d=KRPdjUaqMwQa%26icp=1%26.intl=us","Size":"6288"}},{"Title":"132 - Loss and resumption of Australian citizenship - Declaration of desre to resume Australian citizenship under ... ","Summary":"... retain another citizenship \\u0096 be under the age of 25 years. 132 (Design date 0705) - Page 1 ... 23A, 23AA, 23AB or 23B. 132 (Design date 0705) - Page 2 ...","Url":"http:\\/\\/www.immi.gov.au\\/allforms\\/pdf\\/132.pdf","ClickUrl":"http:\\/\\/www.immi.gov.au\\/allforms\\/pdf\\/132.pdf#search=\'\'","ModificationDate":1141113600,"MimeType":"application\\/pdf","Cache":{"Url":"http:\\/\\/uk.wrs.yahoo.com\\/_ylt=A0Je5VwQjWVEsGcBsh3dmMwF;_ylu=X3oDMTBxYzdmNTNvBGNvbG8DdwRwb3MDNTMEc2VjA3NyBHZ0aWQD\\/SIG=16gtd8vkd\\/EXP=1147592336\\/**http%3a\\/\\/66.218.69.11\\/search\\/cache%3fei=UTF-8%26query=132%26output=json%26results=100%26appid=jennyhan_ac%26u=www.immi.gov.au\\/allforms\\/pdf\\/132.pdf%26w=132%26d=XLvxbUaqMvqk%26icp=1%26.intl=us","Size":"118238"}},{"Title":"Communication Workersof America Local 3808","Summary":"News Highlights and Headlines. Nominations for one (1) 402 Franklin Road Area Representative will be taken at the June 6, 2006 Membership Meeting. BellSouth CONTRACT INFO. Frequently asked Q&A","Url":"http:\\/\\/cwa3808.org\\/","ClickUrl":"http:\\/\\/uk.wrs.yahoo.com\\/_ylt=A0Je5VwQjWVEsGcBtB3dmMwF;_ylu=X3oDMTEwMGJ0MmQ1BGNvbG8DdwRsA1dTMQRwb3MDNTQEc2VjA3NyBHZ0aWQD\\/SIG=117pqud0l\\/EXP=1147592336\\/**http%3a\\/\\/cwa3808.org\\/","ModificationDate":1147071600,"MimeType":"text\\/html","Cache":{"Url":"http:\\/\\/uk.wrs.yahoo.com\\/_ylt=A0Je5VwQjWVEsGcBuR3dmMwF;_ylu=X3oDMTBxY3NiaDkyBGNvbG8DdwRwb3MDNTQEc2VjA3NyBHZ0aWQD\\/SIG=15od3j3p8\\/EXP=1147592336\\/**http%3a\\/\\/66.218.69.11\\/search\\/cache%3fei=UTF-8%26query=132%26output=json%26results=100%26appid=jennyhan_ac%26u=cwa3808.org\\/%26w=132%26d=ahqtKEaqMwC6%26icp=1%26.intl=us","Size":"53103"}},{"Title":"Mirabilis ICQ 98a Vulnerability","Summary":"... Bugtraq ID: 132. Class: Failure to Handle Exceptional Conditions ...","Url":"http:\\/\\/www.securityfocus.com\\/bid\\/132","ClickUrl":"http:\\/\\/uk.wrs.yahoo.com\\/_ylt=A0Je5VwQjWVEsGcBux3dmMwF;_ylu=X3oDMTEwNXIwZzI2BGNvbG8DdwRsA1dTMQRwb3MDNTUEc2VjA3NyBHZ0aWQD\\/SIG=11ocj9p23\\/EXP=1147592336\\/**http%3a\\/\\/www.securityfocus.com\\/bid\\/132","ModificationDate":1146034800,"MimeType":"text\\/html","Cache":{"Url":"http:\\/\\/uk.wrs.yahoo.com\\/_ylt=A0Je5VwQjWVEsGcBwB3dmMwF;_ylu=X3oDMTBxbnNnYWFhBGNvbG8DdwRwb3MDNTUEc2VjA3NyBHZ0aWQD\\/SIG=169dn3s31\\/EXP=1147592336\\/**http%3a\\/\\/66.218.69.11\\/search\\/cache%3fei=UTF-8%26query=132%26output=json%26results=100%26appid=jennyhan_ac%26u=www.securityfocus.com\\/bid\\/132%26w=132%26d=bbuQiUaqMsU1%26icp=1%26.intl=us","Size":"11819"}},{"Title":"Downloaded 23 Dec 2001 to 132.76.33.15. Redistribution subject to AIP license or copyright, see http:\\/\\/ojps.aip.org\\/... ","Summary":"Downloaded 23 Dec 2001 to 132.76.33.15. Redistribution subject to AIP license or copyright, see http:\\/\\/ojps.aip.org\\/jcpo\\/jcpcr.jsp. Downloaded 23 Dec 2001 to 132.76.33.15.","Url":"http:\\/\\/theochem.weizmann.ac.il\\/AIPreprints\\/8.pdf","ClickUrl":"http:\\/\\/theochem.weizmann.ac.il\\/AIPreprints\\/8.pdf#search=\'\'","ModificationDate":1092294000,"MimeType":"application\\/pdf","Cache":{"Url":"http:\\/\\/uk.wrs.yahoo.com\\/_ylt=A0Je5VwQjWVEsGcBxR3dmMwF;_ylu=X3oDMTBxcjhpcTNrBGNvbG8DdwRwb3MDNTYEc2VjA3NyBHZ0aWQD\\/SIG=16l1r1fiu\\/EXP=1147592336\\/**http%3a\\/\\/66.218.69.11\\/search\\/cache%3fei=UTF-8%26query=132%26output=json%26results=100%26appid=jennyhan_ac%26u=theochem.weizmann.ac.il\\/AIPreprints\\/8.pdf%26w=132%26d=VrF160aqMjIt%26icp=1%26.intl=us","Size":"1754089"}},{"Title":"Chapter RL 132","Summary":"DEPARTMENT OF REGULATION AND LICENSING. Unofficial Text (See Printed Volume). Current through date and Register shown on Title Page. Register, July, 1999, No. 523. Chapter RL 132. APPLICATIONS. RL 132.01. Authority. RL 132.02 ... Note: Chapter RL 132 was created as an emergency rule effective 11\\u20131\\u201398 ...","Url":"http:\\/\\/www.legis.state.wi.us\\/rsb\\/code\\/rl\\/rl132.pdf","ClickUrl":"http:\\/\\/www.legis.state.wi.us\\/rsb\\/code\\/rl\\/rl132.pdf#search=\'\'","ModificationDate":1011859200,"MimeType":"application\\/pdf","Cache":{"Url":"http:\\/\\/uk.wrs.yahoo.com\\/_ylt=A0Je5VwQjWVEsGcByh3dmMwF;_ylu=X3oDMTBxZjI4aHZhBGNvbG8DdwRwb3MDNTcEc2VjA3NyBHZ0aWQD\\/SIG=16nps3tc2\\/EXP=1147592336\\/**http%3a\\/\\/66.218.69.11\\/search\\/cache%3fei=UTF-8%26query=132%26output=json%26results=100%26appid=jennyhan_ac%26u=www.legis.state.wi.us\\/rsb\\/code\\/rl\\/rl132.pdf%26w=132%26d=VTECeUaqMi-4%26icp=1%26.intl=us","Size":"8138"}},{"Title":"Rebuffing Bush, 132 Mayors Embrace Kyoto Rules - New York Times","Summary":"Greg Nickels of Seattle and 131 other like-minded mayors have joined a bipartisan coalition to fight global warming on the local level.","Url":"http:\\/\\/www.nytimes.com\\/2005\\/05\\/14\\/national\\/14kyoto.html?ex=1273723200&en=c02e1cce1ca43706&ei=5088","ClickUrl":"http:\\/\\/uk.wrs.yahoo.com\\/_ylt=A0Je5VwQjWVEsGcBzB3dmMwF;_ylu=X3oDMTEwbm43bzM3BGNvbG8DdwRsA1dTMQRwb3MDNTgEc2VjA3NyBHZ0aWQD\\/SIG=13repbe72\\/EXP=1147592336\\/**http%3a\\/\\/www.nytimes.com\\/2005\\/05\\/14\\/national\\/14kyoto.html%3fex=1273723200%26en=c02e1cce1ca43706%26ei=5088","ModificationDate":1147330800,"MimeType":"text\\/html"},{"Title":"DHS-Revised Rule 132","Summary":"Easy access to Illinois services and information ... an e-mail address to pose questions regarding Rule 132. Please review the Rule 132 Q&A document posted on ...","Url":"http:\\/\\/www.dhs.state.il.us\\/revisedRule132","ClickUrl":"http:\\/\\/uk.wrs.yahoo.com\\/_ylt=A0Je5VwQjWVEsGcB0h3dmMwF;_ylu=X3oDMTEwMjl1dW84BGNvbG8DdwRsA1dTMQRwb3MDNTkEc2VjA3NyBHZ0aWQD\\/SIG=11tb4gcma\\/EXP=1147592336\\/**http%3a\\/\\/www.dhs.state.il.us\\/revisedRule132","ModificationDate":1147244400,"MimeType":"text\\/html","Cache":{"Url":"http:\\/\\/uk.wrs.yahoo.com\\/_ylt=A0Je5VwQjWVEsGcB1x3dmMwF;_ylu=X3oDMTBxOWMyazRxBGNvbG8DdwRwb3MDNTkEc2VjA3NyBHZ0aWQD\\/SIG=16e8khp3d\\/EXP=1147592336\\/**http%3a\\/\\/66.218.69.11\\/search\\/cache%3fei=UTF-8%26query=132%26output=json%26results=100%26appid=jennyhan_ac%26u=www.dhs.state.il.us\\/revisedRule132%26w=132%26d=Oc4YikaqMwgM%26icp=1%26.intl=us","Size":"22903"}},{"Title":"211 CMR: DIVISION OF INSURANCE 6\\/27\\/97 211 CMR - 837 211 CMR 132.00: ACTUARIAL OPINION AND MEMORANDUM REGULATION ... ","Summary":"... 132.01: Purpose. 132.02: Authority. 132.03: Scope. 132.04: Definitions. 132.05: General Requirements. 132.06: Required Opinions. 132 ... Adequacy Analysis. 132.08: Statement of Actuarial ...","Url":"http:\\/\\/www.mass.gov\\/doi\\/Legal_Hearings\\/211_132.PDF","ClickUrl":"http:\\/\\/www.mass.gov\\/doi\\/Legal_Hearings\\/211_132.PDF#search=\'\'","ModificationDate":1003906800,"MimeType":"application\\/pdf","Cache":{"Url":"http:\\/\\/uk.wrs.yahoo.com\\/_ylt=A0Je5VwQjWVEsGcB3B3dmMwF;_ylu=X3oDMTBxdG9ldThsBGNvbG8DdwRwb3MDNjAEc2VjA3NyBHZ0aWQD\\/SIG=16no3ibvg\\/EXP=1147592336\\/**http%3a\\/\\/66.218.69.11\\/search\\/cache%3fei=UTF-8%26query=132%26output=json%26results=100%26appid=jennyhan_ac%26u=www.mass.gov\\/doi\\/Legal_Hearings\\/211_132.PDF%26w=132%26d=C4QXPkaqMjRM%26icp=1%26.intl=us","Size":"45945"}},{"Title":"Downloaded 22 Jul 2003 to 132.66.16.23. Redistribution subject to AIP license or copyright, see http:\\/\\/ojps.aip.org\\/... ","Summary":"Downloaded 22 Jul 2003 to 132.66.16.23. Redistribution subject to AIP license or copyright, see http:\\/\\/ojps.aip.org\\/jcpo\\/jcpcr.jsp. Downloaded 22 Jul 2003 to 132.66.16.23.","Url":"http:\\/\\/star.tau.ac.il\\/~andelman\\/reprints\\/021_JCP_1987_87_7229.pdf","ClickUrl":"http:\\/\\/star.tau.ac.il\\/~andelman\\/reprints\\/021_JCP_1987_87_7229.pdf#search=\'\'","ModificationDate":1058857200,"MimeType":"application\\/pdf","Cache":{"Url":"http:\\/\\/uk.wrs.yahoo.com\\/_ylt=A0Je5VwQjWVEsGcB4R3dmMwF;_ylu=X3oDMTBxZzZxbDZiBGNvbG8DdwRwb3MDNjEEc2VjA3NyBHZ0aWQD\\/SIG=17adesqgt\\/EXP=1147592336\\/**http%3a\\/\\/66.218.69.11\\/search\\/cache%3fei=UTF-8%26query=132%26output=json%26results=100%26appid=jennyhan_ac%26u=star.tau.ac.il\\/%257Eandelman\\/reprints\\/021_JCP_1987_87_7229.pdf%26w=132%26d=Lvkyh0aqMh8L%26icp=1%26.intl=us","Size":"1798906"}},{"Title":"Special Troops Battalion, 4th Brigade, 10th Mountain Division Insignia","Summary":"The Institute of Heraldry\'s Special Troops Battalion Section, Special Troops Battalion, 4th Brigade, 10th Mountain Division Insignia Page","Url":"http:\\/\\/www.tioh.hqda.pentagon.mil\\/STB\\/STB4Brigade10MountainDivision.htm","ClickUrl":"http:\\/\\/uk.wrs.yahoo.com\\/_ylt=A0Je5VwQjWVEsGcB4x3dmMwF;_ylu=X3oDMTEwZjFqOHFiBGNvbG8DdwRsA1dTMQRwb3MDNjIEc2VjA3NyBHZ0aWQD\\/SIG=12rjb6bu4\\/EXP=1147592336\\/**http%3a\\/\\/www.tioh.hqda.pentagon.mil\\/STB\\/STB4Brigade10MountainDivision.htm","ModificationDate":1109923200,"MimeType":"text\\/html","Cache":{"Url":"http:\\/\\/uk.wrs.yahoo.com\\/_ylt=A0Je5VwQjWVEsGcB6B3dmMwF;_ylu=X3oDMTBxZzN1cnRoBGNvbG8DdwRwb3MDNjIEc2VjA3NyBHZ0aWQD\\/SIG=17c61sq2b\\/EXP=1147592336\\/**http%3a\\/\\/66.218.69.11\\/search\\/cache%3fei=UTF-8%26query=132%26output=json%26results=100%26appid=jennyhan_ac%26u=www.tioh.hqda.pentagon.mil\\/STB\\/STB4Brigade10MountainDivision.htm%26w=132%26d=CjDx1kaqMwEn%26icp=1%26.intl=us","Size":"8896"}},{"Title":"NNSA\'s Brooks lauds partnership in nonproliferation","Summary":"... ite Way. U133. 132. A-4. 135. 134. 132. Fun With Science ...","Url":"http:\\/\\/www.llnl.gov\\/llnl\\/06news\\/employee\\/articles\\/2001\\/12.21.01newsline.pdf","ClickUrl":"http:\\/\\/www.llnl.gov\\/llnl\\/06news\\/employee\\/articles\\/2001\\/12.21.01newsline.pdf#search=\'\'","ModificationDate":1099555200,"MimeType":"application\\/pdf","Cache":{"Url":"http:\\/\\/uk.wrs.yahoo.com\\/_ylt=A0Je5VwQjWVEsGcB7R3dmMwF;_ylu=X3oDMTBxZ25nbWN0BGNvbG8DdwRwb3MDNjMEc2VjA3NyBHZ0aWQD\\/SIG=17go91rgp\\/EXP=1147592336\\/**http%3a\\/\\/66.218.69.11\\/search\\/cache%3fei=UTF-8%26query=132%26output=json%26results=100%26appid=jennyhan_ac%26u=www.llnl.gov\\/llnl\\/06news\\/employee\\/articles\\/2001\\/12.21.01newsline.pdf%26w=132%26d=aLdSWEaqMjYB%26icp=1%26.intl=us","Size":"472758"}},{"Title":"Psalms 132. The Holy Bible: King James Version.","Summary":"... Reference &gt; The Bible &gt; The King James Version &gt; Psalms &gt; 132 ... The Psalms. 132. A Prayer for Blessing on the Sanctuary ...","Url":"http:\\/\\/www.bartleby.com\\/108\\/19\\/132.html","ClickUrl":"http:\\/\\/uk.wrs.yahoo.com\\/_ylt=A0Je5VwQjWVEsGcB7x3dmMwF;_ylu=X3oDMTEwdm1iOTMzBGNvbG8DdwRsA1dTMQRwb3MDNjQEc2VjA3NyBHZ0aWQD\\/SIG=11rfct28r\\/EXP=1147592336\\/**http%3a\\/\\/www.bartleby.com\\/108\\/19\\/132.html","ModificationDate":1134460800,"MimeType":"text\\/html","Cache":{"Url":"http:\\/\\/uk.wrs.yahoo.com\\/_ylt=A0Je5VwQjWVEsGcB9B3dmMwF;_ylu=X3oDMTBxa3RqY29tBGNvbG8DdwRwb3MDNjQEc2VjA3NyBHZ0aWQD\\/SIG=16ckhlf21\\/EXP=1147592336\\/**http%3a\\/\\/66.218.69.11\\/search\\/cache%3fei=UTF-8%26query=132%26output=json%26results=100%26appid=jennyhan_ac%26u=www.bartleby.com\\/108\\/19\\/132.html%26w=132%26d=Om0HPEaqMjyM%26icp=1%26.intl=us","Size":"26896"}},{"Title":"The Criterion Collection: Ruling Class, The","Summary":"Title Person. Film Info. 1972. 154 minutes. Color. 1.77:1. Dolby Digital Mono 1.0. Anamorphic. English. Release Info. Catalog Number: CC1575D. ISBN: 1-55940-922-3. UPC: 7-15515-0124-2-3. SRP: \$39.95. Synopsis","Url":"http:\\/\\/www.criterionco.com\\/asp\\/release.asp?id=132","ClickUrl":"http:\\/\\/uk.wrs.yahoo.com\\/_ylt=A0Je5VwQjWVEsGcB9h3dmMwF;_ylu=X3oDMTEwcTRya2ltBGNvbG8DdwRsA1dTMQRwb3MDNjUEc2VjA3NyBHZ0aWQD\\/SIG=1272o9dh7\\/EXP=1147592336\\/**http%3a\\/\\/www.criterionco.com\\/asp\\/release.asp%3fid=132","ModificationDate":1147244400,"MimeType":"text\\/html","Cache":{"Url":"http:\\/\\/uk.wrs.yahoo.com\\/_ylt=A0Je5VwQjWVEsGcB.x3dmMwF;_ylu=X3oDMTBxdDMwMGJvBGNvbG8DdwRwb3MDNjUEc2VjA3NyBHZ0aWQD\\/SIG=16u4fa0dg\\/EXP=1147592336\\/**http%3a\\/\\/66.218.69.11\\/search\\/cache%3fei=UTF-8%26query=132%26output=json%26results=100%26appid=jennyhan_ac%26u=www.criterionco.com\\/asp\\/release.asp%253Fid%253D132%26w=132%26d=L2PGVEaqMwN7%26icp=1%26.intl=us","Size":"16920"}},{"Title":"AJP Legacy -- Table of Contents (February 28 1941, 132 [2])","Summary":"Contents: February 28 1941, Volume 132, Issue 2 [Index by Author] Other Issues: To see an article, click its [Full Text] link.","Url":"http:\\/\\/ajplegacy.physiology.org\\/content\\/vol132\\/issue2\\/index.shtml","ClickUrl":"http:\\/\\/uk.wrs.yahoo.com\\/_ylt=A0Je5VwQjWVEsGcB_R3dmMwF;_ylu=X3oDMTEwZWhkczJpBGNvbG8DdwRsA1dTMQRwb3MDNjYEc2VjA3NyBHZ0aWQD\\/SIG=12lf1ce7j\\/EXP=1147592336\\/**http%3a\\/\\/ajplegacy.physiology.org\\/content\\/vol132\\/issue2\\/index.shtml","ModificationDate":1141459200,"MimeType":"text\\/html","Cache":{"Url":"http:\\/\\/uk.wrs.yahoo.com\\/_ylt=A0Je5VwQjWVEsGcBAh7dmMwF;_ylu=X3oDMTBxNzI0azAwBGNvbG8DdwRwb3MDNjYEc2VjA3NyBHZ0aWQD\\/SIG=176uub081\\/EXP=1147592336\\/**http%3a\\/\\/66.218.69.11\\/search\\/cache%3fei=UTF-8%26query=132%26output=json%26results=100%26appid=jennyhan_ac%26u=ajplegacy.physiology.org\\/content\\/vol132\\/issue2\\/index.shtml%26w=132%26d=Ms_vOEaqMj-H%26icp=1%26.intl=us","Size":"24095"}},{"Title":"released a letter (PDF)","Summary":"","Url":"http:\\/\\/www.house.gov\\/judiciary_democrats\\/letters\\/rovehrgrequestltr71405.pdf","ClickUrl":"http:\\/\\/www.house.gov\\/judiciary_democrats\\/letters\\/rovehrgrequestltr71405.pdf#search=\'\'","ModificationDate":1121410800,"MimeType":"application\\/pdf","Cache":{"Url":"http:\\/\\/uk.wrs.yahoo.com\\/_ylt=A0Je5VwQjWVEsGcBBx7dmMwF;_ylu=X3oDMTBxOXQ3MWF0BGNvbG8DdwRwb3MDNjcEc2VjA3NyBHZ0aWQD\\/SIG=17g69a880\\/EXP=1147592336\\/**http%3a\\/\\/66.218.69.11\\/search\\/cache%3fei=UTF-8%26query=132%26output=json%26results=100%26appid=jennyhan_ac%26u=www.house.gov\\/judiciary_democrats\\/letters\\/rovehrgrequestltr71405.pdf%26w=132%26d=LPrB50aqMqRY%26icp=1%26.intl=us","Size":"381000"}},{"Title":"NC General Statutes Chapter 132","Summary":"North Carolina. State Public Records Law. North Carolina General Statutes. Chapter 132. Public Records. Last updated December 10th, 1999. Contents. Section Title. 132-1. \\"Public records\\" defined. 132-1.1. ... Section Title. 132-1. \\"Public records\\" defined. 132-1.1. Confidential communications by legal counsel to public board or agency; State tax ...","Url":"http:\\/\\/www.ah.dcr.state.nc.us\\/e-records\\/ncgs\\/ncgs132.htm","ClickUrl":"http:\\/\\/uk.wrs.yahoo.com\\/_ylt=A0Je5VwQjWVEsGcBCR7dmMwF;_ylu=X3oDMTEwMjJmbW84BGNvbG8DdwRsA1dTMQRwb3MDNjgEc2VjA3NyBHZ0aWQD\\/SIG=12ctoo16c\\/EXP=1147592336\\/**http%3a\\/\\/www.ah.dcr.state.nc.us\\/e-records\\/ncgs\\/ncgs132.htm","ModificationDate":953625600,"MimeType":"text\\/html","Cache":{"Url":"http:\\/\\/uk.wrs.yahoo.com\\/_ylt=A0Je5VwQjWVEsGcBDh7dmMwF;_ylu=X3oDMTBxYjJtcGphBGNvbG8DdwRwb3MDNjgEc2VjA3NyBHZ0aWQD\\/SIG=16t5vbni8\\/EXP=1147592336\\/**http%3a\\/\\/66.218.69.11\\/search\\/cache%3fei=UTF-8%26query=132%26output=json%26results=100%26appid=jennyhan_ac%26u=www.ah.dcr.state.nc.us\\/e-records\\/ncgs\\/ncgs132.htm%26w=132%26d=MyfGH0aqMwR0%26icp=1%26.intl=us","Size":"43695"}},{"Title":"Technical Introduction to CDMA","Summary":"Course 132. Technical. Introduction to CDMA. Technical. Introduction to CDMA. IS-95, CDMA2000 and a glimpse of 1xEV. February, 2005. 132 - 1. Technical Introduction to CDMA v4.0 (c) 2005 Scott Baxter. Course Outline. Basic CDMA Principles. Coding","Url":"http:\\/\\/www.howcdmaworks.com\\/intro\\/132v3.pdf","ClickUrl":"http:\\/\\/www.howcdmaworks.com\\/intro\\/132v3.pdf#search=\'\'","ModificationDate":1107590400,"MimeType":"application\\/pdf","Cache":{"Url":"http:\\/\\/uk.wrs.yahoo.com\\/_ylt=A0Je5VwQjWVEsGcBEx7dmMwF;_ylu=X3oDMTBxbTJnbmxhBGNvbG8DdwRwb3MDNjkEc2VjA3NyBHZ0aWQD\\/SIG=16ghr9cvr\\/EXP=1147592336\\/**http%3a\\/\\/66.218.69.11\\/search\\/cache%3fei=UTF-8%26query=132%26output=json%26results=100%26appid=jennyhan_ac%26u=www.howcdmaworks.com\\/intro\\/132v3.pdf%26w=132%26d=B6dAbEaqMu7t%26icp=1%26.intl=us","Size":"4342039"}},{"Title":"Thread Images Digitizing","Summary":"Free embroidery design. Specializes in providing custom quality embroidery designs to the professional embroiderer.","Url":"http:\\/\\/www.threadimages.com\\/","ClickUrl":"http:\\/\\/uk.wrs.yahoo.com\\/_ylt=A0Je5VwQjWVEsGcBFR7dmMwF;_ylu=X3oDMTEwMmI2cWQzBGNvbG8DdwRsA1dTMQRwb3MDNzAEc2VjA3NyBHZ0aWQD\\/SIG=11gsp7523\\/EXP=1147592336\\/**http%3a\\/\\/www.threadimages.com\\/","ModificationDate":1147158000,"MimeType":"text\\/html","Cache":{"Url":"http:\\/\\/uk.wrs.yahoo.com\\/_ylt=A0Je5VwQjWVEsGcBGx7dmMwF;_ylu=X3oDMTBxaml0dDF0BGNvbG8DdwRwb3MDNzAEc2VjA3NyBHZ0aWQD\\/SIG=161ukrsfh\\/EXP=1147592336\\/**http%3a\\/\\/66.218.69.11\\/search\\/cache%3fei=UTF-8%26query=132%26output=json%26results=100%26appid=jennyhan_ac%26u=www.threadimages.com\\/%26w=132%26d=BmPG10aqMwgW%26icp=1%26.intl=us","Size":"55861"}},{"Title":"Psalms Chapter 132:1-18.","Summary":"Read the Hebrew Transliteration Psalms 132:1-18 Online.","Url":"http:\\/\\/bibledbdata.org\\/onlinebibles\\/hebrew_translit\\/19_132.htm","ClickUrl":"http:\\/\\/uk.wrs.yahoo.com\\/_ylt=A0Je5VwQjWVEsGcBHR7dmMwF;_ylu=X3oDMTEwdXJnMnJuBGNvbG8DdwRsA1dTMQRwb3MDNzEEc2VjA3NyBHZ0aWQD\\/SIG=12i1mped7\\/EXP=1147592336\\/**http%3a\\/\\/bibledbdata.org\\/onlinebibles\\/hebrew_translit\\/19_132.htm","ModificationDate":1044172800,"MimeType":"text\\/html","Cache":{"Url":"http:\\/\\/uk.wrs.yahoo.com\\/_ylt=A0Je5VwQjWVEsGcBIh7dmMwF;_ylu=X3oDMTBxNmJocG1iBGNvbG8DdwRwb3MDNzEEc2VjA3NyBHZ0aWQD\\/SIG=173o8ajtj\\/EXP=1147592336\\/**http%3a\\/\\/66.218.69.11\\/search\\/cache%3fei=UTF-8%26query=132%26output=json%26results=100%26appid=jennyhan_ac%26u=bibledbdata.org\\/onlinebibles\\/hebrew_translit\\/19_132.htm%26w=132%26d=dfiAJkaqMi1u%26icp=1%26.intl=us","Size":"9706"}},{"Title":"PRC-132","Summary":"K6ERO Portable and pedestrian mobile amateur radio. PRC-132 &amp; M50B. To the left is a Loral Terracom M50B. made in 1988 Serial#19 . Its 10 inches tall. with out battery box or external power. box , 3.5 inches wide and 5.25 inches. deep, weight 6.9 lbs . ... The M50B is the early issue version of the. PRC-132 special operations HF Radio ...","Url":"http:\\/\\/www.muttmotorpool.com\\/PRC-132","ClickUrl":"http:\\/\\/uk.wrs.yahoo.com\\/_ylt=A0Je5VwQjWVEsGcBJB7dmMwF;_ylu=X3oDMTEwYm80YTY1BGNvbG8DdwRsA1dTMQRwb3MDNzIEc2VjA3NyBHZ0aWQD\\/SIG=11ou3h7bi\\/EXP=1147592336\\/**http%3a\\/\\/www.muttmotorpool.com\\/PRC-132","ModificationDate":1146294000,"MimeType":"text\\/html","Cache":{"Url":"http:\\/\\/uk.wrs.yahoo.com\\/_ylt=A0Je5VwQjWVEsGcBKR7dmMwF;_ylu=X3oDMTBxaDgzYWcxBGNvbG8DdwRwb3MDNzIEc2VjA3NyBHZ0aWQD\\/SIG=169r7ofhd\\/EXP=1147592336\\/**http%3a\\/\\/66.218.69.11\\/search\\/cache%3fei=UTF-8%26query=132%26output=json%26results=100%26appid=jennyhan_ac%26u=www.muttmotorpool.com\\/PRC-132%26w=132%26d=Utj0H0aqMs48%26icp=1%26.intl=us","Size":"19723"}},{"Title":"Firenze 132 \\/ 170","Summary":"Firenze 132 \\/ 170. Matte Presentation Paper. 132 gram 2-side coated. 170 gram single side coated. Magicl\\u00e9e\\u00ae Firenze 132 and Firenze 170 matte. papers are designed for poster applications and. have an impressive price performance ratio. The ... If using the 132 gram. paper for 2-sided imaging ink limit on ...","Url":"http:\\/\\/www.magicinkjet.com\\/client_data_pdf\\/guides\\/Firenze.pdf","ClickUrl":"http:\\/\\/www.magicinkjet.com\\/client_data_pdf\\/guides\\/Firenze.pdf#search=\'\'","ModificationDate":1081839600,"MimeType":"application\\/pdf","Cache":{"Url":"http:\\/\\/uk.wrs.yahoo.com\\/_ylt=A0Je5VwQjWVEsGcBLh7dmMwF;_ylu=X3oDMTBxbXY4b2luBGNvbG8DdwRwb3MDNzMEc2VjA3NyBHZ0aWQD\\/SIG=172sdum75\\/EXP=1147592336\\/**http%3a\\/\\/66.218.69.11\\/search\\/cache%3fei=UTF-8%26query=132%26output=json%26results=100%26appid=jennyhan_ac%26u=www.magicinkjet.com\\/client_data_pdf\\/guides\\/Firenze.pdf%26w=132%26d=Q4ILzEaqMh1n%26icp=1%26.intl=us","Size":"2152647"}},{"Title":"Museletter # 132 \\/ February 2003: The US and Eurasia: End Game for the Industrial Era?","Summary":"Defining democracy in the wake of the 2002 elections in the U.S.A..","Url":"http:\\/\\/www.museletter.com\\/archive\\/132.html","ClickUrl":"http:\\/\\/uk.wrs.yahoo.com\\/_ylt=A0Je5VwQjWVEsGcBMB7dmMwF;_ylu=X3oDMTEwNGRiZ3FjBGNvbG8DdwRsA1dTMQRwb3MDNzQEc2VjA3NyBHZ0aWQD\\/SIG=11upr7v32\\/EXP=1147592336\\/**http%3a\\/\\/www.museletter.com\\/archive\\/132.html","ModificationDate":1108540800,"MimeType":"text\\/html","Cache":{"Url":"http:\\/\\/uk.wrs.yahoo.com\\/_ylt=A0Je5VwQjWVEsGcBNR7dmMwF;_ylu=X3oDMTBxZTNpbG1nBGNvbG8DdwRwb3MDNzQEc2VjA3NyBHZ0aWQD\\/SIG=16fg9g4no\\/EXP=1147592336\\/**http%3a\\/\\/66.218.69.11\\/search\\/cache%3fei=UTF-8%26query=132%26output=json%26results=100%26appid=jennyhan_ac%26u=www.museletter.com\\/archive\\/132.html%26w=132%26d=SS0AQEaqMvuR%26icp=1%26.intl=us","Size":"47428"}},{"Title":"Downloaded 25 Oct 2002 to 132.66.16.12. Redistribution subject to AIP license or copyright, see http:\\/\\/ojps.aip.org\\/... ","Summary":"Downloaded 25 Oct 2002 to 132.66.16.12. Redistribution subject to AIP license or copyright, see http:\\/\\/ojps.aip.org\\/jcpo\\/jcpcr.jsp. Downloaded 25 Oct 2002 to 132.66.16.12.","Url":"http:\\/\\/star.tau.ac.il\\/~andelman\\/reprints\\/018_JCP_1987_86_3673.pdf","ClickUrl":"http:\\/\\/star.tau.ac.il\\/~andelman\\/reprints\\/018_JCP_1987_86_3673.pdf#search=\'\'","ModificationDate":1035529200,"MimeType":"application\\/pdf","Cache":{"Url":"http:\\/\\/uk.wrs.yahoo.com\\/_ylt=A0Je5VwQjWVEsGcBOh7dmMwF;_ylu=X3oDMTBxbGZmanU1BGNvbG8DdwRwb3MDNzUEc2VjA3NyBHZ0aWQD\\/SIG=17a4s312u\\/EXP=1147592336\\/**http%3a\\/\\/66.218.69.11\\/search\\/cache%3fei=UTF-8%26query=132%26output=json%26results=100%26appid=jennyhan_ac%26u=star.tau.ac.il\\/%257Eandelman\\/reprints\\/018_JCP_1987_86_3673.pdf%26w=132%26d=YANT3kaqMhfd%26icp=1%26.intl=us","Size":"1204421"}},{"Title":"Hepatitis B Virus: A Comprehensive Strategy for Eliminating Transmission in the United States Through Universal ... ","Summary":"Hepatitis B Virus: A Comprehensive Strategy for Eliminating Transmission in the United States Through Universal Childhood Vaccination: Recommendations of the Immunization Practices Advisory Committee (ACIP)","Url":"http:\\/\\/www.cdc.gov\\/mmwr\\/preview\\/mmwrhtml\\/00033405.htm","ClickUrl":"http:\\/\\/uk.wrs.yahoo.com\\/_ylt=A0Je5VwQjWVEsGcBPB7dmMwF;_ylu=X3oDMTEwb2NlbHRuBGNvbG8DdwRsA1dTMQRwb3MDNzYEc2VjA3NyBHZ0aWQD\\/SIG=129kdm2n4\\/EXP=1147592336\\/**http%3a\\/\\/www.cdc.gov\\/mmwr\\/preview\\/mmwrhtml\\/00033405.htm","ModificationDate":1139990400,"MimeType":"text\\/html","Cache":{"Url":"http:\\/\\/uk.wrs.yahoo.com\\/_ylt=A0Je5VwQjWVEsGcBQR7dmMwF;_ylu=X3oDMTBxZm44bG9sBGNvbG8DdwRwb3MDNzYEc2VjA3NyBHZ0aWQD\\/SIG=16qv48dkp\\/EXP=1147592336\\/**http%3a\\/\\/66.218.69.11\\/search\\/cache%3fei=UTF-8%26query=132%26output=json%26results=100%26appid=jennyhan_ac%26u=www.cdc.gov\\/mmwr\\/preview\\/mmwrhtml\\/00033405.htm%26w=132%26d=b-Kz6UaqMwIM%26icp=1%26.intl=us","Size":"87232"}},{"Title":"Tour de France 2005","Summary":"... QUICK STEP - INNERGETIC. 132 - CRETSKENS Wilfried (BEL) Born in 10\\/07\\/1976 \\u00e0 Herk-de-Stad (BEL ...","Url":"http:\\/\\/www.letour.fr\\/2005\\/TDF\\/RIDERS\\/us\\/coureurs\\/132.html","ClickUrl":"http:\\/\\/uk.wrs.yahoo.com\\/_ylt=A0Je5VwQjWVEsGcBQx7dmMwF;_ylu=X3oDMTEwYjdwazg2BGNvbG8DdwRsA1dTMQRwb3MDNzcEc2VjA3NyBHZ0aWQD\\/SIG=12dpjmcf6\\/EXP=1147592336\\/**http%3a\\/\\/www.letour.fr\\/2005\\/TDF\\/RIDERS\\/us\\/coureurs\\/132.html","ModificationDate":1121583600,"MimeType":"text\\/html","Cache":{"Url":"http:\\/\\/uk.wrs.yahoo.com\\/_ylt=A0Je5VwQjWVEsGcBSB7dmMwF;_ylu=X3oDMTBxa21laGFvBGNvbG8DdwRwb3MDNzcEc2VjA3NyBHZ0aWQD\\/SIG=16u0nn96f\\/EXP=1147592336\\/**http%3a\\/\\/66.218.69.11\\/search\\/cache%3fei=UTF-8%26query=132%26output=json%26results=100%26appid=jennyhan_ac%26u=www.letour.fr\\/2005\\/TDF\\/RIDERS\\/us\\/coureurs\\/132.html%26w=132%26d=BTTUC0aqMv4Z%26icp=1%26.intl=us","Size":"12171"}},{"Title":"This American Life | Father\'s Day \'99","Summary":"... 6\\/18\\/99. Episode 132. For Father\'s Day, stories about fathers going out of their way to protect their kids, and kids going ...","Url":"http:\\/\\/www.thisamericanlife.org\\/pages\\/descriptions\\/99\\/132.html","ClickUrl":"http:\\/\\/uk.wrs.yahoo.com\\/_ylt=A0Je5VwQjWVEsGcBSh7dmMwF;_ylu=X3oDMTEwNDFvam42BGNvbG8DdwRsA1dTMQRwb3MDNzgEc2VjA3NyBHZ0aWQD\\/SIG=12iobnkgv\\/EXP=1147592336\\/**http%3a\\/\\/www.thisamericanlife.org\\/pages\\/descriptions\\/99\\/132.html","ModificationDate":1146466800,"MimeType":"text\\/html","Cache":{"Url":"http:\\/\\/uk.wrs.yahoo.com\\/_ylt=A0Je5VwQjWVEsGcBTx7dmMwF;_ylu=X3oDMTBxZzFuNDV2BGNvbG8DdwRwb3MDNzgEc2VjA3NyBHZ0aWQD\\/SIG=1738d5fam\\/EXP=1147592336\\/**http%3a\\/\\/66.218.69.11\\/search\\/cache%3fei=UTF-8%26query=132%26output=json%26results=100%26appid=jennyhan_ac%26u=www.thisamericanlife.org\\/pages\\/descriptions\\/99\\/132.html%26w=132%26d=Ss_yvkaqMvWK%26icp=1%26.intl=us","Size":"8411"}},{"Title":"Downloaded 21 Jan 2004 to 132.66.16.34. Redistribution subject to AIP license or copyright, see http:\\/\\/ojps.aip.org\\/... ","Summary":"Downloaded 21 Jan 2004 to 132.66.16.34. Redistribution subject to AIP license or copyright, see http:\\/\\/ojps.aip.org\\/jcpo\\/jcpcr.jsp. Downloaded 21 Jan 2004 to 132.66.16.34.","Url":"http:\\/\\/femto.tau.ac.il\\/~nitzan\\/3.pdf","ClickUrl":"http:\\/\\/femto.tau.ac.il\\/~nitzan\\/3.pdf#search=\'\'","ModificationDate":1088665200,"MimeType":"application\\/pdf","Cache":{"Url":"http:\\/\\/uk.wrs.yahoo.com\\/_ylt=A0Je5VwQjWVEsGcBVB7dmMwF;_ylu=X3oDMTBxdXJmcnJsBGNvbG8DdwRwb3MDNzkEc2VjA3NyBHZ0aWQD\\/SIG=16da99c2u\\/EXP=1147592336\\/**http%3a\\/\\/66.218.69.11\\/search\\/cache%3fei=UTF-8%26query=132%26output=json%26results=100%26appid=jennyhan_ac%26u=femto.tau.ac.il\\/%257Enitzan\\/3.pdf%26w=132%26d=b5Br7UaqMjB1%26icp=1%26.intl=us","Size":"1071954"}},{"Title":"CHAPTER 12 ENVIRONMENTAL REVIEW \\u2013 EAST 132","Summary":"Solid Waste Management Plan. 12-1. October2004. DEIS. CHAPTER 12. ENVIRONMENTAL REVIEW \\u2013 EAST 132. ND. STREET SITE. 12.1 Introduction. The East 132. nd. Street Site is currently permitted to handle 2,999 tpd of putrescible waste, with a","Url":"http:\\/\\/www.nyc.gov\\/html\\/dsny\\/downloads\\/pdf\\/pubnrpts\\/swmp-4oct\\/deis\\/chapter12.pdf","ClickUrl":"http:\\/\\/www.nyc.gov\\/html\\/dsny\\/downloads\\/pdf\\/pubnrpts\\/swmp-4oct\\/deis\\/chapter12.pdf#search=\'\'","ModificationDate":1099555200,"MimeType":"application\\/pdf","Cache":{"Url":"http:\\/\\/uk.wrs.yahoo.com\\/_ylt=A0Je5VwQjWVEsGcBWR7dmMwF;_ylu=X3oDMTBxaHNlODZrBGNvbG8DdwRwb3MDODAEc2VjA3NyBHZ0aWQD\\/SIG=17llu5bkp\\/EXP=1147592336\\/**http%3a\\/\\/66.218.69.11\\/search\\/cache%3fei=UTF-8%26query=132%26output=json%26results=100%26appid=jennyhan_ac%26u=www.nyc.gov\\/html\\/dsny\\/downloads\\/pdf\\/pubnrpts\\/swmp-4oct\\/deis\\/chapter12.pdf%26w=132%26d=RPmqz0aqMiKh%26icp=1%26.intl=us","Size":"1417879"}},{"Title":"Psalms 132 \\/ Hebrew - English Bible \\/ Mechon-Mamre","Summary":"... 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 ... Psalms Chapter 132. \\u00e0 \\u00f9\\u00d1\\u00c4\\u00e9\\u00f8, \\u00e4\\u00c7\\u00ee\\u00cc\\u00c7\\u00f2\\u00c2\\u00ec\\u00e5\\u00c9\\u00fa ...","Url":"http:\\/\\/www.mechon-mamre.org\\/p\\/pt\\/pt26d2.htm","ClickUrl":"http:\\/\\/uk.wrs.yahoo.com\\/_ylt=A0Je5VwQjWVEsGcBWx7dmMwF;_ylu=X3oDMTEwc3RoZXBrBGNvbG8DdwRsA1dTMQRwb3MDODEEc2VjA3NyBHZ0aWQD\\/SIG=11vhbotpk\\/EXP=1147592336\\/**http%3a\\/\\/www.mechon-mamre.org\\/p\\/pt\\/pt26d2.htm","ModificationDate":1138694400,"MimeType":"text\\/html","Cache":{"Url":"http:\\/\\/uk.wrs.yahoo.com\\/_ylt=A0Je5VwQjWVEsGcBYB7dmMwF;_ylu=X3oDMTBxNjUwMGs2BGNvbG8DdwRwb3MDODEEc2VjA3NyBHZ0aWQD\\/SIG=16gg7tf89\\/EXP=1147592336\\/**http%3a\\/\\/66.218.69.11\\/search\\/cache%3fei=UTF-8%26query=132%26output=json%26results=100%26appid=jennyhan_ac%26u=www.mechon-mamre.org\\/p\\/pt\\/pt26d2.htm%26w=132%26d=WTHLVUaqMu6s%26icp=1%26.intl=us","Size":"13881"}},{"Title":"US CODE: Title 28,132. Creation and composition of district courts","Summary":"Creation and composition of district courts. Release date: 2005-09-29. (a) There shall be in each judicial district a district court which shall be a court of record known as the United States District Court for the district.","Url":"http:\\/\\/www4.law.cornell.edu\\/uscode\\/28\\/132.html","ClickUrl":"http:\\/\\/uk.wrs.yahoo.com\\/_ylt=A0Je5VwQjWVEsGcBYh7dmMwF;_ylu=X3oDMTEwcWlsMGMxBGNvbG8DdwRsA1dTMQRwb3MDODIEc2VjA3NyBHZ0aWQD\\/SIG=122ek55sr\\/EXP=1147592336\\/**http%3a\\/\\/www4.law.cornell.edu\\/uscode\\/28\\/132.html","ModificationDate":1143273600,"MimeType":"text\\/html","Cache":{"Url":"http:\\/\\/uk.wrs.yahoo.com\\/_ylt=A0Je5VwQjWVEsGcBZx7dmMwF;_ylu=X3oDMTBxYWs1NmFvBGNvbG8DdwRwb3MDODIEc2VjA3NyBHZ0aWQD\\/SIG=16jb47dcg\\/EXP=1147592336\\/**http%3a\\/\\/66.218.69.11\\/search\\/cache%3fei=UTF-8%26query=132%26output=json%26results=100%26appid=jennyhan_ac%26u=www4.law.cornell.edu\\/uscode\\/28\\/132.html%26w=132%26d=QQ2S7EaqMjbv%26icp=1%26.intl=us","Size":"9107"}},{"Title":"Fiscal Note","Summary":"... Bill, Resolutions and Memorial Documents. SB05-132 ... Final Act\\/ Resolutions or Memorial: 132_enr.pdfn. 132.enrn. Preamended Documents ...","Url":"http:\\/\\/www.leg.state.co.us\\/Clics2005a\\/csl.nsf\\/fsbillcont3\\/A4058D1E27570DC987256F7E0059EAA8?Open&file=132_enr.pdf","ClickUrl":"http:\\/\\/www.leg.state.co.us\\/Clics2005a\\/csl.nsf\\/fsbillcont3\\/A4058D1E27570DC987256F7E0059EAA8?Open&file=132_enr.pdf#search=\'\'","ModificationDate":1124521200,"MimeType":"application\\/pdf","Cache":{"Url":"http:\\/\\/uk.wrs.yahoo.com\\/_ylt=A0Je5VwQjWVEsGcBbB7dmMwF;_ylu=X3oDMTBxbGJmNjEwBGNvbG8DdwRwb3MDODMEc2VjA3NyBHZ0aWQD\\/SIG=191n41l4b\\/EXP=1147592336\\/**http%3a\\/\\/66.218.69.11\\/search\\/cache%3fei=UTF-8%26query=132%26output=json%26results=100%26appid=jennyhan_ac%26u=www.leg.state.co.us\\/Clics2005a\\/csl.nsf\\/fsbillcont3\\/A4058D1E27570DC987256F7E0059EAA8%253FOpen%2526file%253D132_enr.pdf%26w=132%26d=LViIXUaqMkKL%26icp=1%26.intl=us","Size":"87930"}},{"Title":"Development -- Table of Contents (January 1 2005, 132 [1])","Summary":"To see an article, click its [Full Text] link. To review many abstracts, check the boxes to the left of the titles you want, and click the \'Get All Checked Abstract(s)\' button. To see one abstract at a time, click its [Abstract] link.","Url":"http:\\/\\/dev.biologists.org\\/content\\/vol132\\/issue1","ClickUrl":"http:\\/\\/uk.wrs.yahoo.com\\/_ylt=A0Je5VwQjWVEsGcBbh7dmMwF;_ylu=X3oDMTEwdWdwcnIyBGNvbG8DdwRsA1dTMQRwb3MDODQEc2VjA3NyBHZ0aWQD\\/SIG=123019ojj\\/EXP=1147592336\\/**http%3a\\/\\/dev.biologists.org\\/content\\/vol132\\/issue1","ModificationDate":1147071600,"MimeType":"text\\/html","Cache":{"Url":"http:\\/\\/uk.wrs.yahoo.com\\/_ylt=A0Je5VwQjWVEsGcBcx7dmMwF;_ylu=X3oDMTBxczM2ZHFvBGNvbG8DdwRwb3MDODQEc2VjA3NyBHZ0aWQD\\/SIG=16kng2m03\\/EXP=1147592336\\/**http%3a\\/\\/66.218.69.11\\/search\\/cache%3fei=UTF-8%26query=132%26output=json%26results=100%26appid=jennyhan_ac%26u=dev.biologists.org\\/content\\/vol132\\/issue1%26w=132%26d=LFOVEUaqMwR5%26icp=1%26.intl=us","Size":"25711"}},{"Title":"Winter Carnival (1939)","Summary":"Winter Carnival - Cast, Crew, Reviews, Plot Summary, Comments, Discussion, Taglines, Trailers, Posters, Photos, Showtimes, Link to Official Site, Fan Sites","Url":"http:\\/\\/www.imdb.com\\/title\\/tt0032132\\/","ClickUrl":"http:\\/\\/uk.wrs.yahoo.com\\/_ylt=A0Je5VwQjWVEsGcBdR7dmMwF;_ylu=X3oDMTEwb3IzajNvBGNvbG8DdwRsA1dTMQRwb3MDODUEc2VjA3NyBHZ0aWQD\\/SIG=11o6bhdhm\\/EXP=1147592336\\/**http%3a\\/\\/www.imdb.com\\/title\\/tt0032132\\/","ModificationDate":1147417200,"MimeType":"text\\/html","Cache":{"Url":"http:\\/\\/uk.wrs.yahoo.com\\/_ylt=A0Je5VwQjWVEsGcBeh7dmMwF;_ylu=X3oDMTBxcG9jdDNjBGNvbG8DdwRwb3MDODUEc2VjA3NyBHZ0aWQD\\/SIG=1696d85k0\\/EXP=1147592336\\/**http%3a\\/\\/66.218.69.11\\/search\\/cache%3fei=UTF-8%26query=132%26output=json%26results=100%26appid=jennyhan_ac%26u=www.imdb.com\\/title\\/tt0032132\\/%26w=132%26d=OnC3HUaqMw5H%26icp=1%26.intl=us","Size":"44616"}},{"Title":"XM Radio - C-SPAN Radio","Summary":"... XM 132. &lt;Previous. Next ...","Url":"http:\\/\\/www.xmradio.com\\/programming\\/channel_page.jsp?ch=132","ClickUrl":"http:\\/\\/uk.wrs.yahoo.com\\/_ylt=A0Je5VwQjWVEsGcBfB7dmMwF;_ylu=X3oDMTEwa3RyODBuBGNvbG8DdwRsA1dTMQRwb3MDODYEc2VjA3NyBHZ0aWQD\\/SIG=12gtfnvt7\\/EXP=1147592336\\/**http%3a\\/\\/www.xmradio.com\\/programming\\/channel_page.jsp%3fch=132","ModificationDate":1147158000,"MimeType":"text\\/html","Cache":{"Url":"http:\\/\\/uk.wrs.yahoo.com\\/_ylt=A0Je5VwQjWVEsGcBgR7dmMwF;_ylu=X3oDMTBxN24xYzc0BGNvbG8DdwRwb3MDODYEc2VjA3NyBHZ0aWQD\\/SIG=1774en6i4\\/EXP=1147592336\\/**http%3a\\/\\/66.218.69.11\\/search\\/cache%3fei=UTF-8%26query=132%26output=json%26results=100%26appid=jennyhan_ac%26u=www.xmradio.com\\/programming\\/channel_page.jsp%253Fch%253D132%26w=132%26d=WS_5a0aqMwE5%26icp=1%26.intl=us","Size":"23601"}},{"Title":"Al-Qaeda tape says bin Laden alive, urges Iraqis to fight - theage.com.au","Summary":"Arabic television channel Al Arabiya has aired what it says is an audiotape from an al-Qaeda spokesman who says Osama bin Laden is alive and well. - The Age","Url":"http:\\/\\/www.theage.com.au\\/articles\\/2003\\/08\\/18\\/1061059775995.html","ClickUrl":"http:\\/\\/uk.wrs.yahoo.com\\/_ylt=A0Je5VwQjWVEsGcBgx7dmMwF;_ylu=X3oDMTEwNXU4aDFlBGNvbG8DdwRsA1dTMQRwb3MDODcEc2VjA3NyBHZ0aWQD\\/SIG=12jscc3ng\\/EXP=1147592336\\/**http%3a\\/\\/www.theage.com.au\\/articles\\/2003\\/08\\/18\\/1061059775995.html","ModificationDate":1147158000,"MimeType":"text\\/html","Cache":{"Url":"http:\\/\\/uk.wrs.yahoo.com\\/_ylt=A0Je5VwQjWVEsGcBiB7dmMwF;_ylu=X3oDMTBxZjFrNnYwBGNvbG8DdwRwb3MDODcEc2VjA3NyBHZ0aWQD\\/SIG=174fs4fo6\\/EXP=1147592336\\/**http%3a\\/\\/66.218.69.11\\/search\\/cache%3fei=UTF-8%26query=132%26output=json%26results=100%26appid=jennyhan_ac%26u=www.theage.com.au\\/articles\\/2003\\/08\\/18\\/1061059775995.html%26w=132%26d=VUVD3UaqMwJD%26icp=1%26.intl=us","Size":"25163"}},{"Title":"Psalms 132","Summary":"Psalms 132. 132:1. Lord, remember David, and all his afflictions: 132:2. How he sware unto the LORD, and vowed unto the mighty God of Jacob; 132:3 ... Psalms 132. Chapters: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 ... 132:3. Surely I will not come into the tabernacle of my ...","Url":"http:\\/\\/www.maitreg.com\\/bible\\/view.asp?book=38&chapter=132","ClickUrl":"http:\\/\\/uk.wrs.yahoo.com\\/_ylt=A0Je5VwQjWVEsGcBih7dmMwF;_ylu=X3oDMTEwZjVxcHI4BGNvbG8DdwRsA1dTMQRwb3MDODgEc2VjA3NyBHZ0aWQD\\/SIG=12hild8td\\/EXP=1147592336\\/**http%3a\\/\\/www.maitreg.com\\/bible\\/view.asp%3fbook=38%26chapter=132","ModificationDate":1117609200,"MimeType":"text\\/html","Cache":{"Url":"http:\\/\\/uk.wrs.yahoo.com\\/_ylt=A0Je5VwQjWVEsGcBjx7dmMwF;_ylu=X3oDMTBxb2JpMW5pBGNvbG8DdwRwb3MDODgEc2VjA3NyBHZ0aWQD\\/SIG=17elhve1h\\/EXP=1147592336\\/**http%3a\\/\\/66.218.69.11\\/search\\/cache%3fei=UTF-8%26query=132%26output=json%26results=100%26appid=jennyhan_ac%26u=www.maitreg.com\\/bible\\/view.asp%253Fbook%253D38%2526chapter%253D132%26w=132%26d=TMHn-UaqMjbU%26icp=1%26.intl=us","Size":"27216"}},{"Title":"132","Summary":"35 U.S.C. 132 Notice of rejection; reexamination. - Patent Laws. 35 U.S.C. 132 Notice of rejection; reexamination.","Url":"http:\\/\\/www.uspto.gov\\/web\\/offices\\/pac\\/mpep\\/documents\\/appxl_35_U_S_C_132.htm","ClickUrl":"http:\\/\\/uk.wrs.yahoo.com\\/_ylt=A0Je5VwQjWVEsGcBkR7dmMwF;_ylu=X3oDMTEwNTA2aTh1BGNvbG8DdwRsA1dTMQRwb3MDODkEc2VjA3NyBHZ0aWQD\\/SIG=12ucmimjn\\/EXP=1147592336\\/**http%3a\\/\\/www.uspto.gov\\/web\\/offices\\/pac\\/mpep\\/documents\\/appxl_35_U_S_C_132.htm","ModificationDate":1133942400,"MimeType":"text\\/html","Cache":{"Url":"http:\\/\\/uk.wrs.yahoo.com\\/_ylt=A0Je5VwQjWVEsGcBlh7dmMwF;_ylu=X3oDMTBxNmVndjYxBGNvbG8DdwRwb3MDODkEc2VjA3NyBHZ0aWQD\\/SIG=17f2jjpsh\\/EXP=1147592336\\/**http%3a\\/\\/66.218.69.11\\/search\\/cache%3fei=UTF-8%26query=132%26output=json%26results=100%26appid=jennyhan_ac%26u=www.uspto.gov\\/web\\/offices\\/pac\\/mpep\\/documents\\/appxl_35_U_S_C_132.htm%26w=132%26d=Nil-N0aqMjBx%26icp=1%26.intl=us","Size":"8182"}},{"Title":"A CONCISE SUMMARY OF THE PUBLIC HEARINGS","Summary":"... hearing on Bill 132. It shows you who was for, who was ... Opposes BSL, pointed out many anomalies in Bill 132, for example you can\'t teach a pit bull to ...","Url":"http:\\/\\/www.dogwatch.net\\/bill132.pdf","ClickUrl":"http:\\/\\/www.dogwatch.net\\/bill132.pdf#search=\'\'","ModificationDate":1109232000,"MimeType":"application\\/pdf","Cache":{"Url":"http:\\/\\/uk.wrs.yahoo.com\\/_ylt=A0Je5VwQjWVEsGcBmx7dmMwF;_ylu=X3oDMTBxZ2gwNnM2BGNvbG8DdwRwb3MDOTAEc2VjA3NyBHZ0aWQD\\/SIG=168j23ta7\\/EXP=1147592336\\/**http%3a\\/\\/66.218.69.11\\/search\\/cache%3fei=UTF-8%26query=132%26output=json%26results=100%26appid=jennyhan_ac%26u=www.dogwatch.net\\/bill132.pdf%26w=132%26d=PkjRQEaqMuwO%26icp=1%26.intl=us","Size":"1982792"}},{"Title":"JPL News -- A Galaxy Far, Far Away Eyed by Linked Hawaiian Telescopes","Summary":"... Keck Observatory, Kamuela, Hawaii. 2003-132. Site Manager: Webmasters ...","Url":"http:\\/\\/www.jpl.nasa.gov\\/releases\\/2003\\/132.cfm","ClickUrl":"http:\\/\\/uk.wrs.yahoo.com\\/_ylt=A0Je5VwQjWVEsGcBnR7dmMwF;_ylu=X3oDMTEwaTAxcXV0BGNvbG8DdwRsA1dTMQRwb3MDOTEEc2VjA3NyBHZ0aWQD\\/SIG=12170u1vu\\/EXP=1147592336\\/**http%3a\\/\\/www.jpl.nasa.gov\\/releases\\/2003\\/132.cfm","ModificationDate":1136016000,"MimeType":"text\\/html","Cache":{"Url":"http:\\/\\/uk.wrs.yahoo.com\\/_ylt=A0Je5VwQjWVEsGcBoh7dmMwF;_ylu=X3oDMTBxanNkbHBvBGNvbG8DdwRwb3MDOTEEc2VjA3NyBHZ0aWQD\\/SIG=16i2p31tn\\/EXP=1147592336\\/**http%3a\\/\\/66.218.69.11\\/search\\/cache%3fei=UTF-8%26query=132%26output=json%26results=100%26appid=jennyhan_ac%26u=www.jpl.nasa.gov\\/releases\\/2003\\/132.cfm%26w=132%26d=VNPrSUaqMkiG%26icp=1%26.intl=us","Size":"22198"}},{"Title":"(132) Justinian I","Summary":"(132) Justinian I - AV solidus, A.D. 527-545, 4.45 g. ( inv. 91.270). Obverse: Facing helmeted and cuirassed bust of Justinian, holding globus cruciger in r.; at l.","Url":"http:\\/\\/www.lawrence.edu\\/dept\\/art\\/buerger\\/catalogue\\/132.html","ClickUrl":"http:\\/\\/uk.wrs.yahoo.com\\/_ylt=A0Je5VwQjWVEsGcBpB7dmMwF;_ylu=X3oDMTEwamM1Y3A2BGNvbG8DdwRsA1dTMQRwb3MDOTIEc2VjA3NyBHZ0aWQD\\/SIG=12f6r1r1h\\/EXP=1147592336\\/**http%3a\\/\\/www.lawrence.edu\\/dept\\/art\\/buerger\\/catalogue\\/132.html","ModificationDate":1006848000,"MimeType":"text\\/html","Cache":{"Url":"http:\\/\\/uk.wrs.yahoo.com\\/_ylt=A0Je5VwQjWVEsGcBqR7dmMwF;_ylu=X3oDMTBxZWNpdmpnBGNvbG8DdwRwb3MDOTIEc2VjA3NyBHZ0aWQD\\/SIG=1709bh559\\/EXP=1147592336\\/**http%3a\\/\\/66.218.69.11\\/search\\/cache%3fei=UTF-8%26query=132%26output=json%26results=100%26appid=jennyhan_ac%26u=www.lawrence.edu\\/dept\\/art\\/buerger\\/catalogue\\/132.html%26w=132%26d=BJJDnkaqMjfk%26icp=1%26.intl=us","Size":"3186"}},{"Title":"131","Summary":"35 U.S.C. 131 Examination of application. - Patent Laws. 35 U.S.C. 131 Examination of application.","Url":"http:\\/\\/www.uspto.gov\\/web\\/offices\\/pac\\/mpep\\/documents\\/appxl_35_U_S_C_131.htm","ClickUrl":"http:\\/\\/uk.wrs.yahoo.com\\/_ylt=A0Je5VwQjWVEsGcBqx7dmMwF;_ylu=X3oDMTEwdDUzZHBhBGNvbG8DdwRsA1dTMQRwb3MDOTMEc2VjA3NyBHZ0aWQD\\/SIG=12u6cdfcn\\/EXP=1147592336\\/**http%3a\\/\\/www.uspto.gov\\/web\\/offices\\/pac\\/mpep\\/documents\\/appxl_35_U_S_C_131.htm","ModificationDate":1133942400,"MimeType":"text\\/html","Cache":{"Url":"http:\\/\\/uk.wrs.yahoo.com\\/_ylt=A0Je5VwQjWVEsGcBsB7dmMwF;_ylu=X3oDMTBxdXZhZWxkBGNvbG8DdwRwb3MDOTMEc2VjA3NyBHZ0aWQD\\/SIG=17f8j8d98\\/EXP=1147592336\\/**http%3a\\/\\/66.218.69.11\\/search\\/cache%3fei=UTF-8%26query=132%26output=json%26results=100%26appid=jennyhan_ac%26u=www.uspto.gov\\/web\\/offices\\/pac\\/mpep\\/documents\\/appxl_35_U_S_C_131.htm%26w=132%26d=R2aGhUaqMj30%26icp=1%26.intl=us","Size":"7341"}},{"Title":"132 on Flickr - Photo Sharing!","Summary":"... 132. To take full advantage of Flickr, you should use a JavaScript-enabled browser and ...","Url":"http:\\/\\/www.flickr.com\\/photos\\/brettsky\\/53839790\\/","ClickUrl":"http:\\/\\/uk.wrs.yahoo.com\\/_ylt=A0Je5VwQjWVEsGcBsh7dmMwF;_ylu=X3oDMTEwZ2lxZDhhBGNvbG8DdwRsA1dTMQRwb3MDOTQEc2VjA3NyBHZ0aWQD\\/SIG=123ojcbf0\\/EXP=1147592336\\/**http%3a\\/\\/www.flickr.com\\/photos\\/brettsky\\/53839790\\/","ModificationDate":1145862000,"MimeType":"text\\/html","Cache":{"Url":"http:\\/\\/uk.wrs.yahoo.com\\/_ylt=A0Je5VwQjWVEsGcBtx7dmMwF;_ylu=X3oDMTBxYTJvNGFhBGNvbG8DdwRwb3MDOTQEc2VjA3NyBHZ0aWQD\\/SIG=16ks6e563\\/EXP=1147592336\\/**http%3a\\/\\/66.218.69.11\\/search\\/cache%3fei=UTF-8%26query=132%26output=json%26results=100%26appid=jennyhan_ac%26u=www.flickr.com\\/photos\\/brettsky\\/53839790\\/%26w=132%26d=GA_4oEaqMq4P%26icp=1%26.intl=us","Size":"74392"}},{"Title":"Ag GPS 124 \\/ 132","Summary":"AgGPS 124 \\/ 132. Operation Manual. AgGPS Receiver Firmware Version 1.40, 1.41 and 1.42. Part Number 38747-00-ENG. Revision C. September 2000. T. Support Offices. Trimble Precision Agricultural Systems. 9290 Bond Street, Suite 102. Overland Park, KS 66214 U.S.A. ... describes how to install and configure the AgGPS_ 124, 132, and 132. Air receivers ...","Url":"http:\\/\\/www.linco.com\\/AG124132REVB.PDF","ClickUrl":"http:\\/\\/www.linco.com\\/AG124132REVB.PDF#search=\'\'","ModificationDate":986281200,"MimeType":"application\\/pdf","Cache":{"Url":"http:\\/\\/uk.wrs.yahoo.com\\/_ylt=A0Je5VwQjWVEsGcBvB7dmMwF;_ylu=X3oDMTBxbDgxOWxkBGNvbG8DdwRwb3MDOTUEc2VjA3NyBHZ0aWQD\\/SIG=16ajtq3hk\\/EXP=1147592336\\/**http%3a\\/\\/66.218.69.11\\/search\\/cache%3fei=UTF-8%26query=132%26output=json%26results=100%26appid=jennyhan_ac%26u=www.linco.com\\/AG124132REVB.PDF%26w=132%26d=FCohUkaqMjOV%26icp=1%26.intl=us","Size":"3610097"}},{"Title":"Tehillim - Chapter 132 | Chabad.org","Summary":"Please login for more site features. Tehillim - Chapter 132. 1. A song of ascents. Remember, O Lord, onto David all his affliction. 2. That he swore to the Lord, he vowed to the Mighty One of Jacob; ... Chabad.org \\" Library \\" Classic Texts \\" The Bible (with Rashi) \\" K\'tuvim \\" Tehillim \\" Chapter 132 ...","Url":"http:\\/\\/www.chabad.org\\/library\\/article.asp?AID=16353","ClickUrl":"http:\\/\\/uk.wrs.yahoo.com\\/_ylt=A0Je5VwQjWVEsGcBvh7dmMwF;_ylu=X3oDMTEwam44NW9vBGNvbG8DdwRsA1dTMQRwb3MDOTYEc2VjA3NyBHZ0aWQD\\/SIG=129b821nj\\/EXP=1147592336\\/**http%3a\\/\\/www.chabad.org\\/library\\/article.asp%3fAID=16353","ModificationDate":1146898800,"MimeType":"text\\/html","Cache":{"Url":"http:\\/\\/uk.wrs.yahoo.com\\/_ylt=A0Je5VwQjWVEsGcBwx7dmMwF;_ylu=X3oDMTBxczRxYWlqBGNvbG8DdwRwb3MDOTYEc2VjA3NyBHZ0aWQD\\/SIG=170gmib5a\\/EXP=1147592336\\/**http%3a\\/\\/66.218.69.11\\/search\\/cache%3fei=UTF-8%26query=132%26output=json%26results=100%26appid=jennyhan_ac%26u=www.chabad.org\\/library\\/article.asp%253FAID%253D16353%26w=132%26d=I-adaEaqMvld%26icp=1%26.intl=us","Size":"41051"}},{"Title":"Downloaded 19 Jan 2003 to 132.77.4.43. Redistribution subject to AIP license or copyright, see http:\\/\\/ojps.aip.org\\/... ","Summary":"Downloaded 19 Jan 2003 to 132.77.4.43. Redistribution subject to AIP license or copyright, see http:\\/\\/ojps.aip.org\\/jcpo\\/jcpcr.jsp. Downloaded 19 Jan 2003 to 132.77.4.43.","Url":"http:\\/\\/www.weizmann.ac.il\\/chemphys\\/Frydman_group\\/Publications\\/ExchDynamics-JCP90.pdf","ClickUrl":"http:\\/\\/www.weizmann.ac.il\\/chemphys\\/Frydman_group\\/Publications\\/ExchDynamics-JCP90.pdf#search=\'\'","ModificationDate":1061622000,"MimeType":"application\\/pdf","Cache":{"Url":"http:\\/\\/uk.wrs.yahoo.com\\/_ylt=A0Je5VwQjWVEsGcByB7dmMwF;_ylu=X3oDMTBxZGVwcTFiBGNvbG8DdwRwb3MDOTcEc2VjA3NyBHZ0aWQD\\/SIG=17p1893is\\/EXP=1147592336\\/**http%3a\\/\\/66.218.69.11\\/search\\/cache%3fei=UTF-8%26query=132%26output=json%26results=100%26appid=jennyhan_ac%26u=www.weizmann.ac.il\\/chemphys\\/Frydman_group\\/Publications\\/ExchDynamics-JCP90.pdf%26w=132%26d=KPVdS0aqMkW1%26icp=1%26.intl=us","Size":"816603"}},{"Title":"Downloaded 19 May 2003 to 132.77.4.43. Redistribution subject to AIP license or copyright, see http:\\/\\/ojps.aip.org\\/... ","Summary":"Downloaded 19 May 2003 to 132.77.4.43. Redistribution subject to AIP license or copyright, see http:\\/\\/ojps.aip.org\\/japo\\/japcr.jsp. Downloaded 19 May 2003 to 132.77.4.43.","Url":"http:\\/\\/www.weizmann.ac.il\\/wagner\\/COURSES\\/Reading%20material%20(papers)\\/030_JAP_1990_ContactAngle.pdf","ClickUrl":"http:\\/\\/www.weizmann.ac.il\\/wagner\\/COURSES\\/Reading%20material%20(papers)\\/030_JAP_1990_ContactAngle.pdf#search=\'\'","ModificationDate":1136880000,"MimeType":"application\\/pdf","Cache":{"Url":"http:\\/\\/uk.wrs.yahoo.com\\/_ylt=A0Je5VwQjWVEsGcBzR7dmMwF;_ylu=X3oDMTBxMjBxZ2VoBGNvbG8DdwRwb3MDOTgEc2VjA3NyBHZ0aWQD\\/SIG=18pfdig62\\/EXP=1147592336\\/**http%3a\\/\\/66.218.69.11\\/search\\/cache%3fei=UTF-8%26query=132%26output=json%26results=100%26appid=jennyhan_ac%26u=www.weizmann.ac.il\\/wagner\\/COURSES\\/Reading%252520material%252520%2528papers%2529\\/030_JAP_1990_ContactAngle.pdf%26w=132%26d=Nf5MWEaqMkV0%26icp=1%26.intl=us","Size":"784314"}},{"Title":"Downloaded 24 Jul 2002 to 132.163.135.12. Redistribution subject to AIP license or copyright, see http:\\/\\/ojps.aip... ","Summary":"Downloaded 24 Jul 2002 to 132.163.135.12. Redistribution subject to AIP license or copyright, see http:\\/\\/ojps.aip.org\\/japo\\/japcr.jsp. Downloaded 24 Jul 2002 to 132.163.135.12.","Url":"http:\\/\\/tf.nist.gov\\/general\\/pdf\\/569.pdf","ClickUrl":"http:\\/\\/tf.nist.gov\\/general\\/pdf\\/569.pdf#search=\'\'","ModificationDate":1027494000,"MimeType":"application\\/pdf","Cache":{"Url":"http:\\/\\/uk.wrs.yahoo.com\\/_ylt=A0Je5VwQjWVEsGcB0h7dmMwF;_ylu=X3oDMTBxNmJhcjNhBGNvbG8DdwRwb3MDOTkEc2VjA3NyBHZ0aWQD\\/SIG=16b31en6n\\/EXP=1147592336\\/**http%3a\\/\\/66.218.69.11\\/search\\/cache%3fei=UTF-8%26query=132%26output=json%26results=100%26appid=jennyhan_ac%26u=tf.nist.gov\\/general\\/pdf\\/569.pdf%26w=132%26d=IpdTwEaqMirR%26icp=1%26.intl=us","Size":"1002734"}},{"Title":"[DB] naruto 132","Summary":"","Url":"http:\\/\\/yhbt.mine.nu\\/t\\/n132.torrent","ClickUrl":"http:\\/\\/uk.wrs.yahoo.com\\/_ylt=A0Je5VwQjWVEsGcB1B7dmMwF;_ylu=X3oDMTExaW11dG45BGNvbG8DdwRsA1dTMQRwb3MDMTAwBHNlYwNzcgR2dGlkAw--\\/SIG=11m58k4sj\\/EXP=1147592336\\/**http%3a\\/\\/yhbt.mine.nu\\/t\\/n132.torrent","ModificationDate":1114671600,"MimeType":"unknown"}]}}');
+
+  assertEquals(result.groupCount + 1, 5);
+}
diff --git a/tests/corelib/regexp/standalones_test.dart b/tests/corelib/regexp/standalones_test.dart
new file mode 100644
index 0000000..bdc0481
--- /dev/null
+++ b/tests/corelib/regexp/standalones_test.dart
@@ -0,0 +1,84 @@
+// Copyright (c) 2014, the Dart project authors. All rights reserved.
+// Copyright 2008 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+//       copyright notice, this list of conditions and the following
+//       disclaimer in the documentation and/or other materials provided
+//       with the distribution.
+//     * Neither the name of Google Inc. nor the names of its
+//       contributors may be used to endorse or promote products derived
+//       from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+import 'v8_regexp_utils.dart';
+import 'package:expect/expect.dart';
+
+void main() {
+  /* Many of the Mozilla regexp tests used 'toSource' to test their
+  * results.  Since we don't currently support toSource, those tests
+  * are disabled and standalone versions are included here.
+  */
+
+  // Tests from ecma_3/RegExp/regress-78156.js
+  var string = 'aaa\n789\r\nccc\r\n345';
+  var pattern = new RegExp(r"^\d", multiLine: true);
+  var result = pattern.allMatches(string).toList();
+  assertEquals(2, result.length, "1");
+  assertEquals('7', result[0].group(0), "2");
+  assertEquals('3', result[1].group(0), "3");
+
+  pattern = new RegExp(r"\d$", multiLine: true);
+  result = pattern.allMatches(string).toList();
+  assertEquals(2, result.length, "4");
+  assertEquals('9', result[0].group(0), "5");
+  assertEquals('5', result[1].group(0), "6");
+
+  string = 'aaa\n789\r\nccc\r\nddd';
+  pattern = new RegExp(r"^\d", multiLine: true);
+  result = pattern.allMatches(string).toList();
+  assertEquals(1, result.length, "7");
+  assertEquals('7', result[0].group(0), "8");
+
+  pattern = new RegExp(r"\d$", multiLine: true);
+  result = pattern.allMatches(string).toList();
+  assertEquals(1, result.length, "9");
+  assertEquals('9', result[0].group(0), "10");
+
+  // Tests from ecma_3/RegExp/regress-72964.js
+  pattern = new RegExp(r"[\S]+");
+  string = '\u00BF\u00CD\u00BB\u00A7';
+  result = pattern.firstMatch(string);
+  assertEquals(1, result.groupCount + 1, "11");
+  assertEquals(string, result.group(0), "12");
+
+  string = '\u00BF\u00CD \u00BB\u00A7';
+  result = pattern.firstMatch(string);
+  assertEquals(1, result.groupCount + 1, "13");
+  assertEquals('\u00BF\u00CD', result.group(0), "14");
+
+  string = '\u4e00\uac00\u4e03\u4e00';
+  result = pattern.firstMatch(string);
+  assertEquals(1, result.groupCount + 1, "15");
+  assertEquals(string, result.group(0), "16");
+
+  string = '\u4e00\uac00 \u4e03\u4e00';
+  result = pattern.firstMatch(string);
+  assertEquals(1, result.groupCount + 1, "17");
+  assertEquals('\u4e00\uac00', result.group(0), "18");
+}
diff --git a/tests/corelib/regexp/toString_test.dart b/tests/corelib/regexp/toString_test.dart
new file mode 100644
index 0000000..0f9ea60
--- /dev/null
+++ b/tests/corelib/regexp/toString_test.dart
@@ -0,0 +1,70 @@
+// Copyright (c) 2014, the Dart project authors. All rights reserved.
+// Copyright 2013 the V8 project authors. All rights reserved.
+// Copyright (C) 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1.  Redistributions of source code must retain the above copyright
+//     notice, this list of conditions and the following disclaimer.
+// 2.  Redistributions in binary form must reproduce the above copyright
+//     notice, this list of conditions and the following disclaimer in the
+//     documentation and/or other materials provided with the distribution.
+//
+// THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
+// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+import 'v8_regexp_utils.dart';
+import 'package:expect/expect.dart';
+
+void main() {
+  dynamic testForwardSlash(pattern, _string)
+  {
+      var string = _string;
+
+      var re1 = new RegExp(pattern);
+
+      return re1.hasMatch(string);
+  }
+
+  dynamic testLineTerminator(pattern)
+  {
+      var re1 = new RegExp(pattern);
+
+      return new RegExp(r"\n|\r|\u2028|\u2029").hasMatch(re1.toString());
+  }
+
+  // These strings are equivalent, since the '\' is identity escaping the '/' at the string level.
+  shouldBeTrue(testForwardSlash("^/\$", "/"));
+  shouldBeTrue(testForwardSlash("^\/\$", "/"));
+  // This string passes "^\/$" to the RegExp, so the '/' is escaped in the re!
+  shouldBeTrue(testForwardSlash("^\\/\$", "/"));
+  // These strings pass "^\\/$" and "^\\\/$" respectively to the RegExp, giving one '\' to match.
+  shouldBeTrue(testForwardSlash("^\\\\/\$", "\\/"));
+  shouldBeTrue(testForwardSlash("^\\\\\\/\$", "\\/"));
+  // These strings match two backslashes (the second with the '/' escaped).
+  shouldBeTrue(testForwardSlash("^\\\\\\\\/\$", "\\\\/"));
+  shouldBeTrue(testForwardSlash("^\\\\\\\\\\/\$", "\\\\/"));
+  // Test that nothing goes wrongif there are multiple forward slashes!
+  shouldBeTrue(testForwardSlash("x/x/x", "x/x/x"));
+  shouldBeTrue(testForwardSlash("x\\/x/x", "x/x/x"));
+  shouldBeTrue(testForwardSlash("x/x\\/x", "x/x/x"));
+  shouldBeTrue(testForwardSlash("x\\/x\\/x", "x/x/x"));
+
+  shouldBeFalse(testLineTerminator("\\n"));
+  shouldBeFalse(testLineTerminator("\\\\n"));
+  shouldBeFalse(testLineTerminator("\\r"));
+  shouldBeFalse(testLineTerminator("\\\\r"));
+  shouldBeFalse(testLineTerminator("\\u2028"));
+  shouldBeFalse(testLineTerminator("\\\\u2028"));
+  shouldBeFalse(testLineTerminator("\\u2029"));
+  shouldBeFalse(testLineTerminator("\\\\u2029"));
+}
diff --git a/tests/corelib/regexp/unicode-handling_test.dart b/tests/corelib/regexp/unicode-handling_test.dart
new file mode 100644
index 0000000..8874135
--- /dev/null
+++ b/tests/corelib/regexp/unicode-handling_test.dart
@@ -0,0 +1,75 @@
+// Copyright (c) 2014, the Dart project authors. All rights reserved.
+// Copyright 2013 the V8 project authors. All rights reserved.
+// Copyright (C) 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1.  Redistributions of source code must retain the above copyright
+//     notice, this list of conditions and the following disclaimer.
+// 2.  Redistributions in binary form must reproduce the above copyright
+//     notice, this list of conditions and the following disclaimer in the
+//     documentation and/or other materials provided with the distribution.
+//
+// THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
+// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+import 'v8_regexp_utils.dart';
+import 'package:expect/expect.dart';
+
+void main() {
+  description(
+  'Test for proper handling of Unicode RegExps and <a href="http://bugzilla.webkit.org/show_bug.cgi?id=7445">bug 7445</a>: Gmail puts wrong subject in replies.'
+  );
+
+  // Regex to match Re in various languanges straight from Gmail source
+  var I3=new RegExp(r"^\s*(fwd|re|aw|antw|antwort|wg|sv|ang|odp|betreff|betr|transf|reenv\.|reenv|in|res|resp|resp\.|enc|\u8f6c\u53d1|\u56DE\u590D|\u041F\u0435\u0440\u0435\u0441\u043B|\u041E\u0442\u0432\u0435\u0442):\s*(.*)$", caseSensitive: false);
+
+  // Other RegExs from Gmail source
+  var Ci=new RegExp(r"\s+");
+  var BC=new RegExp(r"^ ");
+  var BG=new RegExp(r" $");
+
+  // This function replaces consecutive whitespace with a single space
+  // then removes a leading and trailing space if they exist. (From Gmail)
+  dynamic Gn(a) {
+      return a.replaceAll(Ci, " ").replaceAll(BC, "").replaceAll(BG, "");
+  }
+
+  // Strips leading Re or similar (from Gmail source)
+  dynamic cy(a) {
+      //var b = I3.firstMatch(a);
+      var b = I3.firstMatch(a);
+
+      if (b != null) {
+          a = b.group(2);
+      }
+
+      return Gn(a);
+  }
+
+  assertEquals(cy('Re: Moose'), 'Moose');
+  assertEquals(cy('\u8f6c\u53d1: Moose'), 'Moose');
+
+  // Test handling of \u2820 (skull and crossbones)
+  var sample="sample bm\u2820p cm\\u2820p";
+
+  var inlineRe=new RegExp(r".m\u2820p");
+  assertEquals(inlineRe.firstMatch(sample).group(0), 'bm\u2820p');
+
+
+  // Test handling of \u007c "|"
+  var bsample="sample bm\u007cp cm\\u007cp";
+
+  var binlineRe=new RegExp(r".m\u007cp");
+
+  assertEquals(binlineRe.firstMatch(bsample).group(0), 'bm|p');
+}
diff --git a/tests/corelib/regexp/unicodeCaseInsensitive_test.dart b/tests/corelib/regexp/unicodeCaseInsensitive_test.dart
new file mode 100644
index 0000000..44eb86e
--- /dev/null
+++ b/tests/corelib/regexp/unicodeCaseInsensitive_test.dart
@@ -0,0 +1,99 @@
+// Copyright (c) 2014, the Dart project authors. All rights reserved.
+// Copyright 2013 the V8 project authors. All rights reserved.
+// Copyright (C) 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1.  Redistributions of source code must retain the above copyright
+//     notice, this list of conditions and the following disclaimer.
+// 2.  Redistributions in binary form must reproduce the above copyright
+//     notice, this list of conditions and the following disclaimer in the
+//     documentation and/or other materials provided with the distribution.
+//
+// THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
+// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+import 'v8_regexp_utils.dart';
+import 'package:expect/expect.dart';
+
+void main() {
+  shouldBeTrue(new RegExp(r"ΣΤΙΓΜΑΣ", caseSensitive: false).hasMatch("στιγμας"));
+  shouldBeTrue(new RegExp(r"ΔΣΔ", caseSensitive: false).hasMatch("δςδ"));
+  shouldBeTrue(new RegExp(r"ς", caseSensitive: false).hasMatch("σ"));
+  shouldBeTrue(new RegExp(r"σ", caseSensitive: false).hasMatch("ς"));
+
+  // Simple case, has no canonical equivalents
+  shouldBeTrue(new RegExp(r"\u1f16", caseSensitive: false).hasMatch("\u1f16"));
+
+  // Test the sets of USC2 code points that have more than one canonically equivalent value.
+  dynamic ucs2CodePoint(x) => new String.fromCharCode(x);
+  dynamic testSet(s)
+  {
+      for (var i in s) {
+          for (var j in s) {
+              shouldBeTrue(new RegExp(ucs2CodePoint(i), caseSensitive: false).hasMatch(ucs2CodePoint(j)));
+              shouldBeTrue(new RegExp("[${ucs2CodePoint(i - 1)}-${ucs2CodePoint(i + 1)}]", caseSensitive: false).hasMatch(ucs2CodePoint(j)));
+          }
+      }
+  }
+  testSet([ 0x01c4, 0x01c5, 0x01c6 ]);
+  testSet([ 0x01c7, 0x01c8, 0x01c9 ]);
+  testSet([ 0x01ca, 0x01cb, 0x01cc ]);
+  testSet([ 0x01f1, 0x01f2, 0x01f3 ]);
+  testSet([ 0x0392, 0x03b2, 0x03d0 ]);
+  testSet([ 0x0395, 0x03b5, 0x03f5 ]);
+  testSet([ 0x0398, 0x03b8, 0x03d1 ]);
+  testSet([ 0x0345, 0x0399, 0x03b9, 0x1fbe ]);
+  testSet([ 0x039a, 0x03ba, 0x03f0 ]);
+  testSet([ 0x00b5, 0x039c, 0x03bc ]);
+  testSet([ 0x03a0, 0x03c0, 0x03d6 ]);
+  testSet([ 0x03a1, 0x03c1, 0x03f1 ]);
+  testSet([ 0x03a3, 0x03c2, 0x03c3 ]);
+  testSet([ 0x03a6, 0x03c6, 0x03d5 ]);
+  testSet([ 0x1e60, 0x1e61, 0x1e9b ]);
+
+  // Test a couple of lo/hi pairs
+  shouldBeTrue(new RegExp(r"\u03cf", caseSensitive: false).hasMatch("\u03cf"));
+  shouldBeTrue(new RegExp(r"\u03d7", caseSensitive: false).hasMatch("\u03cf"));
+  shouldBeTrue(new RegExp(r"\u03cf", caseSensitive: false).hasMatch("\u03d7"));
+  shouldBeTrue(new RegExp(r"\u03d7", caseSensitive: false).hasMatch("\u03d7"));
+  shouldBeTrue(new RegExp(r"\u1f11", caseSensitive: false).hasMatch("\u1f11"));
+  shouldBeTrue(new RegExp(r"\u1f19", caseSensitive: false).hasMatch("\u1f11"));
+  shouldBeTrue(new RegExp(r"\u1f11", caseSensitive: false).hasMatch("\u1f19"));
+  shouldBeTrue(new RegExp(r"\u1f19", caseSensitive: false).hasMatch("\u1f19"));
+
+  // Test an aligned alternating capitalization pair.
+  shouldBeFalse(new RegExp(r"\u0489", caseSensitive: false).hasMatch("\u048a"));
+  shouldBeTrue(new RegExp(r"\u048a", caseSensitive: false).hasMatch("\u048a"));
+  shouldBeTrue(new RegExp(r"\u048b", caseSensitive: false).hasMatch("\u048a"));
+  shouldBeFalse(new RegExp(r"\u048c", caseSensitive: false).hasMatch("\u048a"));
+  shouldBeFalse(new RegExp(r"\u0489", caseSensitive: false).hasMatch("\u048b"));
+  shouldBeTrue(new RegExp(r"\u048a", caseSensitive: false).hasMatch("\u048b"));
+  shouldBeTrue(new RegExp(r"\u048b", caseSensitive: false).hasMatch("\u048b"));
+  shouldBeFalse(new RegExp(r"\u048c", caseSensitive: false).hasMatch("\u048b"));
+  shouldBeTrue(new RegExp(r"[\u0489-\u048a]", caseSensitive: false).hasMatch("\u048b"));
+  shouldBeTrue(new RegExp(r"[\u048b-\u048c]", caseSensitive: false).hasMatch("\u048a"));
+
+  // Test an unaligned alternating capitalization pair.
+  shouldBeFalse(new RegExp(r"\u04c4", caseSensitive: false).hasMatch("\u04c5"));
+  shouldBeTrue(new RegExp(r"\u04c5", caseSensitive: false).hasMatch("\u04c5"));
+  shouldBeTrue(new RegExp(r"\u04c6", caseSensitive: false).hasMatch("\u04c5"));
+  shouldBeFalse(new RegExp(r"\u04c7", caseSensitive: false).hasMatch("\u04c5"));
+  shouldBeFalse(new RegExp(r"\u04c4", caseSensitive: false).hasMatch("\u04c6"));
+  shouldBeTrue(new RegExp(r"\u04c5", caseSensitive: false).hasMatch("\u04c6"));
+  shouldBeTrue(new RegExp(r"\u04c6", caseSensitive: false).hasMatch("\u04c6"));
+  shouldBeFalse(new RegExp(r"\u04c7", caseSensitive: false).hasMatch("\u04c6"));
+  shouldBeTrue(new RegExp(r"[\u04c4-\u04c5]", caseSensitive: false).hasMatch("\u04c6"));
+  shouldBeTrue(new RegExp(r"[\u04c6-\u04c7]", caseSensitive: false).hasMatch("\u04c5"));
+
+  var successfullyParsed = true;
+}
diff --git a/tests/corelib/regexp/v8_regexp_utils.dart b/tests/corelib/regexp/v8_regexp_utils.dart
new file mode 100644
index 0000000..83e56d0
--- /dev/null
+++ b/tests/corelib/regexp/v8_regexp_utils.dart
@@ -0,0 +1,49 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Utility functions to easily port V8 tests.
+
+import "package:expect/expect.dart";
+
+void assertEquals(actual, expected, [String message = null]) {
+  Expect.equals(actual, expected, message);
+}
+void assertTrue(actual, [String message = null]) { Expect.isTrue(actual, message); }
+void assertFalse(actual, [String message = null]) { Expect.isFalse(actual, message); }
+void assertThrows(fn, [num testid = null]) {
+  Expect.throws(fn, null, "Test $testid");
+}
+void assertNull(actual, [num testid = null]) {
+  Expect.isNull(actual, "Test $testid");
+}
+
+void assertToStringEquals(str, match, num testid) {
+  var actual = [];
+  for (int i = 0; i <= match.groupCount; i++) {
+    var g = match.group(i);
+    actual.add((g == null) ? "" : g);
+  }
+  Expect.equals(str, actual.join(","), "Test $testid");
+}
+
+void shouldBeTrue(actual) { Expect.isTrue(actual); }
+void shouldBeFalse(actual) { Expect.isFalse(actual); }
+void shouldBeNull(actual) { Expect.isNull(actual); }
+
+void shouldBe(actual, expected, [String message = null]) {
+  if (expected == null) {
+    Expect.isNull(actual, message);
+  } else {
+    Expect.equals(expected.length, actual.groupCount + 1);
+    for (int i = 0; i <= actual.groupCount; i++) {
+      Expect.equals(expected[i], actual.group(i), message);
+    }
+  }
+}
+
+Match firstMatch(String str, RegExp pattern) => pattern.firstMatch(str);
+List<String> allStringMatches(String str, RegExp pattern) =>
+    pattern.allMatches(str).map((Match m) => m.group(0)).toList();
+
+void description(str) { }
diff --git a/tests/corelib/regexp/zero-length-alternatives_test.dart b/tests/corelib/regexp/zero-length-alternatives_test.dart
new file mode 100644
index 0000000..1c7c949
--- /dev/null
+++ b/tests/corelib/regexp/zero-length-alternatives_test.dart
@@ -0,0 +1,280 @@
+// Copyright (c) 2014, the Dart project authors. All rights reserved.
+// Copyright 2013 the V8 project authors. All rights reserved.
+// Copyright (C) 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1.  Redistributions of source code must retain the above copyright
+//     notice, this list of conditions and the following disclaimer.
+// 2.  Redistributions in binary form must reproduce the above copyright
+//     notice, this list of conditions and the following disclaimer in the
+//     documentation and/or other materials provided with the distribution.
+//
+// THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
+// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+import 'v8_regexp_utils.dart';
+import 'package:expect/expect.dart';
+
+void main() {
+  description(
+  'Test regular expression processing with alternatives that match consuming no characters'
+  );
+
+  var emptyStr = "";
+  var s1 = "xxxx";
+  var s2 = "aaaa";
+  var s3 = "aax";
+  var s4 = "abab";
+  var s5 = "ab";
+  var s6 = "xabx";
+  var s7 = "g0";
+
+  // Non-capturing empty first alternative greedy '*'
+  var re1 = new RegExp(r"(?:|a|z)*");
+  shouldBe(firstMatch(emptyStr, re1), [""]);
+  shouldBe(firstMatch(s1, re1), [""]);
+  shouldBe(firstMatch(s2, re1), ["aaaa"]);
+  shouldBe(firstMatch(s3, re1), ["aa"]);
+
+  // Non-capturing empty middle alternative greedy '*'
+  var re2 = new RegExp(r"(?:a||z)*");
+  shouldBe(firstMatch(emptyStr, re2), [""]);
+  shouldBe(firstMatch(s1, re2), [""]);
+  shouldBe(firstMatch(s2, re2), ["aaaa"]);
+  shouldBe(firstMatch(s3, re2), ["aa"]);
+
+  // Non-capturing empty last alternative greedy '*'
+  var re3 = new RegExp(r"(?:a|z|)*");
+  shouldBe(firstMatch(emptyStr, re3), [""]);
+  shouldBe(firstMatch(s1, re3), [""]);
+  shouldBe(firstMatch(s2, re3), ["aaaa"]);
+  shouldBe(firstMatch(s3, re3), ["aa"]);
+
+  // Capturing empty first alternative greedy '*'
+  var re4 = new RegExp(r"(|a|z)*");
+  shouldBe(firstMatch(emptyStr, re4), ["", null]);
+  shouldBe(firstMatch(s1, re4), ["", null]);
+  shouldBe(firstMatch(s2, re4), ["aaaa", "a"]);
+  shouldBe(firstMatch(s3, re4), ["aa", "a"]);
+
+  // Capturing empty middle alternative greedy '*'
+  var re5 = new RegExp(r"(a||z)*");
+  shouldBe(firstMatch(emptyStr, re5), ["", null]);
+  shouldBe(firstMatch(s1, re5), ["", null]);
+  shouldBe(firstMatch(s2, re5), ["aaaa", "a"]);
+  shouldBe(firstMatch(s3, re5), ["aa", "a"]);
+
+  // Capturing empty last alternative greedy '*'
+  var re6 = new RegExp(r"(a|z|)*");
+  shouldBe(firstMatch(emptyStr, re6), ["", null]);
+  shouldBe(firstMatch(s1, re6), ["", null]);
+  shouldBe(firstMatch(s2, re6), ["aaaa", "a"]);
+  shouldBe(firstMatch(s3, re6), ["aa", "a"]);
+
+  // Non-capturing empty first alternative fixed-count
+  var re7 = new RegExp(r"(?:|a|z){2,5}");
+  shouldBe(firstMatch(emptyStr, re7), [""]);
+  shouldBe(firstMatch(s1, re7), [""]);
+  shouldBe(firstMatch(s2, re7), ["aaa"]);
+  shouldBe(firstMatch(s3, re7), ["aa"]);
+
+  // Non-capturing empty middle alternative fixed-count
+  var re8 = new RegExp(r"(?:a||z){2,5}");
+  shouldBe(firstMatch(emptyStr, re8), [""]);
+  shouldBe(firstMatch(s1, re8), [""]);
+  shouldBe(firstMatch(s2, re8), ["aaaa"]);
+  shouldBe(firstMatch(s3, re8), ["aa"]);
+
+  // Non-capturing empty last alternative fixed-count
+  var re9 = new RegExp(r"(?:a|z|){2,5}");
+  shouldBe(firstMatch(emptyStr, re9), [""]);
+  shouldBe(firstMatch(s1, re9), [""]);
+  shouldBe(firstMatch(s2, re9), ["aaaa"]);
+  shouldBe(firstMatch(s3, re9), ["aa"]);
+
+  // Non-capturing empty first alternative non-greedy '*'
+  var re10 = new RegExp(r"(?:|a|z)*?");
+  shouldBe(firstMatch(emptyStr, re10), [""]);
+  shouldBe(firstMatch(s1, re10), [""]);
+  shouldBe(firstMatch(s2, re10), [""]);
+  shouldBe(firstMatch(s3, re10), [""]);
+
+  // Non-capturing empty middle alternative non-greedy '*'
+  var re11 = new RegExp(r"(?:a||z)*?");
+  shouldBe(firstMatch(emptyStr, re11), [""]);
+  shouldBe(firstMatch(s1, re11), [""]);
+  shouldBe(firstMatch(s2, re11), [""]);
+  shouldBe(firstMatch(s3, re11), [""]);
+
+  // Non-capturing empty last alternative non-greedy '*'
+  var re12 = new RegExp(r"(?:a|z|)*?");
+  shouldBe(firstMatch(emptyStr, re12), [""]);
+  shouldBe(firstMatch(s1, re12), [""]);
+  shouldBe(firstMatch(s2, re12), [""]);
+  shouldBe(firstMatch(s3, re12), [""]);
+
+  // Capturing empty first alternative non-greedy '*'
+  var re13 = new RegExp(r"(|a|z)*?");
+  shouldBe(firstMatch(emptyStr, re13), ["", null]);
+  shouldBe(firstMatch(s1, re13), ["", null]);
+  shouldBe(firstMatch(s2, re13), ["", null]);
+  shouldBe(firstMatch(s3, re13), ["", null]);
+
+  // Capturing empty middle alternative non-greedy '*'
+  var re14 = new RegExp(r"(a||z)*?");
+  shouldBe(firstMatch(emptyStr, re14), ["", null]);
+  shouldBe(firstMatch(s1, re14), ["", null]);
+  shouldBe(firstMatch(s2, re14), ["", null]);
+  shouldBe(firstMatch(s3, re14), ["", null]);
+
+  // Capturing empty last alternative non-greedy '*'
+  var re15 = new RegExp(r"(a|z|)*?");
+  shouldBe(firstMatch(emptyStr, re15), ["", null]);
+  shouldBe(firstMatch(s1, re15), ["", null]);
+  shouldBe(firstMatch(s2, re15), ["", null]);
+  shouldBe(firstMatch(s3, re15), ["", null]);
+
+  // Non-capturing empty first alternative greedy '?'
+  var re16 = new RegExp(r"(?:|a|z)?");
+  shouldBe(firstMatch(emptyStr, re16), [""]);
+  shouldBe(firstMatch(s1, re16), [""]);
+  shouldBe(firstMatch(s2, re16), ["a"]);
+  shouldBe(firstMatch(s3, re16), ["a"]);
+
+  // Non-capturing empty middle alternative greedy '?'
+  var re17 = new RegExp(r"(?:a||z)?");
+  shouldBe(firstMatch(emptyStr, re17), [""]);
+  shouldBe(firstMatch(s1, re17), [""]);
+  shouldBe(firstMatch(s2, re17), ["a"]);
+  shouldBe(firstMatch(s3, re17), ["a"]);
+
+  // Non-capturing empty last alternative greedy '?'
+  var re18 = new RegExp(r"(?:a|z|)?");
+  shouldBe(firstMatch(emptyStr, re18), [""]);
+  shouldBe(firstMatch(s1, re18), [""]);
+  shouldBe(firstMatch(s2, re18), ["a"]);
+  shouldBe(firstMatch(s3, re18), ["a"]);
+
+  // Capturing empty first alternative greedy '?'
+  var re19 = new RegExp(r"(|a|z)?");
+  shouldBe(firstMatch(emptyStr, re19), ["", null]);
+  shouldBe(firstMatch(s1, re19), ["", null]);
+  shouldBe(firstMatch(s2, re19), ["a", "a"]);
+  shouldBe(firstMatch(s3, re19), ["a", "a"]);
+
+  // Capturing empty middle alternative greedy '?'
+  var re20 = new RegExp(r"(a||z)?");
+  shouldBe(firstMatch(emptyStr, re20), ["", null]);
+  shouldBe(firstMatch(s1, re20), ["", null]);
+  shouldBe(firstMatch(s2, re20), ["a", "a"]);
+  shouldBe(firstMatch(s3, re20), ["a", "a"]);
+
+  // Capturing empty last alternative greedy '?'
+  var re21 = new RegExp(r"(a|z|)?");
+  shouldBe(firstMatch(emptyStr, re21), ["", null]);
+  shouldBe(firstMatch(s1, re21), ["", null]);
+  shouldBe(firstMatch(s2, re21), ["a", "a"]);
+  shouldBe(firstMatch(s3, re21), ["a", "a"]);
+
+  // Non-capturing empty first alternative non-greedy '?'
+  var re22 = new RegExp(r"(?:|a|z)??");
+  shouldBe(firstMatch(emptyStr, re22), [""]);
+  shouldBe(firstMatch(s1, re22), [""]);
+  shouldBe(firstMatch(s2, re22), [""]);
+  shouldBe(firstMatch(s3, re22), [""]);
+
+  // Non-capturing empty middle alternative non-greedy '?'
+  var re23 = new RegExp(r"(?:a||z)??");
+  shouldBe(firstMatch(emptyStr, re23), [""]);
+  shouldBe(firstMatch(s1, re23), [""]);
+  shouldBe(firstMatch(s2, re23), [""]);
+  shouldBe(firstMatch(s3, re23), [""]);
+
+  // Non-capturing empty last alternative non-greedy '?'
+  var re24 = new RegExp(r"(?:a|z|)??");
+  shouldBe(firstMatch(emptyStr, re24), [""]);
+  shouldBe(firstMatch(s1, re24), [""]);
+  shouldBe(firstMatch(s2, re24), [""]);
+  shouldBe(firstMatch(s3, re24), [""]);
+
+  // Capturing empty first alternative non-greedy '?'
+  var re25 = new RegExp(r"(|a|z)??");
+  shouldBe(firstMatch(emptyStr, re25), ["", null]);
+  shouldBe(firstMatch(s1, re25), ["", null]);
+  shouldBe(firstMatch(s2, re25), ["", null]);
+  shouldBe(firstMatch(s3, re25), ["", null]);
+
+  // Capturing empty middle alternative non-greedy '?'
+  var re26 = new RegExp(r"(a||z)??");
+  shouldBe(firstMatch(emptyStr, re26), ["", null]);
+  shouldBe(firstMatch(s1, re26), ["", null]);
+  shouldBe(firstMatch(s2, re26), ["", null]);
+  shouldBe(firstMatch(s3, re26), ["", null]);
+
+  // Capturing empty last alternative non-greedy '?'
+  var re27 = new RegExp(r"(a|z|)??");
+  shouldBe(firstMatch(emptyStr, re27), ["", null]);
+  shouldBe(firstMatch(s1, re27), ["", null]);
+  shouldBe(firstMatch(s2, re27), ["", null]);
+  shouldBe(firstMatch(s3, re27), ["", null]);
+
+  // Non-capturing empty first alternative greedy '*' non-terminal
+  var re28 = new RegExp(r"(?:|a|z)*x");
+  shouldBe(firstMatch(emptyStr, re28), null);
+  shouldBe(firstMatch(s1, re28), ["x"]);
+  shouldBe(firstMatch(s2, re28), null);
+  shouldBe(firstMatch(s3, re28), ["aax"]);
+
+  // Non-capturing empty middle alternative greedy '*' non-terminal
+  var re29 = new RegExp(r"(?:a||z)*x");
+  shouldBe(firstMatch(emptyStr, re29), null);
+  shouldBe(firstMatch(s1, re29), ["x"]);
+  shouldBe(firstMatch(s2, re29), null);
+  shouldBe(firstMatch(s3, re29), ["aax"]);
+
+  // Non-capturing empty last alternative greedy '*' non-terminal
+  var re30 = new RegExp(r"(?:a|z|)*x");
+  shouldBe(firstMatch(emptyStr, re30), null);
+  shouldBe(firstMatch(s1, re30), ["x"]);
+  shouldBe(firstMatch(s2, re30), null);
+  shouldBe(firstMatch(s3, re30), ["aax"]);
+
+  // Non-capturing two possibly empty alternatives greedy '*'
+  var re31 = new RegExp(r"(?:a*|b*)*");
+  shouldBe(firstMatch(emptyStr, re31), [""]);
+  shouldBe(firstMatch(s1, re31), [""]);
+  shouldBe(firstMatch(s3, re31), ["aa"]);
+  shouldBe(firstMatch(s4, re31), ["abab"]);
+
+  // Non-capturing two possibly empty non-greedy alternatives non-greedy '*'
+  var re32 = new RegExp(r"(?:a*?|b*?)*");
+  shouldBe(firstMatch(emptyStr, re32), [""]);
+  shouldBe(firstMatch(s1, re32), [""]);
+  shouldBe(firstMatch(s2, re32), ["aaaa"]);
+  shouldBe(firstMatch(s4, re32), ["abab"]);
+  shouldBe(firstMatch(s5, re32), ["ab"]);
+  shouldBe(firstMatch(s6, re32), [""]);
+
+  // Three possibly empty alternatives with greedy +
+  var re33 = new RegExp(r"(?:(?:(?!))|g?|0*\*?)+");
+  shouldBe(firstMatch(emptyStr, re33), [""]);
+  shouldBe(firstMatch(s1, re33), [""]);
+  shouldBe(firstMatch(s7, re33), ["g0"]);
+
+  // first alternative zero length fixed count
+  var re34 = new RegExp(r"(?:|a)");
+  shouldBe(firstMatch(emptyStr, re34), [""]);
+  shouldBe(firstMatch(s1, re34), [""]);
+  shouldBe(firstMatch(s2, re34), [""]);
+  shouldBe(firstMatch(s3, re34), [""]);
+}
diff --git a/tests/html/audioelement_test.dart b/tests/html/audioelement_test.dart
index 2828596..02c8935 100644
--- a/tests/html/audioelement_test.dart
+++ b/tests/html/audioelement_test.dart
@@ -13,9 +13,9 @@
     });
 
   test('constructorTest2', () {
-      var audio = new AudioElement('hahaURL');
+      var audio = new AudioElement('IntentionallyMissingFileURL');
       expect(audio, isNotNull);
       expect(audio is AudioElement, isTrue);
-      expect(audio.src, contains('hahaURL'));
+      expect(audio.src, contains('IntentionallyMissingFileURL'));
     });
 }
diff --git a/tests/html/html.status b/tests/html/html.status
index 8fadbe3..b0f6b4f 100644
--- a/tests/html/html.status
+++ b/tests/html/html.status
@@ -257,8 +257,7 @@
 input_element_test/supported_datetime-local: Fail
 touchevent_test/supported: Fail
 
-[ $runtime == safari && $builder_tag == mac10_8 ]
-element_test/_ElementList: RuntimeError # Issue 21434
+[ $runtime == safari && ($builder_tag == mac10_8 || $builder_tag == mac10_9) ]
 indexeddb_1_test/functional: RuntimeError # Issue 21433
 indexeddb_2_test: RuntimeError # Issue 21433
 indexeddb_4_test: RuntimeError # Issue 21433
diff --git a/tests/language/first_class_types_literals_test.dart b/tests/language/first_class_types_literals_test.dart
index 2f32cfe..c0a0e0f 100644
--- a/tests/language/first_class_types_literals_test.dart
+++ b/tests/language/first_class_types_literals_test.dart
@@ -48,16 +48,16 @@
   Expect.equals((D).runtimeType, (D).runtimeType.runtimeType);
 
   // Test that operator calls on class literals go to Type.
-  Expect.throws(() => C = 1, (e) => e is NoSuchMethodError);
-  Expect.throws(() => C++, (e) => e is NoSuchMethodError);
-  Expect.throws(() => C + 1, (e) => e is NoSuchMethodError);
-  Expect.throws(() => C[2], (e) => e is NoSuchMethodError);
-  Expect.throws(() => C[2] = 'hest', (e) => e is NoSuchMethodError);
-  Expect.throws(() => dynamic = 1, (e) => e is NoSuchMethodError);
-  Expect.throws(() => dynamic++, (e) => e is NoSuchMethodError);
-  Expect.throws(() => dynamic + 1, (e) => e is NoSuchMethodError);
-  Expect.throws(() => dynamic[2], (e) => e is NoSuchMethodError);
-  Expect.throws(() => dynamic[2] = 'hest', (e) => e is NoSuchMethodError);
+  Expect.throws(() => C = 1, (e) => e is NoSuchMethodError); /// 03: static type warning
+  Expect.throws(() => C++, (e) => e is NoSuchMethodError); /// 04: static type warning
+  Expect.throws(() => C + 1, (e) => e is NoSuchMethodError); /// 05: static type warning
+  Expect.throws(() => C[2], (e) => e is NoSuchMethodError); /// 06: static type warning
+  Expect.throws(() => C[2] = 'hest', (e) => e is NoSuchMethodError); /// 07: static type warning
+  Expect.throws(() => dynamic = 1, (e) => e is NoSuchMethodError); /// 08: static type warning
+  Expect.throws(() => dynamic++, (e) => e is NoSuchMethodError); /// 09: static type warning
+  Expect.throws(() => dynamic + 1, (e) => e is NoSuchMethodError); /// 10: static type warning
+  Expect.throws(() => dynamic[2], (e) => e is NoSuchMethodError); /// 11: static type warning
+  Expect.throws(() => dynamic[2] = 'hest', (e) => e is NoSuchMethodError); /// 12: static type warning
 
   Expect.equals((dynamic).toString(), 'dynamic');
 }
diff --git a/tests/language/identical_const_test.dart b/tests/language/identical_const_test.dart
new file mode 100644
index 0000000..cd96244
--- /dev/null
+++ b/tests/language/identical_const_test.dart
@@ -0,0 +1,37 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for 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 'package:expect/expect.dart';
+
+f() {}
+const g = 1;
+
+const identical_ff = identical(f, f);
+const identical_fg = identical(f, g);
+const identical_gf = identical(g, f);
+const identical_gg = identical(g, g);
+
+// Verify proper compile time computation of identical()
+const a = const {
+  identical_ff: 0, /// 01: static type warning
+  identical_gg: 0, /// 02: static type warning
+  true: 0 };
+
+const b = const {
+  identical_fg: 0, /// 03: static type warning
+  identical_gf: 0, /// 04: static type warning
+  false: 0 };
+
+use(x) => x;
+
+main() {
+  use(a);
+  use(b);
+
+  // Verify proper run time computation of identical()
+  Expect.isTrue(identical_ff); /// 05: ok
+  Expect.isTrue(identical_gg); /// 06: ok
+  Expect.isFalse(identical_fg); /// 07: ok
+  Expect.isFalse(identical_gf); /// 08: ok
+}
diff --git a/tests/language/language_analyzer.status b/tests/language/language_analyzer.status
index 2c5db5a..dacf223 100644
--- a/tests/language/language_analyzer.status
+++ b/tests/language/language_analyzer.status
@@ -17,7 +17,7 @@
 external_test/24: Fail
 external_test/25: Fail
 constructor_duplicate_final_test/03: Fail
-
+identical_const_test: Fail # Issue 21177
 
 # Please add new failing tests before this line.
 # Section below is for invalid tests.
@@ -209,7 +209,11 @@
 field5_negative_test: CompileTimeError
 field6a_negative_test: CompileTimeError
 field6_negative_test: CompileTimeError
-first_class_types_literals_test: StaticWarning # Issue 18731
+first_class_types_literals_test/08: MissingStaticWarning # Issue 18731
+first_class_types_literals_test/09: MissingStaticWarning # Issue 18731
+first_class_types_literals_test/10: MissingStaticWarning # Issue 18731
+first_class_types_literals_test/11: MissingStaticWarning # Issue 18731
+first_class_types_literals_test/12: MissingStaticWarning # Issue 18731
 function_malformed_result_type_test: StaticWarning
 function_subtype_bound_closure7_test: StaticWarning
 function_subtype_checked0_test: StaticWarning
diff --git a/tests/language/language_analyzer2.status b/tests/language/language_analyzer2.status
index 739cc54..dc4e312 100644
--- a/tests/language/language_analyzer2.status
+++ b/tests/language/language_analyzer2.status
@@ -209,7 +209,6 @@
 field5_negative_test: CompileTimeError
 field6a_negative_test: CompileTimeError
 field6_negative_test: CompileTimeError
-first_class_types_literals_test: StaticWarning # Issue 18731
 function_malformed_result_type_test: StaticWarning
 function_subtype_bound_closure7_test: StaticWarning
 function_subtype_checked0_test: StaticWarning
@@ -455,5 +454,3 @@
 main_not_a_function_test/01: Fail # http://dartbug.com/20030
 main_test/03: Fail # http://dartbug.com/20030
 no_main_test/01: Fail # http://dartbug.com/20030
-
-compile_time_constant10_test/none: CompileTimeError # Issue 21177
diff --git a/tests/language/mixin_type_parameter5_test.dart b/tests/language/mixin_type_parameter5_test.dart
new file mode 100644
index 0000000..ce6bad0
--- /dev/null
+++ b/tests/language/mixin_type_parameter5_test.dart
@@ -0,0 +1,26 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for 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 MixinA<T> {
+  T intField;
+}
+
+class MixinB<S> {
+  S stringField;
+}
+
+class MixinC<U, V> {
+  U listField;
+  V mapField;
+}
+
+class C extends Object with MixinA<int>, MixinB<String>, MixinC<List, Map> {}
+
+void main() {
+  var c = new C();
+  c.intField = 0;
+  c.stringField = '';
+  c.listField = [];
+  c.mapField = {};
+}
diff --git a/tests/language/mixin_type_parameter6_test.dart b/tests/language/mixin_type_parameter6_test.dart
new file mode 100644
index 0000000..401a1a5
--- /dev/null
+++ b/tests/language/mixin_type_parameter6_test.dart
@@ -0,0 +1,17 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for 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<T> {}
+
+class B<S> {
+  int foo(S s) => null;
+}
+
+class C extends A<int> with B<String> {}
+
+main() {
+  var list = <String>['foo'];
+  var c = new C();
+  list.map(c.foo);
+}
diff --git a/tests/language/vm/closure_memory_retention_test.dart b/tests/language/vm/closure_memory_retention_test.dart
new file mode 100644
index 0000000..8a41b31
--- /dev/null
+++ b/tests/language/vm/closure_memory_retention_test.dart
@@ -0,0 +1,28 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for 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=--old_gen_heap_size=50
+
+// Test that non-capturing closures don't retain unnecessary memory.
+// It tests that the context of `f` allocated within `bar` not leaking and does
+// not become the context of empty non-capturing closure allocated inside `foo`.
+// If failing it crashes with an OOM error.
+
+import "package:expect/expect.dart";
+
+foo() {
+  return () { };
+}
+
+bar(a, b) {
+  f() => [a, b];
+  return foo();
+}
+
+main() {
+  var closure = null;
+  for (var i = 0; i < 100; i++) {
+    closure = bar(closure, new List(1024 * 1024));
+  }
+  Expect.isTrue(closure is Function);
+}
diff --git a/tests/lib/analyzer/analyze_library.status b/tests/lib/analyzer/analyze_library.status
index 6f8d9bd..b69a25e 100644
--- a/tests/lib/analyzer/analyze_library.status
+++ b/tests/lib/analyzer/analyze_library.status
@@ -15,9 +15,13 @@
 lib/web_audio/dart2js/web_audio_dart2js: CompileTimeError # Issue 16522
 lib/web_gl/dart2js/web_gl_dart2js: CompileTimeError # Issue 16522
 lib/web_sql/dart2js/web_sql_dart2js: CompileTimeError # Issue 16522
-
+ 
 lib/_internal/compiler/samples/compile_loop/compile_loop: CompileTimeError  # Issue 16524
 
+# The async_await compiler isn't part of the repo so it shouldn't be tested by
+# repo tests.
+lib/_internal/pub_generated/bin/async_compile: Skip
+
 # Pub is starting to use the new async syntax, which isn't supported on the
 # analyzer bots yet.
 lib/_internal/pub/*: Pass, CompileTimeError
diff --git a/tests/lib/lib.status b/tests/lib/lib.status
index 97c7512..923014f 100644
--- a/tests/lib/lib.status
+++ b/tests/lib/lib.status
@@ -110,10 +110,6 @@
 typed_data/setRange_3_test: Fail # Safari doesn't fully implement spec for TypedArray.set
 typed_data/setRange_4_test: Fail # Safari doesn't fully implement spec for TypedArray.set
 
-
-[ $runtime == safari && $builder_tag == mac10_8 ]
-mirrors/generics_test/none: RuntimeError # Issue 21427
-
 [ $compiler == dart2js && $runtime == chromeOnAndroid ]
 typed_data/setRange_2_test: RuntimeError # TODO(dart2js-team): Please triage this failure.
 typed_data/setRange_3_test: RuntimeError # TODO(dart2js-team): Please triage this failure.
diff --git a/tests/lib/mirrors/class_declarations_test.dart b/tests/lib/mirrors/class_declarations_test.dart
index f957c10..6067e07 100644
--- a/tests/lib/mirrors/class_declarations_test.dart
+++ b/tests/lib/mirrors/class_declarations_test.dart
@@ -190,7 +190,11 @@
         ' with test.declarations_model.Mixin.inheritedRedirectingConstructor)'
         ' in s(test.declarations_model.Superclass'
         ' with test.declarations_model.Mixin), constructor)',
-    'Method(s(toString) in s(Object))'],
+    'Method(s(toString) in s(Object))',
+    'Variable(s(mixinStaticVariable) in s(Mixin), static)',
+    'Method(s(mixinStaticGetter) in s(Mixin), static, getter)',
+    'Method(s(mixinStaticSetter=) in s(Mixin), static, setter)',
+    'Method(s(mixinStaticMethod) in s(Mixin), static)'],
     inheritedDeclarations(cm).where((dm) => !dm.isPrivate).map(stringify),
     'transitive public');
   // The public members of Object should be the same in all implementations, so
@@ -322,7 +326,15 @@
     'Method(s(test.declarations_model.Superclass'
         ' with test.declarations_model.Mixin.inheritedRedirectingConstructor)'
         ' in s(test.declarations_model.Superclass'
-        ' with test.declarations_model.Mixin), constructor)'],
+        ' with test.declarations_model.Mixin), constructor)',
+    'Variable(s(mixinStaticVariable) in s(Mixin), static)',
+    'Variable(s(_mixinStaticVariable) in s(Mixin), private, static)',
+    'Method(s(mixinStaticGetter) in s(Mixin), static, getter)',
+    'Method(s(mixinStaticSetter=) in s(Mixin), static, setter)',
+    'Method(s(mixinStaticMethod) in s(Mixin), static)',
+    'Method(s(_mixinStaticGetter) in s(Mixin), private, static, getter)',
+    'Method(s(_mixinStaticSetter=) in s(Mixin), private, static, setter)',
+    'Method(s(_mixinStaticMethod) in s(Mixin), private, static)'],
     inheritedDeclarations(cm)
         .difference(reflectClass(Object).declarations.values.toSet())
         .map(stringify),
diff --git a/tests/standalone/io/http_headers_test.dart b/tests/standalone/io/http_headers_test.dart
index c9006ea..6d2b92d 100644
--- a/tests/standalone/io/http_headers_test.dart
+++ b/tests/standalone/io/http_headers_test.dart
@@ -332,12 +332,14 @@
 
   contentType = new ContentType("text",
                                 "html",
-                                parameters: {"CHARSET": "UTF-8", "xxx": "yyy"});
-  check(contentType, "text", "html", {"charset": "utf-8", "xxx": "yyy"});
+                                parameters: {"CHARSET": "UTF-8", "xxx": "YYY"});
+  check(contentType, "text", "html", {"charset": "utf-8", "xxx": "YYY"});
   String s = contentType.toString();
-  bool expectedToString = (s == "text/html; charset=utf-8; xxx=yyy" ||
-                           s == "text/html; xxx=yyy; charset=utf-8");
+  bool expectedToString = (s == "text/html; charset=utf-8; xxx=YYY" ||
+                           s == "text/html; xxx=YYY; charset=utf-8");
   Expect.isTrue(expectedToString);
+  contentType = ContentType.parse("text/html; CHARSET=UTF-8; xxx=YYY");
+  check(contentType, "text", "html", {"charset": "utf-8", "xxx": "YYY"});
   Expect.throws(() => contentType.parameters["xxx"] = "yyy",
                 (e) => e is UnsupportedError);
 
diff --git a/tests/standalone/priority_queue_stress_test.dart b/tests/standalone/priority_queue_stress_test.dart
new file mode 100644
index 0000000..a795892
--- /dev/null
+++ b/tests/standalone/priority_queue_stress_test.dart
@@ -0,0 +1,323 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for 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 priority_queue;
+
+import 'dart:collection';
+import 'dart:math';
+
+/**
+ * A priority used for the priority queue. Subclasses only need to implement
+ * the compareTo function.
+ */
+abstract class Priority implements Comparable {
+  /**
+   * Return < 0 if other is bigger, >0 if other is smaller, 0 if they are equal.
+   */
+  int compareTo(Priority other);
+  bool operator<(Priority other) => compareTo(other) < 0;
+  bool operator>(Priority other) => compareTo(other) > 0;
+  bool operator==(Priority other) => compareTo(other) == 0;
+}
+
+/**
+ * Priority based on integers.
+ */
+class IntPriority extends Priority {
+  int priority;
+  IntPriority(int this.priority);
+
+  int compareTo(IntPriority other) {
+    return priority - other.priority;
+  }
+  String toString() => "$priority";
+}
+
+/**
+ * An element of a priority queue. The type is used restriction based
+ * querying of the queues.
+ */
+abstract class TypedElement<V> {
+  bool typeEquals(var other);
+}
+
+class StringTypedElement<V> extends TypedElement{
+  String type;
+  V value;
+  StringTypedElement(String this.type, V this.value);
+  bool typeEquals(String otherType) => otherType == type;
+  String toString() => "<Type: $type, Value: $value>";
+}
+
+
+/**
+ * A priority node in a priority queue. A priority node contains all of the
+ * values for a given priority in a given queue. It is part of a linked
+ * list of nodes, with prev and next pointers.
+ */
+class PriorityNode<N extends TypedElement, T extends Priority> {
+  T priority;
+  Queue<N> values;
+  PriorityNode prev;
+  PriorityNode next;
+  PriorityNode(N initialNode, T this.priority)
+    : values = new Queue<N>() {
+    add(initialNode);
+  }
+
+  void add(N n) => values.add(n);
+
+  bool remove(N n) => values.remove(n);
+
+  N removeFirst() => values.removeFirst();
+
+  bool get isEmpty => values.isEmpty;
+
+  N get first => values.first;
+
+  String toString() => "Priority: $priority $values";
+}
+
+/**
+ * A priority queue with a FIFO property for nodes with same priority.
+ * The queue guarantees that nodes are returned in the same order they
+ * are added for a given priority.
+ * For type safety this queue is guarded by the elements being subclasses of
+ * TypedElement - this is not strictly neccesary since we never actually
+ * use the value or type of the nodes.
+ */
+class PriorityQueue<N extends TypedElement, P extends Priority> {
+  PriorityNode<N, P> head;
+  int length = 0;
+
+  void add(N value, P priority) {
+    length++;
+    if (head == null) {
+      head = new PriorityNode<N, P>(value, priority);
+      return;
+    }
+    assert(head.next == null);
+    var node = head;
+    while (node.prev != null && node.priority > priority) {
+      node = node.prev;
+    }
+    if (node.priority == priority) {
+      node.add(value);
+    } else if (node.priority < priority) {
+      var newNode = new PriorityNode<N, P>(value, priority);
+      newNode.next = node.next;
+      if (node.next != null) node.next.prev = newNode;
+      newNode.prev = node;
+      node.next = newNode;
+      if (node == head) head = newNode;
+    } else {
+      var newNode = new PriorityNode<N, P>(value, priority);
+      node.prev = newNode;
+      newNode.next = node;
+    }
+  }
+
+  N get first => head.first;
+
+  Priority get firstPriority => head.priority;
+
+  bool get isEmpty => head == null;
+
+  N removeFirst() {
+    if (isEmpty) throw "Can't get element from empty queue";
+    var value = head.removeFirst();
+    if (head.isEmpty) {
+      if (head.prev != null) {
+        head.prev.next = null;
+      }
+      head = head.prev;
+    }
+    length--;
+    assert(head == null || head.next == null);
+    return value;
+  }
+
+  String toString() {
+    if (head == null) return "Empty priority queue";
+    var node = head;
+    var buffer = new StringBuffer();
+    while (node.prev != null) {
+      buffer.writeln(node);
+      node = node.prev;
+    }
+    buffer.writeln(node);
+    return buffer.toString();
+  }
+}
+
+/**
+ * Implements a specialized priority queue that efficiently allows getting
+ * the highest priorized node that adheres to a set of restrictions.
+ * Most notably it allows to get the highest priority node where the node's
+ * type is not in an exclude list.
+ * In addition, the queue has a number of properties:
+ *   The queue has fifo semantics for nodes with the same priority and type,
+ *   i.e., if nodes a and b are added to the queue with priority x and type z
+ *   then a is returned first iff a was added before b
+ * For different types with the same priority no guarantees are given, but
+ * the returned values try to be fair by returning from the biggest list of
+ * tasks in case of priority clash. (This could be fixed by adding timestamps
+ * to every node, that is _only_ used when collisions occur, not for
+ * insertions)
+ */
+class RestrictViewPriorityQueue<N extends TypedElement, P extends Priority> {
+  // We can't use the basic dart priority queue since it does not guarantee
+  // FIFO for items with the same order. This is currently not uptimized for
+  // different N, if many different N is expected here we should have a
+  // priority queue instead of a list.
+  List<PriorityQueue<N, P>> restrictedQueues = new List<PriorityQueue<N, P>>();
+  PriorityQueue<N, P> mainQueue = new PriorityQueue<N, P>();
+
+  void add(N value, P priority) {
+    for (var queue in restrictedQueues) {
+      if (queue.first.value == value) {
+        queue.add(value, priority);
+      }
+    }
+    mainQueue.add(value, priority);
+  }
+
+  bool get isEmpty => restrictedQueues.length + mainQueue.length == 0;
+
+  int get length => restrictedQueues.fold(0, (v, e) => v + element.length) +
+                    mainQueue.length;
+
+  PriorityQueue getRestricted(List<N> restrictions) {
+    var current = null;
+    // Find highest restricted priority.
+    for (var queue in restrictedQueues) {
+      if (!restrictions.any((e) => queue.head.first.typeEquals(e))) {
+        if (current == null || queue.firstPriority > current.firstPriority) {
+          current = queue;
+        } else if (current.firstPriority == queue.firstPriority) {
+          current = queue.length > current.length ? queue : current;
+        }
+      }
+    }
+    return current;
+  }
+
+  N get first {
+    if (isEmpty) throw "Trying to remove node from empty queue";
+    var candidate = getRestricted([]);
+    if (candidate != null &&
+        (mainQueue.isEmpty ||
+         mainQueue.first.priority < candidate.first.priority)) {
+      return candidate.first;
+    }
+    return mainQueue.isEmpty ? null : mainQueue.first;
+  }
+
+  /**
+   * Returns the node that under the given set of restrictions.
+   * If the queue is empty this function throws.
+   * If the queue is not empty, but no node exists that adheres to the
+   * restrictions we return null.
+   */
+  N removeFirst({List restrictions: const []}) {
+    if (isEmpty) throw "Trying to remove node from empty queue";
+    var candidate = getRestricted(restrictions);
+
+    if (candidate != null &&
+        (mainQueue.isEmpty ||
+         mainQueue.firstPriority < candidate.firstPriority)) {
+      var value = candidate.removeFirst();
+      if (candidate.isEmpty) restrictedQueues.remove(candidate);
+      return value;
+    }
+    while (!mainQueue.isEmpty) {
+      var currentPriority = mainQueue.firstPriority;
+      var current = mainQueue.removeFirst();
+      if (!restrictions.any((e) => current.typeEquals(e))) {
+        return current;
+      } else {
+        var restrictedQueue = restrictedQueues
+          .firstWhere((e) => current.typeEquals(e.first.type),
+                      orElse: () => null);
+        if (restrictedQueue == null) {
+          restrictedQueue = new PriorityQueue<N, P>();
+          restrictedQueues.add(restrictedQueue);
+        }
+        restrictedQueue.add(current, currentPriority);
+      }
+    }
+  }
+
+  String toString() {
+    if (isEmpty) return "Empty queue";
+    var buffer = new StringBuffer();
+    if (!restrictedQueues.isEmpty) {
+      buffer.writeln("Restricted queues");
+      for (var queue in restrictedQueues) {
+        buffer.writeln("$queue");
+      }
+    }
+    buffer.writeln("Main queue:");
+    buffer.writeln("$mainQueue");
+    return buffer.toString();
+  }
+}
+
+/// TEMPORARY TESTING AND PERFORMANCE
+void main([args]) {
+  stress(new RestrictViewPriorityQueue<StringTypedElement, IntPriority>());
+}
+
+void stress(queue) {
+  final int SIZE = 50000;
+  Random random = new Random(29);
+
+  var priorities = [1, 2, 3, 16, 32, 42, 56, 57, 59, 90];
+  var values = [new StringTypedElement('safari', 'foo'),
+                new StringTypedElement('ie', 'bar'),
+                new StringTypedElement('ff', 'foobar'),
+                new StringTypedElement('dartium', 'barfoo'),
+                new StringTypedElement('chrome', 'hest'),
+                new StringTypedElement('drt', 'fisk')];
+
+  var restricted = ['safari', 'chrome'];
+
+
+  void addRandom() {
+    queue.add(values[random.nextInt(values.length)],
+              new IntPriority(priorities[random.nextInt(priorities.length)]));
+  }
+
+  var stopwatch = new Stopwatch()..start();
+  while(queue.length < SIZE) {
+    addRandom();
+  }
+
+  stopwatch.stop();
+  print("Adding took: ${stopwatch.elapsedMilliseconds}");
+  print("Queue length: ${queue.length}");
+
+  stopwatch = new Stopwatch()..start();
+  while(queue.length > 0) {
+    queue.removeFirst();
+  }
+  stopwatch.stop();
+  print("Remowing took: ${stopwatch.elapsedMilliseconds}");
+  print("Queue length: ${queue.length}");
+
+
+  print("Restricted add/remove");
+  while(queue.length < SIZE) {
+    addRandom();
+  }
+
+  for (int i = 0; i < SIZE; i++) {
+    if (random.nextDouble() < 0.5) {
+      queue.removeFirst(restrictions: restricted);
+    } else {
+      queue.removeFirst();
+    }
+    addRandom();
+  }
+}
diff --git a/tests/standalone/standalone.status b/tests/standalone/standalone.status
index d51d56e..80365fc 100644
--- a/tests/standalone/standalone.status
+++ b/tests/standalone/standalone.status
@@ -60,6 +60,8 @@
 # This is runtime test.
 io/process_exit_negative_test: Skip
 
+priority_queue_stress_test: StaticWarning # Issue 21468
+
 [ $compiler == dart2js ]
 number_identity_test: Skip # Bigints and int/double diff. not supported.
 typed_data_test: Skip # dart:typed_data support needed.
diff --git a/tests/try/try.status b/tests/try/try.status
index 02c8edc..d045b0b 100644
--- a/tests/try/try.status
+++ b/tests/try/try.status
@@ -31,5 +31,10 @@
 [ $compiler == dart2js ]
 poi/*: Skip # http://dartbug.com/20031
 
-[ $runtime == ff || $checked || ($system == windows && $compiler == dart2js)]
-web/incremental_compilation_update_test: Slow, Pass
+[ $runtime == ff && $unchecked ]
+# Compilation is slow, test fails at runtime due to time out.
+web/incremental_compilation_update_test: Slow, Fail
+
+[ $compiler == dart2js && $checked ]
+# Compilation is slow, test fails at runtime due to time out.
+web/incremental_compilation_update_test: Slow, Fail
diff --git a/tests/try/web/incremental_compilation_update_test.dart b/tests/try/web/incremental_compilation_update_test.dart
index db2e40ad..70c6544 100644
--- a/tests/try/web/incremental_compilation_update_test.dart
+++ b/tests/try/web/incremental_compilation_update_test.dart
@@ -22,6 +22,8 @@
 
 import 'program_result.dart';
 
+const int TIMEOUT = 100;
+
 const List<List<ProgramResult>> tests = const <List<ProgramResult>>[
     // Basic hello-world test.
     const <ProgramResult>[
@@ -157,8 +159,43 @@
   instance.m();
 }
 """,
-            // TODO(ahe): This test is failing, should print "v2".
+            const <String> ['v2']),
+    ],
+
+    // Test that a stored instance tearoff changes behavior when updated.
+    const <ProgramResult>[
+        const ProgramResult(
+            """
+class C {
+  m() {
+    print('v1');
+  }
+}
+var closure;
+main() {
+  if (closure == null) {
+    closure = new C().m;
+  }
+  closure();
+}
+""",
             const <String> ['v1']),
+        const ProgramResult(
+            """
+class C {
+  m() {
+    print('v2');
+  }
+}
+var closure;
+main() {
+  if (closure == null) {
+    closure = new C().m;
+  }
+  closure();
+}
+""",
+            const <String> ['v2']),
     ],
 ];
 
@@ -203,7 +240,7 @@
           Uri uri = test.scriptUri.resolve('?v${version++}');
           inputProvider.cachedSources[uri] = new Future.value(program.code);
           Future future = test.incrementalCompiler.compileUpdates(
-              {test.scriptUri: uri}, logVerbose: print, logTime: print);
+              {test.scriptUri: uri}, logVerbose: logger, logTime: logger);
           return future.then((String update) {
             print({'update': update});
             iframe.contentWindow.postMessage(['apply-update', update], '*');
@@ -221,3 +258,13 @@
     iframe.remove();
   });
 }
+
+void logger(x) {
+  print(x);
+  bool isCheckedMode = false;
+  assert(isCheckedMode = true);
+  int timeout = isCheckedMode ? TIMEOUT * 2 : TIMEOUT;
+  if (listener.elapsed > timeout) {
+    throw 'Test timed out.';
+  }
+}
diff --git a/tests/try/web/sandbox.dart b/tests/try/web/sandbox.dart
index e11567c..c099165 100644
--- a/tests/try/web/sandbox.dart
+++ b/tests/try/web/sandbox.dart
@@ -83,6 +83,10 @@
 
   String expectedMessage;
 
+  Stopwatch wallclock;
+
+  int get elapsed => wallclock.elapsedMilliseconds ~/ 1000;
+
   void onMessage(MessageEvent e) {
     String message = e.data;
     if (expectedMessage == message) {
@@ -117,6 +121,7 @@
   }
 
   void start() {
+    wallclock = new Stopwatch()..start();
     window.onMessage.listen(onMessage);
   }
 }
diff --git a/tools/VERSION b/tools/VERSION
index 6f49db1..998fa2d 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
 MAJOR 1
 MINOR 8
 PATCH 0
-PRERELEASE 2
+PRERELEASE 3
 PRERELEASE_PATCH 0
diff --git a/tools/bots/compiler.py b/tools/bots/compiler.py
index 246e87f..3a94d30 100644
--- a/tools/bots/compiler.py
+++ b/tools/bots/compiler.py
@@ -26,7 +26,7 @@
     r'dart2js-(linux|mac|windows)(-(jsshell))?-(debug|release)(-(checked|host-checked))?(-(host-checked))?(-(minified))?(-(x64))?(-(batch))?-?(\d*)-?(\d*)')
 DART2JS_FULL_BUILDER = r'full-(linux|mac|win7|win8)(-(ie10|ie11))?(-checked)?(-minified)?-(\d+)-(\d+)'
 WEB_BUILDER = (
-    r'dart2js-(ie9|ie10|ie11|ff|safari|chrome|chromeOnAndroid|safarimobilesim|opera|drt)-(win7|win8|mac10\.8|mac10\.7|linux)(-(all|html))?(-(csp))?(-(\d+)-(\d+))?')
+    r'dart2js-(ie9|ie10|ie11|ff|safari|chrome|chromeOnAndroid|safarimobilesim|opera|drt)-(win7|win8|mac10\.7|mac10\.8|mac10\.9|linux)(-(all|html))?(-(csp))?(-(\d+)-(\d+))?')
 
 IE_VERSIONS = ['ie10', 'ie11']
 
@@ -138,7 +138,7 @@
     system = 'windows'
 
   # We have both 10.8 and 10.7 bots, functionality is the same.
-  if system == 'mac10.8' or system == 'mac10.7':
+  if system == 'mac10.7' or system == 'mac10.8' or system == 'mac10.9':
     builder_tag = system.replace('.', '_')
     system = 'mac'
 
diff --git a/tools/testing/dart/browser_controller.dart b/tools/testing/dart/browser_controller.dart
index d17612d..8a57d69 100644
--- a/tools/testing/dart/browser_controller.dart
+++ b/tools/testing/dart/browser_controller.dart
@@ -1466,11 +1466,14 @@
       var number_of_tests = 0;
       var current_id;
       var next_id;
-      // Describes a state where we are currently fetching the next test
-      // from the server. We use this to never double request tasks.
+
+      // Has the test in the current iframe reported that it is done?
       var test_completed = true;
+      // Has the test in the current iframe reported that it is started?
+      var test_started = false;
       var testing_window;
 
+      var embedded_iframe_div = document.getElementById('embedded_iframe_div');
       var embedded_iframe = document.getElementById('embedded_iframe');
       var number_div = document.getElementById('number');
       var executing_div = document.getElementById('currently_executing');
@@ -1582,6 +1585,11 @@
           } else {
             embedded_iframe.onload = null;
           }
+          embedded_iframe_div.removeChild(embedded_iframe);
+          embedded_iframe = document.createElement('iframe');
+          embedded_iframe.id = "embedded_iframe";
+          embedded_iframe.style="width:100%;height:100%";
+          embedded_iframe_div.appendChild(embedded_iframe);
           embedded_iframe.src = url;
         } else {
           if (typeof testing_window != 'undefined') {
@@ -1589,6 +1597,8 @@
           }
           testing_window = window.open(url);
         }
+        test_started = false;
+        test_completed = false;
       }
 
       window.onerror = function (message, url, lineNumber) {
@@ -1613,8 +1623,14 @@
 
       function reportMessage(msg, isFirstMessage, isStatusUpdate) {
         if (isFirstMessage) {
-          test_completed = false;
+          if (test_started) {
+            reportMessage(
+                "FAIL: test started more than once (test reloads itself) " +
+                msg, false, false);
+            return;
+          }
           current_id = next_id;
+          test_started = true;
           contactBrowserController(
             'POST', '$startedPath/${browserId}?id=' + current_id,
             function () {}, msg, true);
@@ -1666,7 +1682,12 @@
       function messageHandler(e) {
         var msg = e.data;
         if (typeof msg != 'string') return;
-
+        var expectedSource =
+            use_iframe ? embedded_iframe.contentWindow : testing_window;
+        if (e.source != expectedSource) {
+            reportError("Message received from old test window: " + msg);
+            return;
+        }
         var parsedData = parseResult(msg);
         if (parsedData) {
           // Only if the JSON message contains all required parameters,
@@ -1744,7 +1765,7 @@
     Currently executing: <span id="currently_executing"></span><br>
     Unhandled error: <span id="unhandled_error"></span>
     </div>
-    <div class="test box">
+    <div id="embedded_iframe_div" class="test box">
       <iframe style="width:100%;height:100%;" id="embedded_iframe"></iframe>
     </div>
   </body>
diff --git a/tools/testing/dart/http_server.dart b/tools/testing/dart/http_server.dart
index 14cb0ff..a5e7b8e 100644
--- a/tools/testing/dart/http_server.dart
+++ b/tools/testing/dart/http_server.dart
@@ -126,17 +126,7 @@
     "/foo",
     "/bar",
     "/NonExistingFile",
-    "/NonExistingFile.js",
-    "/hahaURL",
-    "/IntentionallyMissingFile",
-    "/IntentionallyMissingFile.dart",
-    "/IntentionallyMissingFile.html",
-    "/IntentionallyMissingFile.png",
-    "/IntentionallyMissingFile.css",
-    "/IntentionallyMissingFile.jpg",
-    "/IntentionallyMissingFile.ttf",
-    "/IntentionallyMissingFile.otf",
-    "/IntentionallyMissingFile.jpeg"
+    "IntentionallyMissingFile",
   ];
 
   List _serverList = [];
@@ -419,8 +409,8 @@
 
   void _sendNotFound(HttpRequest request) {
     bool isHarmlessPath(String path) {
-      return _HARMLESS_REQUEST_PATH_ENDINGS.any((ending) {
-        return path.endsWith(ending);
+      return _HARMLESS_REQUEST_PATH_ENDINGS.any((pattern) {
+        return path.contains(pattern);
       });
     }
     if (!isHarmlessPath(request.uri.path)) {
diff --git a/tools/testing/dart/test_runner.dart b/tools/testing/dart/test_runner.dart
index 3eb76e3..befa478 100644
--- a/tools/testing/dart/test_runner.dart
+++ b/tools/testing/dart/test_runner.dart
@@ -2581,6 +2581,13 @@
 
 bool shouldRetryCommand(CommandOutput output) {
   var command = output.command;
+  // We rerun tests on Safari because 6.2 and 7.1 are flaky. Issue 21434.
+  if (command is BrowserTestCommand && command.browser == 'safari' &&
+      output is BrowserControllerTestOutcome &&
+      output._rawOutcome != Expectation.PASS) {
+    // TODO(whesse): This retries tests that fail intentionally. Fix this
+    return true;
+  }
 
   if (!output.successful) {
     List<String> stdout, stderr;
@@ -2605,8 +2612,8 @@
       }
     }
 
-    // We currently rerun dartium tests, see issue 14074
-    if (command is BrowserTestCommand && command.displayName == 'dartium') {
+    // We currently rerun dartium tests, see issue 14074.
+    if (command is BrowserTestCommand && command.browser == 'dartium') {
       return true;
     }
   }
diff --git a/utils/apidoc/docgen.gyp b/utils/apidoc/docgen.gyp
index ee33b15..0cdd4ea 100644
--- a/utils/apidoc/docgen.gyp
+++ b/utils/apidoc/docgen.gyp
@@ -57,7 +57,8 @@
             '<(PRODUCT_DIR)/<(EXECUTABLE_PREFIX)dart<(EXECUTABLE_SUFFIX)',
             '<(SHARED_INTERMEDIATE_DIR)/utils_wrapper.dart.snapshot',
             '<!@(["python", "../../tools/list_files.py", "\\.(css|ico|js|json|png|sh|txt|yaml|py)$", ".", "../../sdk/lib/_internal/dartdoc"])',
-            '<!@(["python", "../../tools/list_files.py", "\\.dart$", ".", "../../sdk/lib", "../../runtime/lib", "../../runtime/bin"])',
+	    # We implicitly depend on the sdk/lib and vm runtime files by depending on the dart binary above.
+            '<!@(["python", "../../tools/list_files.py", "\\.dart$", "."])',
             '../../sdk/bin/dart',
             '../../sdk/bin/dart.bat',
             '../../sdk/bin/dart2js',