@Nullable
  @Contract("null -> null")
  public Object evaluate(@Nullable PyExpression expression) {
    if (expression == null || myVisited.contains(expression)) {
      return null;
    }
    PyUtil.verboseOnly(() -> PyPsiUtils.assertValid(expression));
    myVisited.add(expression);
    if (expression instanceof PyParenthesizedExpression) {
      return evaluate(((PyParenthesizedExpression)expression).getContainedExpression());
    }
    else if (expression instanceof PySequenceExpression) {
      return evaluateSequence((PySequenceExpression)expression);
    }
    final Boolean bool = evaluateBoolean(expression);
    if (bool != null) {
      return bool;
    }
    if (expression instanceof PyCallExpression) {
      return evaluateCall((PyCallExpression)expression);
    }
    else if (expression instanceof PyReferenceExpression) {
      return evaluateReference((PyReferenceExpression)expression);
    }
    else if (expression instanceof PyStringLiteralExpression) {
      return ((PyStringLiteralExpression)expression).getStringValue();
    }
    else if (expression instanceof PyBinaryExpression) {
      return evaluateBinary((PyBinaryExpression)expression);
    }
    else if (expression instanceof PyNumericLiteralExpression) {
      return evaluateNumeric((PyNumericLiteralExpression)expression);
    }
    else if (expression instanceof PyPrefixExpression) {
      return evaluatePrefix((PyPrefixExpression)expression);
    }
    return null;
  }
@Nullable
  @Contract("null -> null")
  public Object evaluate(@Nullable PyExpression expression)