public static boolean canAddLineBreakpoint(Project project, final Document document, final int lineIndex) {
    if (lineIndex < 0 || lineIndex >= document.getLineCount()) {
      return false;
    }
    final BreakpointManager breakpointManager = DebuggerManagerEx.getInstanceEx(project).getBreakpointManager();
    final LineBreakpoint breakpointAtLine = breakpointManager.findBreakpoint(document, document.getLineStartOffset(lineIndex), CATEGORY);
    if (breakpointAtLine != null) {
      // there already exists a line breakpoint at this line
      return false;
    }
    PsiDocumentManager.getInstance(project).commitDocument(document);

    final boolean[] canAdd = new boolean[]{false};
    XDebuggerUtil.getInstance().iterateLine(project, document, lineIndex, element -> {
      if ((element instanceof PsiWhiteSpace) || (PsiTreeUtil.getParentOfType(element, PsiComment.class, false) != null)) {
        return true;
      }
      PsiElement child = element;
      while (element != null) {

        final int offset = element.getTextOffset();
        if (offset >= 0) {
          if (document.getLineNumber(offset) != lineIndex) {
            break;
          }
        }
        child = element;
        element = element.getParent();
      }

      if (child instanceof PsiMethod && child.getTextRange().getEndOffset() >= document.getLineEndOffset(lineIndex)) {
        PsiCodeBlock body = ((PsiMethod)child).getBody();
        if (body == null) {
          canAdd[0] = false;
        }
        else {
          PsiStatement[] statements = body.getStatements();
          canAdd[0] = statements.length > 0 && document.getLineNumber(statements[0].getTextOffset()) == lineIndex;
        }
      }
      else {
        canAdd[0] = true;
      }
      return false;
    });

    return canAdd[0];
  }
public static boolean canAddLineBreakpoint(Project project, final Document document, final int lineIndex)