@Override
    public void visitBinaryExpression(@NotNull GrBinaryExpression expression) {
      final IElementType type = expression.getOperationTokenType();
      final GrExpression left = expression.getLeftOperand();
      final GrExpression right = expression.getRightOperand();

      final GrExpression other = myExpression == left ? right : left;
      final PsiType otherType = other != null ? other.getType() : null;

      if (otherType == null) return;

      final GroovyResolveResult[] callVariants = PsiUtilKt.multiResolve(expression);
      if (myExpression == left || callVariants.length == 0) {
        if (type == GroovyTokenTypes.mPLUS && otherType.equalsToText(CommonClassNames.JAVA_LANG_STRING)) {
          final PsiClassType obj = TypesUtil.getJavaLangObject(expression);
          myResult = createSimpleSubTypeResult(obj);
        }
        else if (type == GroovyTokenTypes.mREGEX_FIND || type == GroovyTokenTypes.mREGEX_MATCH) {
          final PsiClassType string = TypesUtil.createType(CommonClassNames.JAVA_LANG_STRING, expression);
          myResult = createSimpleSubTypeResult(string);
        }
        else {
          myResult = createSimpleSubTypeResult(otherType);
        }
      }
      else { //myExpression == right
        processCallVariants(expression, callVariants, GrNamedArgument.EMPTY_ARRAY, new GrExpression[]{myExpression},
                            GrClosableBlock.EMPTY_ARRAY);
      }
    }
@Override
    public void visitBinaryExpression(@NotNull GrBinaryExpression expression)