@Override
  public void insertQualifiedName(@NotNull String fqn, @NotNull PsiElement element, @NotNull Editor editor, @NotNull Project project) {
    final PsiDocumentManager documentManager = PsiDocumentManager.getInstance(project);
    Document document = editor.getDocument();

    final PsiFile file = documentManager.getPsiFile(document);

    final int offset = editor.getCaretModel().getOffset();
    PsiElement elementAtCaret = file.findElementAt(offset);

    fqn = fqn.replace('#', '.');
    String toInsert;
    String suffix = "";

    if (!(element instanceof PsiMember)) {
      toInsert = fqn;
    }
    else if (elementAtCaret != null && (element instanceof PsiMethod || element instanceof PsiField) && PsiUtil.isInsideJavadocComment(elementAtCaret)) {
      // use fqn#methodName(ParamType)
      PsiMember member = (PsiMember)element;
      PsiClass aClass = member.getContainingClass();
      String className = aClass == null ? "" : aClass.getQualifiedName();
      toInsert = className == null ? "" : className;
      if (toInsert.length() != 0) toInsert += "#";
      toInsert += member.getName();
      if (member instanceof PsiMethod) {
        toInsert += getParameterString((PsiMethod)member, true);
      }
    }
    else if (elementAtCaret == null ||
             PsiTreeUtil.getNonStrictParentOfType(elementAtCaret, PsiLiteralExpression.class, PsiComment.class) != null ||
             PsiTreeUtil.getNonStrictParentOfType(elementAtCaret, PsiJavaFile.class) == null ||
             isEndOfLineComment(elementAtCaret)) {
      toInsert = fqn;
    }
    else {
      PsiMember targetElement = (PsiMember)element;

      toInsert = targetElement.getName();
      if (targetElement instanceof PsiMethod) {
        suffix = "()";
        int parenthIdx = fqn.indexOf('(');
        if (parenthIdx >= 0) {
          fqn = fqn.substring(0, parenthIdx);
        }

        if (((PsiMethod)targetElement).isConstructor()) {
          targetElement = targetElement.getContainingClass();
          fqn = StringUtil.getPackageName(fqn);
        }
      }
      else if (targetElement instanceof PsiClass) {
        if (isAfterNew(file, elementAtCaret)) {
          // pasting reference to default constructor of the class after new
          suffix = "()";
        }
        else if (toInsert != null && toInsert.length() != 0 && Character.isJavaIdentifierPart(toInsert.charAt(toInsert.length()-1)) && Character.isJavaIdentifierPart(elementAtCaret.getText().charAt(0))) {
          //separate identifiers with space
          suffix = " ";
        }
      }
      final PsiElementFactory factory = JavaPsiFacade.getElementFactory(project);
      final PsiExpression expression;
      try {
        expression = factory.createExpressionFromText(toInsert + suffix, elementAtCaret);
        final PsiReferenceExpression referenceExpression = expression instanceof PsiMethodCallExpression
                                                           ? ((PsiMethodCallExpression)expression).getMethodExpression()
                                                           : expression instanceof PsiReferenceExpression
                                                             ? (PsiReferenceExpression)expression
                                                             : null;
        if (referenceExpression == null || !referenceExpression.isValid()) {
          toInsert = fqn;
        }
        else if (!isReferencedTo(referenceExpression, targetElement)) {
          try {
            referenceExpression.bindToElement(targetElement);
          }
          catch (IncorrectOperationException e) {
            // failed to bind
          }
          if (!referenceExpression.isValid() || !isReferencedTo(referenceExpression, targetElement)) {
            toInsert = fqn;
          }
        }
      }
      catch (IncorrectOperationException ignored) {}
    }
    if (toInsert == null) toInsert = "";

    document.insertString(offset, toInsert+suffix);
    documentManager.commitAllDocuments();
    int endOffset = offset + toInsert.length() + suffix.length();
    RangeMarker rangeMarker = document.createRangeMarker(endOffset, endOffset);
    elementAtCaret = file.findElementAt(offset);

    if (elementAtCaret != null && elementAtCaret.isValid()) {
      try {
        shortenReference(elementAtCaret);
      }
      catch (IncorrectOperationException e) {
        LOG.error(e);
      }
    }
    CodeInsightUtilCore.forcePsiPostprocessAndRestoreElement(file);
    try {
      CodeStyleManager.getInstance(project).adjustLineIndent(file, offset);
    }
    catch (IncorrectOperationException e) {
      LOG.error(e);
    }

    int caretOffset = rangeMarker.getEndOffset();
    if (element instanceof PsiMethod && !((PsiMethod)element).getParameterList().isEmpty() && StringUtil.endsWithChar(suffix,')')) {
      caretOffset --;
    }
    editor.getCaretModel().moveToOffset(caretOffset);
  }
@Override
  public void insertQualifiedName(@NotNull String fqn, @NotNull PsiElement element, @NotNull Editor editor, @NotNull Project project)