anchor.diff:        _inferGenericInvocationExpression(node);
       }
       // Record types of the variable invoked as a function.
  -    if (staticMethodElement is VariableElement) {
  +    if (propagateTypes && staticMethodElement is VariableElement) {
         DartType propagatedType = _overrideManager.getType(staticMethodElement);
         _resolver.recordPropagatedTypeIfBetter(methodNameNode, propagatedType);
       }
  
positive.code:       _recordStaticType(prefixedIdentifier, staticType);
        _recordStaticType(node, staticType);
      }
      Element propagatedElement = prefixedIdentifier.propagatedElement;
      // HACK: special case for object getters ([hashCode] and [runtimeType]) on
      // dynamic expressions. More special cases in [visitMethodInvocation].
      if (propagatedElement == null) {
        propagatedElement =
            _typeProvider.objectType.getGetter(prefixedIdentifier.name);
      }
      if (propagatedElement is ClassElement) {
        if (_isNotTypeLiteral(node)) {
          propagatedType = propagatedElement.type;
        } else {
          propagatedType = _typeProvider.typeType;
        }
      } else if (propagatedElement is FunctionTypeAliasElement) {
        propagatedType = propagatedElement.type;
      } else if (propagatedElement is MethodElement) {
        propagatedType = propagatedElement.type;
      } else if (propagatedElement is PropertyAccessorElement) {
        propagatedType = _getTypeOfProperty(propagatedElement);
        propagatedType =
            _getPropertyPropagatedType(propagatedElement, propagatedType);
      } else if (propagatedElement is ExecutableElement) {
        propagatedType = propagatedElement.type;
      } else if (propagatedElement is TypeParameterElement) {
        propagatedType = propagatedElement.type;
      } else if (propagatedElement is VariableElement) {
        propagatedType = propagatedElement.type;
      }
      DartType overriddenType = _overrideManager.getType(propagatedElement);
      if (propagatedType == null ||
          (overriddenType != null &&
              overriddenType.isMoreSpecificThan(propagatedType))) {
        propagatedType = overriddenType;
      }
      _resolver.recordPropagatedTypeIfBetter(prefixedIdentifier, propagatedType);
      _resolver.recordPropagatedTypeIfBetter(node, propagatedType);
      return null;
    }
  
  
negative.code:       _recordStaticType(node, staticStaticType);
      }
  
      if (propagateTypes) {
        // Record propagated return type of the static element.
        DartType staticPropagatedType =
            _computePropagatedReturnType(staticMethodElement);
        _resolver.recordPropagatedTypeIfBetter(node, staticPropagatedType);
        // Check for special cases.
        bool needPropagatedType = true;
        String methodName = methodNameNode.name;
        if (!_strongMode && methodName == "then") {
          Expression target = node.realTarget;
          if (target != null) {
            DartType targetType = target.bestType;
            if (targetType.isDartAsyncFuture) {
              // Future.then(closure) return type is:
              // 1) the returned Future type, if the closure returns a Future;
              // 2) Future<valueType>, if the closure returns a value.
              NodeList<Expression> arguments = node.argumentList.arguments;
              if (arguments.length == 1) {
                // TODO(brianwilkerson) Handle the case where both arguments are
                // provided.
                Expression closureArg = arguments[0];
                if (closureArg is FunctionExpression) {
                  FunctionExpression closureExpr = closureArg;
                  DartType returnType =
                      _computePropagatedReturnType(closureExpr.element);
                  if (returnType != null) {
                    // prepare the type of the returned Future
                    InterfaceType newFutureType = _typeProvider.futureType
                        .instantiate([returnType.flattenFutures(_typeSystem)]);
                    // set the 'then' invocation type
                    _resolver.recordPropagatedTypeIfBetter(node, newFutureType);
                    needPropagatedType = false;
                    return null;
                  }
                }
              }
            }
          }
        } else if (methodName == "\$dom_createEvent") {
          Expression target = node.realTarget;
          if (target != null) {
            DartType targetType = target.bestType;
            if (targetType is InterfaceType &&
                (targetType.name == "HtmlDocument" ||
                    targetType.name == "Document")) {
              LibraryElement library = targetType.element.library;
              if (_isHtmlLibrary(library)) {
                DartType returnType =
                    _getFirstArgumentAsType(library, node.argumentList);
                if (returnType != null) {
                  _recordPropagatedType(node, returnType);
                  needPropagatedType = false;
                }
              }
            }
          }
        } else if (methodName == "query") {
          Expression target = node.realTarget;
          if (target == null) {
            Element methodElement = methodNameNode.bestElement;
            if (methodElement != null) {
              LibraryElement library = methodElement.library;
              if (_isHtmlLibrary(library)) {
                DartType returnType =
                    _getFirstArgumentAsQuery(library, node.argumentList);
                if (returnType != null) {
                  _recordPropagatedType(node, returnType);
                  needPropagatedType = false;
                }
              }
            }
          } else {
            DartType targetType = target.bestType;
            if (targetType is InterfaceType &&
                (targetType.name == "HtmlDocument" ||
                    targetType.name == "Document")) {
              LibraryElement library = targetType.element.library;
              if (_isHtmlLibrary(library)) {
                DartType returnType =
                    _getFirstArgumentAsQuery(library, node.argumentList);
                if (returnType != null) {
                  _recordPropagatedType(node, returnType);
                  needPropagatedType = false;
                }
              }
            }
          }
        } else if (methodName == "\$dom_createElement") {
          Expression target = node.realTarget;
          if (target != null) {
            DartType targetType = target.bestType;
            if (targetType is InterfaceType &&
                (targetType.name == "HtmlDocument" ||
                    targetType.name == "Document")) {
              LibraryElement library = targetType.element.library;
              if (_isHtmlLibrary(library)) {
                DartType returnType =
                    _getFirstArgumentAsQuery(library, node.argumentList);
                if (returnType != null) {
                  _recordPropagatedType(node, returnType);
                  needPropagatedType = false;
                }
              }
            }
          }
        } else if (methodName == "JS") {
          DartType returnType = _getFirstArgumentAsType(
              _typeProvider.objectType.element.library, node.argumentList);
          if (returnType != null) {
            _recordPropagatedType(node, returnType);
            needPropagatedType = false;
          }
        } else if (methodName == "getContext") {
          Expression target = node.realTarget;
          if (target != null) {
            DartType targetType = target.bestType;
            if (targetType is InterfaceType &&
                (targetType.name == "CanvasElement")) {
              NodeList<Expression> arguments = node.argumentList.arguments;
              if (arguments.length == 1) {
                Expression argument = arguments[0];
                if (argument is StringLiteral) {
                  String value = argument.stringValue;
                  if ("2d" == value) {
                    PropertyAccessorElement getter =
                        targetType.element.getGetter("context2D");
                    if (getter != null) {
                      DartType returnType = getter.returnType;
                      if (returnType != null) {
                        _recordPropagatedType(node, returnType);
                        needPropagatedType = false;
                      }
                    }
                  }
                }
  