@Override
  @Nullable
  public Pair<PsiElement, TextRange> findExpression(PsiElement element, boolean allowMethodCalls) {
    PsiElement expression = null;
    PsiElement parent = element.getParent();
    if (parent instanceof PsiLiteralExpression) {
      if (((PsiLiteralExpression)parent).isTextBlock() && !allowMethodCalls) {
        return null;
      }
      element = parent;
      parent = parent.getParent();
    }
    else if (parent instanceof PsiLambdaExpression) {
      element = parent;
      parent = parent.getParent();
    }
    if (parent instanceof PsiVariable) {
      expression = element;
    }
    else if (parent instanceof PsiReferenceExpression) {
      final PsiElement pparent = parent.getParent();
      if (parent instanceof PsiMethodReferenceExpression ||
          (pparent instanceof PsiCallExpression && ((PsiCallExpression)pparent).getArgumentList() != null)) { // skip arrays
        parent = pparent;
      }
      else if (pparent instanceof PsiReferenceExpression) {
        if (((PsiReferenceExpression)parent).resolve() instanceof PsiClass) {
          return findExpression(pparent, allowMethodCalls);
        }
      }
      if (allowMethodCalls || !DebuggerUtils.hasSideEffects(parent)) {
        expression = parent;
      }
    }
    else if (parent instanceof PsiThisExpression) {
      expression = parent;
    }
    else if (parent instanceof PsiExpressionList && parent.getParent() instanceof PsiMethodCallExpression) {
      if (allowMethodCalls) {
        expression = parent.getParent();
      }
    }
    else if (parent instanceof PsiArrayInitializerExpression) {
      if (allowMethodCalls) {
        PsiNewExpression newExpr = PsiTreeUtil.getParentOfType(element, PsiNewExpression.class);
        if (newExpr != null) {
          expression = newExpr;
        }
      }
    }
    else if (parent instanceof PsiExpression &&
             !(parent instanceof PsiNewExpression) &&
             !(parent instanceof PsiLambdaExpression)) {
      if (allowMethodCalls || !DebuggerUtils.hasSideEffects(parent)) {
        expression = parent;
      }
    }
    else {
      PsiElement castExpr = PsiTreeUtil.getParentOfType(element, PsiTypeCastExpression.class);
      if (castExpr != null) {
        if (allowMethodCalls || !DebuggerUtils.hasSideEffects(castExpr)) {
          expression = castExpr;
        }
      }
      else if (allowMethodCalls) {
        PsiElement e = PsiTreeUtil.getParentOfType(element, PsiVariable.class, PsiExpression.class, PsiMethod.class);
        if (e instanceof PsiNewExpression) {
          if (((PsiNewExpression)e).getAnonymousClass() == null) {
            expression = e;
          }
        }
      }
    }

    if (expression != null) {
      try {
        PsiElement context = element;
        if (parent instanceof PsiParameter) {
          try {
            context = ((PsiMethod)((PsiParameter)parent).getDeclarationScope()).getBody();
          }
          catch (Throwable ignored) {
          }
        }
        else {
          while (context != null && !(context instanceof PsiStatement) && !(context instanceof PsiClass)) {
            context = context.getParent();
          }
        }
        TextRange textRange = expression.getTextRange();
        PsiElement psiExpression = JavaPsiFacade.getElementFactory(expression.getProject())
          .createExpressionFromText(expression.getText(), context);
        return Pair.create(psiExpression, textRange);
      }
      catch (IncorrectOperationException e) {
        LOG.debug(e);
      }
    }
    return null;
  }
@Override
  @Nullable
  public Pair<PsiElement, TextRange> findExpression(PsiElement element, boolean allowMethodCalls)