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;
-    }