anchor.diff:      _resolver.nullShortingTermination(node);
     }
   
  -  /// Return the non-nullable variant of the [type] if NNBD is enabled, otherwise
  -  /// return the type itself.
  -  ///
  -  /// TODO(scheglov) this is duplicate
  -  DartType _nonNullable(DartType type) {
  -    if (_isNonNullableByDefault) {
  -      return _typeSystem.promoteToNonNull(type);
  -    }
  -    return type;
  -  }
  -
  -  /**
  -   * Set the static type of [node] to be the least upper bound of the static
  -   * types of subexpressions [expr1] and [expr2].
  -   *
  -   * TODO(scheglov) this is duplicate
  -   */
  -  void _analyzeLeastUpperBound(
  -      Expression node, Expression expr1, Expression expr2,
  -      {bool read = false}) {
  -    DartType staticType1 = _getExpressionType(expr1, read: read);
  -    DartType staticType2 = _getExpressionType(expr2, read: read);
  -
  -    _analyzeLeastUpperBoundTypes(node, staticType1, staticType2);
  -  }
  -
  -  /**
  -   * Gets the definite type of expression, which can be used in cases where
  -   * the most precise type is desired, for example computing the least upper
  -   * bound.
  -   *
  -   * See [getExpressionType] for more information. Without strong mode, this is
  -   * equivalent to [_getStaticType].
  -   *
  -   * TODO(scheglov) this is duplicate
  -   */
  -  DartType _getExpressionType(Expression expr, {bool read = false}) =>
  -      getExpressionType(expr, _typeSystem, _typeProvider,
  -          read: read, elementTypeProvider: _elementTypeProvider);
  -
  -  /**
  -   * Set the static type of [node] to be the least upper bound of the static
  -   * types [staticType1] and [staticType2].
  -   *
  -   * TODO(scheglov) this is duplicate
  -   */
  -  void _analyzeLeastUpperBoundTypes(
  -      Expression node, DartType staticType1, DartType staticType2) {
  -    if (staticType1 == null) {
  -      // TODO(brianwilkerson) Determine whether this can still happen.
  -      staticType1 = DynamicTypeImpl.instance;
  -    }
  -
  -    if (staticType2 == null) {
  -      // TODO(brianwilkerson) Determine whether this can still happen.
  -      staticType2 = DynamicTypeImpl.instance;
  -    }
  -
  -    DartType staticType =
  -        _typeSystem.getLeastUpperBound(staticType1, staticType2) ??
  -            DynamicTypeImpl.instance;
  -
  -    staticType = _resolver.toLegacyTypeIfOptOut(staticType);
  -
  -    _inferenceHelper.recordStaticType(node, staticType);
  -  }
  -
  -  /**
  -   * Return the static type of the given [expression].
  -   *
  -   * TODO(scheglov) this is duplicate
  -   */
  -  DartType _getStaticType2(Expression expression, {bool read = false}) {
  -    DartType type;
  -    if (read) {
  -      type = getReadType(expression, elementTypeProvider: _elementTypeProvider);
  -    } else {
  -      if (expression is SimpleIdentifier && expression.inSetterContext()) {
  -        var element = expression.staticElement;
  -        if (element is PromotableElement) {
  -          // We're writing to the element so ignore promotions.
  -          type = _elementTypeProvider.getVariableType(element);
  -        } else {
  -          type = expression.staticType;
  -        }
  -      } else {
  -        type = expression.staticType;
  -      }
  -    }
  -    if (type == null) {
  -      // TODO(brianwilkerson) Determine the conditions for which the static type
  -      // is null.
  -      return DynamicTypeImpl.instance;
  -    }
  -    return type;
  +  /**
  +   * 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.
  +   *
  +   * TODO(scheglov) this is duplicate
  +   */
  +  DartType _resolveTypeParameter(DartType type) =>
  +      type?.resolveToBound(_typeProvider.objectType);
  +
  +  /**
  +   * Return `true` if we should report an error for the lookup [result] on
  +   * the [type].
  +   *
  +   * TODO(scheglov) this is duplicate
  +   */
  +  bool _shouldReportInvalidMember(DartType type, ResolutionResult result) {
  +    if (result.isNone && type != null && !type.isDynamic) {
  +      if (_typeSystem.isNonNullableByDefault &&
  +          _typeSystem.isPotentiallyNullable(type)) {
  +        return false;
  +      }
  +      return true;
  +    }
  +    return false;
     }
   }
   
  
positive.code:         operator == TokenType.QUESTION_QUESTION_EQ
              ? node.rightHandSide.staticType
              : node.staticType);
    }
  
    void _resolve1(AssignmentExpressionImpl node) {
  
negative.code:     }
    }
  
    void _resolve2(AssignmentExpressionImpl node) {
      TokenType operator = node.operator.type;
      if (operator == TokenType.EQ) {
  