anchor.diff:      // ignore: avoid_returning_null
       return null;
     }
  +
  +  bool _isLengthAccess(Expression operand) {
  +    var node = _drillDownTo(operand, ignoreParens: true, ignoreAs: true);
  +    if (node == null) {
  +      return false;
  +    }
  +
  +    SimpleIdentifier? identifier;
  +    InterfaceType? type;
  +
  +    if (node is PrefixedIdentifier) {
  +      identifier = node.identifier;
  +      var operandType = node.prefix.staticType;
  +      if (operandType is InterfaceType) {
  +        type = operandType;
  +      }
  +    } else if (node is PropertyAccess) {
  +      identifier = node.propertyName;
  +      var parentType = node.target?.staticType;
  +      if (parentType is InterfaceType) {
  +        type = parentType;
  +      }
  +    }
  +
  +    if (identifier?.name != 'length') {
  +      return false;
  +    }
  +
  +    // Should be subtype of Iterable, Map or String.
  +    if (type == null ||
  +        !DartTypeUtilities.implementsInterface(type, 'Iterable', 'dart.core') &&
  +            !DartTypeUtilities.implementsInterface(type, 'Map', 'dart.core') &&
  +            !type.isDartCoreString) {
  +      return false;
  +    }
  +
  +    return true;
  +  }
   }
  
positive.code: 
      // Or in a const context.
      // See: https://github.com/dart-lang/linter/issues/1719
      if (binaryExpression.inConstantContext) {
        return;
      }
  
      var operator = binaryExpression.operator;
  
      // Comparing constants with length.
      var value = _getIntValue(binaryExpression.rightOperand);
  
      if (value != null) {
        // Constant is on right side of comparison operator.
        if (value == 0) {
          if (operator.type == TokenType.EQ_EQ ||
              operator.type == TokenType.LT_EQ) {
            rule.reportLintWithDescription(binaryExpression, useIsEmpty);
          } else if (operator.type == TokenType.GT ||
              operator.type == TokenType.BANG_EQ) {
            rule.reportLintWithDescription(binaryExpression, useIsNotEmpty);
          } else if (operator.type == TokenType.LT) {
            rule.reportLintWithDescription(binaryExpression, alwaysFalse);
          } else if (operator.type == TokenType.GT_EQ) {
            rule.reportLintWithDescription(binaryExpression, alwaysTrue);
          }
        } else if (value == 1) {
          // 'length >= 1' is same as 'isNotEmpty',
          // and 'length < 1' is same as 'isEmpty'
          if (operator.type == TokenType.GT_EQ) {
            rule.reportLintWithDescription(binaryExpression, useIsNotEmpty);
          } else if (operator.type == TokenType.LT) {
            rule.reportLintWithDescription(binaryExpression, useIsEmpty);
          }
        } else if (value < 0) {
          // 'length' is always >= 0, so comparing with negative makes no sense.
          if (operator.type == TokenType.EQ_EQ ||
              operator.type == TokenType.LT_EQ ||
              operator.type == TokenType.LT) {
            rule.reportLintWithDescription(binaryExpression, alwaysFalse);
          } else if (operator.type == TokenType.BANG_EQ ||
              operator.type == TokenType.GT_EQ ||
              operator.type == TokenType.GT) {
            rule.reportLintWithDescription(binaryExpression, alwaysTrue);
          }
        }
        return;
      }
  
      value = _getIntValue(binaryExpression.leftOperand);
  
      // ignore: invariant_booleans
      if (value != null) {
        // Constant is on left side of comparison operator.
        if (value == 0) {
          if (operator.type == TokenType.EQ_EQ ||
              operator.type == TokenType.GT_EQ) {
            rule.reportLintWithDescription(binaryExpression, useIsEmpty);
          } else if (operator.type == TokenType.LT ||
              operator.type == TokenType.BANG_EQ) {
            rule.reportLintWithDescription(binaryExpression, useIsNotEmpty);
          } else if (operator.type == TokenType.GT) {
            rule.reportLintWithDescription(binaryExpression, alwaysFalse);
          } else if (operator.type == TokenType.LT_EQ) {
            rule.reportLintWithDescription(binaryExpression, alwaysTrue);
          }
        } else if (value == 1) {
          // '1 <= length' is same as 'isNotEmpty',
          // and '1 > length' is same as 'isEmpty'
          if (operator.type == TokenType.LT_EQ) {
            rule.reportLintWithDescription(binaryExpression, useIsNotEmpty);
          } else if (operator.type == TokenType.GT) {
            rule.reportLintWithDescription(binaryExpression, useIsEmpty);
          }
        } else if (value < 0) {
          // 'length' is always >= 0, so comparing with negative makes no sense.
          if (operator.type == TokenType.EQ_EQ ||
              operator.type == TokenType.GT_EQ ||
              operator.type == TokenType.GT) {
            rule.reportLintWithDescription(binaryExpression, alwaysFalse);
          } else if (operator.type == TokenType.BANG_EQ ||
              operator.type == TokenType.LT_EQ ||
              operator.type == TokenType.LT) {
            rule.reportLintWithDescription(binaryExpression, alwaysTrue);
          }
        }
      }
    }
  
    /// Returns the value of an [IntegerLiteral] or [PrefixExpression] with a
  
negative.code:   void registerNodeProcessors(
        NodeLintRegistry registry, LinterContext context) {
      var visitor = _Visitor(this, context);
      registry.addBinaryExpression(this, visitor);
    }
  
    void reportLintWithDescription(AstNode node, String description) {
      reporter.reportErrorForNode(_LintCode(name, description), node, []);
    }
  }
  
  